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