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