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