1 /* 2 * Copyright 2005-2022 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Augustin Cavalier <waddlesplash> 7 * DarkWyrm <bpmagic@columbus.rr.com> 8 * René Gollent 9 * John Scipione, jscipione@gmail.com 10 * Wim van der Meer <WPJvanderMeer@gmail.com> 11 */ 12 13 14 #include <ctype.h> 15 #include <stdio.h> 16 #include <time.h> 17 #include <unistd.h> 18 19 #include <algorithm> 20 #include <map> 21 #include <string> 22 23 #include <AboutWindow.h> 24 #include <AppFileInfo.h> 25 #include <Application.h> 26 #include <Bitmap.h> 27 #include <ColorConversion.h> 28 #include <ControlLook.h> 29 #include <DateTimeFormat.h> 30 #include <Dragger.h> 31 #include <DurationFormat.h> 32 #include <File.h> 33 #include <FindDirectory.h> 34 #include <Font.h> 35 #include <fs_attr.h> 36 #include <LayoutBuilder.h> 37 #include <MessageRunner.h> 38 #include <Messenger.h> 39 #include <NumberFormat.h> 40 #include <ObjectList.h> 41 #include <OS.h> 42 #include <Path.h> 43 #include <PathFinder.h> 44 #include <PopUpMenu.h> 45 #include <Resources.h> 46 #include <Screen.h> 47 #include <ScrollView.h> 48 #include <String.h> 49 #include <StringFormat.h> 50 #include <StringList.h> 51 #include <StringView.h> 52 #include <TextView.h> 53 #include <TranslationUtils.h> 54 #include <TranslatorFormats.h> 55 #include <View.h> 56 #include <ViewPrivate.h> 57 #include <Volume.h> 58 #include <VolumeRoster.h> 59 #include <Window.h> 60 #include <WindowPrivate.h> 61 62 #include <AppMisc.h> 63 #include <AutoDeleter.h> 64 #include <AutoDeleterPosix.h> 65 #include <cpu_type.h> 66 #include <parsedate.h> 67 #include <system_revision.h> 68 69 #include <Catalog.h> 70 #include <Language.h> 71 #include <Locale.h> 72 #include <LocaleRoster.h> 73 74 #include "HyperTextActions.h" 75 #include "HyperTextView.h" 76 #include "Utilities.h" 77 78 #include "Credits.h" 79 80 81 #ifndef LINE_MAX 82 #define LINE_MAX 2048 83 #endif 84 85 86 #undef B_TRANSLATION_CONTEXT 87 #define B_TRANSLATION_CONTEXT "AboutWindow" 88 89 90 static const char* kSignature = "application/x-vnd.Haiku-About"; 91 92 static const float kWindowWidth = 500.0f; 93 static const float kWindowHeight = 300.0f; 94 95 static const float kSysInfoMinWidth = 163.0f; 96 static const float kSysInfoMinHeight = 193.0f; 97 98 static const int32 kMsgScrollCreditsView = 'mviv'; 99 100 static int ignored_pages(system_info*); 101 static int max_pages(system_info*); 102 static int max_and_ignored_pages(system_info*); 103 static int used_pages(system_info*); 104 105 static const rgb_color kIdealHaikuGreen = { 42, 131, 36, 255 }; 106 static const rgb_color kIdealHaikuOrange = { 255, 69, 0, 255 }; 107 static const rgb_color kIdealHaikuYellow = { 255, 176, 0, 255 }; 108 static const rgb_color kIdealBeOSBlue = { 0, 0, 200, 255 }; 109 static const rgb_color kIdealBeOSRed = { 200, 0, 0, 255 }; 110 111 static const char* kBSDTwoClause = B_TRANSLATE_MARK("BSD (2-clause)"); 112 static const char* kBSDThreeClause = B_TRANSLATE_MARK("BSD (3-clause)"); 113 static const char* kBSDFourClause = B_TRANSLATE_MARK("BSD (4-clause)"); 114 static const char* kGPLv2 = B_TRANSLATE_MARK("GNU GPL v2"); 115 static const char* kGPLv3 = B_TRANSLATE_MARK("GNU GPL v3"); 116 static const char* kLGPLv2 = B_TRANSLATE_MARK("GNU LGPL v2"); 117 static const char* kLGPLv21 = B_TRANSLATE_MARK("GNU LGPL v2.1"); 118 #if 0 119 static const char* kPublicDomain = B_TRANSLATE_MARK("Public Domain"); 120 #endif 121 #ifdef __i386__ 122 static const char* kIntel2xxxFirmware = B_TRANSLATE_MARK("Intel (2xxx firmware)"); 123 static const char* kIntelFirmware = B_TRANSLATE_MARK("Intel WiFi Firmware"); 124 static const char* kMarvellFirmware = B_TRANSLATE_MARK("Marvell (firmware)"); 125 static const char* kRalinkFirmware = B_TRANSLATE_MARK("Ralink WiFi Firmware"); 126 #endif 127 128 129 // #pragma mark - TranslationComparator function 130 131 132 static int 133 TranslationComparator(const void* left, const void* right) 134 { 135 const Translation* leftTranslation = *(const Translation**)left; 136 const Translation* rightTranslation = *(const Translation**)right; 137 138 BLanguage* language; 139 BString leftName; 140 if (BLocaleRoster::Default()->GetLanguage(leftTranslation->languageCode, 141 &language) == B_OK) { 142 language->GetName(leftName); 143 delete language; 144 } else 145 leftName = leftTranslation->languageCode; 146 147 BString rightName; 148 if (BLocaleRoster::Default()->GetLanguage(rightTranslation->languageCode, 149 &language) == B_OK) { 150 language->GetName(rightName); 151 delete language; 152 } else 153 rightName = rightTranslation->languageCode; 154 155 BCollator collator; 156 BLocale::Default()->GetCollator(&collator); 157 return collator.Compare(leftName.String(), rightName.String()); 158 } 159 160 161 // #pragma mark - class definitions 162 163 164 class AboutApp : public BApplication { 165 public: 166 AboutApp(); 167 void MessageReceived(BMessage* message); 168 }; 169 170 171 class AboutView; 172 173 class AboutWindow : public BWindow { 174 public: 175 AboutWindow(); 176 177 virtual bool QuitRequested(); 178 179 AboutView* fAboutView; 180 }; 181 182 183 class LogoView : public BView { 184 public: 185 LogoView(); 186 virtual ~LogoView(); 187 188 virtual BSize MinSize(); 189 virtual BSize MaxSize(); 190 191 virtual void Draw(BRect updateRect); 192 193 private: 194 BBitmap* fLogo; 195 }; 196 197 198 class CropView : public BView { 199 public: 200 CropView(BView* target, int32 left, int32 top, 201 int32 right, int32 bottom); 202 virtual ~CropView(); 203 204 virtual BSize MinSize(); 205 virtual BSize MaxSize(); 206 207 virtual void DoLayout(); 208 209 private: 210 BView* fTarget; 211 int32 fCropLeft; 212 int32 fCropTop; 213 int32 fCropRight; 214 int32 fCropBottom; 215 }; 216 217 218 class SysInfoView : public BView { 219 public: 220 SysInfoView(); 221 SysInfoView(BMessage* archive); 222 virtual ~SysInfoView(); 223 224 virtual status_t Archive(BMessage* archive, bool deep = true) const; 225 static BArchivable* Instantiate(BMessage* archive); 226 227 virtual void AttachedToWindow(); 228 virtual void AllAttached(); 229 virtual void Draw(BRect); 230 virtual void MessageReceived(BMessage* message); 231 virtual void Pulse(); 232 233 void CacheInitialSize(); 234 235 float MinWidth() const { return fCachedMinWidth; }; 236 float MinHeight() const { return fCachedMinHeight; }; 237 238 private: 239 void _AdjustColors(); 240 void _AdjustTextColors() const; 241 rgb_color _DesktopTextColor(int32 workspace = -1) const; 242 bool _OnDesktop() const; 243 244 BStringView* _CreateLabel(const char*, const char*); 245 void _UpdateLabel(BStringView*); 246 BStringView* _CreateSubtext(const char*, const char*); 247 void _UpdateSubtext(BStringView*); 248 void _UpdateText(BTextView*); 249 void _CreateDragger(); 250 251 float _BaseWidth(); 252 float _BaseHeight(); 253 254 BString _GetOSVersion(); 255 BString _GetABIVersion(); 256 BString _GetCPUCount(system_info*); 257 BString _GetCPUInfo(); 258 BString _GetCPUFrequency(); 259 BString _GetRamSize(system_info*); 260 BString _GetRamUsage(system_info*); 261 BString _GetKernelDateTime(system_info*); 262 BString _GetUptime(); 263 264 float _UptimeHeight(); 265 266 private: 267 rgb_color fDesktopTextColor; 268 269 BStringView* fVersionLabelView; 270 BStringView* fVersionInfoView; 271 BStringView* fCPULabelView; 272 BStringView* fCPUInfoView; 273 BStringView* fMemSizeView; 274 BStringView* fMemUsageView; 275 BStringView* fKernelDateTimeView; 276 BTextView* fUptimeView; 277 278 BDragger* fDragger; 279 280 BNumberFormat fNumberFormat; 281 282 float fCachedBaseWidth; 283 float fCachedMinWidth; 284 float fCachedBaseHeight; 285 float fCachedMinHeight; 286 287 bool fIsReplicant : 1; 288 289 static const uint8 kLabelCount = 5; 290 static const uint8 kSubtextCount = 5; 291 }; 292 293 294 class AboutView : public BView { 295 public: 296 AboutView(); 297 ~AboutView(); 298 299 virtual void AttachedToWindow(); 300 virtual void Pulse(); 301 virtual void MessageReceived(BMessage* message); 302 virtual void MouseDown(BPoint where); 303 304 void AddCopyrightEntry(const char* name, 305 const char* text, 306 const StringVector& licenses, 307 const StringVector& sources, 308 const char* url); 309 void AddCopyrightEntry(const char* name, 310 const char* text, const char* url = NULL); 311 void PickRandomHaiku(); 312 313 private: 314 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 315 316 void _CreateScrollRunner(); 317 LogoView* _CreateLogoView(); 318 SysInfoView* _CreateSysInfoView(); 319 CropView* _CreateCreditsView(); 320 status_t _GetLicensePath(const char* license, 321 BPath& path); 322 void _AddCopyrightsFromAttribute(); 323 void _AddPackageCredit(const PackageCredit& package); 324 void _AddPackageCreditEntries(); 325 326 327 private: 328 LogoView* fLogoView; 329 SysInfoView* fSysInfoView; 330 HyperTextView* fCreditsView; 331 332 bigtime_t fLastActionTime; 333 BMessageRunner* fScrollRunner; 334 335 float fCachedMinWidth; 336 float fCachedMinHeight; 337 338 PackageCreditMap fPackageCredits; 339 340 private: 341 rgb_color fTextColor; 342 rgb_color fLinkColor; 343 rgb_color fHaikuOrangeColor; 344 rgb_color fHaikuGreenColor; 345 rgb_color fHaikuYellowColor; 346 rgb_color fBeOSRedColor; 347 rgb_color fBeOSBlueColor; 348 }; 349 350 351 // #pragma mark - AboutApp 352 353 354 AboutApp::AboutApp() 355 : 356 BApplication(kSignature) 357 { 358 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("AboutSystem"); 359 360 AboutWindow* window = new(std::nothrow) AboutWindow(); 361 if (window != NULL) 362 window->Show(); 363 } 364 365 366 void 367 AboutApp::MessageReceived(BMessage* message) 368 { 369 switch (message->what) { 370 case B_SILENT_RELAUNCH: 371 WindowAt(0)->Activate(); 372 break; 373 } 374 375 BApplication::MessageReceived(message); 376 } 377 378 379 // #pragma mark - AboutWindow 380 381 382 AboutWindow::AboutWindow() 383 : 384 BWindow(BRect(0, 0, kWindowWidth, kWindowHeight), 385 B_TRANSLATE("About this system"), B_TITLED_WINDOW, 386 B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE) 387 { 388 SetLayout(new BGroupLayout(B_VERTICAL, 0)); 389 390 fAboutView = new AboutView(); 391 AddChild(fAboutView); 392 393 CenterOnScreen(); 394 } 395 396 397 bool 398 AboutWindow::QuitRequested() 399 { 400 be_app->PostMessage(B_QUIT_REQUESTED); 401 return true; 402 } 403 404 405 #undef B_TRANSLATION_CONTEXT 406 #define B_TRANSLATION_CONTEXT "AboutView" 407 408 409 // #pragma mark - LogoView 410 411 412 LogoView::LogoView() 413 : 414 BView("logo", B_WILL_DRAW), 415 fLogo(BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png")) 416 { 417 // Set view color to panel background color when fLogo is NULL 418 // to prevent a white pixel from being drawn. 419 if (fLogo != NULL) 420 SetViewColor(255, 255, 255); 421 else 422 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 423 } 424 425 426 LogoView::~LogoView() 427 { 428 delete fLogo; 429 } 430 431 432 BSize 433 LogoView::MinSize() 434 { 435 if (fLogo == NULL) 436 return BSize(0, 0); 437 438 return BSize(fLogo->Bounds().Width(), fLogo->Bounds().Height()); 439 } 440 441 442 BSize 443 LogoView::MaxSize() 444 { 445 if (fLogo == NULL) 446 return BSize(0, 0); 447 448 return BSize(B_SIZE_UNLIMITED, fLogo->Bounds().Height()); 449 } 450 451 452 void 453 LogoView::Draw(BRect updateRect) 454 { 455 if (fLogo == NULL) 456 return; 457 458 DrawBitmap(fLogo, BPoint((Bounds().Width() - fLogo->Bounds().Width()) / 2, 0)); 459 } 460 461 462 // #pragma mark - CropView 463 464 465 CropView::CropView(BView* target, int32 left, int32 top, int32 right, 466 int32 bottom) 467 : 468 BView("crop view", 0), 469 fTarget(target), 470 fCropLeft(left), 471 fCropTop(top), 472 fCropRight(right), 473 fCropBottom(bottom) 474 { 475 AddChild(target); 476 } 477 478 479 CropView::~CropView() 480 { 481 } 482 483 484 BSize 485 CropView::MinSize() 486 { 487 if (fTarget == NULL) 488 return BSize(); 489 490 BSize size = fTarget->MinSize(); 491 if (size.width != B_SIZE_UNSET) 492 size.width -= fCropLeft + fCropRight; 493 if (size.height != B_SIZE_UNSET) 494 size.height -= fCropTop + fCropBottom; 495 496 return size; 497 } 498 499 500 BSize 501 CropView::MaxSize() 502 { 503 if (fTarget == NULL) 504 return BSize(); 505 506 BSize size = fTarget->MaxSize(); 507 if (size.width != B_SIZE_UNSET) 508 size.width -= fCropLeft + fCropRight; 509 if (size.height != B_SIZE_UNSET) 510 size.height -= fCropTop + fCropBottom; 511 512 return size; 513 } 514 515 516 void 517 CropView::DoLayout() 518 { 519 BView::DoLayout(); 520 521 if (fTarget == NULL) 522 return; 523 524 fTarget->MoveTo(-fCropLeft, -fCropTop); 525 fTarget->ResizeTo(Bounds().Width() + fCropLeft + fCropRight, 526 Bounds().Height() + fCropTop + fCropBottom); 527 } 528 529 530 // #pragma mark - SysInfoView 531 532 533 SysInfoView::SysInfoView() 534 : 535 BView("AboutSystem", B_WILL_DRAW | B_PULSE_NEEDED), 536 fVersionLabelView(NULL), 537 fVersionInfoView(NULL), 538 fCPULabelView(NULL), 539 fCPUInfoView(NULL), 540 fMemSizeView(NULL), 541 fMemUsageView(NULL), 542 fKernelDateTimeView(NULL), 543 fUptimeView(NULL), 544 fDragger(NULL), 545 fCachedBaseWidth(kSysInfoMinWidth), 546 fCachedMinWidth(kSysInfoMinWidth), 547 fCachedBaseHeight(kSysInfoMinHeight), 548 fCachedMinHeight(kSysInfoMinHeight), 549 fIsReplicant(false) 550 { 551 // Begin construction of system information controls. 552 system_info sysInfo; 553 get_system_info(&sysInfo); 554 555 // Create all the various labels for system infomation. 556 557 // OS Version / ABI 558 fVersionLabelView = _CreateLabel("oslabel", _GetOSVersion()); 559 fVersionInfoView = _CreateSubtext("ostext", _GetABIVersion()); 560 561 // CPU count, type and clock speed 562 fCPULabelView = _CreateLabel("cpulabel", _GetCPUCount(&sysInfo)); 563 fCPUInfoView = _CreateSubtext("cputext", _GetCPUInfo()); 564 565 // Memory size and usage 566 fMemSizeView = _CreateLabel("memlabel", _GetRamSize(&sysInfo)); 567 fMemUsageView = _CreateSubtext("ramusagetext", _GetRamUsage(&sysInfo)); 568 569 // Kernel build time/date 570 BStringView* kernelLabel = _CreateLabel("kernellabel", B_TRANSLATE("Kernel:")); 571 fKernelDateTimeView = _CreateSubtext("kerneltext", _GetKernelDateTime(&sysInfo)); 572 573 // Uptime 574 BStringView* uptimeLabel = _CreateLabel("uptimelabel", B_TRANSLATE("Time running:")); 575 fUptimeView = new BTextView("uptimetext"); 576 fUptimeView->SetText(_GetUptime()); 577 _UpdateText(fUptimeView); 578 579 // Now comes the layout 580 581 const float offset = be_control_look->DefaultLabelSpacing(); 582 const float inset = offset; 583 584 SetLayout(new BGroupLayout(B_VERTICAL, 0)); 585 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 586 // Version: 587 .Add(fVersionLabelView) 588 .Add(fVersionInfoView) 589 .AddStrut(offset) 590 // Processors: 591 .Add(fCPULabelView) 592 .Add(fCPUInfoView) 593 .AddStrut(offset) 594 // Memory: 595 .Add(fMemSizeView) 596 .Add(fMemUsageView) 597 .AddStrut(offset) 598 // Kernel: 599 .Add(kernelLabel) 600 .Add(fKernelDateTimeView) 601 .AddStrut(offset) 602 // Time running: 603 .Add(uptimeLabel) 604 .Add(fUptimeView) 605 .AddGlue() 606 .SetInsets(inset) 607 .End(); 608 609 _CreateDragger(); 610 } 611 612 613 SysInfoView::SysInfoView(BMessage* archive) 614 : 615 BView(archive), 616 fVersionLabelView(NULL), 617 fVersionInfoView(NULL), 618 fCPULabelView(NULL), 619 fCPUInfoView(NULL), 620 fMemSizeView(NULL), 621 fMemUsageView(NULL), 622 fKernelDateTimeView(NULL), 623 fUptimeView(NULL), 624 fDragger(NULL), 625 fCachedBaseWidth(kSysInfoMinWidth), 626 fCachedMinWidth(kSysInfoMinWidth), 627 fCachedBaseHeight(kSysInfoMinHeight), 628 fCachedMinHeight(kSysInfoMinHeight), 629 fIsReplicant(true) 630 { 631 BLayout* layout = GetLayout(); 632 int32 itemCount = layout->CountItems() - 1; 633 // leave out dragger 634 635 system_info sysInfo; 636 get_system_info(&sysInfo); 637 638 for (int32 index = 0; index < itemCount; index++) { 639 BView* view = layout->ItemAt(index)->View(); 640 if (view == NULL) 641 continue; 642 643 BString name(view->Name()); 644 if (name == "uptimetext") { 645 fUptimeView = dynamic_cast<BTextView*>(view); 646 _UpdateText(fUptimeView); 647 } else if (name.IEndsWith("text")) { 648 _UpdateSubtext(dynamic_cast<BStringView*>(view)); 649 if (name == "ostext") 650 fVersionInfoView = dynamic_cast<BStringView*>(view); 651 else if (name == "cputext") 652 fCPUInfoView = dynamic_cast<BStringView*>(view); 653 else if (name == "ramusagetext") 654 fMemUsageView = dynamic_cast<BStringView*>(view); 655 else if (name == "kerneltext") 656 fKernelDateTimeView = dynamic_cast<BStringView*>(view); 657 } else if (name.IEndsWith("label")) { 658 _UpdateLabel(dynamic_cast<BStringView*>(view)); 659 if (name == "oslabel") 660 fVersionLabelView = dynamic_cast<BStringView*>(view); 661 else if (name == "cpulabel") 662 fCPULabelView = dynamic_cast<BStringView*>(view); 663 else if (name == "memlabel") 664 fMemSizeView = dynamic_cast<BStringView*>(view); 665 } 666 } 667 668 // These might have changed since the replicant instance was created; 669 fVersionLabelView->SetText(_GetOSVersion()); 670 fVersionInfoView->SetText(_GetABIVersion()); 671 fCPULabelView->SetText(_GetCPUCount(&sysInfo)); 672 fCPUInfoView->SetText(_GetCPUInfo()); 673 fMemSizeView->SetText(_GetRamSize(&sysInfo)); 674 fMemUsageView->SetText(_GetRamUsage(&sysInfo)); 675 fKernelDateTimeView->SetText(_GetKernelDateTime(&sysInfo)); 676 677 fDragger = dynamic_cast<BDragger*>(ChildAt(0)); 678 } 679 680 681 SysInfoView::~SysInfoView() 682 { 683 } 684 685 686 status_t 687 SysInfoView::Archive(BMessage* archive, bool deep) const 688 { 689 // record inherited class members 690 status_t result = BView::Archive(archive, deep); 691 692 // record app signature for replicant add-on loading 693 if (result == B_OK) 694 result = archive->AddString("add_on", kSignature); 695 696 // record class last 697 if (result == B_OK) 698 result = archive->AddString("class", "SysInfoView"); 699 700 return result; 701 } 702 703 704 BArchivable* 705 SysInfoView::Instantiate(BMessage* archive) 706 { 707 if (!validate_instantiation(archive, "SysInfoView")) 708 return NULL; 709 710 return new SysInfoView(archive); 711 } 712 713 714 void 715 SysInfoView::AttachedToWindow() 716 { 717 BView::AttachedToWindow(); 718 719 Window()->SetPulseRate(500000); 720 DoLayout(); 721 } 722 723 724 void 725 SysInfoView::AllAttached() 726 { 727 BView::AllAttached(); 728 729 if (fIsReplicant) { 730 CacheInitialSize(); 731 // if replicant the parent view doesn't do this for us 732 fDesktopTextColor = _DesktopTextColor(); 733 } 734 735 // Update colors here to override system colors for replicant, 736 // this works when the view is in AboutView too. 737 _AdjustColors(); 738 } 739 740 741 void 742 SysInfoView::CacheInitialSize() 743 { 744 fCachedBaseWidth = _BaseWidth(); 745 // memory size is too wide in Greek, account for this here 746 float insets = be_control_look->DefaultLabelSpacing() * 2; 747 fCachedMinWidth = ceilf(std::max(fCachedBaseWidth, 748 fMemSizeView->StringWidth(fMemSizeView->Text()) + insets)); 749 750 // width is fixed, height can grow in Pulse() 751 fCachedBaseHeight = _BaseHeight(); 752 753 // determine initial line count using current font 754 float lineCount = ceilf(be_plain_font->StringWidth(fUptimeView->Text()) 755 / (fCachedMinWidth - insets)); 756 float uptimeHeight = fUptimeView->LineHeight(0) * lineCount; 757 fCachedMinHeight = fCachedBaseHeight + uptimeHeight; 758 759 // set view size 760 SetExplicitMinSize(BSize(fCachedMinWidth, B_SIZE_UNSET)); 761 SetExplicitMaxSize(BSize(fCachedMinWidth, fCachedMinHeight)); 762 fUptimeView->SetExplicitMaxSize(BSize(fCachedMinWidth - insets, 763 uptimeHeight)); 764 } 765 766 767 void 768 SysInfoView::Draw(BRect updateRect) 769 { 770 BView::Draw(updateRect); 771 772 if (_OnDesktop()) { 773 // stroke a line around the view 774 SetHighColor(fDesktopTextColor); 775 StrokeRect(Bounds()); 776 } 777 } 778 779 780 void 781 SysInfoView::MessageReceived(BMessage* message) 782 { 783 switch (message->what) { 784 case B_COLORS_UPDATED: 785 { 786 if (_OnDesktop()) 787 break; 788 789 if (message->HasColor(ui_color_name(B_PANEL_TEXT_COLOR))) { 790 _AdjustTextColors(); 791 Invalidate(); 792 } 793 794 break; 795 } 796 797 case B_WORKSPACE_ACTIVATED: 798 { 799 if (!_OnDesktop()) 800 break; 801 802 bool active; 803 int32 workspace; 804 if (message->FindBool("active", &active) == B_OK && active 805 && message->FindInt32("workspace", &workspace) == B_OK) { 806 BLayout* layout = GetLayout(); 807 int32 itemCount = layout->CountItems() - 2; 808 // leave out dragger and uptime 809 810 fDesktopTextColor = _DesktopTextColor(workspace); 811 SetHighColor(fDesktopTextColor); 812 813 for (int32 index = 0; index < itemCount; index++) { 814 BView* view = layout->ItemAt(index)->View(); 815 if (view == NULL) 816 continue; 817 818 view->SetDrawingMode(B_OP_ALPHA); 819 view->SetHighColor(fDesktopTextColor); 820 } 821 822 fUptimeView->SetDrawingMode(B_OP_ALPHA); 823 fUptimeView->SetFontAndColor(NULL, 0, &fDesktopTextColor); 824 825 Invalidate(); 826 } 827 828 break; 829 } 830 831 default: 832 BView::MessageReceived(message); 833 break; 834 } 835 } 836 837 838 void 839 SysInfoView::Pulse() 840 { 841 system_info sysInfo; 842 get_system_info(&sysInfo); 843 844 fMemUsageView->SetText(_GetRamUsage(&sysInfo)); 845 fUptimeView->SetText(_GetUptime()); 846 847 float newHeight = fCachedBaseHeight + _UptimeHeight(); 848 float difference = newHeight - fCachedMinHeight; 849 if (difference != 0) { 850 if (_OnDesktop()) { 851 // move view to keep the bottom in place 852 // so that the dragger is not pushed off screen 853 ResizeBy(0, difference); 854 MoveBy(0, -difference); 855 Invalidate(); 856 } 857 fCachedMinHeight = newHeight; 858 } 859 860 SetExplicitMinSize(BSize(fCachedMinWidth, B_SIZE_UNSET)); 861 SetExplicitMaxSize(BSize(fCachedMinWidth, fCachedMinHeight)); 862 } 863 864 865 void 866 SysInfoView::_AdjustColors() 867 { 868 if (_OnDesktop()) { 869 // SetColor 870 SetFlags(Flags() | B_TRANSPARENT_BACKGROUND); 871 SetDrawingMode(B_OP_ALPHA); 872 873 SetViewColor(B_TRANSPARENT_COLOR); 874 SetLowColor(B_TRANSPARENT_COLOR); 875 SetHighColor(fDesktopTextColor); 876 } else { 877 // SetUIColor 878 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 879 SetLowUIColor(B_PANEL_BACKGROUND_COLOR); 880 SetHighUIColor(B_PANEL_TEXT_COLOR); 881 } 882 883 _AdjustTextColors(); 884 Invalidate(); 885 } 886 887 888 void 889 SysInfoView::_AdjustTextColors() const 890 { 891 BLayout* layout = GetLayout(); 892 int32 itemCount = layout->CountItems() - 2; 893 // leave out dragger and uptime 894 895 if (_OnDesktop()) { 896 // SetColor 897 for (int32 index = 0; index < itemCount; index++) { 898 BView* view = layout->ItemAt(index)->View(); 899 if (view == NULL) 900 continue; 901 902 view->SetFlags(view->Flags() | B_TRANSPARENT_BACKGROUND); 903 view->SetDrawingMode(B_OP_ALPHA); 904 905 view->SetViewColor(B_TRANSPARENT_COLOR); 906 view->SetLowColor(blend_color(B_TRANSPARENT_COLOR, 907 fDesktopTextColor, 192)); 908 view->SetHighColor(fDesktopTextColor); 909 } 910 911 fUptimeView->SetFlags(fUptimeView->Flags() | B_TRANSPARENT_BACKGROUND); 912 fUptimeView->SetDrawingMode(B_OP_ALPHA); 913 914 fUptimeView->SetViewColor(B_TRANSPARENT_COLOR); 915 fUptimeView->SetLowColor(blend_color(B_TRANSPARENT_COLOR, 916 fDesktopTextColor, 192)); 917 fUptimeView->SetFontAndColor(NULL, 0, &fDesktopTextColor); 918 } else { 919 // SetUIColor 920 for (int32 index = 0; index < itemCount; index++) { 921 BView* view = layout->ItemAt(index)->View(); 922 if (view == NULL) 923 continue; 924 925 view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 926 view->SetLowUIColor(B_PANEL_BACKGROUND_COLOR); 927 view->SetHighUIColor(B_PANEL_TEXT_COLOR); 928 } 929 930 fUptimeView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 931 fUptimeView->SetLowUIColor(B_PANEL_BACKGROUND_COLOR); 932 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 933 fUptimeView->SetFontAndColor(NULL, 0, &textColor); 934 } 935 } 936 937 938 rgb_color 939 SysInfoView::_DesktopTextColor(int32 workspace) const 940 { 941 // set text color to black or white depending on desktop background color 942 rgb_color textColor; 943 BScreen screen(Window()); 944 if (workspace < 0) 945 workspace = current_workspace(); 946 947 rgb_color viewColor = screen.DesktopColor(workspace); 948 int viewBrightness = BPrivate::perceptual_brightness(viewColor); 949 textColor.blue = textColor.green = textColor.red = viewBrightness > 127 950 ? 0 : 255; 951 textColor.alpha = 255; 952 953 return textColor; 954 } 955 956 957 bool 958 SysInfoView::_OnDesktop() const 959 { 960 return fIsReplicant && Window() != NULL 961 && Window()->Look() == kDesktopWindowLook 962 && Window()->Feel() == kDesktopWindowFeel; 963 } 964 965 966 BStringView* 967 SysInfoView::_CreateLabel(const char* name, const char* text) 968 { 969 BStringView* label = new BStringView(name, text); 970 _UpdateLabel(label); 971 972 return label; 973 } 974 975 976 void 977 SysInfoView::_UpdateLabel(BStringView* label) 978 { 979 label->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 980 B_ALIGN_VERTICAL_UNSET)); 981 label->SetFont(be_bold_font, B_FONT_FAMILY_AND_STYLE); 982 } 983 984 985 BStringView* 986 SysInfoView::_CreateSubtext(const char* name, const char* text) 987 { 988 BStringView* subtext = new BStringView(name, text); 989 _UpdateSubtext(subtext); 990 991 return subtext; 992 } 993 994 995 void 996 SysInfoView::_UpdateSubtext(BStringView* subtext) 997 { 998 subtext->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 999 B_ALIGN_VERTICAL_UNSET)); 1000 subtext->SetFont(be_plain_font, B_FONT_FAMILY_AND_STYLE); 1001 } 1002 1003 1004 void 1005 SysInfoView::_UpdateText(BTextView* textView) 1006 { 1007 textView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP)); 1008 textView->SetFontAndColor(be_plain_font, B_FONT_FAMILY_AND_STYLE); 1009 textView->SetColorSpace(B_RGBA32); 1010 textView->MakeResizable(false); 1011 textView->MakeEditable(false); 1012 textView->MakeSelectable(false); 1013 textView->SetWordWrap(true); 1014 textView->SetDoesUndo(false); 1015 textView->SetInsets(0, 0, 0, 0); 1016 } 1017 1018 1019 void 1020 SysInfoView::_CreateDragger() 1021 { 1022 // create replicant dragger and add it as the new child 0 1023 fDragger = new BDragger(BRect(0, 0, 7, 7), this, 1024 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 1025 BPopUpMenu* popUp = new BPopUpMenu("Shelf", false, false, B_ITEMS_IN_COLUMN); 1026 popUp->AddItem(new BMenuItem(B_TRANSLATE("Remove replicant"), 1027 new BMessage(kDeleteReplicant))); 1028 fDragger->SetPopUp(popUp); 1029 AddChild(fDragger, ChildAt(0)); 1030 } 1031 1032 1033 float 1034 SysInfoView::_BaseWidth() 1035 { 1036 // based on font size 1037 return be_plain_font->StringWidth("M") * 24; 1038 } 1039 1040 1041 float 1042 SysInfoView::_BaseHeight() 1043 { 1044 // based on line heights 1045 font_height plainFH; 1046 be_plain_font->GetHeight(&plainFH); 1047 font_height boldFH; 1048 be_bold_font->GetHeight(&boldFH); 1049 1050 return ceilf(((boldFH.ascent + boldFH.descent) * kLabelCount 1051 + (plainFH.ascent + plainFH.descent) * kSubtextCount 1052 + be_control_look->DefaultLabelSpacing() * kLabelCount)); 1053 } 1054 1055 1056 BString 1057 SysInfoView::_GetOSVersion() 1058 { 1059 BString revision; 1060 // add system revision to os version 1061 const char* hrev = __get_haiku_revision(); 1062 if (hrev != NULL) 1063 revision.SetToFormat(B_TRANSLATE_COMMENT("Version: %s", 1064 "Version: R1 or hrev99999"), hrev); 1065 else 1066 revision = B_TRANSLATE("Version:"); 1067 1068 return revision; 1069 } 1070 1071 1072 BString 1073 SysInfoView::_GetABIVersion() 1074 { 1075 BString abiVersion; 1076 1077 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 1078 BPath path; 1079 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 1080 path.Append("libbe.so"); 1081 1082 BAppFileInfo appFileInfo; 1083 version_info versionInfo; 1084 BFile file; 1085 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 1086 && appFileInfo.SetTo(&file) == B_OK 1087 && appFileInfo.GetVersionInfo(&versionInfo, 1088 B_APP_VERSION_KIND) == B_OK 1089 && versionInfo.short_info[0] != '\0') 1090 abiVersion = versionInfo.short_info; 1091 } 1092 1093 if (abiVersion.IsEmpty()) 1094 abiVersion = B_TRANSLATE("Unknown"); 1095 1096 abiVersion << " (" << B_HAIKU_ABI_NAME << ")"; 1097 1098 return abiVersion; 1099 } 1100 1101 1102 BString 1103 SysInfoView::_GetCPUCount(system_info* sysInfo) 1104 { 1105 static BStringFormat format(B_TRANSLATE_COMMENT( 1106 "{0, plural, one{Processor:} other{# Processors:}}", 1107 "\"Processor:\" or \"2 Processors:\"")); 1108 1109 BString processorLabel; 1110 format.Format(processorLabel, sysInfo->cpu_count); 1111 return processorLabel; 1112 } 1113 1114 1115 BString 1116 SysInfoView::_GetCPUInfo() 1117 { 1118 uint32 topologyNodeCount = 0; 1119 cpu_topology_node_info* topology = NULL; 1120 1121 get_cpu_topology_info(NULL, &topologyNodeCount); 1122 if (topologyNodeCount != 0) 1123 topology = new cpu_topology_node_info[topologyNodeCount]; 1124 get_cpu_topology_info(topology, &topologyNodeCount); 1125 1126 enum cpu_platform platform = B_CPU_UNKNOWN; 1127 enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; 1128 uint32 cpuModel = 0; 1129 1130 for (uint32 i = 0; i < topologyNodeCount; i++) { 1131 switch (topology[i].type) { 1132 case B_TOPOLOGY_ROOT: 1133 platform = topology[i].data.root.platform; 1134 break; 1135 1136 case B_TOPOLOGY_PACKAGE: 1137 cpuVendor = topology[i].data.package.vendor; 1138 break; 1139 1140 case B_TOPOLOGY_CORE: 1141 cpuModel = topology[i].data.core.model; 1142 break; 1143 1144 default: 1145 break; 1146 } 1147 } 1148 1149 delete[] topology; 1150 1151 BString cpuType; 1152 cpuType << get_cpu_vendor_string(cpuVendor) << " " 1153 << get_cpu_model_string(platform, cpuVendor, cpuModel) 1154 << " @ " << _GetCPUFrequency(); 1155 1156 return cpuType; 1157 } 1158 1159 1160 BString 1161 SysInfoView::_GetCPUFrequency() 1162 { 1163 BString clockSpeed; 1164 1165 int32 frequency = get_rounded_cpu_speed(); 1166 if (frequency < 1000) { 1167 clockSpeed.SetToFormat(B_TRANSLATE_COMMENT("%ld MHz", 1168 "750 Mhz (CPU clock speed)"), frequency); 1169 } 1170 else { 1171 clockSpeed.SetToFormat(B_TRANSLATE_COMMENT("%.2f GHz", 1172 "3.49 Ghz (CPU clock speed)"), frequency / 1000.0f); 1173 } 1174 1175 return clockSpeed; 1176 } 1177 1178 1179 BString 1180 SysInfoView::_GetRamSize(system_info* sysInfo) 1181 { 1182 BString ramSize; 1183 ramSize.SetToFormat(B_TRANSLATE_COMMENT("%d MiB Memory:", 1184 "2048 MiB Memory:"), max_and_ignored_pages(sysInfo)); 1185 1186 return ramSize; 1187 } 1188 1189 1190 BString 1191 SysInfoView::_GetRamUsage(system_info* sysInfo) 1192 { 1193 BString ramUsage; 1194 BString data; 1195 double usedMemoryPercent = double(sysInfo->used_pages) / sysInfo->max_pages; 1196 1197 if (fNumberFormat.FormatPercent(data, usedMemoryPercent) != B_OK) 1198 data.SetToFormat("%d%%", (int)(100 * usedMemoryPercent)); 1199 1200 ramUsage.SetToFormat(B_TRANSLATE_COMMENT("%d MiB used (%s)", 1201 "326 MiB used (16%)"), used_pages(sysInfo), data.String()); 1202 1203 return ramUsage; 1204 } 1205 1206 1207 BString 1208 SysInfoView::_GetKernelDateTime(system_info* sysInfo) 1209 { 1210 BString kernelDateTime; 1211 1212 BString buildDateTime; 1213 buildDateTime << sysInfo->kernel_build_date << " " << sysInfo->kernel_build_time; 1214 1215 time_t buildDateTimeStamp = parsedate(buildDateTime, -1); 1216 1217 if (buildDateTimeStamp > 0) { 1218 if (BDateTimeFormat().Format(kernelDateTime, buildDateTimeStamp, 1219 B_LONG_DATE_FORMAT, B_MEDIUM_TIME_FORMAT) != B_OK) 1220 kernelDateTime.SetTo(buildDateTime); 1221 } else 1222 kernelDateTime.SetTo(buildDateTime); 1223 1224 return kernelDateTime; 1225 } 1226 1227 1228 BString 1229 SysInfoView::_GetUptime() 1230 { 1231 BDurationFormat formatter; 1232 BString uptimeText; 1233 1234 bigtime_t uptime = system_time(); 1235 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1236 formatter.Format(uptimeText, now - uptime, now); 1237 1238 return uptimeText; 1239 } 1240 1241 1242 float 1243 SysInfoView::_UptimeHeight() 1244 { 1245 return fUptimeView->LineHeight(0) * fUptimeView->CountLines(); 1246 } 1247 1248 1249 // #pragma mark - AboutView 1250 1251 1252 AboutView::AboutView() 1253 : 1254 BView("aboutview", B_WILL_DRAW | B_PULSE_NEEDED), 1255 fLogoView(NULL), 1256 fSysInfoView(NULL), 1257 fCreditsView(NULL), 1258 fLastActionTime(system_time()), 1259 fScrollRunner(NULL), 1260 fCachedMinWidth(kSysInfoMinWidth), 1261 fCachedMinHeight(kSysInfoMinHeight) 1262 { 1263 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 1264 1265 // Assign the colors, sadly this does not respect live color updates 1266 fTextColor = ui_color(B_DOCUMENT_TEXT_COLOR); 1267 fLinkColor = ui_color(B_LINK_TEXT_COLOR); 1268 fHaikuOrangeColor = mix_color(fTextColor, kIdealHaikuOrange, 191); 1269 fHaikuGreenColor = mix_color(fTextColor, kIdealHaikuGreen, 191); 1270 fHaikuYellowColor = mix_color(fTextColor, kIdealHaikuYellow, 191); 1271 fBeOSRedColor = mix_color(fTextColor, kIdealBeOSRed, 191); 1272 fBeOSBlueColor = mix_color(fTextColor, kIdealBeOSBlue, 191); 1273 1274 SetLayout(new BGroupLayout(B_HORIZONTAL, 0)); 1275 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 1276 .AddGroup(B_VERTICAL, 0) 1277 .Add(_CreateLogoView()) 1278 .Add(_CreateSysInfoView()) 1279 .AddGlue() 1280 .End() 1281 .Add(_CreateCreditsView()) 1282 .End(); 1283 } 1284 1285 1286 AboutView::~AboutView() 1287 { 1288 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1289 it != fPackageCredits.end(); it++) { 1290 1291 delete it->second; 1292 } 1293 1294 delete fScrollRunner; 1295 delete fCreditsView; 1296 delete fSysInfoView; 1297 delete fLogoView; 1298 } 1299 1300 1301 void 1302 AboutView::AttachedToWindow() 1303 { 1304 BView::AttachedToWindow(); 1305 1306 fSysInfoView->CacheInitialSize(); 1307 1308 float insets = be_control_look->DefaultLabelSpacing() * 2; 1309 float infoWidth = fSysInfoView->MinWidth() + insets; 1310 float creditsWidth = roundf(infoWidth * 1.25f); 1311 fCachedMinWidth = std::max(infoWidth + creditsWidth, 1312 fCachedMinWidth); 1313 // set once 1314 float logoViewHeight = fLogoView->Bounds().Height(); 1315 float sysInfoViewHeight = fSysInfoView->MinHeight() + insets; 1316 fCachedMinHeight = std::max(logoViewHeight + sysInfoViewHeight, 1317 fCachedMinHeight); 1318 // updated when height changes in pulse 1319 fCreditsView->SetExplicitMinSize(BSize(creditsWidth, fCachedMinHeight)); 1320 // set credits min height to logo height + sys-info height 1321 1322 SetEventMask(B_POINTER_EVENTS); 1323 DoLayout(); 1324 } 1325 1326 1327 void 1328 AboutView::MouseDown(BPoint where) 1329 { 1330 BRect rect(92, 26, 105, 31); 1331 if (rect.Contains(where)) 1332 BMessenger(this).SendMessage('eegg'); 1333 1334 if (Bounds().Contains(where)) { 1335 fLastActionTime = system_time(); 1336 delete fScrollRunner; 1337 fScrollRunner = NULL; 1338 } 1339 } 1340 1341 1342 void 1343 AboutView::Pulse() 1344 { 1345 // sys-info handles height because it may be a replicant 1346 float insets = be_control_look->DefaultLabelSpacing() * 2; 1347 float logoViewHeight = fLogoView->Bounds().Height(); 1348 float sysInfoViewHeight = fSysInfoView->MinHeight() + insets; 1349 float newHeight = logoViewHeight + sysInfoViewHeight; 1350 if (newHeight != fCachedMinHeight) { 1351 fCreditsView->SetExplicitMinSize(BSize( 1352 fCachedMinWidth - (fSysInfoView->MinWidth() + insets), newHeight)); 1353 fCachedMinHeight = newHeight; 1354 } 1355 1356 if (fScrollRunner == NULL && system_time() > fLastActionTime + 10000000) 1357 _CreateScrollRunner(); 1358 } 1359 1360 1361 void 1362 AboutView::MessageReceived(BMessage* message) 1363 { 1364 switch (message->what) { 1365 case kMsgScrollCreditsView: 1366 { 1367 BScrollBar* scrollBar = fCreditsView->ScrollBar(B_VERTICAL); 1368 if (scrollBar == NULL) 1369 break; 1370 float min; 1371 float max; 1372 scrollBar->GetRange(&min, &max); 1373 if (scrollBar->Value() < max) 1374 fCreditsView->ScrollBy(0, 1); 1375 1376 break; 1377 } 1378 1379 case 'eegg': 1380 { 1381 printf("Easter egg\n"); 1382 PickRandomHaiku(); 1383 break; 1384 } 1385 1386 default: 1387 BView::MessageReceived(message); 1388 break; 1389 } 1390 } 1391 1392 1393 void 1394 AboutView::AddCopyrightEntry(const char* name, const char* text, 1395 const char* url) 1396 { 1397 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 1398 } 1399 1400 1401 void 1402 AboutView::AddCopyrightEntry(const char* name, const char* text, 1403 const StringVector& licenses, const StringVector& sources, 1404 const char* url) 1405 { 1406 BFont font(be_bold_font); 1407 //font.SetSize(be_bold_font->Size()); 1408 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 1409 1410 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuYellowColor); 1411 fCreditsView->Insert(name); 1412 fCreditsView->Insert("\n"); 1413 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1414 fCreditsView->Insert(text); 1415 fCreditsView->Insert("\n"); 1416 1417 if (licenses.CountStrings() > 0) { 1418 if (licenses.CountStrings() > 1) 1419 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 1420 else 1421 fCreditsView->Insert(B_TRANSLATE("License: ")); 1422 1423 for (int32 i = 0; i < licenses.CountStrings(); i++) { 1424 const char* license = licenses.StringAt(i); 1425 1426 if (i > 0) 1427 fCreditsView->Insert(", "); 1428 1429 BString licenseName; 1430 BString licenseURL; 1431 parse_named_url(license, licenseName, licenseURL); 1432 1433 BPath licensePath; 1434 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 1435 fCreditsView->InsertHyperText(B_TRANSLATE_NOCOLLECT(licenseName), 1436 new OpenFileAction(licensePath.Path())); 1437 } else 1438 fCreditsView->Insert(licenseName); 1439 } 1440 1441 fCreditsView->Insert("\n"); 1442 } 1443 1444 if (sources.CountStrings() > 0) { 1445 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 1446 1447 for (int32 i = 0; i < sources.CountStrings(); i++) { 1448 const char* source = sources.StringAt(i); 1449 1450 if (i > 0) 1451 fCreditsView->Insert(", "); 1452 1453 BString urlName; 1454 BString urlAddress; 1455 parse_named_url(source, urlName, urlAddress); 1456 1457 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 1458 &fLinkColor); 1459 fCreditsView->InsertHyperText(urlName, 1460 new URLAction(urlAddress)); 1461 } 1462 1463 fCreditsView->Insert("\n"); 1464 } 1465 1466 if (url) { 1467 BString urlName; 1468 BString urlAddress; 1469 parse_named_url(url, urlName, urlAddress); 1470 1471 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 1472 &fLinkColor); 1473 fCreditsView->InsertHyperText(urlName, 1474 new URLAction(urlAddress)); 1475 fCreditsView->Insert("\n"); 1476 } 1477 fCreditsView->Insert("\n"); 1478 } 1479 1480 1481 void 1482 AboutView::PickRandomHaiku() 1483 { 1484 BPath path; 1485 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK) 1486 path = "/system/data"; 1487 path.Append("fortunes"); 1488 path.Append("Haiku"); 1489 1490 BFile fortunes(path.Path(), B_READ_ONLY); 1491 struct stat st; 1492 if (fortunes.InitCheck() < B_OK) 1493 return; 1494 if (fortunes.GetStat(&st) < B_OK) 1495 return; 1496 1497 char* buff = (char*)malloc((size_t)st.st_size + 1); 1498 if (buff == NULL) 1499 return; 1500 1501 buff[(size_t)st.st_size] = '\0'; 1502 BList haikuList; 1503 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 1504 char* p = buff; 1505 while (p && *p) { 1506 char* e = strchr(p, '%'); 1507 BString* s = new BString(p, e ? (e - p) : -1); 1508 haikuList.AddItem(s); 1509 p = e; 1510 if (p && (*p == '%')) 1511 p++; 1512 if (p && (*p == '\n')) 1513 p++; 1514 } 1515 } 1516 free(buff); 1517 1518 if (haikuList.CountItems() < 1) 1519 return; 1520 1521 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 1522 BFont font(be_bold_font); 1523 font.SetSize(be_bold_font->Size()); 1524 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 1525 fCreditsView->SelectAll(); 1526 fCreditsView->Delete(); 1527 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fTextColor); 1528 fCreditsView->Insert(s->String()); 1529 fCreditsView->Insert("\n"); 1530 while ((s = (BString*)haikuList.RemoveItem((int32)0))) 1531 delete s; 1532 } 1533 1534 1535 void 1536 AboutView::_CreateScrollRunner() 1537 { 1538 #if 0 1539 BMessage scroll(kMsgScrollCreditsView); 1540 fScrollRunner = new(std::nothrow) BMessageRunner(this, &scroll, 25000, -1); 1541 #endif 1542 } 1543 1544 1545 LogoView* 1546 AboutView::_CreateLogoView() 1547 { 1548 fLogoView = new(std::nothrow) LogoView(); 1549 1550 return fLogoView; 1551 } 1552 1553 1554 SysInfoView* 1555 AboutView::_CreateSysInfoView() 1556 { 1557 fSysInfoView = new(std::nothrow) SysInfoView(); 1558 1559 return fSysInfoView; 1560 } 1561 1562 1563 CropView* 1564 AboutView::_CreateCreditsView() 1565 { 1566 // Begin construction of the credits view 1567 fCreditsView = new HyperTextView("credits"); 1568 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 1569 fCreditsView->SetStylable(true); 1570 fCreditsView->MakeEditable(false); 1571 fCreditsView->SetWordWrap(true); 1572 fCreditsView->SetInsets(5, 5, 5, 5); 1573 fCreditsView->SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); 1574 1575 BScrollView* creditsScroller = new BScrollView("creditsScroller", 1576 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 1577 B_PLAIN_BORDER); 1578 1579 // Haiku copyright 1580 BFont font(be_bold_font); 1581 font.SetSize(font.Size() + 4); 1582 1583 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 1584 fCreditsView->Insert("Haiku\n"); 1585 1586 time_t time = ::time(NULL); 1587 struct tm* tm = localtime(&time); 1588 int32 year = tm->tm_year + 1900; 1589 if (year < 2008) 1590 year = 2008; 1591 BString text; 1592 text.SetToFormat( 1593 B_TRANSLATE(COPYRIGHT_STRING "2001-%" B_PRId32 " The Haiku project. "), 1594 year); 1595 1596 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1597 fCreditsView->Insert(text.String()); 1598 1599 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1600 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 1601 "property of Haiku, Inc. or of the respective authors where expressly " 1602 "noted in the source. Haiku" B_UTF8_REGISTERED 1603 " and the HAIKU logo" B_UTF8_REGISTERED 1604 " are registered trademarks of Haiku, Inc." 1605 "\n\n")); 1606 1607 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 1608 fCreditsView->InsertHyperText("https://www.haiku-os.org", 1609 new URLAction("https://www.haiku-os.org")); 1610 fCreditsView->Insert("\n\n"); 1611 1612 font.SetSize(be_bold_font->Size()); 1613 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 1614 1615 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1616 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 1617 1618 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1619 fCreditsView->Insert(kCurrentMaintainers); 1620 1621 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1622 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 1623 1624 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1625 fCreditsView->Insert(kPastMaintainers); 1626 1627 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1628 fCreditsView->Insert(B_TRANSLATE("Website & marketing:\n")); 1629 1630 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1631 fCreditsView->Insert(kWebsiteTeam); 1632 1633 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1634 fCreditsView->Insert(B_TRANSLATE("Past website & marketing:\n")); 1635 1636 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1637 fCreditsView->Insert(kPastWebsiteTeam); 1638 1639 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1640 fCreditsView->Insert(B_TRANSLATE("Testing and bug triaging:\n")); 1641 1642 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1643 fCreditsView->Insert(kTestingTeam); 1644 1645 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1646 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 1647 1648 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1649 fCreditsView->Insert(kContributors); 1650 fCreditsView->Insert( 1651 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 1652 "and probably some more we forgot to mention (sorry!)" 1653 "\n\n")); 1654 1655 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1656 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 1657 1658 BLanguage* lang; 1659 BString langName; 1660 1661 BList sortedTranslations; 1662 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1663 const Translation* translation = &kTranslations[i]; 1664 sortedTranslations.AddItem((void*)translation); 1665 } 1666 sortedTranslations.SortItems(TranslationComparator); 1667 1668 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1669 const Translation& translation 1670 = *(const Translation*)sortedTranslations.ItemAt(i); 1671 1672 langName.Truncate(0); 1673 if (BLocaleRoster::Default()->GetLanguage(translation.languageCode, 1674 &lang) == B_OK) { 1675 lang->GetName(langName); 1676 delete lang; 1677 } else { 1678 // We failed to get the localized readable name, 1679 // go with what we have. 1680 langName.Append(translation.languageCode); 1681 } 1682 1683 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 1684 fCreditsView->Insert("\n"); 1685 fCreditsView->Insert(langName); 1686 fCreditsView->Insert("\n"); 1687 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1688 fCreditsView->Insert(translation.names); 1689 } 1690 1691 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1692 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 1693 1694 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1695 BString beosCredits(B_TRANSLATE( 1696 "Be Inc. and its developer team, for having created BeOS!\n\n")); 1697 int32 beosOffset = beosCredits.FindFirst("BeOS"); 1698 fCreditsView->Insert(beosCredits.String(), 1699 (beosOffset < 0) ? beosCredits.Length() : beosOffset); 1700 if (beosOffset > -1) { 1701 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fBeOSBlueColor); 1702 fCreditsView->Insert("B"); 1703 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fBeOSRedColor); 1704 fCreditsView->Insert("e"); 1705 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1706 beosCredits.Remove(0, beosOffset + 2); 1707 fCreditsView->Insert(beosCredits.String(), beosCredits.Length()); 1708 } 1709 fCreditsView->Insert( 1710 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 1711 fCreditsView->Insert( 1712 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 1713 fCreditsView->Insert( 1714 B_TRANSLATE("The HaikuPorts team\n")); 1715 fCreditsView->Insert( 1716 B_TRANSLATE("The Haikuware team and their bounty program\n")); 1717 fCreditsView->Insert( 1718 B_TRANSLATE("The BeGeistert team\n")); 1719 fCreditsView->Insert( 1720 B_TRANSLATE("Google and their Google Summer of Code and Google Code In " 1721 "programs\n")); 1722 fCreditsView->Insert( 1723 B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n")); 1724 fCreditsView->Insert( 1725 B_TRANSLATE(B_UTF8_ELLIPSIS "and the many people making donations!\n\n")); 1726 1727 // copyrights for various projects we use 1728 1729 BPath mitPath; 1730 _GetLicensePath("MIT", mitPath); 1731 BPath lgplPath; 1732 _GetLicensePath("GNU LGPL v2.1", lgplPath); 1733 1734 font.SetSize(be_bold_font->Size() + 4); 1735 font.SetFace(B_BOLD_FACE); 1736 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 1737 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 1738 1739 // Haiku license 1740 BString haikuLicense = B_TRANSLATE_COMMENT("The code that is unique to " 1741 "Haiku, especially the kernel and all code that applications may link " 1742 "against, is distributed under the terms of the <MIT license>. " 1743 "Some system libraries contain third party code distributed under the " 1744 "<LGPL license>. You can find the copyrights to third party code below." 1745 "\n\n", "<MIT license> and <LGPL license> aren't variables and can be " 1746 "translated. However, please, don't remove < and > as they're needed " 1747 "as placeholders for proper hypertext functionality."); 1748 int32 licensePart1 = haikuLicense.FindFirst("<"); 1749 int32 licensePart2 = haikuLicense.FindFirst(">"); 1750 int32 licensePart3 = haikuLicense.FindLast("<"); 1751 int32 licensePart4 = haikuLicense.FindLast(">"); 1752 BString part; 1753 haikuLicense.CopyInto(part, 0, licensePart1); 1754 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1755 fCreditsView->Insert(part); 1756 1757 part.Truncate(0); 1758 haikuLicense.CopyInto(part, licensePart1 + 1, licensePart2 - 1 1759 - licensePart1); 1760 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 1761 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1762 1763 part.Truncate(0); 1764 haikuLicense.CopyInto(part, licensePart2 + 1, licensePart3 - 1 1765 - licensePart2); 1766 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1767 fCreditsView->Insert(part); 1768 1769 part.Truncate(0); 1770 haikuLicense.CopyInto(part, licensePart3 + 1, licensePart4 - 1 1771 - licensePart3); 1772 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 1773 fCreditsView->InsertHyperText(part, new OpenFileAction(lgplPath.Path())); 1774 1775 part.Truncate(0); 1776 haikuLicense.CopyInto(part, licensePart4 + 1, haikuLicense.Length() - 1 1777 - licensePart4); 1778 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1779 fCreditsView->Insert(part); 1780 1781 // GNU copyrights 1782 AddCopyrightEntry("The GNU Project", 1783 B_TRANSLATE("Contains software from the GNU Project, " 1784 "released under the GPL and LGPL licenses:\n" 1785 "GNU C Library, " 1786 "GNU coretools, diffutils, findutils, " 1787 "sharutils, gawk, bison, m4, make, " 1788 "wget, ncurses, termcap, " 1789 "Bourne Again Shell.\n" 1790 COPYRIGHT_STRING "The Free Software Foundation."), 1791 StringVector(kLGPLv21, kGPLv2, kGPLv3, NULL), 1792 StringVector(), 1793 "https://www.gnu.org"); 1794 1795 // FreeBSD copyrights 1796 AddCopyrightEntry("The FreeBSD Project", 1797 B_TRANSLATE("Contains software from the FreeBSD Project, " 1798 "released under the BSD license:\n" 1799 "ftpd, ping, telnet, telnetd, traceroute\n" 1800 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1801 "All rights reserved."), 1802 StringVector(kBSDTwoClause, kBSDThreeClause, kBSDFourClause, 1803 NULL), 1804 StringVector(), 1805 "https://www.freebsd.org"); 1806 1807 // FFmpeg copyrights 1808 _AddPackageCredit(PackageCredit("FFmpeg") 1809 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000-2019 Fabrice " 1810 "Bellard, et al.")) 1811 .SetLicenses(kLGPLv21, kLGPLv2, NULL) 1812 .SetURL("https://www.ffmpeg.org")); 1813 1814 // AGG copyrights 1815 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1816 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2006 Maxim " 1817 "Shemanarev (McSeem).")) 1818 .SetLicenses("Anti-Grain Geometry", kBSDThreeClause, NULL) 1819 .SetURL("http://www.antigrain.com")); 1820 1821 // FreeType copyrights 1822 _AddPackageCredit(PackageCredit("FreeType2") 1823 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1996-2002, 2006 " 1824 "David Turner, Robert Wilhelm and Werner Lemberg."), 1825 COPYRIGHT_STRING "2014 The FreeType Project. " 1826 "All rights reserved.", 1827 NULL) 1828 .SetLicense("FreeType") 1829 .SetURL("http://www.freetype.org")); 1830 1831 // Mesa3D (http://www.mesa3d.org) copyrights 1832 _AddPackageCredit(PackageCredit("Mesa") 1833 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1834 "Mesa3D Project. All rights reserved.")) 1835 .SetLicense("MIT") 1836 .SetURL("http://www.mesa3d.org")); 1837 1838 // SGI's GLU implementation copyrights 1839 _AddPackageCredit(PackageCredit("GLU") 1840 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1991-2000 " 1841 "Silicon Graphics, Inc. All rights reserved.")) 1842 .SetLicense("SGI Free B") 1843 .SetURL("http://www.sgi.com/products/software/opengl")); 1844 1845 // GLUT implementation copyrights 1846 _AddPackageCredit(PackageCredit("GLUT") 1847 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1848 "All rights reserved."), 1849 COPYRIGHT_STRING "1997 Be Inc.", 1850 COPYRIGHT_STRING "1999 Jake Hamby.", 1851 NULL) 1852 .SetLicense("MIT") 1853 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1854 1855 // OpenGroup & DEC (BRegion backend) copyright 1856 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1857 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1858 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1859 "Corporation, Maynard, Massachusetts.\n" 1860 "All rights reserved."), 1861 NULL) 1862 .SetLicenses("OpenGroup", "DEC", NULL) 1863 .SetURL("https://xfree86.org")); 1864 1865 // Bitstream Charter font 1866 _AddPackageCredit(PackageCredit("Bitstream Charter font") 1867 .SetCopyrights(COPYRIGHT_STRING "1989-1992 Bitstream Inc.," 1868 "Cambridge, MA.", 1869 B_TRANSLATE("BITSTREAM CHARTER is a registered trademark of " 1870 "Bitstream Inc."), 1871 NULL) 1872 .SetLicense("Bitstream Charter") 1873 .SetURL("http://www.bitstream.com/")); 1874 1875 // Noto fonts copyright 1876 _AddPackageCredit(PackageCredit("Noto fonts") 1877 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING 1878 "2012-2016 Google Internationalization team."), 1879 NULL) 1880 .SetLicense("SIL Open Font Licence v1.1") 1881 .SetURL("http://www.google.com/get/noto/")); 1882 1883 // expat copyrights 1884 _AddPackageCredit(PackageCredit("expat") 1885 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1886 "Open Source Software Center Ltd and Clark Cooper."), 1887 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1888 NULL) 1889 .SetLicense("Expat") 1890 .SetURL("http://expat.sourceforge.net")); 1891 1892 // zlib copyrights 1893 _AddPackageCredit(PackageCredit("zlib") 1894 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1895 "Gailly and Mark Adler.")) 1896 .SetLicense("Zlib") 1897 .SetURL("http://www.zlib.net")); 1898 1899 // zip copyrights 1900 _AddPackageCredit(PackageCredit("Info-ZIP") 1901 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1902 "All rights reserved.")) 1903 .SetLicense("Info-ZIP") 1904 .SetURL("http://www.info-zip.org")); 1905 1906 // bzip2 copyrights 1907 _AddPackageCredit(PackageCredit("bzip2") 1908 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1909 "Seward. All rights reserved.")) 1910 .SetLicense(kBSDFourClause) 1911 .SetURL("http://bzip.org")); 1912 1913 // OpenEXR copyrights 1914 _AddPackageCredit(PackageCredit("OpenEXR") 1915 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2014 Industrial " 1916 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1917 .SetLicense(kBSDThreeClause) 1918 .SetURL("http://www.openexr.com")); 1919 1920 // acpica copyrights 1921 _AddPackageCredit(PackageCredit("ACPI Component Architecture (ACPICA)") 1922 .SetCopyright(COPYRIGHT_STRING "1999-2018 Intel Corp.") 1923 .SetLicense("Intel (ACPICA)") 1924 .SetURL("https://www.acpica.org")); 1925 1926 // libpng copyrights 1927 _AddPackageCredit(PackageCredit("libpng") 1928 .SetCopyright(COPYRIGHT_STRING "1995-2017 libpng authors") 1929 .SetLicense("LibPNG") 1930 .SetURL("http://www.libpng.org")); 1931 1932 // libjpeg copyrights 1933 _AddPackageCredit(PackageCredit("libjpeg") 1934 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1935 "Lane, Guido Vollbeding. This software is based in part on the " 1936 "work of the Independent JPEG Group.")) 1937 .SetLicense("LibJPEG") 1938 .SetURL("http://www.ijg.org")); 1939 1940 // libprint copyrights 1941 _AddPackageCredit(PackageCredit("libprint") 1942 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1943 "All rights reserved."))); 1944 // TODO: License! 1945 1946 // cortex copyrights 1947 _AddPackageCredit(PackageCredit("Cortex") 1948 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1949 .SetLicense(kBSDThreeClause) 1950 .SetURL("http://cortex.sourceforge.net/documentation")); 1951 1952 // FluidSynth copyrights 1953 _AddPackageCredit(PackageCredit("FluidSynth") 1954 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1955 "and others.")) 1956 .SetLicense(kLGPLv2) 1957 .SetURL("http://www.fluidsynth.org")); 1958 1959 // Xiph.org Foundation copyrights 1960 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1961 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1962 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1963 "All rights reserved."), NULL) 1964 .SetLicense(kBSDThreeClause) 1965 .SetURL("http://www.xiph.org")); 1966 1967 // Matroska 1968 _AddPackageCredit(PackageCredit("libmatroska") 1969 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1970 "All rights reserved.")) 1971 .SetLicense(kLGPLv21) 1972 .SetURL("http://www.matroska.org")); 1973 1974 // BColorQuantizer (originally CQuantizer code) 1975 _AddPackageCredit(PackageCredit("CQuantizer") 1976 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1977 "All rights reserved.")) 1978 .SetLicense("CQuantizer") 1979 .SetURL("http://www.xdp.it")); 1980 1981 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1982 _AddPackageCredit(PackageCredit("MAPM") 1983 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1984 "Ring. All rights reserved.")) 1985 .SetLicense("MAPM") 1986 .SetURL("http://tc.umn.edu/~ringx004")); 1987 1988 // MkDepend 1.7 copyright (Makefile dependency generator) 1989 _AddPackageCredit(PackageCredit("MkDepend") 1990 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1991 "All rights reserved.")) 1992 .SetLicense("MIT") 1993 .SetURL("http://bearnip.com/lars/be")); 1994 1995 // libhttpd copyright (used as Poorman backend) 1996 _AddPackageCredit(PackageCredit("libhttpd") 1997 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 1998 "Jef Poskanzer. All rights reserved.")) 1999 .SetLicense(kBSDTwoClause) 2000 .SetURL("http://www.acme.com/software/thttpd/")); 2001 2002 #ifdef __i386__ 2003 // Udis86 copyrights 2004 _AddPackageCredit(PackageCredit("Udis86") 2005 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 2006 "Vivek Mohan. All rights reserved.")) 2007 .SetLicense(kBSDTwoClause) 2008 .SetURL("http://udis86.sourceforge.net")); 2009 2010 // Intel PRO/Wireless 2100 & 2200BG firmwares 2011 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 & 2200BG firmwares") 2012 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 2013 "Intel Corporation. All rights reserved.")) 2014 .SetLicense(kIntel2xxxFirmware) 2015 .SetURL("http://www.intellinuxwireless.org/")); 2016 2017 // Intel wireless firmwares 2018 _AddPackageCredit( 2019 PackageCredit("Intel PRO/Wireless network adapter firmwares") 2020 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2015 " 2021 "Intel Corporation. All rights reserved.")) 2022 .SetLicense(kIntelFirmware) 2023 .SetURL("http://www.intellinuxwireless.org/")); 2024 2025 // Marvell 88w8363 2026 _AddPackageCredit(PackageCredit("Marvell 88w8363") 2027 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 2028 "Marvell Semiconductor, Inc. All rights reserved.")) 2029 .SetLicense(kMarvellFirmware) 2030 .SetURL("http://www.marvell.com/")); 2031 2032 // Ralink Firmware RT2501/RT2561/RT2661 2033 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 2034 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 2035 "Ralink Technology Corporation. All rights reserved.")) 2036 .SetLicense(kRalinkFirmware) 2037 .SetURL("http://www.ralinktech.com/")); 2038 #endif 2039 2040 // Gutenprint 2041 _AddPackageCredit(PackageCredit("Gutenprint") 2042 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2043 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 2044 .SetLicense(kGPLv2) 2045 .SetURL("http://gutenprint.sourceforge.net/")); 2046 2047 // libwebp 2048 _AddPackageCredit(PackageCredit("libwebp") 2049 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2050 "2010-2011 Google Inc. All rights reserved.")) 2051 .SetLicense(kBSDThreeClause) 2052 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 2053 2054 // libavif 2055 _AddPackageCredit(PackageCredit("libavif") 2056 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2057 "2019 Joe Drago. All rights reserved.")) 2058 .SetLicense(kBSDThreeClause) 2059 .SetURL("https://github.com/AOMediaCodec/libavif")); 2060 2061 // GTF 2062 _AddPackageCredit(PackageCredit("GTF") 2063 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 2064 "Generalized Timing Formula")) 2065 .SetLicense(kBSDThreeClause) 2066 .SetURL("http://gtf.sourceforge.net/")); 2067 2068 // libqrencode 2069 _AddPackageCredit(PackageCredit("libqrencode") 2070 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2012 Kentaro Fukuchi")) 2071 .SetLicense(kLGPLv21) 2072 .SetURL("http://fukuchi.org/works/qrencode/")); 2073 2074 // scrypt 2075 _AddPackageCredit(PackageCredit("scrypt") 2076 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2009 Colin Percival")) 2077 .SetLicense(kBSDTwoClause) 2078 .SetURL("https://tarsnap.com/scrypt.html")); 2079 2080 _AddCopyrightsFromAttribute(); 2081 _AddPackageCreditEntries(); 2082 2083 return new CropView(creditsScroller, 0, 1, 1, 1); 2084 } 2085 2086 2087 status_t 2088 AboutView::_GetLicensePath(const char* license, BPath& path) 2089 { 2090 BPathFinder pathFinder; 2091 BStringList paths; 2092 struct stat st; 2093 2094 status_t error = pathFinder.FindPaths(B_FIND_PATH_DATA_DIRECTORY, 2095 "licenses", paths); 2096 2097 for (int i = 0; i < paths.CountStrings(); ++i) { 2098 if (error == B_OK && path.SetTo(paths.StringAt(i)) == B_OK 2099 && path.Append(license) == B_OK 2100 && lstat(path.Path(), &st) == 0) { 2101 return B_OK; 2102 } 2103 } 2104 2105 path.Unset(); 2106 return B_ENTRY_NOT_FOUND; 2107 } 2108 2109 2110 void 2111 AboutView::_AddCopyrightsFromAttribute() 2112 { 2113 #ifdef __HAIKU__ 2114 // open the app executable file 2115 char appPath[B_PATH_NAME_LENGTH]; 2116 int appFD; 2117 if (BPrivate::get_app_path(appPath) != B_OK 2118 || (appFD = open(appPath, O_RDONLY)) < 0) { 2119 return; 2120 } 2121 2122 // open the attribute 2123 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 2124 close(appFD); 2125 if (attrFD < 0) 2126 return; 2127 2128 // attach it to a FILE 2129 FileCloser attrFile(fdopen(attrFD, "r")); 2130 if (!attrFile.IsSet()) { 2131 close(attrFD); 2132 return; 2133 } 2134 2135 // read and parse the copyrights 2136 BMessage package; 2137 BString fieldName; 2138 BString fieldValue; 2139 char lineBuffer[LINE_MAX]; 2140 while (char* line 2141 = fgets(lineBuffer, sizeof(lineBuffer), attrFile.Get())) { 2142 // chop off line break 2143 size_t lineLen = strlen(line); 2144 if (lineLen > 0 && line[lineLen - 1] == '\n') 2145 line[--lineLen] = '\0'; 2146 2147 // flush previous field, if a new field begins, otherwise append 2148 if (lineLen == 0 || !isspace(line[0])) { 2149 // new field -- flush the previous one 2150 if (fieldName.Length() > 0) { 2151 fieldValue = trim_string(fieldValue.String(), 2152 fieldValue.Length()); 2153 package.AddString(fieldName.String(), fieldValue); 2154 fieldName = ""; 2155 } 2156 } else if (fieldName.Length() > 0) { 2157 // append to current field 2158 fieldValue += line; 2159 continue; 2160 } else { 2161 // bogus line -- ignore 2162 continue; 2163 } 2164 2165 if (lineLen == 0) 2166 continue; 2167 2168 // parse new field 2169 char* colon = strchr(line, ':'); 2170 if (colon == NULL) { 2171 // bogus line -- ignore 2172 continue; 2173 } 2174 2175 fieldName.SetTo(line, colon - line); 2176 fieldName = trim_string(line, colon - line); 2177 if (fieldName.Length() == 0) { 2178 // invalid field name 2179 continue; 2180 } 2181 2182 fieldValue = colon + 1; 2183 2184 if (fieldName == "Package") { 2185 // flush the current package 2186 _AddPackageCredit(PackageCredit(package)); 2187 package.MakeEmpty(); 2188 } 2189 } 2190 2191 // flush current package 2192 _AddPackageCredit(PackageCredit(package)); 2193 #endif 2194 } 2195 2196 2197 void 2198 AboutView::_AddPackageCreditEntries() 2199 { 2200 // sort the packages case-insensitively 2201 PackageCredit* packages[fPackageCredits.size()]; 2202 int32 count = 0; 2203 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 2204 it != fPackageCredits.end(); ++it) { 2205 packages[count++] = it->second; 2206 } 2207 2208 if (count > 1) { 2209 std::sort(packages, packages + count, 2210 &PackageCredit::NameLessInsensitive); 2211 } 2212 2213 // add the credits 2214 BString text; 2215 for (int32 i = 0; i < count; i++) { 2216 PackageCredit* package = packages[i]; 2217 2218 text.SetTo(package->CopyrightAt(0)); 2219 int32 count = package->CountCopyrights(); 2220 for (int32 i = 1; i < count; i++) 2221 text << "\n" << package->CopyrightAt(i); 2222 2223 AddCopyrightEntry(package->PackageName(), text.String(), 2224 package->Licenses(), package->Sources(), package->URL()); 2225 } 2226 } 2227 2228 2229 void 2230 AboutView::_AddPackageCredit(const PackageCredit& package) 2231 { 2232 if (!package.IsValid()) 2233 return; 2234 2235 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 2236 if (it != fPackageCredits.end()) { 2237 // If the new package credit isn't "better" than the old one, ignore it. 2238 PackageCredit* oldPackage = it->second; 2239 if (!package.IsBetterThan(*oldPackage)) 2240 return; 2241 2242 // replace the old credit 2243 fPackageCredits.erase(it); 2244 delete oldPackage; 2245 } 2246 2247 fPackageCredits[package.PackageName()] = new PackageCredit(package); 2248 } 2249 2250 2251 // #pragma mark - static functions 2252 2253 2254 static int 2255 ignored_pages(system_info* sysInfo) 2256 { 2257 return (int)round(sysInfo->ignored_pages * B_PAGE_SIZE / 1048576.0); 2258 } 2259 2260 2261 static int 2262 max_pages(system_info* sysInfo) 2263 { 2264 return (int)round(sysInfo->max_pages * B_PAGE_SIZE / 1048576.0); 2265 } 2266 2267 2268 static int 2269 max_and_ignored_pages(system_info* sysInfo) 2270 { 2271 return max_pages(sysInfo) + ignored_pages(sysInfo); 2272 } 2273 2274 2275 static int 2276 used_pages(system_info* sysInfo) 2277 { 2278 return (int)round(sysInfo->used_pages * B_PAGE_SIZE / 1048576.0); 2279 } 2280 2281 2282 // #pragma mark - main 2283 2284 2285 int 2286 main() 2287 { 2288 AboutApp app; 2289 app.Run(); 2290 2291 return 0; 2292 } 2293