1 /* 2 * Copyright 2005-2018, Haiku, Inc. 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 * Wim van der Meer <WPJvanderMeer@gmail.com> 10 */ 11 12 13 #include <ctype.h> 14 #include <stdio.h> 15 #include <time.h> 16 #include <unistd.h> 17 18 #include <algorithm> 19 #include <map> 20 #include <string> 21 22 #include <AppFileInfo.h> 23 #include <Application.h> 24 #include <Bitmap.h> 25 #include <DateTimeFormat.h> 26 #include <DurationFormat.h> 27 #include <File.h> 28 #include <FindDirectory.h> 29 #include <Font.h> 30 #include <fs_attr.h> 31 #include <LayoutBuilder.h> 32 #include <MessageRunner.h> 33 #include <Messenger.h> 34 #include <ObjectList.h> 35 #include <OS.h> 36 #include <Path.h> 37 #include <PathFinder.h> 38 #include <Resources.h> 39 #include <Screen.h> 40 #include <ScrollView.h> 41 #include <String.h> 42 #include <StringFormat.h> 43 #include <StringList.h> 44 #include <StringView.h> 45 #include <TranslationUtils.h> 46 #include <TranslatorFormats.h> 47 #include <View.h> 48 #include <Volume.h> 49 #include <VolumeRoster.h> 50 #include <Window.h> 51 52 #include <AppMisc.h> 53 #include <AutoDeleter.h> 54 #include <AutoDeleterPosix.h> 55 #include <cpu_type.h> 56 #include <parsedate.h> 57 #include <system_revision.h> 58 59 #include <Catalog.h> 60 #include <Language.h> 61 #include <Locale.h> 62 #include <LocaleRoster.h> 63 64 #include "HyperTextActions.h" 65 #include "HyperTextView.h" 66 #include "Utilities.h" 67 68 #include "Credits.h" 69 70 #ifndef LINE_MAX 71 #define LINE_MAX 2048 72 #endif 73 74 #define SCROLL_CREDITS_VIEW 'mviv' 75 76 #undef B_TRANSLATION_CONTEXT 77 #define B_TRANSLATION_CONTEXT "AboutWindow" 78 79 80 81 static const char* UptimeToString(char string[], size_t size); 82 static const char* MemSizeToString(char string[], size_t size, 83 system_info* info); 84 static const char* MemUsageToString(char string[], size_t size, 85 system_info* info); 86 87 88 static const rgb_color kIdealHaikuGreen = { 42, 131, 36, 255 }; 89 static const rgb_color kIdealHaikuOrange = { 255, 69, 0, 255 }; 90 static const rgb_color kIdealHaikuYellow = { 255, 176, 0, 255 }; 91 static const rgb_color kIdealBeOSBlue = { 0, 0, 200, 255 }; 92 static const rgb_color kIdealBeOSRed = { 200, 0, 0, 255 }; 93 94 static const char* kBSDTwoClause = B_TRANSLATE_MARK("BSD (2-clause)"); 95 static const char* kBSDThreeClause = B_TRANSLATE_MARK("BSD (3-clause)"); 96 static const char* kBSDFourClause = B_TRANSLATE_MARK("BSD (4-clause)"); 97 static const char* kGPLv2 = B_TRANSLATE_MARK("GNU GPL v2"); 98 static const char* kGPLv3 = B_TRANSLATE_MARK("GNU GPL v3"); 99 static const char* kLGPLv2 = B_TRANSLATE_MARK("GNU LGPL v2"); 100 static const char* kLGPLv21 = B_TRANSLATE_MARK("GNU LGPL v2.1"); 101 #if 0 102 static const char* kPublicDomain = B_TRANSLATE_MARK("Public Domain"); 103 #endif 104 #ifdef __i386__ 105 static const char* kIntel2xxxFirmware = B_TRANSLATE_MARK("Intel (2xxx firmware)"); 106 static const char* kIntelFirmware = B_TRANSLATE_MARK("Intel WiFi Firmware"); 107 static const char* kMarvellFirmware = B_TRANSLATE_MARK("Marvell (firmware)"); 108 static const char* kRalinkFirmware = B_TRANSLATE_MARK("Ralink WiFi Firmware"); 109 #endif 110 111 112 static int 113 TranslationComparator(const void* left, const void* right) 114 { 115 const Translation* leftTranslation = *(const Translation**)left; 116 const Translation* rightTranslation = *(const Translation**)right; 117 118 BLanguage* language; 119 BString leftName; 120 if (BLocaleRoster::Default()->GetLanguage(leftTranslation->languageCode, 121 &language) == B_OK) { 122 language->GetName(leftName); 123 delete language; 124 } else 125 leftName = leftTranslation->languageCode; 126 127 BString rightName; 128 if (BLocaleRoster::Default()->GetLanguage(rightTranslation->languageCode, 129 &language) == B_OK) { 130 language->GetName(rightName); 131 delete language; 132 } else 133 rightName = rightTranslation->languageCode; 134 135 BCollator collator; 136 BLocale::Default()->GetCollator(&collator); 137 return collator.Compare(leftName.String(), rightName.String()); 138 } 139 140 141 class AboutApp : public BApplication { 142 public: 143 AboutApp(); 144 void MessageReceived(BMessage* message); 145 }; 146 147 148 class AboutView; 149 150 class AboutWindow : public BWindow { 151 public: 152 AboutWindow(); 153 154 virtual bool QuitRequested(); 155 156 AboutView* fAboutView; 157 }; 158 159 160 class LogoView : public BView { 161 public: 162 LogoView(); 163 virtual ~LogoView(); 164 165 virtual BSize MinSize(); 166 virtual BSize MaxSize(); 167 168 virtual void Draw(BRect updateRect); 169 170 private: 171 BBitmap* fLogo; 172 }; 173 174 175 class CropView : public BView { 176 public: 177 CropView(BView* target, int32 left, int32 top, 178 int32 right, int32 bottom); 179 virtual ~CropView(); 180 181 virtual BSize MinSize(); 182 virtual BSize MaxSize(); 183 184 virtual void DoLayout(); 185 186 private: 187 BView* fTarget; 188 int32 fCropLeft; 189 int32 fCropTop; 190 int32 fCropRight; 191 int32 fCropBottom; 192 }; 193 194 195 class AboutView : public BView { 196 public: 197 AboutView(); 198 ~AboutView(); 199 200 virtual void AttachedToWindow(); 201 virtual void AllAttached(); 202 virtual void Pulse(); 203 204 virtual void MessageReceived(BMessage* msg); 205 virtual void MouseDown(BPoint point); 206 207 void AddCopyrightEntry(const char* name, 208 const char* text, 209 const StringVector& licenses, 210 const StringVector& sources, 211 const char* url); 212 void AddCopyrightEntry(const char* name, 213 const char* text, const char* url = NULL); 214 void PickRandomHaiku(); 215 216 217 void _AdjustTextColors(); 218 private: 219 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 220 221 private: 222 BView* _CreateLabel(const char* name, const char* label); 223 BView* _CreateCreditsView(); 224 status_t _GetLicensePath(const char* license, 225 BPath& path); 226 void _AddCopyrightsFromAttribute(); 227 void _AddPackageCredit(const PackageCredit& package); 228 void _AddPackageCreditEntries(); 229 230 BStringView* fMemView; 231 BStringView* fUptimeView; 232 BView* fInfoView; 233 HyperTextView* fCreditsView; 234 235 BObjectList<BView> fTextViews; 236 BObjectList<BView> fSubTextViews; 237 238 BBitmap* fLogo; 239 240 bigtime_t fLastActionTime; 241 BMessageRunner* fScrollRunner; 242 PackageCreditMap fPackageCredits; 243 244 private: 245 rgb_color fTextColor; 246 rgb_color fLinkColor; 247 rgb_color fHaikuOrangeColor; 248 rgb_color fHaikuGreenColor; 249 rgb_color fHaikuYellowColor; 250 rgb_color fBeOSRedColor; 251 rgb_color fBeOSBlueColor; 252 }; 253 254 255 // #pragma mark - 256 257 258 AboutApp::AboutApp() 259 : BApplication("application/x-vnd.Haiku-About") 260 { 261 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("AboutSystem"); 262 263 AboutWindow *window = new(std::nothrow) AboutWindow(); 264 if (window) 265 window->Show(); 266 } 267 268 269 void 270 AboutApp::MessageReceived(BMessage* message) 271 { 272 switch (message->what) { 273 case B_SILENT_RELAUNCH: 274 WindowAt(0)->Activate(); 275 break; 276 } 277 278 BApplication::MessageReceived(message); 279 } 280 281 282 // #pragma mark - 283 284 285 AboutWindow::AboutWindow() 286 : BWindow(BRect(0, 0, 500, 300), B_TRANSLATE("About this system"), 287 B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE) 288 { 289 SetLayout(new BGroupLayout(B_VERTICAL)); 290 fAboutView = new AboutView(); 291 AddChild(fAboutView); 292 293 // Make sure we take the minimal window size into account when centering 294 BSize size = GetLayout()->MinSize(); 295 ResizeTo(max_c(size.width, Bounds().Width()), 296 max_c(size.height, Bounds().Height())); 297 298 CenterOnScreen(); 299 } 300 301 302 bool 303 AboutWindow::QuitRequested() 304 { 305 be_app->PostMessage(B_QUIT_REQUESTED); 306 return true; 307 } 308 309 310 // #pragma mark - LogoView 311 312 313 LogoView::LogoView() 314 : BView("logo", B_WILL_DRAW) 315 { 316 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png"); 317 SetViewColor(255, 255, 255); 318 } 319 320 321 LogoView::~LogoView() 322 { 323 delete fLogo; 324 } 325 326 327 BSize 328 LogoView::MinSize() 329 { 330 if (fLogo == NULL) 331 return BSize(0, 0); 332 333 return BSize(fLogo->Bounds().Width(), fLogo->Bounds().Height()); 334 } 335 336 337 BSize 338 LogoView::MaxSize() 339 { 340 if (fLogo == NULL) 341 return BSize(0, 0); 342 343 return BSize(B_SIZE_UNLIMITED, fLogo->Bounds().Height()); 344 } 345 346 347 void 348 LogoView::Draw(BRect updateRect) 349 { 350 if (fLogo != NULL) { 351 DrawBitmap(fLogo, 352 BPoint((Bounds().Width() - fLogo->Bounds().Width()) / 2, 0)); 353 } 354 } 355 356 357 // #pragma mark - CropView 358 359 360 CropView::CropView(BView* target, int32 left, int32 top, int32 right, 361 int32 bottom) 362 : BView("crop view", 0), 363 fTarget(target), 364 fCropLeft(left), 365 fCropTop(top), 366 fCropRight(right), 367 fCropBottom(bottom) 368 { 369 AddChild(target); 370 } 371 372 373 CropView::~CropView() 374 { 375 } 376 377 378 BSize 379 CropView::MinSize() 380 { 381 if (fTarget == NULL) 382 return BSize(); 383 384 BSize size = fTarget->MinSize(); 385 if (size.width != B_SIZE_UNSET) 386 size.width -= fCropLeft + fCropRight; 387 if (size.height != B_SIZE_UNSET) 388 size.height -= fCropTop + fCropBottom; 389 390 return size; 391 } 392 393 394 BSize 395 CropView::MaxSize() 396 { 397 if (fTarget == NULL) 398 return BSize(); 399 400 BSize size = fTarget->MaxSize(); 401 if (size.width != B_SIZE_UNSET) 402 size.width -= fCropLeft + fCropRight; 403 if (size.height != B_SIZE_UNSET) 404 size.height -= fCropTop + fCropBottom; 405 406 return size; 407 } 408 409 410 void 411 CropView::DoLayout() 412 { 413 BView::DoLayout(); 414 415 if (fTarget == NULL) 416 return; 417 418 fTarget->MoveTo(-fCropLeft, -fCropTop); 419 fTarget->ResizeTo(Bounds().Width() + fCropLeft + fCropRight, 420 Bounds().Height() + fCropTop + fCropBottom); 421 } 422 423 424 // #pragma mark - AboutView 425 426 #undef B_TRANSLATION_CONTEXT 427 #define B_TRANSLATION_CONTEXT "AboutView" 428 429 AboutView::AboutView() 430 : BView("aboutview", B_WILL_DRAW | B_PULSE_NEEDED), 431 fLastActionTime(system_time()), 432 fScrollRunner(NULL) 433 { 434 // Assign the colors, sadly this does not respect live color updates 435 fTextColor = ui_color(B_DOCUMENT_TEXT_COLOR); 436 fLinkColor = ui_color(B_LINK_TEXT_COLOR); 437 fHaikuOrangeColor = mix_color(fTextColor, kIdealHaikuOrange, 191); 438 fHaikuGreenColor = mix_color(fTextColor, kIdealHaikuGreen, 191); 439 fHaikuYellowColor = mix_color(fTextColor, kIdealHaikuYellow, 191); 440 fBeOSRedColor = mix_color(fTextColor, kIdealBeOSRed, 191); 441 fBeOSBlueColor = mix_color(fTextColor, kIdealBeOSBlue, 191); 442 443 // Begin Construction of System Information controls 444 system_info systemInfo; 445 get_system_info(&systemInfo); 446 447 // Create all the various labels for system infomation 448 449 // OS Version 450 451 char string[1024]; 452 strlcpy(string, B_TRANSLATE("Unknown"), sizeof(string)); 453 454 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 455 BPath path; 456 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 457 path.Append("libbe.so"); 458 459 BAppFileInfo appFileInfo; 460 version_info versionInfo; 461 BFile file; 462 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 463 && appFileInfo.SetTo(&file) == B_OK 464 && appFileInfo.GetVersionInfo(&versionInfo, 465 B_APP_VERSION_KIND) == B_OK 466 && versionInfo.short_info[0] != '\0') 467 strlcpy(string, versionInfo.short_info, sizeof(string)); 468 } 469 470 // Add system revision 471 const char* haikuRevision = __get_haiku_revision(); 472 if (haikuRevision != NULL) { 473 strlcat(string, " (", sizeof(string)); 474 strlcat(string, B_TRANSLATE("Revision"), sizeof(string)); 475 strlcat(string, " ", sizeof(string)); 476 strlcat(string, haikuRevision, sizeof(string)); 477 strlcat(string, ")", sizeof(string)); 478 } 479 480 BStringView* versionView = new BStringView("ostext", string); 481 fSubTextViews.AddItem(versionView); 482 versionView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 483 B_ALIGN_VERTICAL_UNSET)); 484 485 BStringView* abiView = new BStringView("abitext", B_HAIKU_ABI_NAME); 486 fSubTextViews.AddItem(abiView); 487 abiView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 488 B_ALIGN_VERTICAL_UNSET)); 489 490 // CPU count, type and clock speed 491 static BStringFormat format(B_TRANSLATE_COMMENT( 492 "{0, plural, one{Processor:} other{# Processors:}}", 493 "\"Processor:\" or \"2 Processors:\"")); 494 495 BString processorLabel; 496 format.Format(processorLabel, systemInfo.cpu_count); 497 498 uint32 topologyNodeCount = 0; 499 cpu_topology_node_info* topology = NULL; 500 get_cpu_topology_info(NULL, &topologyNodeCount); 501 if (topologyNodeCount != 0) 502 topology = new cpu_topology_node_info[topologyNodeCount]; 503 get_cpu_topology_info(topology, &topologyNodeCount); 504 505 enum cpu_platform platform = B_CPU_UNKNOWN; 506 enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; 507 uint32 cpuModel = 0; 508 for (uint32 i = 0; i < topologyNodeCount; i++) { 509 switch (topology[i].type) { 510 case B_TOPOLOGY_ROOT: 511 platform = topology[i].data.root.platform; 512 break; 513 514 case B_TOPOLOGY_PACKAGE: 515 cpuVendor = topology[i].data.package.vendor; 516 break; 517 518 case B_TOPOLOGY_CORE: 519 cpuModel = topology[i].data.core.model; 520 break; 521 522 default: 523 break; 524 } 525 } 526 527 delete[] topology; 528 529 BString cpuType; 530 cpuType << get_cpu_vendor_string(cpuVendor) 531 << " " << get_cpu_model_string(platform, cpuVendor, cpuModel); 532 533 BStringView* cpuView = new BStringView("cputext", cpuType.String()); 534 fSubTextViews.AddItem(cpuView); 535 cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 536 B_ALIGN_VERTICAL_UNSET)); 537 538 int32 clockSpeed = get_rounded_cpu_speed(); 539 if (clockSpeed < 1000) 540 snprintf(string, sizeof(string), B_TRANSLATE("%ld MHz"), clockSpeed); 541 else 542 snprintf(string, sizeof(string), B_TRANSLATE("%.2f GHz"), 543 clockSpeed / 1000.0f); 544 545 BStringView* frequencyView = new BStringView("frequencytext", string); 546 fSubTextViews.AddItem(frequencyView); 547 frequencyView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 548 B_ALIGN_VERTICAL_UNSET)); 549 550 // RAM 551 BStringView *memSizeView = new BStringView("ramsizetext", 552 MemSizeToString(string, sizeof(string), &systemInfo)); 553 fSubTextViews.AddItem(memSizeView); 554 memSizeView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 555 B_ALIGN_VERTICAL_UNSET)); 556 557 fMemView = new BStringView("ramtext", 558 MemUsageToString(string, sizeof(string), &systemInfo)); 559 fSubTextViews.AddItem(fMemView); 560 fMemView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 561 B_ALIGN_VERTICAL_UNSET)); 562 563 // Kernel build time/date 564 BString kernelTimeDate; 565 kernelTimeDate << systemInfo.kernel_build_date 566 << " " << systemInfo.kernel_build_time; 567 BString buildTimeDate; 568 569 time_t buildTimeDateStamp = parsedate(kernelTimeDate, -1); 570 if (buildTimeDateStamp > 0) { 571 if (BDateTimeFormat().Format(buildTimeDate, buildTimeDateStamp, 572 B_LONG_DATE_FORMAT, B_MEDIUM_TIME_FORMAT) != B_OK) 573 buildTimeDate.SetTo(kernelTimeDate); 574 } else 575 buildTimeDate.SetTo(kernelTimeDate); 576 577 BStringView* kernelView = new BStringView("kerneltext", buildTimeDate); 578 fSubTextViews.AddItem(kernelView); 579 kernelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 580 B_ALIGN_VERTICAL_UNSET)); 581 582 // Uptime 583 fUptimeView = new BStringView("uptimetext", "..."); 584 fSubTextViews.AddItem(fUptimeView); 585 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 586 587 const float offset = 5; 588 589 SetLayout(new BGroupLayout(B_HORIZONTAL, 0)); 590 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 591 592 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 593 .AddGroup(B_VERTICAL, 0) 594 .Add(new LogoView()) 595 .AddGroup(B_VERTICAL, 0) 596 .Add(_CreateLabel("oslabel", B_TRANSLATE("Version:"))) 597 .Add(versionView) 598 .Add(abiView) 599 .AddStrut(offset) 600 .Add(_CreateLabel("cpulabel", processorLabel.String())) 601 .Add(cpuView) 602 .Add(frequencyView) 603 .AddStrut(offset) 604 .Add(_CreateLabel("memlabel", B_TRANSLATE("Memory:"))) 605 .Add(memSizeView) 606 .Add(fMemView) 607 .AddStrut(offset) 608 .Add(_CreateLabel("kernellabel", B_TRANSLATE("Kernel:"))) 609 .Add(kernelView) 610 .AddStrut(offset) 611 .Add(_CreateLabel("uptimelabel", 612 B_TRANSLATE("Time running:"))) 613 .Add(fUptimeView) 614 .AddGlue() 615 .SetInsets(5, 5, 5, 5) 616 .End() 617 // TODO: investigate: adding this causes the time to be cut 618 //.AddGlue() 619 .End() 620 .Add(_CreateCreditsView()); 621 622 float min = fMemView->MinSize().width * 1.1f; 623 fCreditsView->SetExplicitMinSize(BSize(min * 3, min)); 624 } 625 626 627 AboutView::~AboutView() 628 { 629 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 630 it != fPackageCredits.end(); it++) { 631 632 delete it->second; 633 } 634 635 delete fScrollRunner; 636 } 637 638 639 void 640 AboutView::AttachedToWindow() 641 { 642 BView::AttachedToWindow(); 643 Window()->SetPulseRate(500000); 644 SetEventMask(B_POINTER_EVENTS); 645 DoLayout(); 646 } 647 648 649 void 650 AboutView::AllAttached() 651 { 652 _AdjustTextColors(); 653 } 654 655 656 void 657 AboutView::MouseDown(BPoint point) 658 { 659 BRect r(92, 26, 105, 31); 660 if (r.Contains(point)) 661 BMessenger(this).SendMessage('eegg'); 662 663 if (Bounds().Contains(point)) { 664 fLastActionTime = system_time(); 665 delete fScrollRunner; 666 fScrollRunner = NULL; 667 } 668 } 669 670 671 void 672 AboutView::Pulse() 673 { 674 char string[255]; 675 system_info info; 676 get_system_info(&info); 677 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 678 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 679 680 if (fScrollRunner == NULL 681 && system_time() > fLastActionTime + 10000000) { 682 BMessage message(SCROLL_CREDITS_VIEW); 683 //fScrollRunner = new BMessageRunner(this, &message, 25000, -1); 684 } 685 } 686 687 688 void 689 AboutView::MessageReceived(BMessage* msg) 690 { 691 switch (msg->what) { 692 case B_COLORS_UPDATED: 693 { 694 if (msg->HasColor(ui_color_name(B_PANEL_TEXT_COLOR))) 695 _AdjustTextColors(); 696 697 break; 698 } 699 case SCROLL_CREDITS_VIEW: 700 { 701 BScrollBar* scrollBar = 702 fCreditsView->ScrollBar(B_VERTICAL); 703 if (scrollBar == NULL) 704 break; 705 float max, min; 706 scrollBar->GetRange(&min, &max); 707 if (scrollBar->Value() < max) 708 fCreditsView->ScrollBy(0, 1); 709 710 break; 711 } 712 713 case 'eegg': 714 { 715 printf("Easter egg\n"); 716 PickRandomHaiku(); 717 break; 718 } 719 720 default: 721 BView::MessageReceived(msg); 722 break; 723 } 724 } 725 726 727 void 728 AboutView::AddCopyrightEntry(const char* name, const char* text, 729 const char* url) 730 { 731 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 732 } 733 734 735 void 736 AboutView::AddCopyrightEntry(const char* name, const char* text, 737 const StringVector& licenses, const StringVector& sources, 738 const char* url) 739 { 740 BFont font(be_bold_font); 741 //font.SetSize(be_bold_font->Size()); 742 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 743 744 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuYellowColor); 745 fCreditsView->Insert(name); 746 fCreditsView->Insert("\n"); 747 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 748 fCreditsView->Insert(text); 749 fCreditsView->Insert("\n"); 750 751 if (licenses.CountStrings() > 0) { 752 if (licenses.CountStrings() > 1) 753 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 754 else 755 fCreditsView->Insert(B_TRANSLATE("License: ")); 756 757 for (int32 i = 0; i < licenses.CountStrings(); i++) { 758 const char* license = licenses.StringAt(i); 759 760 if (i > 0) 761 fCreditsView->Insert(", "); 762 763 BString licenseName; 764 BString licenseURL; 765 parse_named_url(license, licenseName, licenseURL); 766 767 BPath licensePath; 768 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 769 fCreditsView->InsertHyperText(B_TRANSLATE_NOCOLLECT(licenseName), 770 new OpenFileAction(licensePath.Path())); 771 } else 772 fCreditsView->Insert(licenseName); 773 } 774 775 fCreditsView->Insert("\n"); 776 } 777 778 if (sources.CountStrings() > 0) { 779 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 780 781 for (int32 i = 0; i < sources.CountStrings(); i++) { 782 const char* source = sources.StringAt(i); 783 784 if (i > 0) 785 fCreditsView->Insert(", "); 786 787 BString urlName; 788 BString urlAddress; 789 parse_named_url(source, urlName, urlAddress); 790 791 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 792 &fLinkColor); 793 fCreditsView->InsertHyperText(urlName, 794 new URLAction(urlAddress)); 795 } 796 797 fCreditsView->Insert("\n"); 798 } 799 800 if (url) { 801 BString urlName; 802 BString urlAddress; 803 parse_named_url(url, urlName, urlAddress); 804 805 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 806 &fLinkColor); 807 fCreditsView->InsertHyperText(urlName, 808 new URLAction(urlAddress)); 809 fCreditsView->Insert("\n"); 810 } 811 fCreditsView->Insert("\n"); 812 } 813 814 815 void 816 AboutView::PickRandomHaiku() 817 { 818 BPath path; 819 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK) 820 path = "/system/data"; 821 path.Append("fortunes"); 822 path.Append("Haiku"); 823 824 BFile fortunes(path.Path(), B_READ_ONLY); 825 struct stat st; 826 if (fortunes.InitCheck() < B_OK) 827 return; 828 if (fortunes.GetStat(&st) < B_OK) 829 return; 830 831 char* buff = (char*)malloc((size_t)st.st_size + 1); 832 if (!buff) 833 return; 834 buff[(size_t)st.st_size] = '\0'; 835 BList haikuList; 836 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 837 char* p = buff; 838 while (p && *p) { 839 char* e = strchr(p, '%'); 840 BString* s = new BString(p, e ? (e - p) : -1); 841 haikuList.AddItem(s); 842 p = e; 843 if (p && (*p == '%')) 844 p++; 845 if (p && (*p == '\n')) 846 p++; 847 } 848 } 849 free(buff); 850 if (haikuList.CountItems() < 1) 851 return; 852 853 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 854 BFont font(be_bold_font); 855 font.SetSize(be_bold_font->Size()); 856 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 857 fCreditsView->SelectAll(); 858 fCreditsView->Delete(); 859 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fTextColor); 860 fCreditsView->Insert(s->String()); 861 fCreditsView->Insert("\n"); 862 while ((s = (BString*)haikuList.RemoveItem((int32)0))) { 863 delete s; 864 } 865 } 866 867 868 void 869 AboutView::_AdjustTextColors() 870 { 871 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 872 rgb_color color = mix_color(ViewColor(), textColor, 192); 873 874 BView* view = NULL; 875 for (int32 index = 0; index < fSubTextViews.CountItems(); ++index) { 876 view = fSubTextViews.ItemAt(index); 877 view->SetHighColor(color); 878 view->Invalidate(); 879 } 880 881 // Labels 882 for (int32 index = 0; index < fTextViews.CountItems(); ++index) { 883 view = fTextViews.ItemAt(index); 884 view->SetHighColor(textColor); 885 view->Invalidate(); 886 } 887 } 888 889 890 BView* 891 AboutView::_CreateLabel(const char* name, const char* label) 892 { 893 BStringView* labelView = new BStringView(name, label); 894 labelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 895 B_ALIGN_VERTICAL_UNSET)); 896 labelView->SetFont(be_bold_font); 897 fTextViews.AddItem(labelView); 898 return labelView; 899 } 900 901 902 BView* 903 AboutView::_CreateCreditsView() 904 { 905 // Begin construction of the credits view 906 fCreditsView = new HyperTextView("credits"); 907 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 908 fCreditsView->SetStylable(true); 909 fCreditsView->MakeEditable(false); 910 fCreditsView->SetWordWrap(true); 911 fCreditsView->SetInsets(5, 5, 5, 5); 912 fCreditsView->SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); 913 914 BScrollView* creditsScroller = new BScrollView("creditsScroller", 915 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 916 B_PLAIN_BORDER); 917 918 // Haiku copyright 919 BFont font(be_bold_font); 920 font.SetSize(font.Size() + 4); 921 922 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 923 fCreditsView->Insert("Haiku\n"); 924 925 char string[1024]; 926 time_t time = ::time(NULL); 927 struct tm* tm = localtime(&time); 928 int32 year = tm->tm_year + 1900; 929 if (year < 2008) 930 year = 2008; 931 snprintf(string, sizeof(string), 932 B_TRANSLATE(COPYRIGHT_STRING "2001-%" B_PRId32 " The Haiku project. "), 933 year); 934 935 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 936 fCreditsView->Insert(string); 937 938 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 939 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 940 "property of Haiku, Inc. or of the respective authors where expressly " 941 "noted in the source. Haiku" B_UTF8_REGISTERED 942 " and the HAIKU logo" B_UTF8_REGISTERED 943 " are registered trademarks of Haiku, Inc." 944 "\n\n")); 945 946 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 947 fCreditsView->InsertHyperText("https://www.haiku-os.org", 948 new URLAction("https://www.haiku-os.org")); 949 fCreditsView->Insert("\n\n"); 950 951 font.SetSize(be_bold_font->Size()); 952 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 953 954 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 955 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 956 957 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 958 fCreditsView->Insert(kCurrentMaintainers); 959 960 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 961 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 962 963 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 964 fCreditsView->Insert(kPastMaintainers); 965 966 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 967 fCreditsView->Insert(B_TRANSLATE("Website & marketing:\n")); 968 969 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 970 fCreditsView->Insert(kWebsiteTeam); 971 972 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 973 fCreditsView->Insert(B_TRANSLATE("Past website & marketing:\n")); 974 975 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 976 fCreditsView->Insert(kPastWebsiteTeam); 977 978 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 979 fCreditsView->Insert(B_TRANSLATE("Testing and bug triaging:\n")); 980 981 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 982 fCreditsView->Insert(kTestingTeam); 983 984 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 985 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 986 987 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 988 fCreditsView->Insert(kContributors); 989 fCreditsView->Insert( 990 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 991 "and probably some more we forgot to mention (sorry!)" 992 "\n\n")); 993 994 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 995 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 996 997 BLanguage* lang; 998 BString langName; 999 1000 BList sortedTranslations; 1001 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1002 const Translation* translation = &kTranslations[i]; 1003 sortedTranslations.AddItem((void*)translation); 1004 } 1005 sortedTranslations.SortItems(TranslationComparator); 1006 1007 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1008 const Translation& translation 1009 = *(const Translation*)sortedTranslations.ItemAt(i); 1010 1011 langName.Truncate(0); 1012 if (BLocaleRoster::Default()->GetLanguage(translation.languageCode, 1013 &lang) == B_OK) { 1014 lang->GetName(langName); 1015 delete lang; 1016 } else { 1017 // We failed to get the localized readable name, 1018 // go with what we have. 1019 langName.Append(translation.languageCode); 1020 } 1021 1022 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 1023 fCreditsView->Insert("\n"); 1024 fCreditsView->Insert(langName); 1025 fCreditsView->Insert("\n"); 1026 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1027 fCreditsView->Insert(translation.names); 1028 } 1029 1030 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuOrangeColor); 1031 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 1032 1033 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1034 BString beosCredits(B_TRANSLATE( 1035 "Be Inc. and its developer team, for having created BeOS!\n\n")); 1036 int32 beosOffset = beosCredits.FindFirst("BeOS"); 1037 fCreditsView->Insert(beosCredits.String(), 1038 (beosOffset < 0) ? beosCredits.Length() : beosOffset); 1039 if (beosOffset > -1) { 1040 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fBeOSBlueColor); 1041 fCreditsView->Insert("B"); 1042 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fBeOSRedColor); 1043 fCreditsView->Insert("e"); 1044 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1045 beosCredits.Remove(0, beosOffset + 2); 1046 fCreditsView->Insert(beosCredits.String(), beosCredits.Length()); 1047 } 1048 fCreditsView->Insert( 1049 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 1050 fCreditsView->Insert( 1051 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 1052 fCreditsView->Insert( 1053 B_TRANSLATE("The HaikuPorts team\n")); 1054 fCreditsView->Insert( 1055 B_TRANSLATE("The Haikuware team and their bounty program\n")); 1056 fCreditsView->Insert( 1057 B_TRANSLATE("The BeGeistert team\n")); 1058 fCreditsView->Insert( 1059 B_TRANSLATE("Google and their Google Summer of Code and Google Code In " 1060 "programs\n")); 1061 fCreditsView->Insert( 1062 B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n")); 1063 fCreditsView->Insert( 1064 B_TRANSLATE(B_UTF8_ELLIPSIS "and the many people making donations!\n\n")); 1065 1066 // copyrights for various projects we use 1067 1068 BPath mitPath; 1069 _GetLicensePath("MIT", mitPath); 1070 BPath lgplPath; 1071 _GetLicensePath("GNU LGPL v2.1", lgplPath); 1072 1073 font.SetSize(be_bold_font->Size() + 4); 1074 font.SetFace(B_BOLD_FACE); 1075 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &fHaikuGreenColor); 1076 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 1077 1078 1079 // Haiku license 1080 BString haikuLicense = B_TRANSLATE_COMMENT("The code that is unique to " 1081 "Haiku, especially the kernel and all code that applications may link " 1082 "against, is distributed under the terms of the <MIT license>. " 1083 "Some system libraries contain third party code distributed under the " 1084 "<LGPL license>. You can find the copyrights to third party code below." 1085 "\n\n", "<MIT license> and <LGPL license> aren't variables and can be " 1086 "translated. However, please, don't remove < and > as they're needed " 1087 "as placeholders for proper hypertext functionality."); 1088 int32 licensePart1 = haikuLicense.FindFirst("<"); 1089 int32 licensePart2 = haikuLicense.FindFirst(">"); 1090 int32 licensePart3 = haikuLicense.FindLast("<"); 1091 int32 licensePart4 = haikuLicense.FindLast(">"); 1092 BString part; 1093 haikuLicense.CopyInto(part, 0, licensePart1); 1094 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1095 fCreditsView->Insert(part); 1096 1097 part.Truncate(0); 1098 haikuLicense.CopyInto(part, licensePart1 + 1, licensePart2 - 1 1099 - licensePart1); 1100 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 1101 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1102 1103 part.Truncate(0); 1104 haikuLicense.CopyInto(part, licensePart2 + 1, licensePart3 - 1 1105 - licensePart2); 1106 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1107 fCreditsView->Insert(part); 1108 1109 part.Truncate(0); 1110 haikuLicense.CopyInto(part, licensePart3 + 1, licensePart4 - 1 1111 - licensePart3); 1112 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fLinkColor); 1113 fCreditsView->InsertHyperText(part, new OpenFileAction(lgplPath.Path())); 1114 1115 part.Truncate(0); 1116 haikuLicense.CopyInto(part, licensePart4 + 1, haikuLicense.Length() - 1 1117 - licensePart4); 1118 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &fTextColor); 1119 fCreditsView->Insert(part); 1120 1121 // GNU copyrights 1122 AddCopyrightEntry("The GNU Project", 1123 B_TRANSLATE("Contains software from the GNU Project, " 1124 "released under the GPL and LGPL licenses:\n" 1125 "GNU C Library, " 1126 "GNU coretools, diffutils, findutils, " 1127 "sharutils, gawk, bison, m4, make, " 1128 "wget, ncurses, termcap, " 1129 "Bourne Again Shell.\n" 1130 COPYRIGHT_STRING "The Free Software Foundation."), 1131 StringVector(kLGPLv21, kGPLv2, kGPLv3, NULL), 1132 StringVector(), 1133 "https://www.gnu.org"); 1134 1135 // FreeBSD copyrights 1136 AddCopyrightEntry("The FreeBSD Project", 1137 B_TRANSLATE("Contains software from the FreeBSD Project, " 1138 "released under the BSD license:\n" 1139 "ftpd, ping, telnet, telnetd, traceroute\n" 1140 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1141 "All rights reserved."), 1142 StringVector(kBSDTwoClause, kBSDThreeClause, kBSDFourClause, 1143 NULL), 1144 StringVector(), 1145 "https://www.freebsd.org"); 1146 1147 // FFmpeg copyrights 1148 _AddPackageCredit(PackageCredit("FFmpeg") 1149 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000-2019 Fabrice " 1150 "Bellard, et al.")) 1151 .SetLicenses(kLGPLv21, kLGPLv2, NULL) 1152 .SetURL("https://www.ffmpeg.org")); 1153 1154 // AGG copyrights 1155 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1156 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2006 Maxim " 1157 "Shemanarev (McSeem).")) 1158 .SetLicenses("Anti-Grain Geometry", kBSDThreeClause, NULL) 1159 .SetURL("http://www.antigrain.com")); 1160 1161 // FreeType copyrights 1162 _AddPackageCredit(PackageCredit("FreeType2") 1163 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1996-2002, 2006 " 1164 "David Turner, Robert Wilhelm and Werner Lemberg."), 1165 COPYRIGHT_STRING "2014 The FreeType Project. " 1166 "All rights reserved.", 1167 NULL) 1168 .SetLicense("FreeType") 1169 .SetURL("http://www.freetype.org")); 1170 1171 // Mesa3D (http://www.mesa3d.org) copyrights 1172 _AddPackageCredit(PackageCredit("Mesa") 1173 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1174 "Mesa3D Project. All rights reserved.")) 1175 .SetLicense("MIT") 1176 .SetURL("http://www.mesa3d.org")); 1177 1178 // SGI's GLU implementation copyrights 1179 _AddPackageCredit(PackageCredit("GLU") 1180 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1991-2000 " 1181 "Silicon Graphics, Inc. All rights reserved.")) 1182 .SetLicense("SGI Free B") 1183 .SetURL("http://www.sgi.com/products/software/opengl")); 1184 1185 // GLUT implementation copyrights 1186 _AddPackageCredit(PackageCredit("GLUT") 1187 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1188 "All rights reserved."), 1189 COPYRIGHT_STRING "1997 Be Inc.", 1190 COPYRIGHT_STRING "1999 Jake Hamby.", 1191 NULL) 1192 .SetLicense("MIT") 1193 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1194 1195 // OpenGroup & DEC (BRegion backend) copyright 1196 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1197 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1198 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1199 "Corporation, Maynard, Massachusetts.\n" 1200 "All rights reserved."), 1201 NULL) 1202 .SetLicenses("OpenGroup", "DEC", NULL) 1203 .SetURL("https://xfree86.org")); 1204 1205 // Bitstream Charter font 1206 _AddPackageCredit(PackageCredit("Bitstream Charter font") 1207 .SetCopyrights(COPYRIGHT_STRING "1989-1992 Bitstream Inc.," 1208 "Cambridge, MA.", 1209 B_TRANSLATE("BITSTREAM CHARTER is a registered trademark of " 1210 "Bitstream Inc."), 1211 NULL) 1212 .SetLicense("Bitstream Charter") 1213 .SetURL("http://www.bitstream.com/")); 1214 1215 // Noto fonts copyright 1216 _AddPackageCredit(PackageCredit("Noto fonts") 1217 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING 1218 "2012-2016 Google Internationalization team."), 1219 NULL) 1220 .SetLicense("SIL Open Font Licence v1.1") 1221 .SetURL("http://www.google.com/get/noto/")); 1222 1223 _AddPackageCredit(PackageCredit("Spleen font") 1224 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING 1225 "2018-2021, Frederic Cambus"), 1226 NULL) 1227 .SetLicense(kBSDTwoClause) 1228 .SetURL("https://www.cambus.net/spleen-monospaced-bitmap-fonts/")); 1229 1230 // expat copyrights 1231 _AddPackageCredit(PackageCredit("expat") 1232 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1233 "Open Source Software Center Ltd and Clark Cooper."), 1234 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1235 NULL) 1236 .SetLicense("Expat") 1237 .SetURL("http://expat.sourceforge.net")); 1238 1239 // zlib copyrights 1240 _AddPackageCredit(PackageCredit("zlib") 1241 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1242 "Gailly and Mark Adler.")) 1243 .SetLicense("Zlib") 1244 .SetURL("http://www.zlib.net")); 1245 1246 // zip copyrights 1247 _AddPackageCredit(PackageCredit("Info-ZIP") 1248 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1249 "All rights reserved.")) 1250 .SetLicense("Info-ZIP") 1251 .SetURL("http://www.info-zip.org")); 1252 1253 // bzip2 copyrights 1254 _AddPackageCredit(PackageCredit("bzip2") 1255 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1256 "Seward. All rights reserved.")) 1257 .SetLicense(kBSDFourClause) 1258 .SetURL("http://bzip.org")); 1259 1260 // OpenEXR copyrights 1261 _AddPackageCredit(PackageCredit("OpenEXR") 1262 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2014 Industrial " 1263 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1264 .SetLicense(kBSDThreeClause) 1265 .SetURL("http://www.openexr.com")); 1266 1267 // acpica copyrights 1268 _AddPackageCredit(PackageCredit("ACPI Component Architecture (ACPICA)") 1269 .SetCopyright(COPYRIGHT_STRING "1999-2018 Intel Corp.") 1270 .SetLicense("Intel (ACPICA)") 1271 .SetURL("https://www.acpica.org")); 1272 1273 // libpng copyrights 1274 _AddPackageCredit(PackageCredit("libpng") 1275 .SetCopyright(COPYRIGHT_STRING "1995-2017 libpng authors") 1276 .SetLicense("LibPNG") 1277 .SetURL("http://www.libpng.org")); 1278 1279 // libjpeg copyrights 1280 _AddPackageCredit(PackageCredit("libjpeg") 1281 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1282 "Lane, Guido Vollbeding. This software is based in part on the " 1283 "work of the Independent JPEG Group.")) 1284 .SetLicense("LibJPEG") 1285 .SetURL("http://www.ijg.org")); 1286 1287 // libprint copyrights 1288 _AddPackageCredit(PackageCredit("libprint") 1289 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1290 "All rights reserved."))); 1291 // TODO: License! 1292 1293 // cortex copyrights 1294 _AddPackageCredit(PackageCredit("Cortex") 1295 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1296 .SetLicense(kBSDThreeClause) 1297 .SetURL("http://cortex.sourceforge.net/documentation")); 1298 1299 // FluidSynth copyrights 1300 _AddPackageCredit(PackageCredit("FluidSynth") 1301 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1302 "and others.")) 1303 .SetLicense(kLGPLv2) 1304 .SetURL("http://www.fluidsynth.org")); 1305 1306 // Xiph.org Foundation copyrights 1307 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1308 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1309 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1310 "All rights reserved."), NULL) 1311 .SetLicense(kBSDThreeClause) 1312 .SetURL("http://www.xiph.org")); 1313 1314 // Matroska 1315 _AddPackageCredit(PackageCredit("libmatroska") 1316 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1317 "All rights reserved.")) 1318 .SetLicense(kLGPLv21) 1319 .SetURL("http://www.matroska.org")); 1320 1321 // BColorQuantizer (originally CQuantizer code) 1322 _AddPackageCredit(PackageCredit("CQuantizer") 1323 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1324 "All rights reserved.")) 1325 .SetLicense("CQuantizer") 1326 .SetURL("http://www.xdp.it")); 1327 1328 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1329 _AddPackageCredit(PackageCredit("MAPM") 1330 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1331 "Ring. All rights reserved.")) 1332 .SetLicense("MAPM") 1333 .SetURL("http://tc.umn.edu/~ringx004")); 1334 1335 // MkDepend 1.7 copyright (Makefile dependency generator) 1336 _AddPackageCredit(PackageCredit("MkDepend") 1337 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1338 "All rights reserved.")) 1339 .SetLicense("MIT") 1340 .SetURL("http://bearnip.com/lars/be")); 1341 1342 // libhttpd copyright (used as Poorman backend) 1343 _AddPackageCredit(PackageCredit("libhttpd") 1344 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 1345 "Jef Poskanzer. All rights reserved.")) 1346 .SetLicense(kBSDTwoClause) 1347 .SetURL("http://www.acme.com/software/thttpd/")); 1348 1349 #ifdef __i386__ 1350 // Udis86 copyrights 1351 _AddPackageCredit(PackageCredit("Udis86") 1352 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 1353 "Vivek Mohan. All rights reserved.")) 1354 .SetLicense(kBSDTwoClause) 1355 .SetURL("http://udis86.sourceforge.net")); 1356 1357 // Intel PRO/Wireless 2100 & 2200BG firmwares 1358 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 & 2200BG firmwares") 1359 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 1360 "Intel Corporation. All rights reserved.")) 1361 .SetLicense(kIntel2xxxFirmware) 1362 .SetURL("http://www.intellinuxwireless.org/")); 1363 1364 // Intel wireless firmwares 1365 _AddPackageCredit( 1366 PackageCredit("Intel PRO/Wireless network adapter firmwares") 1367 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2015 " 1368 "Intel Corporation. All rights reserved.")) 1369 .SetLicense(kIntelFirmware) 1370 .SetURL("http://www.intellinuxwireless.org/")); 1371 1372 // Marvell 88w8363 1373 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1374 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 1375 "Marvell Semiconductor, Inc. All rights reserved.")) 1376 .SetLicense(kMarvellFirmware) 1377 .SetURL("http://www.marvell.com/")); 1378 1379 // Ralink Firmware RT2501/RT2561/RT2661 1380 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1381 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 1382 "Ralink Technology Corporation. All rights reserved.")) 1383 .SetLicense(kRalinkFirmware) 1384 .SetURL("http://www.ralinktech.com/")); 1385 #endif 1386 1387 // Gutenprint 1388 _AddPackageCredit(PackageCredit("Gutenprint") 1389 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1390 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 1391 .SetLicense(kGPLv2) 1392 .SetURL("http://gutenprint.sourceforge.net/")); 1393 1394 // libwebp 1395 _AddPackageCredit(PackageCredit("libwebp") 1396 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1397 "2010-2011 Google Inc. All rights reserved.")) 1398 .SetLicense(kBSDThreeClause) 1399 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 1400 1401 // libavif 1402 _AddPackageCredit(PackageCredit("libavif") 1403 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1404 "2019 Joe Drago. All rights reserved.")) 1405 .SetLicense(kBSDThreeClause) 1406 .SetURL("https://github.com/AOMediaCodec/libavif")); 1407 1408 // GTF 1409 _AddPackageCredit(PackageCredit("GTF") 1410 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 1411 "Generalized Timing Formula")) 1412 .SetLicense(kBSDThreeClause) 1413 .SetURL("http://gtf.sourceforge.net/")); 1414 1415 // libqrencode 1416 _AddPackageCredit(PackageCredit("libqrencode") 1417 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2012 Kentaro Fukuchi")) 1418 .SetLicense(kLGPLv21) 1419 .SetURL("http://fukuchi.org/works/qrencode/")); 1420 1421 // scrypt 1422 _AddPackageCredit(PackageCredit("scrypt") 1423 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2009 Colin Percival")) 1424 .SetLicense(kBSDTwoClause) 1425 .SetURL("https://tarsnap.com/scrypt.html")); 1426 1427 _AddCopyrightsFromAttribute(); 1428 _AddPackageCreditEntries(); 1429 1430 return new CropView(creditsScroller, 0, 1, 1, 1); 1431 } 1432 1433 1434 status_t 1435 AboutView::_GetLicensePath(const char* license, BPath& path) 1436 { 1437 BPathFinder pathFinder; 1438 BStringList paths; 1439 struct stat st; 1440 1441 status_t error = pathFinder.FindPaths(B_FIND_PATH_DATA_DIRECTORY, 1442 "licenses", paths); 1443 1444 for (int i = 0; i < paths.CountStrings(); ++i) { 1445 if (error == B_OK && path.SetTo(paths.StringAt(i)) == B_OK 1446 && path.Append(license) == B_OK 1447 && lstat(path.Path(), &st) == 0) { 1448 return B_OK; 1449 } 1450 } 1451 1452 path.Unset(); 1453 return B_ENTRY_NOT_FOUND; 1454 } 1455 1456 1457 void 1458 AboutView::_AddCopyrightsFromAttribute() 1459 { 1460 #ifdef __HAIKU__ 1461 // open the app executable file 1462 char appPath[B_PATH_NAME_LENGTH]; 1463 int appFD; 1464 if (BPrivate::get_app_path(appPath) != B_OK 1465 || (appFD = open(appPath, O_RDONLY)) < 0) { 1466 return; 1467 } 1468 1469 // open the attribute 1470 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1471 close(appFD); 1472 if (attrFD < 0) 1473 return; 1474 1475 // attach it to a FILE 1476 FileCloser attrFile(fdopen(attrFD, "r")); 1477 if (!attrFile.IsSet()) { 1478 close(attrFD); 1479 return; 1480 } 1481 1482 // read and parse the copyrights 1483 BMessage package; 1484 BString fieldName; 1485 BString fieldValue; 1486 char lineBuffer[LINE_MAX]; 1487 while (char* line 1488 = fgets(lineBuffer, sizeof(lineBuffer), attrFile.Get())) { 1489 // chop off line break 1490 size_t lineLen = strlen(line); 1491 if (lineLen > 0 && line[lineLen - 1] == '\n') 1492 line[--lineLen] = '\0'; 1493 1494 // flush previous field, if a new field begins, otherwise append 1495 if (lineLen == 0 || !isspace(line[0])) { 1496 // new field -- flush the previous one 1497 if (fieldName.Length() > 0) { 1498 fieldValue = trim_string(fieldValue.String(), 1499 fieldValue.Length()); 1500 package.AddString(fieldName.String(), fieldValue); 1501 fieldName = ""; 1502 } 1503 } else if (fieldName.Length() > 0) { 1504 // append to current field 1505 fieldValue += line; 1506 continue; 1507 } else { 1508 // bogus line -- ignore 1509 continue; 1510 } 1511 1512 if (lineLen == 0) 1513 continue; 1514 1515 // parse new field 1516 char* colon = strchr(line, ':'); 1517 if (colon == NULL) { 1518 // bogus line -- ignore 1519 continue; 1520 } 1521 1522 fieldName.SetTo(line, colon - line); 1523 fieldName = trim_string(line, colon - line); 1524 if (fieldName.Length() == 0) { 1525 // invalid field name 1526 continue; 1527 } 1528 1529 fieldValue = colon + 1; 1530 1531 if (fieldName == "Package") { 1532 // flush the current package 1533 _AddPackageCredit(PackageCredit(package)); 1534 package.MakeEmpty(); 1535 } 1536 } 1537 1538 // flush current package 1539 _AddPackageCredit(PackageCredit(package)); 1540 #endif 1541 } 1542 1543 1544 void 1545 AboutView::_AddPackageCreditEntries() 1546 { 1547 // sort the packages case-insensitively 1548 PackageCredit* packages[fPackageCredits.size()]; 1549 int32 count = 0; 1550 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1551 it != fPackageCredits.end(); ++it) { 1552 packages[count++] = it->second; 1553 } 1554 1555 if (count > 1) { 1556 std::sort(packages, packages + count, 1557 &PackageCredit::NameLessInsensitive); 1558 } 1559 1560 // add the credits 1561 for (int32 i = 0; i < count; i++) { 1562 PackageCredit* package = packages[i]; 1563 1564 BString text(package->CopyrightAt(0)); 1565 int32 count = package->CountCopyrights(); 1566 for (int32 i = 1; i < count; i++) 1567 text << "\n" << package->CopyrightAt(i); 1568 1569 AddCopyrightEntry(package->PackageName(), text.String(), 1570 package->Licenses(), package->Sources(), package->URL()); 1571 } 1572 } 1573 1574 1575 void 1576 AboutView::_AddPackageCredit(const PackageCredit& package) 1577 { 1578 if (!package.IsValid()) 1579 return; 1580 1581 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1582 if (it != fPackageCredits.end()) { 1583 // If the new package credit isn't "better" than the old one, ignore it. 1584 PackageCredit* oldPackage = it->second; 1585 if (!package.IsBetterThan(*oldPackage)) 1586 return; 1587 1588 // replace the old credit 1589 fPackageCredits.erase(it); 1590 delete oldPackage; 1591 } 1592 1593 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1594 } 1595 1596 1597 // #pragma mark - 1598 1599 1600 static const char* 1601 MemSizeToString(char string[], size_t size, system_info* info) 1602 { 1603 int inaccessibleMemory = int(info->ignored_pages 1604 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1605 if (inaccessibleMemory > 0) { 1606 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1607 "inaccessible")); 1608 1609 snprintf(string, size, "%d", int((info->max_pages 1610 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1611 message.ReplaceFirst("%total", string); 1612 1613 snprintf(string, size, "%d", inaccessibleMemory); 1614 message.ReplaceFirst("%inaccessible", string); 1615 strlcpy(string, message.String(), size); 1616 } else { 1617 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1618 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1619 } 1620 1621 return string; 1622 } 1623 1624 1625 static const char* 1626 MemUsageToString(char string[], size_t size, system_info* info) 1627 { 1628 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1629 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1630 int(100 * info->used_pages / info->max_pages)); 1631 1632 return string; 1633 } 1634 1635 1636 static const char* 1637 UptimeToString(char string[], size_t size) 1638 { 1639 BDurationFormat formatter; 1640 BString str; 1641 1642 bigtime_t uptime = system_time(); 1643 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1644 formatter.Format(str, now - uptime, now); 1645 str.CopyInto(string, 0, size); 1646 string[std::min((size_t)str.Length(), size)] = '\0'; 1647 1648 return string; 1649 } 1650 1651 1652 int 1653 main() 1654 { 1655 AboutApp app; 1656 app.Run(); 1657 return 0; 1658 } 1659 1660