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