1 /* 2 * Copyright (c) 2005-2009, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * René Gollent 8 */ 9 10 #include <ctype.h> 11 #include <stdio.h> 12 #include <sys/utsname.h> 13 #include <time.h> 14 #include <unistd.h> 15 16 #include <map> 17 #include <string> 18 19 #include <AppFileInfo.h> 20 #include <Application.h> 21 #include <Bitmap.h> 22 #include <File.h> 23 #include <FindDirectory.h> 24 #include <Font.h> 25 #include <fs_attr.h> 26 #include <MessageRunner.h> 27 #include <Messenger.h> 28 #include <OS.h> 29 #include <Path.h> 30 #include <Resources.h> 31 #include <Screen.h> 32 #include <ScrollView.h> 33 #include <String.h> 34 #include <StringView.h> 35 #include <TranslationUtils.h> 36 #include <TranslatorFormats.h> 37 #include <View.h> 38 #include <Volume.h> 39 #include <VolumeRoster.h> 40 #include <Window.h> 41 42 #include <AppMisc.h> 43 #include <AutoDeleter.h> 44 #include <cpu_type.h> 45 46 #include "HyperTextActions.h" 47 #include "HyperTextView.h" 48 #include "Utilities.h" 49 50 51 #ifndef LINE_MAX 52 #define LINE_MAX 2048 53 #endif 54 55 #define SCROLL_CREDITS_VIEW 'mviv' 56 57 58 static const char *UptimeToString(char string[], size_t size); 59 static const char *MemUsageToString(char string[], size_t size, 60 system_info *info); 61 62 static const rgb_color kDarkGrey = { 100, 100, 100, 255 }; 63 static const rgb_color kHaikuGreen = { 42, 131, 36, 255 }; 64 static const rgb_color kHaikuOrange = { 255, 69, 0, 255 }; 65 static const rgb_color kHaikuYellow = { 255, 176, 0, 255 }; 66 static const rgb_color kLinkBlue = { 80, 80, 200, 255 }; 67 68 69 class AboutApp : public BApplication { 70 public: 71 AboutApp(); 72 }; 73 74 class AboutWindow : public BWindow { 75 public: 76 AboutWindow(); 77 78 virtual bool QuitRequested(); 79 }; 80 81 class AboutView : public BView { 82 public: 83 AboutView(const BRect& frame); 84 ~AboutView(); 85 86 virtual void AttachedToWindow(); 87 virtual void Pulse(); 88 89 virtual void FrameResized(float width, float height); 90 virtual void Draw(BRect updateRect); 91 virtual void MessageReceived(BMessage* msg); 92 virtual void MouseDown(BPoint point); 93 94 void AddCopyrightEntry(const char* name, 95 const char* text, 96 const StringVector& licenses, 97 const char* url); 98 void AddCopyrightEntry(const char* name, 99 const char* text, const char* url = NULL); 100 void PickRandomHaiku(); 101 102 103 private: 104 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 105 106 private: 107 status_t _GetLicensePath(const char* license, 108 BPath& path); 109 void _AddCopyrightsFromAttribute(); 110 void _AddPackageCredit(const PackageCredit& package); 111 void _AddPackageCreditEntries(); 112 113 BStringView* fMemView; 114 BTextView* fUptimeView; 115 BView* fInfoView; 116 HyperTextView* fCreditsView; 117 118 BBitmap* fLogo; 119 120 BPoint fDrawPoint; 121 122 bigtime_t fLastActionTime; 123 BMessageRunner* fScrollRunner; 124 PackageCreditMap fPackageCredits; 125 }; 126 127 128 // #pragma mark - 129 130 131 AboutApp::AboutApp(void) 132 : BApplication("application/x-vnd.Haiku-About") 133 { 134 AboutWindow *window = new AboutWindow(); 135 window->Show(); 136 } 137 138 139 // #pragma mark - 140 141 142 AboutWindow::AboutWindow() 143 : BWindow(BRect(0, 0, 500, 300), "About This System", B_TITLED_WINDOW, 144 B_NOT_RESIZABLE | B_NOT_ZOOMABLE) 145 { 146 AboutView *view = new AboutView(Bounds()); 147 AddChild(view); 148 149 MoveTo((BScreen().Frame().Width() - Bounds().Width()) / 2, 150 (BScreen().Frame().Height() - Bounds().Height()) / 2 ); 151 } 152 153 154 bool 155 AboutWindow::QuitRequested() 156 { 157 be_app->PostMessage(B_QUIT_REQUESTED); 158 return true; 159 } 160 161 162 AboutView::AboutView(const BRect &rect) 163 : BView(rect, "aboutview", B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED), 164 fLastActionTime(system_time()), 165 fScrollRunner(NULL) 166 { 167 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "haikulogo.png"); 168 if (fLogo) { 169 fDrawPoint.x = (225-fLogo->Bounds().Width()) / 2; 170 fDrawPoint.y = 0; 171 } 172 173 // Begin Construction of System Information controls 174 175 font_height height; 176 float labelHeight, textHeight; 177 178 system_info systemInfo; 179 get_system_info(&systemInfo); 180 181 be_plain_font->GetHeight(&height); 182 textHeight = height.ascent + height.descent + height.leading; 183 184 be_bold_font->GetHeight(&height); 185 labelHeight = height.ascent + height.descent + height.leading; 186 187 BRect r(0, 0, 225, Bounds().bottom); 188 if (fLogo) 189 r.OffsetBy(0, fLogo->Bounds().Height()); 190 191 fInfoView = new BView(r, "infoview", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 192 B_WILL_DRAW); 193 fInfoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 194 fInfoView->SetLowColor(fInfoView->ViewColor()); 195 fInfoView->SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); 196 AddChild(fInfoView); 197 198 // Add all the various labels for system infomation 199 200 BStringView *stringView; 201 202 // OS Version 203 r.Set(5, 5, 224, labelHeight + 5); 204 stringView = new BStringView(r, "oslabel", "Version:"); 205 stringView->SetFont(be_bold_font); 206 fInfoView->AddChild(stringView); 207 stringView->ResizeToPreferred(); 208 209 // we update "labelHeight" to the actual height of the string view 210 labelHeight = stringView->Bounds().Height(); 211 212 r.OffsetBy(0, labelHeight); 213 r.bottom = r.top + textHeight; 214 215 char string[1024]; 216 strcpy(string, "Unknown"); 217 218 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 219 BPath path; 220 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 221 path.Append("libbe.so"); 222 223 BAppFileInfo appFileInfo; 224 version_info versionInfo; 225 BFile file; 226 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 227 && appFileInfo.SetTo(&file) == B_OK 228 && appFileInfo.GetVersionInfo(&versionInfo, 229 B_APP_VERSION_KIND) == B_OK 230 && versionInfo.short_info[0] != '\0') 231 strcpy(string, versionInfo.short_info); 232 } 233 234 // Add revision from uname() info 235 utsname unameInfo; 236 if (uname(&unameInfo) == 0) { 237 long revision; 238 if (sscanf(unameInfo.version, "r%ld", &revision) == 1) { 239 char version[16]; 240 snprintf(version, sizeof(version), "%ld", revision); 241 strlcat(string, " (Revision ", sizeof(string)); 242 strlcat(string, version, sizeof(string)); 243 strlcat(string, ")", sizeof(string)); 244 } 245 } 246 247 stringView = new BStringView(r, "ostext", string); 248 fInfoView->AddChild(stringView); 249 stringView->ResizeToPreferred(); 250 251 // GCC version 252 #if __GNUC__ != 2 253 r.OffsetBy(0, textHeight); 254 r.bottom = r.top + textHeight; 255 256 snprintf(string, sizeof(string), "GCC %d", __GNUC__); 257 258 stringView = new BStringView(r, "gcctext", string); 259 fInfoView->AddChild(stringView); 260 stringView->ResizeToPreferred(); 261 #endif 262 263 // CPU count, type and clock speed 264 r.OffsetBy(0, textHeight * 1.5); 265 r.bottom = r.top + labelHeight; 266 267 if (systemInfo.cpu_count > 1) 268 sprintf(string, "%ld Processors:", systemInfo.cpu_count); 269 else 270 strcpy(string, "Processor:"); 271 272 stringView = new BStringView(r, "cpulabel", string); 273 stringView->SetFont(be_bold_font); 274 fInfoView->AddChild(stringView); 275 stringView->ResizeToPreferred(); 276 277 BString cpuType; 278 cpuType << get_cpu_vendor_string(systemInfo.cpu_type) 279 << " " << get_cpu_model_string(&systemInfo); 280 281 r.OffsetBy(0, labelHeight); 282 r.bottom = r.top + textHeight; 283 stringView = new BStringView(r, "cputext", cpuType.String()); 284 fInfoView->AddChild(stringView); 285 stringView->ResizeToPreferred(); 286 287 r.OffsetBy(0, textHeight); 288 r.bottom = r.top + textHeight; 289 290 int32 clockSpeed = get_rounded_cpu_speed(); 291 if (clockSpeed < 1000) 292 sprintf(string,"%ld MHz", clockSpeed); 293 else 294 sprintf(string,"%.2f GHz", clockSpeed / 1000.0f); 295 296 stringView = new BStringView(r, "mhztext", string); 297 fInfoView->AddChild(stringView); 298 stringView->ResizeToPreferred(); 299 300 // RAM 301 r.OffsetBy(0, textHeight * 1.5); 302 r.bottom = r.top + labelHeight; 303 stringView = new BStringView(r, "ramlabel", "Memory:"); 304 stringView->SetFont(be_bold_font); 305 fInfoView->AddChild(stringView); 306 stringView->ResizeToPreferred(); 307 308 r.OffsetBy(0, labelHeight); 309 r.bottom = r.top + textHeight; 310 311 fMemView = new BStringView(r, "ramtext", ""); 312 fInfoView->AddChild(fMemView); 313 fMemView->SetText(MemUsageToString(string, sizeof(string), &systemInfo)); 314 315 // Kernel build time/date 316 r.OffsetBy(0, textHeight * 1.5); 317 r.bottom = r.top + labelHeight; 318 stringView = new BStringView(r, "kernellabel", "Kernel:"); 319 stringView->SetFont(be_bold_font); 320 fInfoView->AddChild(stringView); 321 stringView->ResizeToPreferred(); 322 323 r.OffsetBy(0, labelHeight); 324 r.bottom = r.top + textHeight; 325 326 snprintf(string, sizeof(string), "%s %s", 327 systemInfo.kernel_build_date, systemInfo.kernel_build_time); 328 329 stringView = new BStringView(r, "kerneltext", string); 330 fInfoView->AddChild(stringView); 331 stringView->ResizeToPreferred(); 332 333 // Uptime 334 r.OffsetBy(0, textHeight * 1.5); 335 r.bottom = r.top + labelHeight; 336 stringView = new BStringView(r, "uptimelabel", "Time Running:"); 337 stringView->SetFont(be_bold_font); 338 fInfoView->AddChild(stringView); 339 stringView->ResizeToPreferred(); 340 341 r.OffsetBy(0, labelHeight); 342 r.bottom = r.top + textHeight * 3; 343 344 fUptimeView = new BTextView(r, "uptimetext", r.OffsetToCopy(0,0), B_FOLLOW_ALL); 345 fUptimeView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 346 fUptimeView->MakeEditable(false); 347 fUptimeView->MakeSelectable(false); 348 fUptimeView->SetWordWrap(true); 349 fInfoView->AddChild(fUptimeView); 350 // string width changes, so we don't do ResizeToPreferred() 351 352 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 353 354 // Begin construction of the credits view 355 r = Bounds(); 356 r.left += fInfoView->Bounds().right + 1; 357 r.right -= B_V_SCROLL_BAR_WIDTH; 358 359 fCreditsView = new HyperTextView(r, "credits", 360 r.OffsetToCopy(0, 0).InsetByCopy(5, 5), B_FOLLOW_ALL); 361 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS ); 362 fCreditsView->SetStylable(true); 363 fCreditsView->MakeEditable(false); 364 fCreditsView->SetWordWrap(true); 365 366 BScrollView *creditsScroller = new BScrollView("creditsScroller", 367 fCreditsView, B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 368 B_PLAIN_BORDER); 369 AddChild(creditsScroller); 370 371 // Haiku copyright 372 BFont font(be_bold_font); 373 font.SetSize(font.Size() + 4); 374 375 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 376 fCreditsView->Insert("Haiku\n"); 377 378 time_t time = ::time(NULL); 379 struct tm* tm = localtime(&time); 380 int32 year = tm->tm_year + 1900; 381 if (year < 2008) 382 year = 2008; 383 snprintf(string, sizeof(string), 384 COPYRIGHT_STRING "2001-%ld The Haiku project. ", year); 385 386 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 387 fCreditsView->Insert(string); 388 389 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 390 fCreditsView->Insert("The copyright to the Haiku code is property of " 391 "Haiku, Inc. or of the respective authors where expressly noted " 392 "in the source." 393 "\n\n"); 394 395 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 396 fCreditsView->InsertHyperText("http://www.haiku-os.org", 397 new URLAction("http://www.haiku-os.org")); 398 fCreditsView->Insert("\n\n"); 399 400 font.SetSize(be_bold_font->Size()); 401 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 402 403 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 404 fCreditsView->Insert("Current Maintainers:\n"); 405 406 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 407 fCreditsView->Insert( 408 "Ithamar R. Adema\n" 409 "Bruno G. Albuquerque\n" 410 "Stephan Aßmus\n" 411 "Salvatore Benedetto\n" 412 "Stefano Ceccherini\n" 413 "Rudolf Cornelissen\n" 414 "Alexandre Deckner\n" 415 "Oliver Ruiz Dorantes\n" 416 "Axel Dörfler\n" 417 "Jérôme Duval\n" 418 "René Gollent\n" 419 "Karsten Heimrich\n" 420 "Philippe Houdoin\n" 421 "Maurice Kalinowski\n" 422 "Euan Kirkhope\n" 423 "Ryan Leavengood\n" 424 "Michael Lotz\n" 425 "David McPaul\n" 426 "Fredrik Modéen\n" 427 "Marcus Overhagen\n" 428 "Michael Pfeiffer\n" 429 "François Revol\n" 430 "Andrej Spielmann\n" 431 "Oliver Tappe\n" 432 "Gerasim Troeglazov\n" 433 "Ingo Weinhold\n" 434 "Siarzhuk Zharski\n" 435 "\n"); 436 437 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 438 fCreditsView->Insert("Past Maintainers:\n"); 439 440 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 441 fCreditsView->Insert( 442 "Andrew Bachmann\n" 443 "Tyler Dauwalder\n" 444 "Daniel Furrer\n" 445 "Andre Alves Garzia\n" 446 "Erik Jaesler\n" 447 "Marcin Konicki\n" 448 "Waldemar Kornewald\n" 449 "Thomas Kurschel\n" 450 "Frans Van Nispen\n" 451 "Adi Oanca\n" 452 "Michael Phipps\n" 453 "Niels Sascha Reedijk\n" 454 "David Reid\n" 455 "Hugo Santos\n" 456 "Alexander G. M. Smith\n" 457 "Jonas Sundström\n" 458 "Bryan Varner\n" 459 "Nathan Whitehorn\n" 460 "Michael Wilber\n" 461 "Jonathan Yoder\n" 462 "Gabe Yoder\n" 463 "\n"); 464 465 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 466 fCreditsView->Insert("Website, Marketing & Documentation:\n"); 467 468 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 469 fCreditsView->Insert( 470 "Phil Greenway\n" 471 "Gavin James\n" 472 "Urias McCullough\n" 473 "Niels Sascha Reedijk\n" 474 "Jonathan Yoder\n" 475 "\n"); 476 477 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 478 fCreditsView->Insert("Contributors:\n"); 479 480 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 481 fCreditsView->Insert( 482 "Andrea Anzani\n" 483 "Andre Braga\n" 484 "Bruce Cameron\n" 485 "Greg Crain\n" 486 "David Dengg\n" 487 "John Drinkwater\n" 488 "Cian Duffy\n" 489 "Mark Erben\n" 490 "Christian Fasshauer\n" 491 "Andreas Färber\n" 492 "Marc Flerackers\n" 493 "Matthijs Hollemans\n" 494 "Mathew Hounsell\n" 495 "Morgan Howe\n" 496 "Carwyn Jones\n" 497 "Vasilis Kaoutsis\n" 498 "James Kim\n" 499 "Shintaro Kinugawa\n" 500 "Jan Klötzke\n" 501 "Kurtis Kopf\n" 502 "Tomáš Kučera\n" 503 "Luboš Kulič\n" 504 "Elad Lahav\n" 505 "Anthony Lee\n" 506 "Santiago Lema\n" 507 "Raynald Lesieur\n" 508 "Oscar Lesta\n" 509 "Jerome Leveque\n" 510 "Christof Lutteroth\n" 511 "Graham MacDonald\n" 512 "Jan Matějek\n" 513 "Brian Matzon\n" 514 "Christopher ML Zumwalt May\n" 515 "Andrew McCall\n" 516 "Scott McCreary\n" 517 "Michele (zuMi)\n" 518 "Marius Middelthon\n" 519 "Marco Minutoli\n" 520 "Misza\n" 521 "MrSiggler\n" 522 "Alan Murta\n" 523 "Pahtz\n" 524 "Michael Paine\n" 525 "Adrian Panasiuk\n" 526 "Francesco Piccinno\n" 527 "David Powell\n" 528 "Jeremy Rand\n" 529 "Hartmut Reh\n" 530 "Daniel Reinhold\n" 531 "Samuel Rodriguez Perez\n" 532 "Thomas Roell\n" 533 "Rafael Romo\n" 534 "Philippe Saint-Pierre\n" 535 "Ralf Schülke\n" 536 "Reznikov Sergei\n" 537 "Zousar Shaker\n" 538 "Daniel Switkin\n" 539 "Atsushi Takamatsu\n" 540 "James Urquhart\n" 541 "Jason Vandermark\n" 542 "Sandor Vroemisse\n" 543 "Denis Washington\n" 544 "Ulrich Wimboeck\n" 545 "James Woodcock\n" 546 "Artur Wyszynski\n" 547 "Gerald Zajac\n" 548 "Clemens Zeidler\n" 549 "Łukasz Zemczak\n" 550 "JiSheng Zhang\n" 551 "Zhao Shuai\n" 552 "\n" B_UTF8_ELLIPSIS " and probably some more we forgot to mention " 553 "(sorry!)" 554 "\n\n"); 555 556 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 557 fCreditsView->Insert("Special Thanks To:\n"); 558 559 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 560 fCreditsView->Insert("Travis Geiselbrecht (and his NewOS kernel)\n"); 561 fCreditsView->Insert("Michael Phipps (project founder)\n\n"); 562 563 // copyrights for various projects we use 564 565 BPath mitPath; 566 _GetLicensePath("MIT", mitPath); 567 568 font.SetSize(be_bold_font->Size() + 4); 569 font.SetFace(B_BOLD_FACE); 570 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 571 fCreditsView->Insert("\nCopyrights\n\n"); 572 573 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 574 fCreditsView->Insert("[Click a license name to read the respective " 575 "license.]\n\n"); 576 577 // Haiku license 578 fCreditsView->Insert("The code that is unique to Haiku, especially the " 579 "kernel and all code that applications may link against, is " 580 "distributed under the terms of the "); 581 fCreditsView->InsertHyperText("MIT license", 582 new OpenFileAction(mitPath.Path())); 583 fCreditsView->Insert(". Some system libraries contain third party code " 584 "distributed under the LGPL license. You can find the copyrights " 585 "to third party code below.\n\n"); 586 587 // GNU copyrights 588 AddCopyrightEntry("The GNU Project", 589 "Contains software from the GNU Project, " 590 "released under the GPL and LGPL licences:\n" 591 "GNU C Library, " 592 "GNU coretools, diffutils, findutils, " 593 "sharutils, gawk, bison, m4, make, " 594 "gdb, wget, ncurses, termcap, " 595 "Bourne Again Shell.\n" 596 COPYRIGHT_STRING "The Free Software Foundation.", 597 StringVector("GNU LGPL v2.1", "GNU GPL v2", "GNU GPL v3", NULL), 598 "http://www.gnu.org"); 599 600 // FreeBSD copyrights 601 AddCopyrightEntry("The FreeBSD Project", 602 "Contains software from the FreeBSD Project, " 603 "released under the BSD licence:\n" 604 "cal, ftpd, ping, telnet, " 605 "telnetd, traceroute\n" 606 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 607 "All rights reserved.", 608 "http://www.freebsd.org"); 609 // TODO: License! 610 611 // NetBSD copyrights 612 AddCopyrightEntry("The NetBSD Project", 613 "Contains software developed by the NetBSD, " 614 "Foundation, Inc. and its contributors:\n" 615 "ftp, tput\n" 616 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 617 "All rights reserved.", 618 "http://www.netbsd.org"); 619 // TODO: License! 620 621 // FFMpeg copyrights 622 _AddPackageCredit(PackageCredit("FFMpeg libavcodec") 623 .SetCopyright(COPYRIGHT_STRING "2000-2007 Fabrice Bellard, et al.") 624 .SetURL("http://www.ffmpeg.org")); 625 // TODO: License! 626 627 // AGG copyrights 628 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 629 .SetCopyright(COPYRIGHT_STRING "2002-2006 Maxim Shemanarev (McSeem).") 630 .SetURL("http://www.antigrain.com")); 631 // TODO: License! 632 633 // PDFLib copyrights 634 _AddPackageCredit(PackageCredit("PDFLib") 635 .SetCopyright(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and Thomas Merz. " 636 "All rights reserved.\n" 637 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.") 638 .SetURL("http://www.pdflib.com")); 639 // TODO: License! 640 641 // FreeType copyrights 642 _AddPackageCredit(PackageCredit("FreeType2") 643 .SetCopyright("Portions of this software are copyright " 644 B_UTF8_COPYRIGHT " 1996-2006 " 645 "The FreeType Project. All rights reserved.") 646 .SetURL("http://www.freetype.org")); 647 // TODO: License! 648 649 // Mesa3D (http://www.mesa3d.org) copyrights 650 _AddPackageCredit(PackageCredit("Mesa") 651 .SetCopyright(COPYRIGHT_STRING "1999-2006 Brian Paul. " 652 "Mesa3D project. All rights reserved.") 653 .SetURL("http://www.mesa3d.org")); 654 // TODO: License! 655 656 // SGI's GLU implementation copyrights 657 _AddPackageCredit(PackageCredit("GLU") 658 .SetCopyright(COPYRIGHT_STRING 659 "1991-2000 Silicon Graphics, Inc. " 660 "SGI's Software FreeB license. All rights reserved.")); 661 // TODO: License! 662 663 // GLUT implementation copyrights 664 _AddPackageCredit(PackageCredit("GLUT") 665 .SetCopyrights(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 666 "All rights reserved.", 667 COPYRIGHT_STRING "1997 Be Inc.", 668 COPYRIGHT_STRING "1999 Jake Hamby.", 669 NULL)); 670 // TODO: License! 671 672 // OpenGroup & DEC (BRegion backend) copyright 673 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 674 .SetCopyrights(COPYRIGHT_STRING "1987, 1988, 1998 The Open Group.", 675 COPYRIGHT_STRING "1987, 1988 Digital Equipment " 676 "Corporation, Maynard, Massachusetts.\n" 677 "All rights reserved.", 678 NULL)); 679 // TODO: License! 680 681 // Konatu font 682 _AddPackageCredit(PackageCredit("Konatu font") 683 .SetCopyright(COPYRIGHT_STRING "2002- MASUDA mitiya.\n" 684 "MIT license. All rights reserved.")); 685 // TODO: License! 686 687 // expat copyrights 688 _AddPackageCredit(PackageCredit("expat") 689 .SetCopyrights(COPYRIGHT_STRING 690 "1998, 1999, 2000 Thai Open Source " 691 "Software Center Ltd and Clark Cooper.", 692 COPYRIGHT_STRING "2001, 2002, 2003 Expat maintainers.", 693 NULL)); 694 // TODO: License! 695 696 // zlib copyrights 697 _AddPackageCredit(PackageCredit("zlib") 698 .SetCopyright(COPYRIGHT_STRING 699 "1995-2004 Jean-loup Gailly and Mark Adler.")); 700 // TODO: License! 701 702 // zip copyrights 703 _AddPackageCredit(PackageCredit("Info-ZIP") 704 .SetCopyright(COPYRIGHT_STRING 705 "1990-2002 Info-ZIP. All rights reserved.")); 706 // TODO: License! 707 708 // bzip2 copyrights 709 _AddPackageCredit(PackageCredit("bzip2") 710 .SetCopyright(COPYRIGHT_STRING 711 "1996-2005 Julian R Seward. All rights reserved.")); 712 // TODO: License! 713 714 // VIM copyrights 715 _AddPackageCredit(PackageCredit("Vi IMproved") 716 .SetCopyright(COPYRIGHT_STRING "Bram Moolenaar et al.")); 717 // TODO: License! 718 719 // lp_solve copyrights 720 _AddPackageCredit(PackageCredit("lp_solve") 721 .SetCopyright(COPYRIGHT_STRING 722 "Michel Berkelaar, Kjell Eikland, Peter Notebaert") 723 .SetLicense("GNU LGPL v2.1") 724 .SetURL("http://lpsolve.sourceforge.net/")); 725 726 // OpenEXR copyrights 727 _AddPackageCredit(PackageCredit("OpenEXR") 728 .SetCopyright(COPYRIGHT_STRING "2002-2005 Industrial Light & Magic, " 729 "a division of Lucas Digital Ltd. LLC.")); 730 // TODO: License! 731 732 // Bullet copyrights 733 _AddPackageCredit(PackageCredit("Bullet") 734 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 735 .SetURL("http://www.bulletphysics.com")); 736 // TODO: License! 737 738 // atftp copyrights 739 _AddPackageCredit(PackageCredit("atftp") 740 .SetCopyright(COPYRIGHT_STRING 741 "2000 Jean-Pierre Lefebvre and Remi Lefebvre")); 742 // TODO: License! 743 744 // Netcat copyrights 745 _AddPackageCredit(PackageCredit("Netcat") 746 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit")); 747 // TODO: License! 748 749 // acpica copyrights 750 _AddPackageCredit(PackageCredit("acpica") 751 .SetCopyright(COPYRIGHT_STRING "1999-2006 Intel Corp.")); 752 // TODO: License! 753 754 // unrar copyrights 755 _AddPackageCredit(PackageCredit("unrar") 756 .SetCopyright(COPYRIGHT_STRING "2002-2008 Alexander L. Roshal. " 757 "All rights reserved.") 758 .SetURL("http://www.rarlab.com")); 759 // TODO: License! 760 761 // libpng copyrights 762 _AddPackageCredit(PackageCredit("libpng") 763 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 764 "Randers-Pehrson.")); 765 // TODO: License! 766 767 // libprint copyrights 768 _AddPackageCredit(PackageCredit("libprint") 769 .SetCopyright(COPYRIGHT_STRING 770 "1999-2000 Y.Takagi. All rights reserved.")); 771 // TODO: License! 772 773 // cortex copyrights 774 _AddPackageCredit(PackageCredit("Cortex") 775 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.")); 776 // TODO: License! 777 778 // FluidSynth copyrights 779 _AddPackageCredit(PackageCredit("FluidSynth") 780 .SetCopyright(COPYRIGHT_STRING "2003 Peter Hanappe and others.")); 781 // TODO: License! 782 783 // CannaIM copyrights 784 _AddPackageCredit(PackageCredit("CannaIM") 785 .SetCopyright(COPYRIGHT_STRING "1999 Masao Kawamura.")); 786 // TODO: License! 787 788 // libxml2, libxslt, libexslt copyrights 789 _AddPackageCredit(PackageCredit("libxml2, libxslt") 790 .SetCopyright(COPYRIGHT_STRING 791 "1998-2003 Daniel Veillard. All rights reserved.")); 792 // TODO: License! 793 794 _AddPackageCredit(PackageCredit("libexslt") 795 .SetCopyright(COPYRIGHT_STRING 796 "2001-2002 Thomas Broyer, Charlie " 797 "Bozeman and Daniel Veillard. All rights reserved.")); 798 // TODO: License! 799 800 // Xiph.org Foundation copyrights 801 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 802 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 803 COPYRIGHT_STRING "1994-2008 Xiph.Org. " 804 "All rights reserved.", 805 NULL) 806 .SetURL("http://www.xiph.org")); 807 // TODO: License! 808 809 // The Tcpdump Group 810 _AddPackageCredit(PackageCredit("The Tcpdump Group") 811 .SetCopyright("tcpdump, libpcap") 812 .SetURL("http://www.tcpdump.org")); 813 // TODO: License! 814 815 // Matroska 816 _AddPackageCredit(PackageCredit("libmatroska") 817 .SetCopyright(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 818 "All rights reserved.") 819 .SetURL("http://www.matroska.org")); 820 // TODO: License! 821 822 // BColorQuantizer (originally CQuantizer code) 823 _AddPackageCredit(PackageCredit("CQuantizer") 824 .SetCopyright(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 825 "All rights reserved.")); 826 // TODO: License! 827 828 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 829 _AddPackageCredit(PackageCredit("MAPM") 830 .SetCopyright(COPYRIGHT_STRING 831 "1999-2007 Michael C. Ring. All rights reserved.") 832 .SetURL("http://tc.umn.edu/~ringx004")); 833 // TODO: License! 834 835 // MkDepend 1.7 copyright (Makefile dependency generator) 836 _AddPackageCredit(PackageCredit("MkDepend") 837 .SetCopyright(COPYRIGHT_STRING "1995-2001 Lars Düning. " 838 "All rights reserved.")); 839 // TODO: License! 840 841 // libhttpd copyright (used as Poorman backend) 842 _AddPackageCredit(PackageCredit("libhttpd") 843 .SetCopyright(COPYRIGHT_STRING 844 "1995,1998,1999,2000,2001 by " 845 "Jef Poskanzer. All rights reserved.") 846 .SetLicense("LibHTTPd") 847 .SetURL("http://www.acme.com/software/thttpd/")); 848 849 #ifdef __INTEL__ 850 // Udis86 copyrights 851 _AddPackageCredit(PackageCredit("Udis86") 852 .SetCopyright(COPYRIGHT_STRING "2002, 2003, 2004 Vivek Mohan. " 853 "All rights reserved.") 854 .SetURL("http://udis86.sourceforge.net")); 855 // TODO: License! 856 #endif 857 858 _AddCopyrightsFromAttribute(); 859 _AddPackageCreditEntries(); 860 } 861 862 863 AboutView::~AboutView(void) 864 { 865 delete fScrollRunner; 866 } 867 868 869 void 870 AboutView::AttachedToWindow(void) 871 { 872 BView::AttachedToWindow(); 873 Window()->SetPulseRate(500000); 874 SetEventMask(B_POINTER_EVENTS); 875 } 876 877 878 void 879 AboutView::MouseDown(BPoint pt) 880 { 881 BRect r(92, 26, 105, 31); 882 if (r.Contains(pt)) { 883 printf("Easter Egg\n"); 884 PickRandomHaiku(); 885 } 886 887 if (Bounds().Contains(pt)) { 888 fLastActionTime = system_time(); 889 delete fScrollRunner; 890 fScrollRunner = NULL; 891 } 892 } 893 894 895 void 896 AboutView::FrameResized(float width, float height) 897 { 898 BRect r = fCreditsView->Bounds(); 899 r.OffsetTo(B_ORIGIN); 900 r.InsetBy(3, 3); 901 fCreditsView->SetTextRect(r); 902 } 903 904 905 void 906 AboutView::Draw(BRect update) 907 { 908 if (fLogo) 909 DrawBitmap(fLogo, fDrawPoint); 910 } 911 912 913 void 914 AboutView::Pulse(void) 915 { 916 char string[255]; 917 system_info info; 918 get_system_info(&info); 919 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 920 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 921 922 if (fScrollRunner == NULL && (system_time() > fLastActionTime + 10000000)) { 923 BMessage message(SCROLL_CREDITS_VIEW); 924 //fScrollRunner = new BMessageRunner(this, &message, 300000, -1); 925 } 926 } 927 928 929 void 930 AboutView::MessageReceived(BMessage *msg) 931 { 932 switch (msg->what) { 933 case SCROLL_CREDITS_VIEW: 934 { 935 BScrollBar *scrollBar = fCreditsView->ScrollBar(B_VERTICAL); 936 if (scrollBar == NULL) 937 break; 938 float max, min; 939 scrollBar->GetRange(&min, &max); 940 if (scrollBar->Value() < max) 941 fCreditsView->ScrollBy(0, 5); 942 943 break; 944 } 945 946 default: 947 BView::MessageReceived(msg); 948 break; 949 } 950 } 951 952 953 void 954 AboutView::AddCopyrightEntry(const char *name, const char *text, 955 const char *url) 956 { 957 AddCopyrightEntry(name, text, StringVector(), url); 958 } 959 960 961 void 962 AboutView::AddCopyrightEntry(const char *name, const char *text, 963 const StringVector& licenses, const char *url) 964 { 965 BFont font(be_bold_font); 966 //font.SetSize(be_bold_font->Size()); 967 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 968 969 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 970 fCreditsView->Insert(name); 971 fCreditsView->Insert("\n"); 972 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 973 fCreditsView->Insert(text); 974 fCreditsView->Insert("\n"); 975 976 if (licenses.CountStrings() > 0) { 977 if (licenses.CountStrings() > 1) 978 fCreditsView->Insert("Licenses: "); 979 else 980 fCreditsView->Insert("License: "); 981 982 for (int32 i = 0; i < licenses.CountStrings(); i++) { 983 const char* license = licenses.StringAt(i); 984 985 if (i > 0) 986 fCreditsView->Insert(", "); 987 988 BPath licensePath; 989 if (_GetLicensePath(license, licensePath) == B_OK) { 990 fCreditsView->InsertHyperText(license, 991 new OpenFileAction(licensePath.Path())); 992 } else 993 fCreditsView->Insert(license); 994 } 995 996 fCreditsView->Insert("\n"); 997 } 998 999 if (url) { 1000 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 1001 fCreditsView->InsertHyperText(url, new URLAction(url)); 1002 fCreditsView->Insert("\n"); 1003 } 1004 fCreditsView->Insert("\n"); 1005 } 1006 1007 1008 void 1009 AboutView::PickRandomHaiku() 1010 { 1011 BFile fortunes( 1012 #ifdef __HAIKU__ 1013 "/etc/fortunes/Haiku", 1014 #else 1015 "data/etc/fortunes/Haiku", 1016 #endif 1017 B_READ_ONLY); 1018 struct stat st; 1019 if (fortunes.InitCheck() < B_OK) 1020 return; 1021 if (fortunes.GetStat(&st) < B_OK) 1022 return; 1023 char *buff = (char *)malloc((size_t)st.st_size + 1); 1024 if (!buff) 1025 return; 1026 buff[(size_t)st.st_size] = '\0'; 1027 BList haikuList; 1028 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 1029 char *p = buff; 1030 while (p && *p) { 1031 char *e = strchr(p, '%'); 1032 BString *s = new BString(p, e ? (e - p) : -1); 1033 haikuList.AddItem(s); 1034 p = e; 1035 if (p && (*p == '%')) 1036 p++; 1037 if (p && (*p == '\n')) 1038 p++; 1039 } 1040 } 1041 free(buff); 1042 if (haikuList.CountItems() < 1) 1043 return; 1044 BString *s = (BString *)haikuList.ItemAt(rand() % haikuList.CountItems()); 1045 BFont font(be_bold_font); 1046 font.SetSize(be_bold_font->Size()); 1047 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 1048 fCreditsView->SelectAll(); 1049 fCreditsView->Delete(); 1050 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 1051 fCreditsView->Insert(s->String()); 1052 fCreditsView->Insert("\n"); 1053 while ((s = (BString *)haikuList.RemoveItem((int32)0))) { 1054 delete s; 1055 } 1056 } 1057 1058 1059 status_t 1060 AboutView::_GetLicensePath(const char* license, BPath& path) 1061 { 1062 static const directory_which directoryConstants[] = { 1063 B_USER_DATA_DIRECTORY, 1064 B_COMMON_DATA_DIRECTORY, 1065 B_SYSTEM_DATA_DIRECTORY 1066 }; 1067 static const int dirCount = 3; 1068 1069 for (int i = 0; i < dirCount; i++) { 1070 struct stat st; 1071 status_t error = find_directory(directoryConstants[i], &path); 1072 if (error == B_OK && path.Append("licenses") == B_OK 1073 && path.Append(license) == B_OK 1074 && lstat(path.Path(), &st) == 0) { 1075 return B_OK; 1076 } 1077 } 1078 1079 path.Unset(); 1080 return B_ENTRY_NOT_FOUND; 1081 } 1082 1083 1084 void 1085 AboutView::_AddCopyrightsFromAttribute() 1086 { 1087 #ifdef __HAIKU__ 1088 // open the app executable file 1089 char appPath[B_PATH_NAME_LENGTH]; 1090 int appFD; 1091 if (BPrivate::get_app_path(appPath) != B_OK 1092 || (appFD = open(appPath, O_RDONLY)) < 0) { 1093 return; 1094 } 1095 1096 // open the attribute 1097 int attrFD = fs_open_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1098 close(appFD); 1099 if (attrFD < 0) 1100 return; 1101 1102 // attach it to a FILE 1103 FILE* attrFile = fdopen(attrFD, "r"); 1104 if (attrFile == NULL) { 1105 close(attrFD); 1106 return; 1107 } 1108 CObjectDeleter<FILE, int> _(attrFile, fclose); 1109 1110 // read and parse the copyrights 1111 BMessage package; 1112 BString fieldName; 1113 BString fieldValue; 1114 char lineBuffer[LINE_MAX]; 1115 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1116 // chop off line break 1117 size_t lineLen = strlen(line); 1118 if (lineLen > 0 && line[lineLen - 1] == '\n') 1119 line[--lineLen] = '\0'; 1120 1121 // flush previous field, if a new field begins, otherwise append 1122 if (lineLen == 0 || !isspace(line[0])) { 1123 // new field -- flush the previous one 1124 if (fieldName.Length() > 0) { 1125 fieldValue = trim_string(fieldValue.String(), 1126 fieldValue.Length()); 1127 package.AddString(fieldName.String(), fieldValue); 1128 fieldName = ""; 1129 } 1130 } else if (fieldName.Length() > 0) { 1131 // append to current field 1132 fieldValue += line; 1133 continue; 1134 } else { 1135 // bogus line -- ignore 1136 continue; 1137 } 1138 1139 if (lineLen == 0) 1140 continue; 1141 1142 // parse new field 1143 char* colon = strchr(line, ':'); 1144 if (colon == NULL) { 1145 // bogus line -- ignore 1146 continue; 1147 } 1148 1149 fieldName.SetTo(line, colon - line); 1150 fieldName = trim_string(line, colon - line); 1151 if (fieldName.Length() == 0) { 1152 // invalid field name 1153 continue; 1154 } 1155 1156 fieldValue = colon + 1; 1157 1158 if (fieldName == "Package") { 1159 // flush the current package 1160 _AddPackageCredit(PackageCredit(package)); 1161 package.MakeEmpty(); 1162 } 1163 } 1164 1165 // flush current package 1166 _AddPackageCredit(PackageCredit(package)); 1167 #endif 1168 } 1169 1170 1171 void 1172 AboutView::_AddPackageCreditEntries() 1173 { 1174 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1175 it != fPackageCredits.end(); ++it) { 1176 PackageCredit* package = it->second; 1177 1178 BString text(package->CopyrightAt(0)); 1179 int32 count = package->CountCopyrights(); 1180 for (int32 i = 1; i < count; i++) 1181 text << "\n" << package->CopyrightAt(i); 1182 1183 AddCopyrightEntry(package->PackageName(), text.String(), 1184 package->Licenses(), package->URL()); 1185 } 1186 } 1187 1188 1189 void 1190 AboutView::_AddPackageCredit(const PackageCredit& package) 1191 { 1192 if (!package.IsValid()) 1193 return; 1194 1195 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1196 if (it != fPackageCredits.end()) { 1197 // If the new package credit isn't "better" than the old one, ignore it. 1198 PackageCredit* oldPackage = it->second; 1199 if (!package.IsBetterThan(*oldPackage)) 1200 return; 1201 1202 // replace the old credit 1203 fPackageCredits.erase(it); 1204 delete oldPackage; 1205 } 1206 1207 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1208 } 1209 1210 1211 // #pragma mark - 1212 1213 1214 static const char * 1215 MemUsageToString(char string[], size_t size, system_info *info) 1216 { 1217 snprintf(string, size, "%d MB total, %d MB used (%d%%)", 1218 int(info->max_pages / 256.0f + 0.5f), 1219 int(info->used_pages / 256.0f + 0.5f), 1220 int(100 * info->used_pages / info->max_pages)); 1221 1222 return string; 1223 } 1224 1225 1226 static const char * 1227 UptimeToString(char string[], size_t size) 1228 { 1229 int64 days, hours, minutes, seconds, remainder; 1230 int64 systime = system_time(); 1231 1232 days = systime / 86400000000LL; 1233 remainder = systime % 86400000000LL; 1234 1235 hours = remainder / 3600000000LL; 1236 remainder = remainder % 3600000000LL; 1237 1238 minutes = remainder / 60000000; 1239 remainder = remainder % 60000000; 1240 1241 seconds = remainder / 1000000; 1242 1243 char *str = string; 1244 if (days) { 1245 str += snprintf(str, size, "%lld day%s",days, days > 1 ? "s" : ""); 1246 } 1247 if (hours) { 1248 str += snprintf(str, size - strlen(string), "%s%lld hour%s", 1249 str != string ? ", " : "", 1250 hours, hours > 1 ? "s" : ""); 1251 } 1252 if (minutes) { 1253 str += snprintf(str, size - strlen(string), "%s%lld minute%s", 1254 str != string ? ", " : "", 1255 minutes, minutes > 1 ? "s" : ""); 1256 } 1257 1258 if (seconds || str == string) { 1259 // Haiku would be well-known to boot very fast. 1260 // Let's be ready to handle below minute uptime, zero second included ;-) 1261 str += snprintf(str, size - strlen(string), "%s%lld second%s", 1262 str != string ? ", " : "", 1263 seconds, seconds > 1 ? "s" : ""); 1264 } 1265 1266 return string; 1267 } 1268 1269 1270 int 1271 main() 1272 { 1273 AboutApp app; 1274 app.Run(); 1275 return 0; 1276 } 1277 1278