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