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