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->GetName(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->GetName(rightName); 194 delete language; 195 } else 196 rightName = rightTranslation->languageCode; 197 198 BCollator collator; 199 be_locale->GetCollator(&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 bool isHybrid = gccFourHybrid.Exists() || gccTwoHybrid.Exists(); 516 517 if (isHybrid) { 518 snprintf(string, sizeof(string), B_TRANSLATE("GCC %d Hybrid"), 519 __GNUC__); 520 } else 521 snprintf(string, sizeof(string), "GCC %d", __GNUC__); 522 523 BStringView* gccView = new BStringView("gcctext", string); 524 gccView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 525 B_ALIGN_VERTICAL_UNSET)); 526 527 #if __GNUC__ == 2 528 if (isHybrid) { 529 // do now show the GCC version if it's the default 530 gccView->Hide(); 531 } 532 #endif 533 534 // CPU count, type and clock speed 535 char processorLabel[256]; 536 if (systemInfo.cpu_count > 1) { 537 snprintf(processorLabel, sizeof(processorLabel), 538 B_TRANSLATE("%ld Processors:"), systemInfo.cpu_count); 539 } else 540 strlcpy(processorLabel, B_TRANSLATE("Processor:"), 541 sizeof(processorLabel)); 542 543 BString cpuType; 544 cpuType << get_cpu_vendor_string(systemInfo.cpu_type) 545 << " " << get_cpu_model_string(&systemInfo); 546 547 BStringView* cpuView = new BStringView("cputext", cpuType.String()); 548 cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 549 B_ALIGN_VERTICAL_UNSET)); 550 551 int32 clockSpeed = get_rounded_cpu_speed(); 552 if (clockSpeed < 1000) 553 sprintf(string, B_TRANSLATE("%ld MHz"), clockSpeed); 554 else 555 sprintf(string, B_TRANSLATE("%.2f GHz"), clockSpeed / 1000.0f); 556 557 BStringView* frequencyView = new BStringView("frequencytext", string); 558 frequencyView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 559 B_ALIGN_VERTICAL_UNSET)); 560 561 // RAM 562 BStringView *memSizeView = new BStringView("ramsizetext", 563 MemSizeToString(string, sizeof(string), &systemInfo)); 564 memSizeView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 565 B_ALIGN_VERTICAL_UNSET)); 566 fMemView = new BStringView("ramtext", 567 MemUsageToString(string, sizeof(string), &systemInfo)); 568 fMemView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 569 B_ALIGN_VERTICAL_UNSET)); 570 571 // Kernel build time/date 572 snprintf(string, sizeof(string), "%s %s", 573 systemInfo.kernel_build_date, systemInfo.kernel_build_time); 574 575 BStringView* kernelView = new BStringView("kerneltext", string); 576 kernelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 577 B_ALIGN_VERTICAL_UNSET)); 578 579 // Uptime 580 fUptimeView = new BTextView("uptimetext"); 581 fUptimeView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 582 fUptimeView->MakeEditable(false); 583 fUptimeView->MakeSelectable(false); 584 fUptimeView->SetWordWrap(true); 585 586 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 587 588 const float offset = 5; 589 590 SetLayout(new BGroupLayout(B_HORIZONTAL, 0)); 591 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 592 593 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 594 .AddGroup(B_VERTICAL, 0) 595 .Add(new LogoView()) 596 .AddGroup(B_VERTICAL, 0) 597 .Add(_CreateLabel("oslabel", B_TRANSLATE("Version:"))) 598 .Add(versionView) 599 .Add(gccView) 600 .AddStrut(offset) 601 .Add(_CreateLabel("cpulabel", processorLabel)) 602 .Add(cpuView) 603 .Add(frequencyView) 604 .AddStrut(offset) 605 .Add(_CreateLabel("memlabel", B_TRANSLATE("Memory:"))) 606 .Add(memSizeView) 607 .Add(fMemView) 608 .AddStrut(offset) 609 .Add(_CreateLabel("kernellabel", B_TRANSLATE("Kernel:"))) 610 .Add(kernelView) 611 .AddStrut(offset) 612 .Add(_CreateLabel("uptimelabel", 613 B_TRANSLATE("Time running:"))) 614 .Add(fUptimeView) 615 .SetInsets(5, 5, 5, 5) 616 .End() 617 // TODO: investigate: adding this causes the time to be cut 618 //.AddGlue() 619 .End() 620 .Add(_CreateCreditsView()); 621 622 float min = fMemView->MinSize().width * 1.1f; 623 fCreditsView->SetExplicitMinSize(BSize(min, min)); 624 } 625 626 627 AboutView::~AboutView() 628 { 629 delete fScrollRunner; 630 } 631 632 633 void 634 AboutView::AttachedToWindow() 635 { 636 BView::AttachedToWindow(); 637 Window()->SetPulseRate(500000); 638 SetEventMask(B_POINTER_EVENTS); 639 } 640 641 642 void 643 AboutView::MouseDown(BPoint point) 644 { 645 BRect r(92, 26, 105, 31); 646 if (r.Contains(point)) { 647 printf("Easter egg\n"); 648 PickRandomHaiku(); 649 } 650 651 if (Bounds().Contains(point)) { 652 fLastActionTime = system_time(); 653 delete fScrollRunner; 654 fScrollRunner = NULL; 655 } 656 } 657 658 659 void 660 AboutView::Pulse() 661 { 662 char string[255]; 663 system_info info; 664 get_system_info(&info); 665 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 666 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 667 668 if (fScrollRunner == NULL 669 && system_time() > fLastActionTime + 10000000) { 670 BMessage message(SCROLL_CREDITS_VIEW); 671 //fScrollRunner = new BMessageRunner(this, &message, 25000, -1); 672 } 673 } 674 675 676 void 677 AboutView::MessageReceived(BMessage* msg) 678 { 679 switch (msg->what) { 680 case SCROLL_CREDITS_VIEW: 681 { 682 BScrollBar* scrollBar = 683 fCreditsView->ScrollBar(B_VERTICAL); 684 if (scrollBar == NULL) 685 break; 686 float max, min; 687 scrollBar->GetRange(&min, &max); 688 if (scrollBar->Value() < max) 689 fCreditsView->ScrollBy(0, 1); 690 691 break; 692 } 693 694 default: 695 BView::MessageReceived(msg); 696 break; 697 } 698 } 699 700 701 void 702 AboutView::AddCopyrightEntry(const char* name, const char* text, 703 const char* url) 704 { 705 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 706 } 707 708 709 void 710 AboutView::AddCopyrightEntry(const char* name, const char* text, 711 const StringVector& licenses, const StringVector& sources, 712 const char* url) 713 { 714 BFont font(be_bold_font); 715 //font.SetSize(be_bold_font->Size()); 716 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 717 718 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 719 fCreditsView->Insert(name); 720 fCreditsView->Insert("\n"); 721 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 722 fCreditsView->Insert(text); 723 fCreditsView->Insert("\n"); 724 725 if (licenses.CountStrings() > 0) { 726 if (licenses.CountStrings() > 1) 727 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 728 else 729 fCreditsView->Insert(B_TRANSLATE("License: ")); 730 731 for (int32 i = 0; i < licenses.CountStrings(); i++) { 732 const char* license = licenses.StringAt(i); 733 734 if (i > 0) 735 fCreditsView->Insert(", "); 736 737 BString licenseName; 738 BString licenseURL; 739 parse_named_url(license, licenseName, licenseURL); 740 741 BPath licensePath; 742 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 743 fCreditsView->InsertHyperText(licenseName, 744 new OpenFileAction(licensePath.Path())); 745 } else 746 fCreditsView->Insert(licenseName); 747 } 748 749 fCreditsView->Insert("\n"); 750 } 751 752 if (sources.CountStrings() > 0) { 753 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 754 755 for (int32 i = 0; i < sources.CountStrings(); i++) { 756 const char* source = sources.StringAt(i); 757 758 if (i > 0) 759 fCreditsView->Insert(", "); 760 761 BString urlName; 762 BString urlAddress; 763 parse_named_url(source, urlName, urlAddress); 764 765 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 766 &kLinkBlue); 767 fCreditsView->InsertHyperText(urlName, 768 new URLAction(urlAddress)); 769 } 770 771 fCreditsView->Insert("\n"); 772 } 773 774 if (url) { 775 BString urlName; 776 BString urlAddress; 777 parse_named_url(url, urlName, urlAddress); 778 779 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 780 &kLinkBlue); 781 fCreditsView->InsertHyperText(urlName, 782 new URLAction(urlAddress)); 783 fCreditsView->Insert("\n"); 784 } 785 fCreditsView->Insert("\n"); 786 } 787 788 789 void 790 AboutView::PickRandomHaiku() 791 { 792 BFile fortunes( 793 #ifdef __HAIKU__ 794 "/etc/fortunes/Haiku", 795 #else 796 "data/etc/fortunes/Haiku", 797 #endif 798 B_READ_ONLY); 799 struct stat st; 800 if (fortunes.InitCheck() < B_OK) 801 return; 802 if (fortunes.GetStat(&st) < B_OK) 803 return; 804 char* buff = (char*)malloc((size_t)st.st_size + 1); 805 if (!buff) 806 return; 807 buff[(size_t)st.st_size] = '\0'; 808 BList haikuList; 809 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 810 char* p = buff; 811 while (p && *p) { 812 char* e = strchr(p, '%'); 813 BString* s = new BString(p, e ? (e - p) : -1); 814 haikuList.AddItem(s); 815 p = e; 816 if (p && (*p == '%')) 817 p++; 818 if (p && (*p == '\n')) 819 p++; 820 } 821 } 822 free(buff); 823 if (haikuList.CountItems() < 1) 824 return; 825 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 826 BFont font(be_bold_font); 827 font.SetSize(be_bold_font->Size()); 828 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 829 fCreditsView->SelectAll(); 830 fCreditsView->Delete(); 831 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 832 fCreditsView->Insert(s->String()); 833 fCreditsView->Insert("\n"); 834 while ((s = (BString*)haikuList.RemoveItem((int32)0))) { 835 delete s; 836 } 837 } 838 839 840 BView* 841 AboutView::_CreateLabel(const char* name, const char* label) 842 { 843 BStringView* labelView = new BStringView(name, label); 844 labelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 845 B_ALIGN_VERTICAL_UNSET)); 846 labelView->SetFont(be_bold_font); 847 return labelView; 848 } 849 850 851 BView* 852 AboutView::_CreateCreditsView() 853 { 854 // Begin construction of the credits view 855 fCreditsView = new HyperTextView("credits"); 856 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 857 fCreditsView->SetStylable(true); 858 fCreditsView->MakeEditable(false); 859 fCreditsView->SetWordWrap(true); 860 fCreditsView->SetInsets(5, 5, 5, 5); 861 fCreditsView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); 862 863 BScrollView* creditsScroller = new BScrollView("creditsScroller", 864 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 865 B_PLAIN_BORDER); 866 867 // Haiku copyright 868 BFont font(be_bold_font); 869 font.SetSize(font.Size() + 4); 870 871 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 872 fCreditsView->Insert("Haiku\n"); 873 874 char string[1024]; 875 time_t time = ::time(NULL); 876 struct tm* tm = localtime(&time); 877 int32 year = tm->tm_year + 1900; 878 if (year < 2008) 879 year = 2008; 880 snprintf(string, sizeof(string), 881 COPYRIGHT_STRING "2001-%ld The Haiku project. ", year); 882 883 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 884 fCreditsView->Insert(string); 885 886 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 887 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 888 "property of Haiku, Inc. or of the respective authors where expressly " 889 "noted in the source. Haiku and the Haiku logo are trademarks of " 890 "Haiku, Inc." 891 "\n\n")); 892 893 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 894 fCreditsView->InsertHyperText("http://www.haiku-os.org", 895 new URLAction("http://www.haiku-os.org")); 896 fCreditsView->Insert("\n\n"); 897 898 font.SetSize(be_bold_font->Size()); 899 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 900 901 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 902 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 903 904 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 905 fCreditsView->Insert( 906 "Ithamar R. Adema\n" 907 "Bruno G. Albuquerque\n" 908 "Stephan Aßmus\n" 909 "Salvatore Benedetto\n" 910 "Stefano Ceccherini\n" 911 "Rudolf Cornelissen\n" 912 "Alexandre Deckner\n" 913 "Adrien Destugues\n" 914 "Oliver Ruiz Dorantes\n" 915 "Axel Dörfler\n" 916 "Jérôme Duval\n" 917 "René Gollent\n" 918 "Bryce Groff\n" 919 "Colin Günther\n" 920 "Karsten Heimrich\n" 921 "Fredrik Holmqvist\n" 922 "Philippe Houdoin\n" 923 "Maurice Kalinowski\n" 924 "Euan Kirkhope\n" 925 "Ryan Leavengood\n" 926 "Michael Lotz\n" 927 "Brecht Machiels\n" 928 "Matt Madia\n" 929 "Scott McCreary\n" 930 "David McPaul\n" 931 "Wim van der Meer\n" 932 "Fredrik Modéen\n" 933 "Marcus Overhagen\n" 934 "Michael Pfeiffer\n" 935 "François Revol\n" 936 "Philippe Saint-Pierre\n" 937 "Andrej Spielmann\n" 938 "Jonas Sundström\n" 939 "Oliver Tappe\n" 940 "Gerasim Troeglazov\n" 941 "Ingo Weinhold\n" 942 "Alex Wilson\n" 943 "Artur Wyszyński\n" 944 "Clemens Zeidler\n" 945 "Siarzhuk Zharski\n" 946 "\n"); 947 948 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 949 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 950 951 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 952 fCreditsView->Insert( 953 "Andrew Bachmann\n" 954 "Tyler Dauwalder\n" 955 "Daniel Furrer\n" 956 "Andre Alves Garzia\n" 957 "Erik Jaesler\n" 958 "Marcin Konicki\n" 959 "Waldemar Kornewald\n" 960 "Thomas Kurschel\n" 961 "Frans Van Nispen\n" 962 "Adi Oanca\n" 963 "Michael Phipps\n" 964 "Niels Sascha Reedijk\n" 965 "David Reid\n" 966 "Hugo Santos\n" 967 "Alexander G. M. Smith\n" 968 "Bryan Varner\n" 969 "Nathan Whitehorn\n" 970 "Michael Wilber\n" 971 "Jonathan Yoder\n" 972 "Gabe Yoder\n" 973 "\n"); 974 975 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 976 fCreditsView->Insert(B_TRANSLATE("Website, marketing & documentation:\n")); 977 978 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 979 fCreditsView->Insert( 980 "Phil Greenway\n" 981 "Gavin James\n" 982 "Jorge G. Mare (aka Koki)\n" 983 "Urias McCullough\n" 984 "Niels Sascha Reedijk\n" 985 "Joachim Seemer (Humdinger)\n" 986 "Jonathan Yoder\n" 987 "\n"); 988 989 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 990 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 991 992 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 993 fCreditsView->Insert( 994 "Andrea Anzani\n" 995 "Sean Bartell\n" 996 "Andre Braga\n" 997 "Bruce Cameron\n" 998 "Greg Crain\n" 999 "David Dengg\n" 1000 "John Drinkwater\n" 1001 "Cian Duffy\n" 1002 "Vincent Duvert\n" 1003 "Fredrik Ekdahl\n" 1004 "Joshua R. Elsasser\n" 1005 "Atis Elsts\n" 1006 "Mark Erben\n" 1007 "Christian Fasshauer\n" 1008 "Andreas Färber\n" 1009 "Janito Ferreira Filho\n" 1010 "Marc Flerackers\n" 1011 "Michele Frau (zuMi)\n" 1012 "Pete Goodeve\n" 1013 "Lucian Adrian Grijincu\n" 1014 "Matthijs Hollemans\n" 1015 "Mathew Hounsell\n" 1016 "Morgan Howe\n" 1017 "Christophe Huriaux\n" 1018 "Ma Jie\n" 1019 "Carwyn Jones\n" 1020 "Vasilis Kaoutsis\n" 1021 "James Kim\n" 1022 "Shintaro Kinugawa\n" 1023 "Jan Klötzke\n" 1024 "Kurtis Kopf\n" 1025 "Tomáš Kučera\n" 1026 "Luboš Kulič\n" 1027 "Elad Lahav\n" 1028 "Anthony Lee\n" 1029 "Santiago Lema\n" 1030 "Raynald Lesieur\n" 1031 "Oscar Lesta\n" 1032 "Jerome Leveque\n" 1033 "Christof Lutteroth\n" 1034 "Graham MacDonald\n" 1035 "Jan Matějek\n" 1036 "Brian Matzon\n" 1037 "Christopher ML Zumwalt May\n" 1038 "Andrew McCall\n" 1039 "Nathan Mentley\n" 1040 "Marius Middelthon\n" 1041 "Marco Minutoli\n" 1042 "Misza\n" 1043 "MrSiggler\n" 1044 "Alan Murta\n" 1045 "Raghuram Nagireddy\n" 1046 "Jeroen Oortwijn (idefix)\n" 1047 "Pahtz\n" 1048 "Michael Paine\n" 1049 "Adrian Panasiuk\n" 1050 "Romain Picard\n" 1051 "Francesco Piccinno\n" 1052 "David Powell\n" 1053 "Jeremy Rand\n" 1054 "Hartmut Reh\n" 1055 "Daniel Reinhold\n" 1056 "Chris Roberts\n" 1057 "Samuel Rodríguez Pérez\n" 1058 "Thomas Roell\n" 1059 "Rafael Romo\n" 1060 "Ralf Schülke\n" 1061 "John Scipione\n" 1062 "Reznikov Sergei\n" 1063 "Zousar Shaker\n" 1064 "Caitlin Shaw\n" 1065 "Daniel Switkin\n" 1066 "Atsushi Takamatsu\n" 1067 "James Urquhart\n" 1068 "Jason Vandermark\n" 1069 "Sandor Vroemisse\n" 1070 "Denis Washington\n" 1071 "Ulrich Wimboeck\n" 1072 "Johannes Wischert\n" 1073 "James Woodcock\n" 1074 "Hong Yul Yang\n" 1075 "Gerald Zajac\n" 1076 "Łukasz Zemczak\n" 1077 "JiSheng Zhang\n" 1078 "Zhao Shuai\n"); 1079 fCreditsView->Insert( 1080 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 1081 " and probably some more we forgot to mention (sorry!)" 1082 "\n\n")); 1083 1084 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1085 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 1086 1087 BLanguage* lang; 1088 BString langName; 1089 1090 BList sortedTranslations; 1091 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1092 const Translation* translation = &gTranslations[i]; 1093 sortedTranslations.AddItem((void*)translation); 1094 } 1095 sortedTranslations.SortItems(TranslationComparator); 1096 1097 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1098 const Translation& translation 1099 = *(const Translation*)sortedTranslations.ItemAt(i); 1100 1101 langName.Truncate(0); 1102 if (be_locale_roster->GetLanguage(translation.languageCode, &lang) 1103 == B_OK) { 1104 lang->GetName(langName); 1105 delete lang; 1106 } else { 1107 // We failed to get the localized readable name, 1108 // go with what we have. 1109 langName.Append(translation.languageCode); 1110 } 1111 1112 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1113 fCreditsView->Insert("\n"); 1114 fCreditsView->Insert(langName); 1115 fCreditsView->Insert("\n"); 1116 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1117 fCreditsView->Insert(translation.names); 1118 } 1119 1120 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1121 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 1122 1123 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1124 fCreditsView->Insert( 1125 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 1126 fCreditsView->Insert( 1127 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 1128 fCreditsView->Insert( 1129 B_TRANSLATE("The Haiku-Ports team\n")); 1130 fCreditsView->Insert( 1131 B_TRANSLATE("The Haikuware team and their bounty program\n")); 1132 fCreditsView->Insert( 1133 B_TRANSLATE("The BeGeistert team\n")); 1134 fCreditsView->Insert( 1135 B_TRANSLATE("Google & their Google Summer of Code program\n")); 1136 fCreditsView->Insert( 1137 B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n")); 1138 fCreditsView->Insert( 1139 B_TRANSLATE("... and the many people making donations!\n\n")); 1140 1141 // copyrights for various projects we use 1142 1143 BPath mitPath; 1144 _GetLicensePath("MIT", mitPath); 1145 1146 font.SetSize(be_bold_font->Size() + 4); 1147 font.SetFace(B_BOLD_FACE); 1148 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1149 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 1150 1151 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1152 fCreditsView->Insert(B_TRANSLATE("[Click a license name to read the " 1153 "respective license.]\n\n")); 1154 1155 // Haiku license 1156 BString haikuLicence = B_TRANSLATE("The code that is unique to Haiku, " 1157 "especially the kernel and all code that applications may link " 1158 "against, is distributed under the terms of the %MIT licence%. " 1159 "Some system libraries contain third party code distributed under the " 1160 "LGPL license. You can find the copyrights to third party code below.\n" 1161 "\n"); 1162 int32 licencePart1 = haikuLicence.FindFirst("%"); 1163 int32 licencePart2 = haikuLicence.FindLast("%"); 1164 BString part; 1165 haikuLicence.CopyCharsInto(part, 0, licencePart1 ); 1166 fCreditsView->Insert(part); 1167 1168 part.Truncate(0); 1169 haikuLicence.CopyCharsInto(part, licencePart1 + 1, licencePart2 - 1 1170 - licencePart1); 1171 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1172 1173 part.Truncate(0); 1174 haikuLicence.CopyCharsInto(part, licencePart2 + 1, haikuLicence.CountChars() 1175 - licencePart2); 1176 fCreditsView->Insert(part); 1177 1178 // GNU copyrights 1179 AddCopyrightEntry("The GNU Project", 1180 "Contains software from the GNU Project, " 1181 "released under the GPL and LGPL licenses:\n" 1182 "GNU C Library, " 1183 "GNU coretools, diffutils, findutils, " 1184 "sharutils, gawk, bison, m4, make, " 1185 "gdb, wget, ncurses, termcap, " 1186 "Bourne Again Shell.\n" 1187 COPYRIGHT_STRING "The Free Software Foundation.", 1188 StringVector("GNU LGPL v2.1", "GNU GPL v2", "GNU GPL v3", NULL), 1189 StringVector(), 1190 "http://www.gnu.org"); 1191 1192 // FreeBSD copyrights 1193 AddCopyrightEntry("The FreeBSD Project", 1194 "Contains software from the FreeBSD Project, " 1195 "released under the BSD license:\n" 1196 "cal, ftpd, ping, telnet, " 1197 "telnetd, traceroute\n" 1198 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1199 "All rights reserved.", 1200 "http://www.freebsd.org"); 1201 // TODO: License! 1202 1203 // NetBSD copyrights 1204 AddCopyrightEntry("The NetBSD Project", 1205 "Contains software developed by the NetBSD, " 1206 "Foundation, Inc. and its contributors:\n" 1207 "ftp, tput\n" 1208 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 1209 "All rights reserved.", 1210 "http://www.netbsd.org"); 1211 // TODO: License! 1212 1213 // FFMpeg copyrights 1214 _AddPackageCredit(PackageCredit("FFMpeg libavcodec") 1215 .SetCopyright(COPYRIGHT_STRING "2000-2007 Fabrice Bellard, et al.") 1216 .SetLicenses("GNU LGPL v2.1", "GNU LGPL v2", NULL) 1217 .SetURL("http://www.ffmpeg.org")); 1218 1219 // AGG copyrights 1220 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1221 .SetCopyright(COPYRIGHT_STRING "2002-2006 Maxim Shemanarev (McSeem).") 1222 .SetLicenses("Anti-Grain Geometry", "BSD (3-clause)", "GPC", NULL) 1223 .SetURL("http://www.antigrain.com")); 1224 1225 // PDFLib copyrights 1226 _AddPackageCredit(PackageCredit("PDFLib") 1227 .SetCopyright(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and Thomas Merz. " 1228 "All rights reserved.\n" 1229 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.") 1230 .SetLicense("PDFlib Lite") 1231 .SetURL("http://www.pdflib.com")); 1232 1233 // FreeType copyrights 1234 _AddPackageCredit(PackageCredit("FreeType2") 1235 .SetCopyright("Portions of this software are copyright " 1236 B_UTF8_COPYRIGHT " 1996-2006 " 1237 "The FreeType Project. All rights reserved.") 1238 .SetLicense("FTL") 1239 .SetURL("http://www.freetype.org")); 1240 1241 // Mesa3D (http://www.mesa3d.org) copyrights 1242 _AddPackageCredit(PackageCredit("Mesa") 1243 .SetCopyright(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1244 "Mesa3D Project. All rights reserved.") 1245 .SetLicense("MIT") 1246 .SetURL("http://www.mesa3d.org")); 1247 1248 // SGI's GLU implementation copyrights 1249 _AddPackageCredit(PackageCredit("GLU") 1250 .SetCopyright(COPYRIGHT_STRING 1251 "1991-2000 Silicon Graphics, Inc. " 1252 "SGI's Software FreeB license. All rights reserved.") 1253 .SetLicense("SGI Free B") 1254 .SetURL("http://www.sgi.com/products/software/opengl")); 1255 1256 // GLUT implementation copyrights 1257 _AddPackageCredit(PackageCredit("GLUT") 1258 .SetCopyrights(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1259 "All rights reserved.", 1260 COPYRIGHT_STRING "1997 Be Inc.", 1261 COPYRIGHT_STRING "1999 Jake Hamby.", 1262 NULL) 1263 .SetLicense("GLUT (Mark Kilgard)") 1264 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1265 1266 // OpenGroup & DEC (BRegion backend) copyright 1267 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1268 .SetCopyrights(COPYRIGHT_STRING "1987, 1988, 1998 The Open Group.", 1269 COPYRIGHT_STRING "1987, 1988 Digital Equipment " 1270 "Corporation, Maynard, Massachusetts.\n" 1271 "All rights reserved.", 1272 NULL) 1273 .SetLicenses("OpenGroup", "DEC", NULL)); 1274 // TODO: URL 1275 1276 // VL-Gothic font 1277 _AddPackageCredit(PackageCredit("VL-Gothic font") 1278 .SetCopyrights(COPYRIGHT_STRING "1990-2003 Wada Laboratory," 1279 " the University of Tokyo", COPYRIGHT_STRING 1280 "2003-2004 Electronic Font Open Laboratory (/efont/)", 1281 COPYRIGHT_STRING "2003-2008 M+ FONTS PROJECT", 1282 COPYRIGHT_STRING "2006-2009 Daisuke SUZUKI", 1283 COPYRIGHT_STRING "2006-2009 Project Vine", 1284 "MIT license. All rights reserved.", 1285 NULL)); 1286 // TODO: License! 1287 1288 // expat copyrights 1289 _AddPackageCredit(PackageCredit("expat") 1290 .SetCopyrights(COPYRIGHT_STRING 1291 "1998, 1999, 2000 Thai Open Source " 1292 "Software Center Ltd and Clark Cooper.", 1293 COPYRIGHT_STRING "2001, 2002, 2003 Expat maintainers.", 1294 NULL) 1295 .SetLicense("Expat") 1296 .SetURL("http://expat.sourceforge.net")); 1297 1298 // zlib copyrights 1299 _AddPackageCredit(PackageCredit("zlib") 1300 .SetCopyright(COPYRIGHT_STRING 1301 "1995-2004 Jean-loup Gailly and Mark Adler.") 1302 .SetLicense("Zlib") 1303 .SetURL("http://www.zlib.net")); 1304 1305 // zip copyrights 1306 _AddPackageCredit(PackageCredit("Info-ZIP") 1307 .SetCopyright(COPYRIGHT_STRING 1308 "1990-2002 Info-ZIP. All rights reserved.") 1309 .SetLicense("Info-ZIP") 1310 .SetURL("http://www.info-zip.org")); 1311 1312 // bzip2 copyrights 1313 _AddPackageCredit(PackageCredit("bzip2") 1314 .SetCopyright(COPYRIGHT_STRING 1315 "1996-2005 Julian R Seward. All rights reserved.") 1316 .SetLicense("BSD (4-clause)") 1317 .SetURL("http://bzip.org")); 1318 1319 // lp_solve copyrights 1320 _AddPackageCredit(PackageCredit("lp_solve") 1321 .SetCopyright(COPYRIGHT_STRING 1322 "Michel Berkelaar, Kjell Eikland, Peter Notebaert") 1323 .SetLicense("GNU LGPL v2.1") 1324 .SetURL("http://lpsolve.sourceforge.net/")); 1325 1326 // OpenEXR copyrights 1327 _AddPackageCredit(PackageCredit("OpenEXR") 1328 .SetCopyright(COPYRIGHT_STRING "2002-2005 Industrial Light & Magic, " 1329 "a division of Lucas Digital Ltd. LLC.") 1330 .SetLicense("BSD (3-clause)") 1331 .SetURL("http://www.openexr.com")); 1332 1333 // Bullet copyrights 1334 _AddPackageCredit(PackageCredit("Bullet") 1335 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 1336 .SetLicense("Bullet") 1337 .SetURL("http://www.bulletphysics.com")); 1338 1339 // atftp copyrights 1340 _AddPackageCredit(PackageCredit("atftp") 1341 .SetCopyright(COPYRIGHT_STRING 1342 "2000 Jean-Pierre ervbefeL and Remi Lefebvre") 1343 .SetLicense("GNU GPL v2")); 1344 // TODO: URL! 1345 1346 // Netcat copyrights 1347 _AddPackageCredit(PackageCredit("Netcat") 1348 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit")); 1349 // TODO: License! 1350 1351 // acpica copyrights 1352 _AddPackageCredit(PackageCredit("acpica") 1353 .SetCopyright(COPYRIGHT_STRING "1999-2006 Intel Corp.") 1354 .SetLicense("Intel (ACPICA)") 1355 .SetURL("http://www.acpica.org")); 1356 1357 // unrar copyrights 1358 _AddPackageCredit(PackageCredit("unrar") 1359 .SetCopyright(COPYRIGHT_STRING "2002-2008 Alexander L. Roshal. " 1360 "All rights reserved.") 1361 .SetLicense("UnRAR") 1362 .SetURL("http://www.rarlab.com")); 1363 1364 // libpng copyrights 1365 _AddPackageCredit(PackageCredit("libpng") 1366 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 1367 "Randers-Pehrson.") 1368 .SetLicense("LibPNG") 1369 .SetURL("http://www.libpng.org")); 1370 1371 // libjpeg copyrights 1372 _AddPackageCredit(PackageCredit("libjpeg") 1373 .SetCopyright(COPYRIGHT_STRING " 1994-2009, Thomas G. Lane," 1374 " Guido Vollbeding. This software is based in part on the " 1375 "work of the Independent JPEG Group") 1376 .SetLicense("LibJPEG") 1377 .SetURL("http://www.ijg.org")); 1378 1379 // libprint copyrights 1380 _AddPackageCredit(PackageCredit("libprint") 1381 .SetCopyright(COPYRIGHT_STRING 1382 "1999-2000 Y.Takagi. All rights reserved.")); 1383 // TODO: License! 1384 1385 // cortex copyrights 1386 _AddPackageCredit(PackageCredit("Cortex") 1387 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1388 .SetLicense("BSD (3-clause)") 1389 .SetURL("http://cortex.sourceforge.net/documentation")); 1390 1391 // FluidSynth copyrights 1392 _AddPackageCredit(PackageCredit("FluidSynth") 1393 .SetCopyright(COPYRIGHT_STRING "2003 Peter Hanappe and others.") 1394 .SetLicense("GNU LGPL v2") 1395 .SetURL("http://www.fluidsynth.org")); 1396 1397 // CannaIM copyrights 1398 _AddPackageCredit(PackageCredit("CannaIM") 1399 .SetCopyright(COPYRIGHT_STRING "1999 Masao Kawamura.")); 1400 // TODO: License! 1401 1402 // libxml2, libxslt, libexslt copyrights 1403 _AddPackageCredit(PackageCredit("libxml2, libxslt") 1404 .SetCopyright(COPYRIGHT_STRING 1405 "1998-2003 Daniel Veillard. All rights reserved.") 1406 .SetLicense("MIT (no promotion)") 1407 .SetURL("http://xmlsoft.org")); 1408 1409 _AddPackageCredit(PackageCredit("libexslt") 1410 .SetCopyright(COPYRIGHT_STRING 1411 "2001-2002 Thomas Broyer, Charlie " 1412 "Bozeman and Daniel Veillard. All rights reserved.") 1413 .SetLicense("MIT (no promotion)") 1414 .SetURL("http://xmlsoft.org")); 1415 1416 // Xiph.org Foundation copyrights 1417 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1418 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1419 COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1420 "All rights reserved.", 1421 NULL) 1422 .SetLicense("BSD (3-clause)") 1423 .SetURL("http://www.xiph.org")); 1424 1425 // The Tcpdump Group 1426 _AddPackageCredit(PackageCredit("The Tcpdump Group") 1427 .SetCopyright("tcpdump, libpcap") 1428 .SetLicense("BSD (3-clause)") 1429 .SetURL("http://www.tcpdump.org")); 1430 1431 // Matroska 1432 _AddPackageCredit(PackageCredit("libmatroska") 1433 .SetCopyright(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1434 "All rights reserved.") 1435 .SetLicense("GNU LGPL v2.1") 1436 .SetURL("http://www.matroska.org")); 1437 1438 // BColorQuantizer (originally CQuantizer code) 1439 _AddPackageCredit(PackageCredit("CQuantizer") 1440 .SetCopyright(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1441 "All rights reserved.") 1442 .SetLicense("CQuantizer") 1443 .SetURL("http://www.xdp.it")); 1444 1445 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1446 _AddPackageCredit(PackageCredit("MAPM") 1447 .SetCopyright(COPYRIGHT_STRING 1448 "1999-2007 Michael C. Ring. All rights reserved.") 1449 .SetLicense("MAPM") 1450 .SetURL("http://tc.umn.edu/~ringx004")); 1451 1452 // MkDepend 1.7 copyright (Makefile dependency generator) 1453 _AddPackageCredit(PackageCredit("MkDepend") 1454 .SetCopyright(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1455 "All rights reserved.") 1456 .SetLicense("MkDepend") 1457 .SetURL("http://bearnip.com/lars/be")); 1458 1459 // libhttpd copyright (used as Poorman backend) 1460 _AddPackageCredit(PackageCredit("libhttpd") 1461 .SetCopyright(COPYRIGHT_STRING 1462 "1995,1998,1999,2000,2001 by " 1463 "Jef Poskanzer. All rights reserved.") 1464 .SetLicense("LibHTTPd") 1465 .SetURL("http://www.acme.com/software/thttpd/")); 1466 1467 #ifdef __INTEL__ 1468 // Udis86 copyrights 1469 _AddPackageCredit(PackageCredit("Udis86") 1470 .SetCopyright(COPYRIGHT_STRING "2002, 2003, 2004 Vivek Mohan. " 1471 "All rights reserved.") 1472 .SetURL("http://udis86.sourceforge.net")); 1473 // TODO: License! 1474 #endif 1475 1476 #ifdef __INTEL__ 1477 // Intel PRO/Wireless 2100 Firmware 1478 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 Firmware") 1479 .SetCopyright(COPYRIGHT_STRING 1480 "2003-2006 by " 1481 "Intel Corporation. All rights reserved.") 1482 .SetLicense("Intel (2xxx firmware)") 1483 .SetURL("http://ipw2100.sourceforge.net/")); 1484 #endif 1485 1486 #ifdef __INTEL__ 1487 // Intel PRO/Wireless 2200BG Firmware 1488 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2200BG Firmware") 1489 .SetCopyright(COPYRIGHT_STRING 1490 "2004-2005 by " 1491 "Intel Corporation. All rights reserved.") 1492 .SetLicense("Intel (2xxx firmware)") 1493 .SetURL("http://ipw2200.sourceforge.net/")); 1494 #endif 1495 1496 #ifdef __INTEL__ 1497 // Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware 1498 _AddPackageCredit( 1499 PackageCredit( 1500 "Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware") 1501 .SetCopyright(COPYRIGHT_STRING 1502 "2006 - 2007 by " 1503 "Intel Corporation. All rights reserved.") 1504 .SetLicense("Intel (firmware)") 1505 .SetURL("http://www.intellinuxwireless.org/")); 1506 #endif 1507 #ifdef __INTEL__ 1508 // Intel Wireless WiFi Link 4965AGN Adapter Firmware 1509 _AddPackageCredit( 1510 PackageCredit("Intel Wireless WiFi Link 4965AGN Adapter Firmware") 1511 .SetCopyright(COPYRIGHT_STRING 1512 "2006 - 2007 by " 1513 "Intel Corporation. All rights reserved.") 1514 .SetLicense("Intel (firmware)") 1515 .SetURL("http://www.intellinuxwireless.org/")); 1516 #endif 1517 1518 #ifdef __INTEL__ 1519 // Marvell 88w8363 1520 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1521 .SetCopyright(COPYRIGHT_STRING 1522 "2007-2009 by " 1523 "Marvell Semiconductor, Inc. All rights reserved.") 1524 .SetLicense("Marvell (firmware)") 1525 .SetURL("http://www.marvell.com/")); 1526 #endif 1527 1528 #ifdef __INTEL__ 1529 // Ralink Firmware RT2501/RT2561/RT2661 1530 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1531 .SetCopyright(COPYRIGHT_STRING 1532 "2007 by " 1533 "Ralink Technology Corporation. All rights reserved.") 1534 .SetLicense("Ralink (firmware)") 1535 .SetURL("http://www.ralinktech.com/")); 1536 #endif 1537 1538 _AddCopyrightsFromAttribute(); 1539 _AddPackageCreditEntries(); 1540 1541 return new CropView(creditsScroller, 0, 1, 1, 1); 1542 } 1543 1544 1545 status_t 1546 AboutView::_GetLicensePath(const char* license, BPath& path) 1547 { 1548 static const directory_which directoryConstants[] = { 1549 B_USER_DATA_DIRECTORY, 1550 B_COMMON_DATA_DIRECTORY, 1551 B_SYSTEM_DATA_DIRECTORY 1552 }; 1553 static const int dirCount = 3; 1554 1555 for (int i = 0; i < dirCount; i++) { 1556 struct stat st; 1557 status_t error = find_directory(directoryConstants[i], &path); 1558 if (error == B_OK && path.Append("licenses") == B_OK 1559 && path.Append(license) == B_OK 1560 && lstat(path.Path(), &st) == 0) { 1561 return B_OK; 1562 } 1563 } 1564 1565 path.Unset(); 1566 return B_ENTRY_NOT_FOUND; 1567 } 1568 1569 1570 void 1571 AboutView::_AddCopyrightsFromAttribute() 1572 { 1573 #ifdef __HAIKU__ 1574 // open the app executable file 1575 char appPath[B_PATH_NAME_LENGTH]; 1576 int appFD; 1577 if (BPrivate::get_app_path(appPath) != B_OK 1578 || (appFD = open(appPath, O_RDONLY)) < 0) { 1579 return; 1580 } 1581 1582 // open the attribute 1583 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1584 close(appFD); 1585 if (attrFD < 0) 1586 return; 1587 1588 // attach it to a FILE 1589 FILE* attrFile = fdopen(attrFD, "r"); 1590 if (attrFile == NULL) { 1591 close(attrFD); 1592 return; 1593 } 1594 CObjectDeleter<FILE, int> _(attrFile, fclose); 1595 1596 // read and parse the copyrights 1597 BMessage package; 1598 BString fieldName; 1599 BString fieldValue; 1600 char lineBuffer[LINE_MAX]; 1601 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1602 // chop off line break 1603 size_t lineLen = strlen(line); 1604 if (lineLen > 0 && line[lineLen - 1] == '\n') 1605 line[--lineLen] = '\0'; 1606 1607 // flush previous field, if a new field begins, otherwise append 1608 if (lineLen == 0 || !isspace(line[0])) { 1609 // new field -- flush the previous one 1610 if (fieldName.Length() > 0) { 1611 fieldValue = trim_string(fieldValue.String(), 1612 fieldValue.Length()); 1613 package.AddString(fieldName.String(), fieldValue); 1614 fieldName = ""; 1615 } 1616 } else if (fieldName.Length() > 0) { 1617 // append to current field 1618 fieldValue += line; 1619 continue; 1620 } else { 1621 // bogus line -- ignore 1622 continue; 1623 } 1624 1625 if (lineLen == 0) 1626 continue; 1627 1628 // parse new field 1629 char* colon = strchr(line, ':'); 1630 if (colon == NULL) { 1631 // bogus line -- ignore 1632 continue; 1633 } 1634 1635 fieldName.SetTo(line, colon - line); 1636 fieldName = trim_string(line, colon - line); 1637 if (fieldName.Length() == 0) { 1638 // invalid field name 1639 continue; 1640 } 1641 1642 fieldValue = colon + 1; 1643 1644 if (fieldName == "Package") { 1645 // flush the current package 1646 _AddPackageCredit(PackageCredit(package)); 1647 package.MakeEmpty(); 1648 } 1649 } 1650 1651 // flush current package 1652 _AddPackageCredit(PackageCredit(package)); 1653 #endif 1654 } 1655 1656 1657 void 1658 AboutView::_AddPackageCreditEntries() 1659 { 1660 // sort the packages case-insensitively 1661 PackageCredit* packages[fPackageCredits.size()]; 1662 int32 count = 0; 1663 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1664 it != fPackageCredits.end(); ++it) { 1665 packages[count++] = it->second; 1666 } 1667 1668 if (count > 1) { 1669 std::sort(packages, packages + count, 1670 &PackageCredit::NameLessInsensitive); 1671 } 1672 1673 // add the credits 1674 for (int32 i = 0; i < count; i++) { 1675 PackageCredit* package = packages[i]; 1676 1677 BString text(package->CopyrightAt(0)); 1678 int32 count = package->CountCopyrights(); 1679 for (int32 i = 1; i < count; i++) 1680 text << "\n" << package->CopyrightAt(i); 1681 1682 AddCopyrightEntry(package->PackageName(), text.String(), 1683 package->Licenses(), package->Sources(), package->URL()); 1684 } 1685 } 1686 1687 1688 void 1689 AboutView::_AddPackageCredit(const PackageCredit& package) 1690 { 1691 if (!package.IsValid()) 1692 return; 1693 1694 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1695 if (it != fPackageCredits.end()) { 1696 // If the new package credit isn't "better" than the old one, ignore it. 1697 PackageCredit* oldPackage = it->second; 1698 if (!package.IsBetterThan(*oldPackage)) 1699 return; 1700 1701 // replace the old credit 1702 fPackageCredits.erase(it); 1703 delete oldPackage; 1704 } 1705 1706 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1707 } 1708 1709 1710 // #pragma mark - 1711 1712 1713 static const char* 1714 MemSizeToString(char string[], size_t size, system_info* info) 1715 { 1716 int inaccessibleMemory = int(info->ignored_pages 1717 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1718 if (inaccessibleMemory > 0) { 1719 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1720 "inaccessible")); 1721 1722 snprintf(string, size, "%d", int((info->max_pages 1723 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1724 message.ReplaceFirst("%total", string); 1725 1726 snprintf(string, size, "%d", inaccessibleMemory); 1727 message.ReplaceFirst("%inaccessible", string); 1728 strncpy(string, message.String(), size); 1729 } else { 1730 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1731 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1732 } 1733 1734 return string; 1735 } 1736 1737 1738 static const char* 1739 MemUsageToString(char string[], size_t size, system_info* info) 1740 { 1741 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1742 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1743 int(100 * info->used_pages / info->max_pages)); 1744 1745 return string; 1746 } 1747 1748 1749 static const char* 1750 UptimeToString(char string[], size_t size) 1751 { 1752 BDurationFormat formatter; 1753 BString str; 1754 1755 bigtime_t uptime = system_time(); 1756 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1757 formatter.Format(now - uptime, now, &str); 1758 str.CopyInto(string, 0, size); 1759 string[std::min((size_t)str.Length(), size)] = '\0'; 1760 1761 return string; 1762 } 1763 1764 1765 int 1766 main() 1767 { 1768 AboutApp app; 1769 app.Run(); 1770 return 0; 1771 } 1772 1773