1 /* 2 * Copyright (c) 2005-2010, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * René Gollent 8 * Wim van der Meer <WPJvanderMeer@gmail.com> 9 */ 10 11 12 #include <ctype.h> 13 #include <stdio.h> 14 #include <sys/utsname.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 <DurationFormat.h> 26 #include <File.h> 27 #include <FindDirectory.h> 28 #include <Font.h> 29 #include <fs_attr.h> 30 #include <LayoutBuilder.h> 31 #include <MessageRunner.h> 32 #include <Messenger.h> 33 #include <OS.h> 34 #include <Path.h> 35 #include <Resources.h> 36 #include <Screen.h> 37 #include <ScrollView.h> 38 #include <String.h> 39 #include <StringView.h> 40 #include <TranslationUtils.h> 41 #include <TranslatorFormats.h> 42 #include <View.h> 43 #include <Volume.h> 44 #include <VolumeRoster.h> 45 #include <Window.h> 46 47 #include <AppMisc.h> 48 #include <AutoDeleter.h> 49 #include <cpu_type.h> 50 51 #include <Catalog.h> 52 #include <Language.h> 53 #include <Locale.h> 54 #include <LocaleRoster.h> 55 56 #include "HyperTextActions.h" 57 #include "HyperTextView.h" 58 #include "Utilities.h" 59 60 61 #ifndef LINE_MAX 62 #define LINE_MAX 2048 63 #endif 64 65 #define SCROLL_CREDITS_VIEW 'mviv' 66 67 68 static const char* UptimeToString(char string[], size_t size); 69 static const char* MemSizeToString(char string[], size_t size, 70 system_info* info); 71 static const char* MemUsageToString(char string[], size_t size, 72 system_info* info); 73 74 75 static const rgb_color kDarkGrey = { 100, 100, 100, 255 }; 76 static const rgb_color kHaikuGreen = { 42, 131, 36, 255 }; 77 static const rgb_color kHaikuOrange = { 255, 69, 0, 255 }; 78 static const rgb_color kHaikuYellow = { 255, 176, 0, 255 }; 79 static const rgb_color kLinkBlue = { 80, 80, 200, 255 }; 80 81 typedef struct 82 { 83 const char* languageCode; 84 const char* names; 85 } Translation; 86 87 static const Translation gTranslations[] = 88 { 89 { "bg", 90 "cssvb94\n" 91 }, 92 { "nl", 93 "Meanwhile\n" 94 }, 95 { "eo", 96 "Travis D. Reed (Dancxjo)\n" 97 }, 98 { "fi", 99 "Jorma Karvonen (Karvjorm)\n" 100 "Jaakko Leikas (Garjala)\n" 101 }, 102 { "fr", 103 "Jean-Loïc Charroud\n" 104 "Adrien Destugues (PulkoMandy)\n" 105 }, 106 { "da", 107 "Brian Matzon\n" 108 }, 109 { "de", 110 "Colin Günther\n" 111 "leszek\n" 112 "Christian Morgenroth\n" 113 "Joachim Seemer (Humdinger)\n" 114 "Matthias Spreiter\n" 115 "svend\n" 116 }, 117 { "hu", 118 "Zoltán Mizsei (miqlas)\n" 119 "Zoltán Szabó (Bird)\n" 120 }, 121 { "it", 122 "Andrea Bernardi\n" 123 }, 124 { "ja", 125 "Satoshi Eguchi\n" 126 "Hironori Ichimiya\n" 127 "Jorge G. Mare (Koki)\n" 128 "Takashi Murai\n" 129 "SHINTA\n" 130 "Hiroyuki Tsutsumi\n" 131 "The JPBE.net user group\n" 132 }, 133 { "lt", 134 "Algirdas Buckus\n" 135 }, 136 { "pl", 137 "Hubert Hareńczyk\n" 138 "Artur Wyszyński\n" 139 }, 140 { "pt", 141 "Marcos Alves (Xeon3D)\n" 142 "Vasco Costa (gluon)\n" 143 "Michael Vinícius de Oliveira (michaelvo)\n" 144 }, 145 { "ru", 146 "Tatyana Fursic (iceid)\n" 147 "StoroZ Gneva\n" 148 "Rustam Islamov (RISC aka HaikuBot)\n" 149 "Eugene Katashov (mrNoisy)\n" 150 "Reznikov Sergei (Diver)\n" 151 "Michael Smirnov\n" 152 }, 153 { "es", 154 "Nicolás C (CapitanPico)\n" 155 "Oscar Carballal (oscarcp)\n" 156 "Miguel Zúñiga González (miguel~1.mx)\n" 157 "César Ortiz Pantoja (ccortiz)\n" 158 }, 159 { "sv", 160 "Johan Holmberg\n" 161 "Jimmy Olsson (phalax)\n" 162 "Victor Widell\n" 163 }, 164 { "uk", 165 "Alex Rudyk (totish)\n" 166 }, 167 { "zh", 168 "Pengfei Han (kurain)\n" 169 } 170 }; 171 172 #define kNumberOfTranslations (sizeof(gTranslations) / sizeof(Translation)) 173 174 175 static int 176 TranslationComparator(const void* left, const void* right) 177 { 178 const Translation* leftTranslation = *(const Translation**)left; 179 const Translation* rightTranslation = *(const Translation**)right; 180 181 BLanguage* language; 182 BString leftName; 183 if (be_locale_roster->GetLanguage(leftTranslation->languageCode, &language) 184 == B_OK) { 185 language->GetTranslatedName(leftName); 186 delete language; 187 } else 188 leftName = leftTranslation->languageCode; 189 190 BString rightName; 191 if (be_locale_roster->GetLanguage(rightTranslation->languageCode, &language) 192 == B_OK) { 193 language->GetTranslatedName(rightName); 194 delete language; 195 } else 196 rightName = rightTranslation->languageCode; 197 198 BCollator collator; 199 be_locale_roster->GetDefaultCollator(&collator); 200 return collator.Compare(leftName.String(), rightName.String()); 201 } 202 203 204 class AboutApp : public BApplication { 205 public: 206 AboutApp(); 207 }; 208 209 210 class AboutWindow : public BWindow { 211 public: 212 AboutWindow(); 213 214 virtual bool QuitRequested(); 215 }; 216 217 218 class LogoView : public BView { 219 public: 220 LogoView(); 221 virtual ~LogoView(); 222 223 virtual BSize MinSize(); 224 virtual BSize MaxSize(); 225 226 virtual void Draw(BRect updateRect); 227 228 private: 229 BBitmap* fLogo; 230 }; 231 232 233 class CropView : public BView { 234 public: 235 CropView(BView* target, int32 left, int32 top, 236 int32 right, int32 bottom); 237 virtual ~CropView(); 238 239 virtual BSize MinSize(); 240 virtual BSize MaxSize(); 241 242 virtual void DoLayout(); 243 244 private: 245 BView* fTarget; 246 int32 fCropLeft; 247 int32 fCropTop; 248 int32 fCropRight; 249 int32 fCropBottom; 250 }; 251 252 253 class AboutView : public BView { 254 public: 255 AboutView(); 256 ~AboutView(); 257 258 virtual void AttachedToWindow(); 259 virtual void Pulse(); 260 261 virtual void MessageReceived(BMessage* msg); 262 virtual void MouseDown(BPoint point); 263 264 void AddCopyrightEntry(const char* name, 265 const char* text, 266 const StringVector& licenses, 267 const StringVector& sources, 268 const char* url); 269 void AddCopyrightEntry(const char* name, 270 const char* text, const char* url = NULL); 271 void PickRandomHaiku(); 272 273 274 private: 275 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 276 277 private: 278 BView* _CreateLabel(const char* name, const char* label); 279 BView* _CreateCreditsView(); 280 status_t _GetLicensePath(const char* license, 281 BPath& path); 282 void _AddCopyrightsFromAttribute(); 283 void _AddPackageCredit(const PackageCredit& package); 284 void _AddPackageCreditEntries(); 285 286 BStringView* fMemView; 287 BTextView* fUptimeView; 288 BView* fInfoView; 289 HyperTextView* fCreditsView; 290 291 BBitmap* fLogo; 292 293 bigtime_t fLastActionTime; 294 BMessageRunner* fScrollRunner; 295 PackageCreditMap fPackageCredits; 296 }; 297 298 299 // #pragma mark - 300 301 302 AboutApp::AboutApp() 303 : BApplication("application/x-vnd.Haiku-About") 304 { 305 AboutWindow *window = new(std::nothrow) AboutWindow(); 306 if (window) 307 window->Show(); 308 } 309 310 311 // #pragma mark - 312 313 314 #undef B_TRANSLATE_CONTEXT 315 #define B_TRANSLATE_CONTEXT "AboutWindow" 316 317 AboutWindow::AboutWindow() 318 : BWindow(BRect(0, 0, 500, 300), B_TRANSLATE("About this system"), 319 B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE) 320 { 321 SetLayout(new BGroupLayout(B_VERTICAL)); 322 AddChild(new AboutView()); 323 324 // Make sure we take the minimal window size into account when centering 325 BSize size = GetLayout()->MinSize(); 326 ResizeTo(max_c(size.width, Bounds().Width()), 327 max_c(size.height, Bounds().Height())); 328 329 CenterOnScreen(); 330 } 331 332 333 bool 334 AboutWindow::QuitRequested() 335 { 336 be_app->PostMessage(B_QUIT_REQUESTED); 337 return true; 338 } 339 340 341 // #pragma mark - LogoView 342 343 344 LogoView::LogoView() 345 : BView("logo", B_WILL_DRAW) 346 { 347 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png"); 348 SetViewColor(255, 255, 255); 349 } 350 351 352 LogoView::~LogoView() 353 { 354 delete fLogo; 355 } 356 357 358 BSize 359 LogoView::MinSize() 360 { 361 if (fLogo == NULL) 362 return BSize(0, 0); 363 364 return BSize(fLogo->Bounds().Width(), fLogo->Bounds().Height()); 365 } 366 367 368 BSize 369 LogoView::MaxSize() 370 { 371 if (fLogo == NULL) 372 return BSize(0, 0); 373 374 return BSize(B_SIZE_UNLIMITED, fLogo->Bounds().Height()); 375 } 376 377 378 void 379 LogoView::Draw(BRect updateRect) 380 { 381 if (fLogo != NULL) { 382 DrawBitmap(fLogo, 383 BPoint((Bounds().Width() - fLogo->Bounds().Width()) / 2, 0)); 384 } 385 } 386 387 388 // #pragma mark - CropView 389 390 391 CropView::CropView(BView* target, int32 left, int32 top, int32 right, 392 int32 bottom) 393 : BView("crop view", 0), 394 fTarget(target), 395 fCropLeft(left), 396 fCropTop(top), 397 fCropRight(right), 398 fCropBottom(bottom) 399 { 400 AddChild(target); 401 } 402 403 404 CropView::~CropView() 405 { 406 } 407 408 409 BSize 410 CropView::MinSize() 411 { 412 if (fTarget == NULL) 413 return BSize(); 414 415 BSize size = fTarget->MinSize(); 416 if (size.width != B_SIZE_UNSET) 417 size.width -= fCropLeft + fCropRight; 418 if (size.height != B_SIZE_UNSET) 419 size.height -= fCropTop + fCropBottom; 420 421 return size; 422 } 423 424 425 BSize 426 CropView::MaxSize() 427 { 428 if (fTarget == NULL) 429 return BSize(); 430 431 BSize size = fTarget->MaxSize(); 432 if (size.width != B_SIZE_UNSET) 433 size.width -= fCropLeft + fCropRight; 434 if (size.height != B_SIZE_UNSET) 435 size.height -= fCropTop + fCropBottom; 436 437 return size; 438 } 439 440 441 void 442 CropView::DoLayout() 443 { 444 BView::DoLayout(); 445 446 if (fTarget == NULL) 447 return; 448 449 fTarget->MoveTo(-fCropLeft, -fCropTop); 450 fTarget->ResizeTo(Bounds().Width() + fCropLeft + fCropRight, 451 Bounds().Height() + fCropTop + fCropBottom); 452 } 453 454 455 // #pragma mark - AboutView 456 457 #undef B_TRANSLATE_CONTEXT 458 #define B_TRANSLATE_CONTEXT "AboutView" 459 460 AboutView::AboutView() 461 : BView("aboutview", B_WILL_DRAW | B_PULSE_NEEDED), 462 fLastActionTime(system_time()), 463 fScrollRunner(NULL) 464 { 465 // Begin Construction of System Information controls 466 467 system_info systemInfo; 468 get_system_info(&systemInfo); 469 470 // Create all the various labels for system infomation 471 472 // OS Version 473 474 char string[1024]; 475 strcpy(string, B_TRANSLATE("Unknown")); 476 477 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 478 BPath path; 479 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 480 path.Append("libbe.so"); 481 482 BAppFileInfo appFileInfo; 483 version_info versionInfo; 484 BFile file; 485 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 486 && appFileInfo.SetTo(&file) == B_OK 487 && appFileInfo.GetVersionInfo(&versionInfo, 488 B_APP_VERSION_KIND) == B_OK 489 && versionInfo.short_info[0] != '\0') 490 strcpy(string, versionInfo.short_info); 491 } 492 493 // Add revision from uname() info 494 utsname unameInfo; 495 if (uname(&unameInfo) == 0) { 496 long revision; 497 if (sscanf(unameInfo.version, "r%ld", &revision) == 1) { 498 char version[16]; 499 snprintf(version, sizeof(version), "%ld", revision); 500 strlcat(string, " (", sizeof(string)); 501 strlcat(string, B_TRANSLATE("Revision"), sizeof(string)); 502 strlcat(string, " ", sizeof(string)); 503 strlcat(string, version, sizeof(string)); 504 strlcat(string, ")", sizeof(string)); 505 } 506 } 507 508 BStringView* versionView = new BStringView("ostext", string); 509 versionView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 510 B_ALIGN_VERTICAL_UNSET)); 511 512 // GCC version 513 BEntry gccFourHybrid("/boot/system/lib/gcc2/libstdc++.r4.so"); 514 BEntry gccTwoHybrid("/boot/system/lib/gcc4/libsupc++.so"); 515 if (gccFourHybrid.Exists() || gccTwoHybrid.Exists()) 516 snprintf(string, sizeof(string), B_TRANSLATE("GCC %d Hybrid"), 517 __GNUC__); 518 else 519 snprintf(string, sizeof(string), "GCC %d", __GNUC__); 520 521 BStringView* gccView = new BStringView("gcctext", string); 522 gccView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 523 B_ALIGN_VERTICAL_UNSET)); 524 525 // CPU count, type and clock speed 526 char processorLabel[256]; 527 if (systemInfo.cpu_count > 1) { 528 snprintf(processorLabel, sizeof(processorLabel), 529 B_TRANSLATE("%ld Processors:"), systemInfo.cpu_count); 530 } else 531 strlcpy(processorLabel, B_TRANSLATE("Processor:"), 532 sizeof(processorLabel)); 533 534 BString cpuType; 535 cpuType << get_cpu_vendor_string(systemInfo.cpu_type) 536 << " " << get_cpu_model_string(&systemInfo); 537 538 BStringView* cpuView = new BStringView("cputext", cpuType.String()); 539 cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 540 B_ALIGN_VERTICAL_UNSET)); 541 542 int32 clockSpeed = get_rounded_cpu_speed(); 543 if (clockSpeed < 1000) 544 sprintf(string, B_TRANSLATE("%ld MHz"), clockSpeed); 545 else 546 sprintf(string, B_TRANSLATE("%.2f GHz"), clockSpeed / 1000.0f); 547 548 BStringView* frequencyView = new BStringView("frequencytext", string); 549 frequencyView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 550 B_ALIGN_VERTICAL_UNSET)); 551 552 // RAM 553 BStringView *memSizeView = new BStringView("ramsizetext", 554 MemSizeToString(string, sizeof(string), &systemInfo)); 555 memSizeView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 556 B_ALIGN_VERTICAL_UNSET)); 557 fMemView = new BStringView("ramtext", 558 MemUsageToString(string, sizeof(string), &systemInfo)); 559 fMemView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 560 B_ALIGN_VERTICAL_UNSET)); 561 562 // Kernel build time/date 563 snprintf(string, sizeof(string), "%s %s", 564 systemInfo.kernel_build_date, systemInfo.kernel_build_time); 565 566 BStringView* kernelView = new BStringView("kerneltext", string); 567 kernelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 568 B_ALIGN_VERTICAL_UNSET)); 569 570 // Uptime 571 fUptimeView = new BTextView("uptimetext"); 572 fUptimeView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 573 fUptimeView->MakeEditable(false); 574 fUptimeView->MakeSelectable(false); 575 fUptimeView->SetWordWrap(true); 576 577 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 578 579 const float offset = 5; 580 581 SetLayout(new BGroupLayout(B_HORIZONTAL)); 582 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 583 584 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 585 .AddGroup(B_VERTICAL) 586 .Add(new LogoView()) 587 .AddGroup(B_VERTICAL) 588 .Add(_CreateLabel("oslabel", B_TRANSLATE("Version:"))) 589 .Add(versionView) 590 .Add(gccView) 591 .AddStrut(offset) 592 .Add(_CreateLabel("cpulabel", processorLabel)) 593 .Add(cpuView) 594 .Add(frequencyView) 595 .AddStrut(offset) 596 .Add(_CreateLabel("memlabel", B_TRANSLATE("Memory:"))) 597 .Add(memSizeView) 598 .Add(fMemView) 599 .AddStrut(offset) 600 .Add(_CreateLabel("kernellabel", B_TRANSLATE("Kernel:"))) 601 .Add(kernelView) 602 .AddStrut(offset) 603 .Add(_CreateLabel("uptimelabel", 604 B_TRANSLATE("Time running:"))) 605 .Add(fUptimeView) 606 .SetInsets(5, 5, 5, 5) 607 .End() 608 // TODO: investigate: adding this causes the time to be cut 609 //.AddGlue() 610 .End() 611 .Add(_CreateCreditsView()); 612 613 float min = fMemView->MinSize().width * 1.1f; 614 fCreditsView->SetExplicitMinSize(BSize(min, min)); 615 } 616 617 618 AboutView::~AboutView() 619 { 620 delete fScrollRunner; 621 } 622 623 624 void 625 AboutView::AttachedToWindow() 626 { 627 BView::AttachedToWindow(); 628 Window()->SetPulseRate(500000); 629 SetEventMask(B_POINTER_EVENTS); 630 } 631 632 633 void 634 AboutView::MouseDown(BPoint point) 635 { 636 BRect r(92, 26, 105, 31); 637 if (r.Contains(point)) { 638 printf("Easter egg\n"); 639 PickRandomHaiku(); 640 } 641 642 if (Bounds().Contains(point)) { 643 fLastActionTime = system_time(); 644 delete fScrollRunner; 645 fScrollRunner = NULL; 646 } 647 } 648 649 650 void 651 AboutView::Pulse() 652 { 653 char string[255]; 654 system_info info; 655 get_system_info(&info); 656 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 657 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 658 659 if (fScrollRunner == NULL 660 && system_time() > fLastActionTime + 10000000) { 661 BMessage message(SCROLL_CREDITS_VIEW); 662 //fScrollRunner = new BMessageRunner(this, &message, 25000, -1); 663 } 664 } 665 666 667 void 668 AboutView::MessageReceived(BMessage* msg) 669 { 670 switch (msg->what) { 671 case SCROLL_CREDITS_VIEW: 672 { 673 BScrollBar* scrollBar = 674 fCreditsView->ScrollBar(B_VERTICAL); 675 if (scrollBar == NULL) 676 break; 677 float max, min; 678 scrollBar->GetRange(&min, &max); 679 if (scrollBar->Value() < max) 680 fCreditsView->ScrollBy(0, 1); 681 682 break; 683 } 684 685 default: 686 BView::MessageReceived(msg); 687 break; 688 } 689 } 690 691 692 void 693 AboutView::AddCopyrightEntry(const char* name, const char* text, 694 const char* url) 695 { 696 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 697 } 698 699 700 void 701 AboutView::AddCopyrightEntry(const char* name, const char* text, 702 const StringVector& licenses, const StringVector& sources, 703 const char* url) 704 { 705 BFont font(be_bold_font); 706 //font.SetSize(be_bold_font->Size()); 707 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 708 709 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 710 fCreditsView->Insert(name); 711 fCreditsView->Insert("\n"); 712 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 713 fCreditsView->Insert(text); 714 fCreditsView->Insert("\n"); 715 716 if (licenses.CountStrings() > 0) { 717 if (licenses.CountStrings() > 1) 718 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 719 else 720 fCreditsView->Insert(B_TRANSLATE("License: ")); 721 722 for (int32 i = 0; i < licenses.CountStrings(); i++) { 723 const char* license = licenses.StringAt(i); 724 725 if (i > 0) 726 fCreditsView->Insert(", "); 727 728 BString licenseName; 729 BString licenseURL; 730 parse_named_url(license, licenseName, licenseURL); 731 732 BPath licensePath; 733 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 734 fCreditsView->InsertHyperText(licenseName, 735 new OpenFileAction(licensePath.Path())); 736 } else 737 fCreditsView->Insert(licenseName); 738 } 739 740 fCreditsView->Insert("\n"); 741 } 742 743 if (sources.CountStrings() > 0) { 744 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 745 746 for (int32 i = 0; i < sources.CountStrings(); i++) { 747 const char* source = sources.StringAt(i); 748 749 if (i > 0) 750 fCreditsView->Insert(", "); 751 752 BString urlName; 753 BString urlAddress; 754 parse_named_url(source, urlName, urlAddress); 755 756 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 757 &kLinkBlue); 758 fCreditsView->InsertHyperText(urlName, 759 new URLAction(urlAddress)); 760 } 761 762 fCreditsView->Insert("\n"); 763 } 764 765 if (url) { 766 BString urlName; 767 BString urlAddress; 768 parse_named_url(url, urlName, urlAddress); 769 770 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 771 &kLinkBlue); 772 fCreditsView->InsertHyperText(urlName, 773 new URLAction(urlAddress)); 774 fCreditsView->Insert("\n"); 775 } 776 fCreditsView->Insert("\n"); 777 } 778 779 780 void 781 AboutView::PickRandomHaiku() 782 { 783 BFile fortunes( 784 #ifdef __HAIKU__ 785 "/etc/fortunes/Haiku", 786 #else 787 "data/etc/fortunes/Haiku", 788 #endif 789 B_READ_ONLY); 790 struct stat st; 791 if (fortunes.InitCheck() < B_OK) 792 return; 793 if (fortunes.GetStat(&st) < B_OK) 794 return; 795 char* buff = (char*)malloc((size_t)st.st_size + 1); 796 if (!buff) 797 return; 798 buff[(size_t)st.st_size] = '\0'; 799 BList haikuList; 800 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 801 char* p = buff; 802 while (p && *p) { 803 char* e = strchr(p, '%'); 804 BString* s = new BString(p, e ? (e - p) : -1); 805 haikuList.AddItem(s); 806 p = e; 807 if (p && (*p == '%')) 808 p++; 809 if (p && (*p == '\n')) 810 p++; 811 } 812 } 813 free(buff); 814 if (haikuList.CountItems() < 1) 815 return; 816 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 817 BFont font(be_bold_font); 818 font.SetSize(be_bold_font->Size()); 819 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 820 fCreditsView->SelectAll(); 821 fCreditsView->Delete(); 822 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 823 fCreditsView->Insert(s->String()); 824 fCreditsView->Insert("\n"); 825 while ((s = (BString*)haikuList.RemoveItem((int32)0))) { 826 delete s; 827 } 828 } 829 830 831 BView* 832 AboutView::_CreateLabel(const char* name, const char* label) 833 { 834 BStringView* labelView = new BStringView(name, label); 835 labelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 836 B_ALIGN_VERTICAL_UNSET)); 837 labelView->SetFont(be_bold_font); 838 return labelView; 839 } 840 841 842 BView* 843 AboutView::_CreateCreditsView() 844 { 845 // Begin construction of the credits view 846 fCreditsView = new HyperTextView("credits"); 847 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 848 fCreditsView->SetStylable(true); 849 fCreditsView->MakeEditable(false); 850 fCreditsView->SetWordWrap(true); 851 fCreditsView->SetInsets(5, 5, 5, 5); 852 fCreditsView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); 853 854 BScrollView* creditsScroller = new BScrollView("creditsScroller", 855 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 856 B_PLAIN_BORDER); 857 858 // Haiku copyright 859 BFont font(be_bold_font); 860 font.SetSize(font.Size() + 4); 861 862 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 863 fCreditsView->Insert("Haiku\n"); 864 865 char string[1024]; 866 time_t time = ::time(NULL); 867 struct tm* tm = localtime(&time); 868 int32 year = tm->tm_year + 1900; 869 if (year < 2008) 870 year = 2008; 871 snprintf(string, sizeof(string), 872 COPYRIGHT_STRING "2001-%ld The Haiku project. ", year); 873 874 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 875 fCreditsView->Insert(string); 876 877 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 878 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 879 "property of Haiku, Inc. or of the respective authors where expressly " 880 "noted in the source. Haiku and the Haiku logo are trademarks of " 881 "Haiku, Inc." 882 "\n\n")); 883 884 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 885 fCreditsView->InsertHyperText("http://www.haiku-os.org", 886 new URLAction("http://www.haiku-os.org")); 887 fCreditsView->Insert("\n\n"); 888 889 font.SetSize(be_bold_font->Size()); 890 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 891 892 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 893 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 894 895 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 896 fCreditsView->Insert( 897 "Ithamar R. Adema\n" 898 "Bruno G. Albuquerque\n" 899 "Stephan Aßmus\n" 900 "Salvatore Benedetto\n" 901 "Stefano Ceccherini\n" 902 "Rudolf Cornelissen\n" 903 "Alexandre Deckner\n" 904 "Adrien Destugues\n" 905 "Oliver Ruiz Dorantes\n" 906 "Axel Dörfler\n" 907 "Jérôme Duval\n" 908 "René Gollent\n" 909 "Bryce Groff\n" 910 "Colin Günther\n" 911 "Karsten Heimrich\n" 912 "Fredrik Holmqvist\n" 913 "Philippe Houdoin\n" 914 "Maurice Kalinowski\n" 915 "Euan Kirkhope\n" 916 "Ryan Leavengood\n" 917 "Michael Lotz\n" 918 "Brecht Machiels\n" 919 "Matt Madia\n" 920 "Scott McCreary\n" 921 "David McPaul\n" 922 "Wim van der Meer\n" 923 "Fredrik Modéen\n" 924 "Marcus Overhagen\n" 925 "Michael Pfeiffer\n" 926 "François Revol\n" 927 "Philippe Saint-Pierre\n" 928 "Andrej Spielmann\n" 929 "Jonas Sundström\n" 930 "Oliver Tappe\n" 931 "Gerasim Troeglazov\n" 932 "Ingo Weinhold\n" 933 "Alex Wilson\n" 934 "Artur Wyszyński\n" 935 "Clemens Zeidler\n" 936 "Siarzhuk Zharski\n" 937 "\n"); 938 939 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 940 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 941 942 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 943 fCreditsView->Insert( 944 "Andrew Bachmann\n" 945 "Tyler Dauwalder\n" 946 "Daniel Furrer\n" 947 "Andre Alves Garzia\n" 948 "Erik Jaesler\n" 949 "Marcin Konicki\n" 950 "Waldemar Kornewald\n" 951 "Thomas Kurschel\n" 952 "Frans Van Nispen\n" 953 "Adi Oanca\n" 954 "Michael Phipps\n" 955 "Niels Sascha Reedijk\n" 956 "David Reid\n" 957 "Hugo Santos\n" 958 "Alexander G. M. Smith\n" 959 "Bryan Varner\n" 960 "Nathan Whitehorn\n" 961 "Michael Wilber\n" 962 "Jonathan Yoder\n" 963 "Gabe Yoder\n" 964 "\n"); 965 966 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 967 fCreditsView->Insert(B_TRANSLATE("Website, marketing & documentation:\n")); 968 969 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 970 fCreditsView->Insert( 971 "Phil Greenway\n" 972 "Gavin James\n" 973 "Jorge G. Mare (aka Koki)\n" 974 "Urias McCullough\n" 975 "Niels Sascha Reedijk\n" 976 "Joachim Seemer (Humdinger)\n" 977 "Jonathan Yoder\n" 978 "\n"); 979 980 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 981 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 982 983 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 984 fCreditsView->Insert( 985 "Andrea Anzani\n" 986 "Sean Bartell\n" 987 "Andre Braga\n" 988 "Bruce Cameron\n" 989 "Greg Crain\n" 990 "David Dengg\n" 991 "John Drinkwater\n" 992 "Cian Duffy\n" 993 "Vincent Duvert\n" 994 "Fredrik Ekdahl\n" 995 "Joshua R. Elsasser\n" 996 "Atis Elsts\n" 997 "Mark Erben\n" 998 "Christian Fasshauer\n" 999 "Andreas Färber\n" 1000 "Janito Ferreira Filho\n" 1001 "Marc Flerackers\n" 1002 "Michele Frau (zuMi)\n" 1003 "Pete Goodeve\n" 1004 "Lucian Adrian Grijincu\n" 1005 "Matthijs Hollemans\n" 1006 "Mathew Hounsell\n" 1007 "Morgan Howe\n" 1008 "Christophe Huriaux\n" 1009 "Ma Jie\n" 1010 "Carwyn Jones\n" 1011 "Vasilis Kaoutsis\n" 1012 "James Kim\n" 1013 "Shintaro Kinugawa\n" 1014 "Jan Klötzke\n" 1015 "Kurtis Kopf\n" 1016 "Tomáš Kučera\n" 1017 "Luboš Kulič\n" 1018 "Elad Lahav\n" 1019 "Anthony Lee\n" 1020 "Santiago Lema\n" 1021 "Raynald Lesieur\n" 1022 "Oscar Lesta\n" 1023 "Jerome Leveque\n" 1024 "Christof Lutteroth\n" 1025 "Graham MacDonald\n" 1026 "Jan Matějek\n" 1027 "Brian Matzon\n" 1028 "Christopher ML Zumwalt May\n" 1029 "Andrew McCall\n" 1030 "Nathan Mentley\n" 1031 "Marius Middelthon\n" 1032 "Marco Minutoli\n" 1033 "Misza\n" 1034 "MrSiggler\n" 1035 "Alan Murta\n" 1036 "Raghuram Nagireddy\n" 1037 "Jeroen Oortwijn (idefix)\n" 1038 "Pahtz\n" 1039 "Michael Paine\n" 1040 "Adrian Panasiuk\n" 1041 "Romain Picard\n" 1042 "Francesco Piccinno\n" 1043 "David Powell\n" 1044 "Jeremy Rand\n" 1045 "Hartmut Reh\n" 1046 "Daniel Reinhold\n" 1047 "Chris Roberts\n" 1048 "Samuel Rodríguez Pérez\n" 1049 "Thomas Roell\n" 1050 "Rafael Romo\n" 1051 "Ralf Schülke\n" 1052 "John Scipione\n" 1053 "Reznikov Sergei\n" 1054 "Zousar Shaker\n" 1055 "Caitlin Shaw\n" 1056 "Daniel Switkin\n" 1057 "Atsushi Takamatsu\n" 1058 "James Urquhart\n" 1059 "Jason Vandermark\n" 1060 "Sandor Vroemisse\n" 1061 "Denis Washington\n" 1062 "Ulrich Wimboeck\n" 1063 "Johannes Wischert\n" 1064 "James Woodcock\n" 1065 "Hong Yul Yang\n" 1066 "Gerald Zajac\n" 1067 "Łukasz Zemczak\n" 1068 "JiSheng Zhang\n" 1069 "Zhao Shuai\n"); 1070 fCreditsView->Insert( 1071 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 1072 " and probably some more we forgot to mention (sorry!)" 1073 "\n\n")); 1074 1075 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1076 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 1077 1078 BLanguage* lang; 1079 BString langName; 1080 1081 BList sortedTranslations; 1082 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1083 const Translation* translation = &gTranslations[i]; 1084 sortedTranslations.AddItem((void*)translation); 1085 } 1086 sortedTranslations.SortItems(TranslationComparator); 1087 1088 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1089 const Translation& translation 1090 = *(const Translation*)sortedTranslations.ItemAt(i); 1091 1092 langName.Truncate(0); 1093 if (be_locale_roster->GetLanguage(translation.languageCode, &lang) 1094 == B_OK) { 1095 lang->GetTranslatedName(langName); 1096 delete lang; 1097 } else { 1098 // We failed to get the localized readable name, 1099 // go with what we have. 1100 langName.Append(translation.languageCode); 1101 } 1102 1103 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1104 fCreditsView->Insert("\n"); 1105 fCreditsView->Insert(langName); 1106 fCreditsView->Insert("\n"); 1107 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1108 fCreditsView->Insert( 1109 translation.names 1110 ); 1111 } 1112 1113 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1114 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 1115 1116 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1117 fCreditsView->Insert( 1118 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 1119 fCreditsView->Insert( 1120 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 1121 fCreditsView->Insert( 1122 B_TRANSLATE("The Haiku-Ports team\n")); 1123 fCreditsView->Insert( 1124 B_TRANSLATE("The Haikuware team and their bounty program\n")); 1125 fCreditsView->Insert( 1126 B_TRANSLATE("The BeGeistert team\n")); 1127 fCreditsView->Insert( 1128 B_TRANSLATE("Google & their Google Summer of Code program\n\n")); 1129 fCreditsView->Insert( 1130 B_TRANSLATE("... and the many people making donations!\n\n")); 1131 1132 // copyrights for various projects we use 1133 1134 BPath mitPath; 1135 _GetLicensePath("MIT", mitPath); 1136 1137 font.SetSize(be_bold_font->Size() + 4); 1138 font.SetFace(B_BOLD_FACE); 1139 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1140 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 1141 1142 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1143 fCreditsView->Insert(B_TRANSLATE("[Click a license name to read the " 1144 "respective license.]\n\n")); 1145 1146 // Haiku license 1147 BString haikuLicence = B_TRANSLATE("The code that is unique to Haiku, " 1148 "especially the kernel and all code that applications may link " 1149 "against, is distributed under the terms of the %MIT licence%. " 1150 "Some system libraries contain third party code distributed under the " 1151 "LGPL license. You can find the copyrights to third party code below.\n" 1152 "\n"); 1153 int32 licencePart1 = haikuLicence.FindFirst("%"); 1154 int32 licencePart2 = haikuLicence.FindLast("%"); 1155 BString part; 1156 haikuLicence.CopyCharsInto(part, 0, licencePart1 ); 1157 fCreditsView->Insert(part); 1158 1159 part.Truncate(0); 1160 haikuLicence.CopyCharsInto(part, licencePart1 + 1, licencePart2 - 1 1161 - licencePart1); 1162 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1163 1164 part.Truncate(0); 1165 haikuLicence.CopyCharsInto(part, licencePart2 + 1, haikuLicence.CountChars() 1166 - licencePart2); 1167 fCreditsView->Insert(part); 1168 1169 // GNU copyrights 1170 AddCopyrightEntry("The GNU Project", 1171 "Contains software from the GNU Project, " 1172 "released under the GPL and LGPL licenses:\n" 1173 "GNU C Library, " 1174 "GNU coretools, diffutils, findutils, " 1175 "sharutils, gawk, bison, m4, make, " 1176 "gdb, wget, ncurses, termcap, " 1177 "Bourne Again Shell.\n" 1178 COPYRIGHT_STRING "The Free Software Foundation.", 1179 StringVector("GNU LGPL v2.1", "GNU GPL v2", "GNU GPL v3", NULL), 1180 StringVector(), 1181 "http://www.gnu.org"); 1182 1183 // FreeBSD copyrights 1184 AddCopyrightEntry("The FreeBSD Project", 1185 "Contains software from the FreeBSD Project, " 1186 "released under the BSD license:\n" 1187 "cal, ftpd, ping, telnet, " 1188 "telnetd, traceroute\n" 1189 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1190 "All rights reserved.", 1191 "http://www.freebsd.org"); 1192 // TODO: License! 1193 1194 // NetBSD copyrights 1195 AddCopyrightEntry("The NetBSD Project", 1196 "Contains software developed by the NetBSD, " 1197 "Foundation, Inc. and its contributors:\n" 1198 "ftp, tput\n" 1199 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 1200 "All rights reserved.", 1201 "http://www.netbsd.org"); 1202 // TODO: License! 1203 1204 // FFMpeg copyrights 1205 _AddPackageCredit(PackageCredit("FFMpeg libavcodec") 1206 .SetCopyright(COPYRIGHT_STRING "2000-2007 Fabrice Bellard, et al.") 1207 .SetLicenses("GNU LGPL v2.1", "GNU LGPL v2", NULL) 1208 .SetURL("http://www.ffmpeg.org")); 1209 1210 // AGG copyrights 1211 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1212 .SetCopyright(COPYRIGHT_STRING "2002-2006 Maxim Shemanarev (McSeem).") 1213 .SetLicenses("Anti-Grain Geometry", "BSD (3-clause)", "GPC", NULL) 1214 .SetURL("http://www.antigrain.com")); 1215 1216 // PDFLib copyrights 1217 _AddPackageCredit(PackageCredit("PDFLib") 1218 .SetCopyright(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and Thomas Merz. " 1219 "All rights reserved.\n" 1220 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.") 1221 .SetLicense("PDFlib Lite") 1222 .SetURL("http://www.pdflib.com")); 1223 1224 // FreeType copyrights 1225 _AddPackageCredit(PackageCredit("FreeType2") 1226 .SetCopyright("Portions of this software are copyright " 1227 B_UTF8_COPYRIGHT " 1996-2006 " 1228 "The FreeType Project. All rights reserved.") 1229 .SetLicense("FTL") 1230 .SetURL("http://www.freetype.org")); 1231 1232 // Mesa3D (http://www.mesa3d.org) copyrights 1233 _AddPackageCredit(PackageCredit("Mesa") 1234 .SetCopyright(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1235 "Mesa3D Project. All rights reserved.") 1236 .SetLicense("MIT") 1237 .SetURL("http://www.mesa3d.org")); 1238 1239 // SGI's GLU implementation copyrights 1240 _AddPackageCredit(PackageCredit("GLU") 1241 .SetCopyright(COPYRIGHT_STRING 1242 "1991-2000 Silicon Graphics, Inc. " 1243 "SGI's Software FreeB license. All rights reserved.") 1244 .SetLicense("SGI Free B") 1245 .SetURL("http://www.sgi.com/products/software/opengl")); 1246 1247 // GLUT implementation copyrights 1248 _AddPackageCredit(PackageCredit("GLUT") 1249 .SetCopyrights(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1250 "All rights reserved.", 1251 COPYRIGHT_STRING "1997 Be Inc.", 1252 COPYRIGHT_STRING "1999 Jake Hamby.", 1253 NULL) 1254 .SetLicense("GLUT (Mark Kilgard)") 1255 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1256 1257 // OpenGroup & DEC (BRegion backend) copyright 1258 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1259 .SetCopyrights(COPYRIGHT_STRING "1987, 1988, 1998 The Open Group.", 1260 COPYRIGHT_STRING "1987, 1988 Digital Equipment " 1261 "Corporation, Maynard, Massachusetts.\n" 1262 "All rights reserved.", 1263 NULL) 1264 .SetLicenses("OpenGroup", "DEC", NULL)); 1265 // TODO: URL 1266 1267 // VL-Gothic font 1268 _AddPackageCredit(PackageCredit("VL-Gothic font") 1269 .SetCopyrights(COPYRIGHT_STRING "1990-2003 Wada Laboratory," 1270 " the University of Tokyo", COPYRIGHT_STRING 1271 "2003-2004 Electronic Font Open Laboratory (/efont/)", 1272 COPYRIGHT_STRING "2003-2008 M+ FONTS PROJECT", 1273 COPYRIGHT_STRING "2006-2009 Daisuke SUZUKI", 1274 COPYRIGHT_STRING "2006-2009 Project Vine", 1275 "MIT license. All rights reserved.", 1276 NULL)); 1277 // TODO: License! 1278 1279 // expat copyrights 1280 _AddPackageCredit(PackageCredit("expat") 1281 .SetCopyrights(COPYRIGHT_STRING 1282 "1998, 1999, 2000 Thai Open Source " 1283 "Software Center Ltd and Clark Cooper.", 1284 COPYRIGHT_STRING "2001, 2002, 2003 Expat maintainers.", 1285 NULL) 1286 .SetLicense("Expat") 1287 .SetURL("http://expat.sourceforge.net")); 1288 1289 // zlib copyrights 1290 _AddPackageCredit(PackageCredit("zlib") 1291 .SetCopyright(COPYRIGHT_STRING 1292 "1995-2004 Jean-loup Gailly and Mark Adler.") 1293 .SetLicense("Zlib") 1294 .SetURL("http://www.zlib.net")); 1295 1296 // zip copyrights 1297 _AddPackageCredit(PackageCredit("Info-ZIP") 1298 .SetCopyright(COPYRIGHT_STRING 1299 "1990-2002 Info-ZIP. All rights reserved.") 1300 .SetLicense("Info-ZIP") 1301 .SetURL("http://www.info-zip.org")); 1302 1303 // bzip2 copyrights 1304 _AddPackageCredit(PackageCredit("bzip2") 1305 .SetCopyright(COPYRIGHT_STRING 1306 "1996-2005 Julian R Seward. All rights reserved.") 1307 .SetLicense("BSD (4-clause)") 1308 .SetURL("http://bzip.org")); 1309 1310 // lp_solve copyrights 1311 _AddPackageCredit(PackageCredit("lp_solve") 1312 .SetCopyright(COPYRIGHT_STRING 1313 "Michel Berkelaar, Kjell Eikland, Peter Notebaert") 1314 .SetLicense("GNU LGPL v2.1") 1315 .SetURL("http://lpsolve.sourceforge.net/")); 1316 1317 // OpenEXR copyrights 1318 _AddPackageCredit(PackageCredit("OpenEXR") 1319 .SetCopyright(COPYRIGHT_STRING "2002-2005 Industrial Light & Magic, " 1320 "a division of Lucas Digital Ltd. LLC.") 1321 .SetLicense("BSD (3-clause)") 1322 .SetURL("http://www.openexr.com")); 1323 1324 // Bullet copyrights 1325 _AddPackageCredit(PackageCredit("Bullet") 1326 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 1327 .SetLicense("Bullet") 1328 .SetURL("http://www.bulletphysics.com")); 1329 1330 // atftp copyrights 1331 _AddPackageCredit(PackageCredit("atftp") 1332 .SetCopyright(COPYRIGHT_STRING 1333 "2000 Jean-Pierre ervbefeL and Remi Lefebvre") 1334 .SetLicense("GNU GPL v2")); 1335 // TODO: URL! 1336 1337 // Netcat copyrights 1338 _AddPackageCredit(PackageCredit("Netcat") 1339 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit")); 1340 // TODO: License! 1341 1342 // acpica copyrights 1343 _AddPackageCredit(PackageCredit("acpica") 1344 .SetCopyright(COPYRIGHT_STRING "1999-2006 Intel Corp.") 1345 .SetLicense("Intel (ACPICA)") 1346 .SetURL("http://www.acpica.org")); 1347 1348 // unrar copyrights 1349 _AddPackageCredit(PackageCredit("unrar") 1350 .SetCopyright(COPYRIGHT_STRING "2002-2008 Alexander L. Roshal. " 1351 "All rights reserved.") 1352 .SetLicense("UnRAR") 1353 .SetURL("http://www.rarlab.com")); 1354 1355 // libpng copyrights 1356 _AddPackageCredit(PackageCredit("libpng") 1357 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 1358 "Randers-Pehrson.") 1359 .SetLicense("LibPNG") 1360 .SetURL("http://www.libpng.org")); 1361 1362 // libjpeg copyrights 1363 _AddPackageCredit(PackageCredit("libjpeg") 1364 .SetCopyright(COPYRIGHT_STRING " 1994-2009, Thomas G. Lane," 1365 " Guido Vollbeding. This software is based in part on the " 1366 "work of the Independent JPEG Group") 1367 .SetLicense("LibJPEG") 1368 .SetURL("http://www.ijg.org")); 1369 1370 // libprint copyrights 1371 _AddPackageCredit(PackageCredit("libprint") 1372 .SetCopyright(COPYRIGHT_STRING 1373 "1999-2000 Y.Takagi. All rights reserved.")); 1374 // TODO: License! 1375 1376 // cortex copyrights 1377 _AddPackageCredit(PackageCredit("Cortex") 1378 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1379 .SetLicense("BSD (3-clause)") 1380 .SetURL("http://cortex.sourceforge.net/documentation")); 1381 1382 // FluidSynth copyrights 1383 _AddPackageCredit(PackageCredit("FluidSynth") 1384 .SetCopyright(COPYRIGHT_STRING "2003 Peter Hanappe and others.") 1385 .SetLicense("GNU LGPL v2") 1386 .SetURL("http://www.fluidsynth.org")); 1387 1388 // CannaIM copyrights 1389 _AddPackageCredit(PackageCredit("CannaIM") 1390 .SetCopyright(COPYRIGHT_STRING "1999 Masao Kawamura.")); 1391 // TODO: License! 1392 1393 // libxml2, libxslt, libexslt copyrights 1394 _AddPackageCredit(PackageCredit("libxml2, libxslt") 1395 .SetCopyright(COPYRIGHT_STRING 1396 "1998-2003 Daniel Veillard. All rights reserved.") 1397 .SetLicense("MIT (no promotion)") 1398 .SetURL("http://xmlsoft.org")); 1399 1400 _AddPackageCredit(PackageCredit("libexslt") 1401 .SetCopyright(COPYRIGHT_STRING 1402 "2001-2002 Thomas Broyer, Charlie " 1403 "Bozeman and Daniel Veillard. All rights reserved.") 1404 .SetLicense("MIT (no promotion)") 1405 .SetURL("http://xmlsoft.org")); 1406 1407 // Xiph.org Foundation copyrights 1408 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1409 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1410 COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1411 "All rights reserved.", 1412 NULL) 1413 .SetLicense("BSD (3-clause)") 1414 .SetURL("http://www.xiph.org")); 1415 1416 // The Tcpdump Group 1417 _AddPackageCredit(PackageCredit("The Tcpdump Group") 1418 .SetCopyright("tcpdump, libpcap") 1419 .SetLicense("BSD (3-clause)") 1420 .SetURL("http://www.tcpdump.org")); 1421 1422 // Matroska 1423 _AddPackageCredit(PackageCredit("libmatroska") 1424 .SetCopyright(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1425 "All rights reserved.") 1426 .SetLicense("GNU LGPL v2.1") 1427 .SetURL("http://www.matroska.org")); 1428 1429 // BColorQuantizer (originally CQuantizer code) 1430 _AddPackageCredit(PackageCredit("CQuantizer") 1431 .SetCopyright(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1432 "All rights reserved.") 1433 .SetLicense("CQuantizer") 1434 .SetURL("http://www.xdp.it")); 1435 1436 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1437 _AddPackageCredit(PackageCredit("MAPM") 1438 .SetCopyright(COPYRIGHT_STRING 1439 "1999-2007 Michael C. Ring. All rights reserved.") 1440 .SetLicense("MAPM") 1441 .SetURL("http://tc.umn.edu/~ringx004")); 1442 1443 // MkDepend 1.7 copyright (Makefile dependency generator) 1444 _AddPackageCredit(PackageCredit("MkDepend") 1445 .SetCopyright(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1446 "All rights reserved.") 1447 .SetLicense("MkDepend") 1448 .SetURL("http://bearnip.com/lars/be")); 1449 1450 // libhttpd copyright (used as Poorman backend) 1451 _AddPackageCredit(PackageCredit("libhttpd") 1452 .SetCopyright(COPYRIGHT_STRING 1453 "1995,1998,1999,2000,2001 by " 1454 "Jef Poskanzer. All rights reserved.") 1455 .SetLicense("LibHTTPd") 1456 .SetURL("http://www.acme.com/software/thttpd/")); 1457 1458 #ifdef __INTEL__ 1459 // Udis86 copyrights 1460 _AddPackageCredit(PackageCredit("Udis86") 1461 .SetCopyright(COPYRIGHT_STRING "2002, 2003, 2004 Vivek Mohan. " 1462 "All rights reserved.") 1463 .SetURL("http://udis86.sourceforge.net")); 1464 // TODO: License! 1465 #endif 1466 1467 #ifdef __INTEL__ 1468 // Intel PRO/Wireless 2100 Firmware 1469 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 Firmware") 1470 .SetCopyright(COPYRIGHT_STRING 1471 "2003-2006 by " 1472 "Intel Corporation. All rights reserved.") 1473 .SetLicense("Intel (2xxx firmware)") 1474 .SetURL("http://ipw2100.sourceforge.net/")); 1475 #endif 1476 1477 #ifdef __INTEL__ 1478 // Intel PRO/Wireless 2200BG Firmware 1479 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2200BG Firmware") 1480 .SetCopyright(COPYRIGHT_STRING 1481 "2004-2005 by " 1482 "Intel Corporation. All rights reserved.") 1483 .SetLicense("Intel (2xxx firmware)") 1484 .SetURL("http://ipw2200.sourceforge.net/")); 1485 #endif 1486 1487 #ifdef __INTEL__ 1488 // Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware 1489 _AddPackageCredit( 1490 PackageCredit( 1491 "Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware") 1492 .SetCopyright(COPYRIGHT_STRING 1493 "2006 - 2007 by " 1494 "Intel Corporation. All rights reserved.") 1495 .SetLicense("Intel (firmware)") 1496 .SetURL("http://www.intellinuxwireless.org/")); 1497 #endif 1498 #ifdef __INTEL__ 1499 // Intel Wireless WiFi Link 4965AGN Adapter Firmware 1500 _AddPackageCredit( 1501 PackageCredit("Intel Wireless WiFi Link 4965AGN Adapter Firmware") 1502 .SetCopyright(COPYRIGHT_STRING 1503 "2006 - 2007 by " 1504 "Intel Corporation. All rights reserved.") 1505 .SetLicense("Intel (firmware)") 1506 .SetURL("http://www.intellinuxwireless.org/")); 1507 #endif 1508 1509 #ifdef __INTEL__ 1510 // Marvell 88w8363 1511 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1512 .SetCopyright(COPYRIGHT_STRING 1513 "2007-2009 by " 1514 "Marvell Semiconductor, Inc. All rights reserved.") 1515 .SetLicense("Marvell (firmware)") 1516 .SetURL("http://www.marvell.com/")); 1517 #endif 1518 1519 #ifdef __INTEL__ 1520 // Ralink Firmware RT2501/RT2561/RT2661 1521 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1522 .SetCopyright(COPYRIGHT_STRING 1523 "2007 by " 1524 "Ralink Technology Corporation. All rights reserved.") 1525 .SetLicense("Ralink (firmware)") 1526 .SetURL("http://www.ralinktech.com/")); 1527 #endif 1528 1529 _AddCopyrightsFromAttribute(); 1530 _AddPackageCreditEntries(); 1531 1532 return new CropView(creditsScroller, 0, 1, 1, 1); 1533 } 1534 1535 1536 status_t 1537 AboutView::_GetLicensePath(const char* license, BPath& path) 1538 { 1539 static const directory_which directoryConstants[] = { 1540 B_USER_DATA_DIRECTORY, 1541 B_COMMON_DATA_DIRECTORY, 1542 B_SYSTEM_DATA_DIRECTORY 1543 }; 1544 static const int dirCount = 3; 1545 1546 for (int i = 0; i < dirCount; i++) { 1547 struct stat st; 1548 status_t error = find_directory(directoryConstants[i], &path); 1549 if (error == B_OK && path.Append("licenses") == B_OK 1550 && path.Append(license) == B_OK 1551 && lstat(path.Path(), &st) == 0) { 1552 return B_OK; 1553 } 1554 } 1555 1556 path.Unset(); 1557 return B_ENTRY_NOT_FOUND; 1558 } 1559 1560 1561 void 1562 AboutView::_AddCopyrightsFromAttribute() 1563 { 1564 #ifdef __HAIKU__ 1565 // open the app executable file 1566 char appPath[B_PATH_NAME_LENGTH]; 1567 int appFD; 1568 if (BPrivate::get_app_path(appPath) != B_OK 1569 || (appFD = open(appPath, O_RDONLY)) < 0) { 1570 return; 1571 } 1572 1573 // open the attribute 1574 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1575 close(appFD); 1576 if (attrFD < 0) 1577 return; 1578 1579 // attach it to a FILE 1580 FILE* attrFile = fdopen(attrFD, "r"); 1581 if (attrFile == NULL) { 1582 close(attrFD); 1583 return; 1584 } 1585 CObjectDeleter<FILE, int> _(attrFile, fclose); 1586 1587 // read and parse the copyrights 1588 BMessage package; 1589 BString fieldName; 1590 BString fieldValue; 1591 char lineBuffer[LINE_MAX]; 1592 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1593 // chop off line break 1594 size_t lineLen = strlen(line); 1595 if (lineLen > 0 && line[lineLen - 1] == '\n') 1596 line[--lineLen] = '\0'; 1597 1598 // flush previous field, if a new field begins, otherwise append 1599 if (lineLen == 0 || !isspace(line[0])) { 1600 // new field -- flush the previous one 1601 if (fieldName.Length() > 0) { 1602 fieldValue = trim_string(fieldValue.String(), 1603 fieldValue.Length()); 1604 package.AddString(fieldName.String(), fieldValue); 1605 fieldName = ""; 1606 } 1607 } else if (fieldName.Length() > 0) { 1608 // append to current field 1609 fieldValue += line; 1610 continue; 1611 } else { 1612 // bogus line -- ignore 1613 continue; 1614 } 1615 1616 if (lineLen == 0) 1617 continue; 1618 1619 // parse new field 1620 char* colon = strchr(line, ':'); 1621 if (colon == NULL) { 1622 // bogus line -- ignore 1623 continue; 1624 } 1625 1626 fieldName.SetTo(line, colon - line); 1627 fieldName = trim_string(line, colon - line); 1628 if (fieldName.Length() == 0) { 1629 // invalid field name 1630 continue; 1631 } 1632 1633 fieldValue = colon + 1; 1634 1635 if (fieldName == "Package") { 1636 // flush the current package 1637 _AddPackageCredit(PackageCredit(package)); 1638 package.MakeEmpty(); 1639 } 1640 } 1641 1642 // flush current package 1643 _AddPackageCredit(PackageCredit(package)); 1644 #endif 1645 } 1646 1647 1648 void 1649 AboutView::_AddPackageCreditEntries() 1650 { 1651 // sort the packages case-insensitively 1652 PackageCredit* packages[fPackageCredits.size()]; 1653 int32 count = 0; 1654 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1655 it != fPackageCredits.end(); ++it) { 1656 packages[count++] = it->second; 1657 } 1658 1659 if (count > 1) { 1660 std::sort(packages, packages + count, 1661 &PackageCredit::NameLessInsensitive); 1662 } 1663 1664 // add the credits 1665 for (int32 i = 0; i < count; i++) { 1666 PackageCredit* package = packages[i]; 1667 1668 BString text(package->CopyrightAt(0)); 1669 int32 count = package->CountCopyrights(); 1670 for (int32 i = 1; i < count; i++) 1671 text << "\n" << package->CopyrightAt(i); 1672 1673 AddCopyrightEntry(package->PackageName(), text.String(), 1674 package->Licenses(), package->Sources(), package->URL()); 1675 } 1676 } 1677 1678 1679 void 1680 AboutView::_AddPackageCredit(const PackageCredit& package) 1681 { 1682 if (!package.IsValid()) 1683 return; 1684 1685 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1686 if (it != fPackageCredits.end()) { 1687 // If the new package credit isn't "better" than the old one, ignore it. 1688 PackageCredit* oldPackage = it->second; 1689 if (!package.IsBetterThan(*oldPackage)) 1690 return; 1691 1692 // replace the old credit 1693 fPackageCredits.erase(it); 1694 delete oldPackage; 1695 } 1696 1697 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1698 } 1699 1700 1701 // #pragma mark - 1702 1703 1704 static const char* 1705 MemSizeToString(char string[], size_t size, system_info* info) 1706 { 1707 int inaccessibleMemory = int(info->ignored_pages 1708 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1709 if (inaccessibleMemory > 0) { 1710 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1711 "inaccessible")); 1712 1713 snprintf(string, size, "%d", int((info->max_pages 1714 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1715 message.ReplaceFirst("%total", string); 1716 1717 snprintf(string, size, "%d", inaccessibleMemory); 1718 message.ReplaceFirst("%inaccessible", string); 1719 strncpy(string, message.String(), size); 1720 } else { 1721 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1722 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1723 } 1724 1725 return string; 1726 } 1727 1728 1729 static const char* 1730 MemUsageToString(char string[], size_t size, system_info* info) 1731 { 1732 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1733 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1734 int(100 * info->used_pages / info->max_pages)); 1735 1736 return string; 1737 } 1738 1739 1740 static const char* 1741 UptimeToString(char string[], size_t size) 1742 { 1743 BDurationFormat formatter; 1744 BString str; 1745 1746 bigtime_t uptime = system_time(); 1747 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1748 formatter.Format(now - uptime, now, &str); 1749 str.CopyInto(string, 0, size); 1750 string[std::min((size_t)str.Length(), size)] = '\0'; 1751 1752 return string; 1753 } 1754 1755 1756 int 1757 main() 1758 { 1759 AboutApp app; 1760 app.Run(); 1761 return 0; 1762 } 1763 1764