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