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