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