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