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 int32 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("http://www.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("http://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("http://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 .SetURL("http://www.sgi.com/products/software/opengl")); 1846 1847 // GLUT implementation copyrights 1848 _AddPackageCredit(PackageCredit("GLUT") 1849 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1850 "All rights reserved."), 1851 COPYRIGHT_STRING "1997 Be Inc.", 1852 COPYRIGHT_STRING "1999 Jake Hamby.", 1853 NULL) 1854 .SetLicense("MIT") 1855 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1856 1857 // OpenGroup & DEC (BRegion backend) copyright 1858 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1859 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1860 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1861 "Corporation, Maynard, Massachusetts.\n" 1862 "All rights reserved."), 1863 NULL) 1864 .SetLicenses("OpenGroup", "DEC", NULL) 1865 .SetURL("https://xfree86.org")); 1866 1867 // Bitstream Charter font 1868 _AddPackageCredit(PackageCredit("Bitstream Charter font") 1869 .SetCopyrights(COPYRIGHT_STRING "1989-1992 Bitstream Inc.," 1870 "Cambridge, MA.", 1871 B_TRANSLATE("BITSTREAM CHARTER is a registered trademark of " 1872 "Bitstream Inc."), 1873 NULL) 1874 .SetLicense("Bitstream Charter") 1875 .SetURL("http://www.bitstream.com/")); 1876 1877 // Noto fonts copyright 1878 _AddPackageCredit(PackageCredit("Noto fonts") 1879 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING 1880 "2012-2016 Google Internationalization team."), 1881 NULL) 1882 .SetLicense("SIL Open Font Licence v1.1") 1883 .SetURL("http://www.google.com/get/noto/")); 1884 1885 // expat copyrights 1886 _AddPackageCredit(PackageCredit("expat") 1887 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1888 "Open Source Software Center Ltd and Clark Cooper."), 1889 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1890 NULL) 1891 .SetLicense("Expat") 1892 .SetURL("http://expat.sourceforge.net")); 1893 1894 // zlib copyrights 1895 _AddPackageCredit(PackageCredit("zlib") 1896 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1897 "Gailly and Mark Adler.")) 1898 .SetLicense("Zlib") 1899 .SetURL("http://www.zlib.net")); 1900 1901 // zip copyrights 1902 _AddPackageCredit(PackageCredit("Info-ZIP") 1903 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1904 "All rights reserved.")) 1905 .SetLicense("Info-ZIP") 1906 .SetURL("http://www.info-zip.org")); 1907 1908 // bzip2 copyrights 1909 _AddPackageCredit(PackageCredit("bzip2") 1910 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1911 "Seward. All rights reserved.")) 1912 .SetLicense(kBSDFourClause) 1913 .SetURL("http://bzip.org")); 1914 1915 // OpenEXR copyrights 1916 _AddPackageCredit(PackageCredit("OpenEXR") 1917 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2014 Industrial " 1918 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1919 .SetLicense(kBSDThreeClause) 1920 .SetURL("http://www.openexr.com")); 1921 1922 // acpica copyrights 1923 _AddPackageCredit(PackageCredit("ACPI Component Architecture (ACPICA)") 1924 .SetCopyright(COPYRIGHT_STRING "1999-2018 Intel Corp.") 1925 .SetLicense("Intel (ACPICA)") 1926 .SetURL("https://www.acpica.org")); 1927 1928 // libpng copyrights 1929 _AddPackageCredit(PackageCredit("libpng") 1930 .SetCopyright(COPYRIGHT_STRING "1995-2017 libpng authors") 1931 .SetLicense("LibPNG") 1932 .SetURL("http://www.libpng.org")); 1933 1934 // libjpeg copyrights 1935 _AddPackageCredit(PackageCredit("libjpeg") 1936 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1937 "Lane, Guido Vollbeding. This software is based in part on the " 1938 "work of the Independent JPEG Group.")) 1939 .SetLicense("LibJPEG") 1940 .SetURL("http://www.ijg.org")); 1941 1942 // libprint copyrights 1943 _AddPackageCredit(PackageCredit("libprint") 1944 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1945 "All rights reserved."))); 1946 // TODO: License! 1947 1948 // cortex copyrights 1949 _AddPackageCredit(PackageCredit("Cortex") 1950 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1951 .SetLicense(kBSDThreeClause) 1952 .SetURL("http://cortex.sourceforge.net/documentation")); 1953 1954 // FluidSynth copyrights 1955 _AddPackageCredit(PackageCredit("FluidSynth") 1956 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1957 "and others.")) 1958 .SetLicense(kLGPLv2) 1959 .SetURL("http://www.fluidsynth.org")); 1960 1961 // Xiph.org Foundation copyrights 1962 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1963 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1964 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1965 "All rights reserved."), NULL) 1966 .SetLicense(kBSDThreeClause) 1967 .SetURL("http://www.xiph.org")); 1968 1969 // Matroska 1970 _AddPackageCredit(PackageCredit("libmatroska") 1971 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1972 "All rights reserved.")) 1973 .SetLicense(kLGPLv21) 1974 .SetURL("http://www.matroska.org")); 1975 1976 // BColorQuantizer (originally CQuantizer code) 1977 _AddPackageCredit(PackageCredit("CQuantizer") 1978 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1979 "All rights reserved.")) 1980 .SetLicense("CQuantizer") 1981 .SetURL("http://www.xdp.it")); 1982 1983 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1984 _AddPackageCredit(PackageCredit("MAPM") 1985 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1986 "Ring. All rights reserved.")) 1987 .SetLicense("MAPM") 1988 .SetURL("http://tc.umn.edu/~ringx004")); 1989 1990 // MkDepend 1.7 copyright (Makefile dependency generator) 1991 _AddPackageCredit(PackageCredit("MkDepend") 1992 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1993 "All rights reserved.")) 1994 .SetLicense("MIT") 1995 .SetURL("http://bearnip.com/lars/be")); 1996 1997 // libhttpd copyright (used as Poorman backend) 1998 _AddPackageCredit(PackageCredit("libhttpd") 1999 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 2000 "Jef Poskanzer. All rights reserved.")) 2001 .SetLicense(kBSDTwoClause) 2002 .SetURL("http://www.acme.com/software/thttpd/")); 2003 2004 #ifdef __i386__ 2005 // Udis86 copyrights 2006 _AddPackageCredit(PackageCredit("Udis86") 2007 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 2008 "Vivek Mohan. All rights reserved.")) 2009 .SetLicense(kBSDTwoClause) 2010 .SetURL("http://udis86.sourceforge.net")); 2011 2012 // Intel PRO/Wireless 2100 & 2200BG firmwares 2013 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 & 2200BG firmwares") 2014 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 2015 "Intel Corporation. All rights reserved.")) 2016 .SetLicense(kIntel2xxxFirmware) 2017 .SetURL("http://www.intellinuxwireless.org/")); 2018 2019 // Intel wireless firmwares 2020 _AddPackageCredit( 2021 PackageCredit("Intel PRO/Wireless network adapter firmwares") 2022 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2015 " 2023 "Intel Corporation. All rights reserved.")) 2024 .SetLicense(kIntelFirmware) 2025 .SetURL("http://www.intellinuxwireless.org/")); 2026 2027 // Marvell 88w8363 2028 _AddPackageCredit(PackageCredit("Marvell 88w8363") 2029 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 2030 "Marvell Semiconductor, Inc. All rights reserved.")) 2031 .SetLicense(kMarvellFirmware) 2032 .SetURL("http://www.marvell.com/")); 2033 2034 // Ralink Firmware RT2501/RT2561/RT2661 2035 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 2036 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 2037 "Ralink Technology Corporation. All rights reserved.")) 2038 .SetLicense(kRalinkFirmware) 2039 .SetURL("http://www.ralinktech.com/")); 2040 #endif 2041 2042 // Gutenprint 2043 _AddPackageCredit(PackageCredit("Gutenprint") 2044 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2045 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 2046 .SetLicense(kGPLv2) 2047 .SetURL("http://gutenprint.sourceforge.net/")); 2048 2049 // libwebp 2050 _AddPackageCredit(PackageCredit("libwebp") 2051 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2052 "2010-2011 Google Inc. All rights reserved.")) 2053 .SetLicense(kBSDThreeClause) 2054 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 2055 2056 // libavif 2057 _AddPackageCredit(PackageCredit("libavif") 2058 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 2059 "2019 Joe Drago. All rights reserved.")) 2060 .SetLicense(kBSDThreeClause) 2061 .SetURL("https://github.com/AOMediaCodec/libavif")); 2062 2063 // GTF 2064 _AddPackageCredit(PackageCredit("GTF") 2065 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 2066 "Generalized Timing Formula")) 2067 .SetLicense(kBSDThreeClause) 2068 .SetURL("http://gtf.sourceforge.net/")); 2069 2070 // libqrencode 2071 _AddPackageCredit(PackageCredit("libqrencode") 2072 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2012 Kentaro Fukuchi")) 2073 .SetLicense(kLGPLv21) 2074 .SetURL("http://fukuchi.org/works/qrencode/")); 2075 2076 // scrypt 2077 _AddPackageCredit(PackageCredit("scrypt") 2078 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2009 Colin Percival")) 2079 .SetLicense(kBSDTwoClause) 2080 .SetURL("https://tarsnap.com/scrypt.html")); 2081 2082 _AddCopyrightsFromAttribute(); 2083 _AddPackageCreditEntries(); 2084 2085 return new CropView(creditsScroller, 0, 1, 1, 1); 2086 } 2087 2088 2089 status_t 2090 AboutView::_GetLicensePath(const char* license, BPath& path) 2091 { 2092 BPathFinder pathFinder; 2093 BStringList paths; 2094 struct stat st; 2095 2096 status_t error = pathFinder.FindPaths(B_FIND_PATH_DATA_DIRECTORY, 2097 "licenses", paths); 2098 2099 for (int i = 0; i < paths.CountStrings(); ++i) { 2100 if (error == B_OK && path.SetTo(paths.StringAt(i)) == B_OK 2101 && path.Append(license) == B_OK 2102 && lstat(path.Path(), &st) == 0) { 2103 return B_OK; 2104 } 2105 } 2106 2107 path.Unset(); 2108 return B_ENTRY_NOT_FOUND; 2109 } 2110 2111 2112 void 2113 AboutView::_AddCopyrightsFromAttribute() 2114 { 2115 #ifdef __HAIKU__ 2116 // open the app executable file 2117 char appPath[B_PATH_NAME_LENGTH]; 2118 int appFD; 2119 if (BPrivate::get_app_path(appPath) != B_OK 2120 || (appFD = open(appPath, O_RDONLY)) < 0) { 2121 return; 2122 } 2123 2124 // open the attribute 2125 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 2126 close(appFD); 2127 if (attrFD < 0) 2128 return; 2129 2130 // attach it to a FILE 2131 FileCloser attrFile(fdopen(attrFD, "r")); 2132 if (!attrFile.IsSet()) { 2133 close(attrFD); 2134 return; 2135 } 2136 2137 // read and parse the copyrights 2138 BMessage package; 2139 BString fieldName; 2140 BString fieldValue; 2141 char lineBuffer[LINE_MAX]; 2142 while (char* line 2143 = fgets(lineBuffer, sizeof(lineBuffer), attrFile.Get())) { 2144 // chop off line break 2145 size_t lineLen = strlen(line); 2146 if (lineLen > 0 && line[lineLen - 1] == '\n') 2147 line[--lineLen] = '\0'; 2148 2149 // flush previous field, if a new field begins, otherwise append 2150 if (lineLen == 0 || !isspace(line[0])) { 2151 // new field -- flush the previous one 2152 if (fieldName.Length() > 0) { 2153 fieldValue = trim_string(fieldValue.String(), 2154 fieldValue.Length()); 2155 package.AddString(fieldName.String(), fieldValue); 2156 fieldName = ""; 2157 } 2158 } else if (fieldName.Length() > 0) { 2159 // append to current field 2160 fieldValue += line; 2161 continue; 2162 } else { 2163 // bogus line -- ignore 2164 continue; 2165 } 2166 2167 if (lineLen == 0) 2168 continue; 2169 2170 // parse new field 2171 char* colon = strchr(line, ':'); 2172 if (colon == NULL) { 2173 // bogus line -- ignore 2174 continue; 2175 } 2176 2177 fieldName.SetTo(line, colon - line); 2178 fieldName = trim_string(line, colon - line); 2179 if (fieldName.Length() == 0) { 2180 // invalid field name 2181 continue; 2182 } 2183 2184 fieldValue = colon + 1; 2185 2186 if (fieldName == "Package") { 2187 // flush the current package 2188 _AddPackageCredit(PackageCredit(package)); 2189 package.MakeEmpty(); 2190 } 2191 } 2192 2193 // flush current package 2194 _AddPackageCredit(PackageCredit(package)); 2195 #endif 2196 } 2197 2198 2199 void 2200 AboutView::_AddPackageCreditEntries() 2201 { 2202 // sort the packages case-insensitively 2203 PackageCredit* packages[fPackageCredits.size()]; 2204 int32 count = 0; 2205 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 2206 it != fPackageCredits.end(); ++it) { 2207 packages[count++] = it->second; 2208 } 2209 2210 if (count > 1) { 2211 std::sort(packages, packages + count, 2212 &PackageCredit::NameLessInsensitive); 2213 } 2214 2215 // add the credits 2216 BString text; 2217 for (int32 i = 0; i < count; i++) { 2218 PackageCredit* package = packages[i]; 2219 2220 text.SetTo(package->CopyrightAt(0)); 2221 int32 count = package->CountCopyrights(); 2222 for (int32 i = 1; i < count; i++) 2223 text << "\n" << package->CopyrightAt(i); 2224 2225 AddCopyrightEntry(package->PackageName(), text.String(), 2226 package->Licenses(), package->Sources(), package->URL()); 2227 } 2228 } 2229 2230 2231 void 2232 AboutView::_AddPackageCredit(const PackageCredit& package) 2233 { 2234 if (!package.IsValid()) 2235 return; 2236 2237 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 2238 if (it != fPackageCredits.end()) { 2239 // If the new package credit isn't "better" than the old one, ignore it. 2240 PackageCredit* oldPackage = it->second; 2241 if (!package.IsBetterThan(*oldPackage)) 2242 return; 2243 2244 // replace the old credit 2245 fPackageCredits.erase(it); 2246 delete oldPackage; 2247 } 2248 2249 fPackageCredits[package.PackageName()] = new PackageCredit(package); 2250 } 2251 2252 2253 // #pragma mark - static functions 2254 2255 2256 static int 2257 ignored_pages(system_info* sysInfo) 2258 { 2259 return (int)round(sysInfo->ignored_pages * B_PAGE_SIZE / 1048576.0); 2260 } 2261 2262 2263 static int 2264 max_pages(system_info* sysInfo) 2265 { 2266 return (int)round(sysInfo->max_pages * B_PAGE_SIZE / 1048576.0); 2267 } 2268 2269 2270 static int 2271 max_and_ignored_pages(system_info* sysInfo) 2272 { 2273 return max_pages(sysInfo) + ignored_pages(sysInfo); 2274 } 2275 2276 2277 static int 2278 used_pages(system_info* sysInfo) 2279 { 2280 return (int)round(sysInfo->used_pages * B_PAGE_SIZE / 1048576.0); 2281 } 2282 2283 2284 // #pragma mark - main 2285 2286 2287 int 2288 main() 2289 { 2290 AboutApp app; 2291 app.Run(); 2292 2293 return 0; 2294 } 2295