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 11 #include <AppFileInfo.h> 12 #include <Application.h> 13 #include <Bitmap.h> 14 #include <File.h> 15 #include <FindDirectory.h> 16 #include <Font.h> 17 #include <MessageRunner.h> 18 #include <Messenger.h> 19 #include <OS.h> 20 #include <Path.h> 21 #include <Query.h> 22 #include <Resources.h> 23 #include <Screen.h> 24 #include <ScrollView.h> 25 #include <String.h> 26 #include <StringView.h> 27 #include <TextView.h> 28 #include <TranslationUtils.h> 29 #include <TranslatorFormats.h> 30 #include <View.h> 31 #include <Volume.h> 32 #include <VolumeRoster.h> 33 #include <Window.h> 34 35 #include <cpu_type.h> 36 37 #include <stdio.h> 38 #include <time.h> 39 #include <sys/utsname.h> 40 41 42 #define SCROLL_CREDITS_VIEW 'mviv' 43 #define READ_APP_QUERY_ENT 'raqe' 44 45 46 static const char *UptimeToString(char string[], size_t size); 47 static const char *MemUsageToString(char string[], size_t size, system_info *info); 48 static const char *CacheUsageToString(char string[], size_t size, system_info *info); 49 50 static const rgb_color kDarkGrey = { 100, 100, 100, 255 }; 51 static const rgb_color kHaikuGreen = { 42, 131, 36, 255 }; 52 static const rgb_color kHaikuOrange = { 255, 69, 0, 255 }; 53 static const rgb_color kHaikuYellow = { 255, 176, 0, 255 }; 54 static const rgb_color kLinkBlue = { 80, 80, 200, 255 }; 55 56 57 class AboutApp : public BApplication { 58 public: 59 AboutApp(void); 60 }; 61 62 class AboutWindow : public BWindow { 63 public: 64 AboutWindow(void); 65 bool QuitRequested(void); 66 }; 67 68 class AboutView : public BView { 69 public: 70 AboutView(const BRect &r); 71 ~AboutView(void); 72 73 virtual void AttachedToWindow(); 74 virtual void Pulse(); 75 76 virtual void FrameResized(float width, float height); 77 virtual void Draw(BRect update); 78 virtual void MessageReceived(BMessage *msg); 79 virtual void MouseDown(BPoint pt); 80 81 void AddCopyrightEntry(const char *name, const char *text, const char *url=NULL); 82 void PickRandomHaiku(); 83 84 private: 85 BStringView *fMemView; 86 BStringView *fUptimeView; 87 BView *fInfoView; 88 BTextView *fCreditsView; 89 90 BBitmap *fLogo; 91 92 BPoint fDrawPoint; 93 94 bigtime_t fLastActionTime; 95 BMessageRunner *fScrollRunner; 96 BQuery fAppsQuery; 97 }; 98 99 100 // #pragma mark - 101 102 103 AboutApp::AboutApp(void) 104 : BApplication("application/x-vnd.Haiku-About") 105 { 106 AboutWindow *window = new AboutWindow(); 107 window->Show(); 108 } 109 110 111 // #pragma mark - 112 113 114 AboutWindow::AboutWindow() 115 : BWindow(BRect(0, 0, 500, 300), "About This System", B_TITLED_WINDOW, 116 B_NOT_RESIZABLE | B_NOT_ZOOMABLE) 117 { 118 AboutView *view = new AboutView(Bounds()); 119 AddChild(view); 120 121 // start reading from the app query 122 BMessage msg(READ_APP_QUERY_ENT); 123 BMessenger msgr(view); 124 msgr.SendMessage(&msg); 125 126 MoveTo((BScreen().Frame().Width() - Bounds().Width()) / 2, 127 (BScreen().Frame().Height() - Bounds().Height()) / 2 ); 128 } 129 130 131 bool 132 AboutWindow::QuitRequested() 133 { 134 be_app->PostMessage(B_QUIT_REQUESTED); 135 return true; 136 } 137 138 139 AboutView::AboutView(const BRect &rect) 140 : BView(rect, "aboutview", B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED), 141 fLastActionTime(system_time()), 142 fScrollRunner(NULL) 143 { 144 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "haikulogo.png"); 145 if (fLogo) { 146 fDrawPoint.x = (225-fLogo->Bounds().Width()) / 2; 147 fDrawPoint.y = 0; 148 } 149 150 // Begin Construction of System Information controls 151 152 font_height height; 153 float labelHeight, textHeight; 154 155 system_info systemInfo; 156 get_system_info(&systemInfo); 157 158 be_plain_font->GetHeight(&height); 159 textHeight = height.ascent + height.descent + height.leading; 160 161 be_bold_font->GetHeight(&height); 162 labelHeight = height.ascent + height.descent + height.leading; 163 164 BRect r(0, 0, 225, Bounds().bottom); 165 if (fLogo) 166 r.OffsetBy(0, fLogo->Bounds().Height()); 167 168 fInfoView = new BView(r, "infoview", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_WILL_DRAW); 169 fInfoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 170 fInfoView->SetLowColor(fInfoView->ViewColor()); 171 fInfoView->SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); 172 AddChild(fInfoView); 173 174 // Add all the various labels for system infomation 175 176 BStringView *stringView; 177 178 // OS Version 179 r.Set(5, 5, 224, labelHeight + 5); 180 stringView = new BStringView(r, "oslabel", "Version:"); 181 stringView->SetFont(be_bold_font); 182 fInfoView->AddChild(stringView); 183 stringView->ResizeToPreferred(); 184 185 // we update "labelHeight" to the actual height of the string view 186 labelHeight = stringView->Bounds().Height(); 187 188 r.OffsetBy(0, labelHeight); 189 r.bottom = r.top + textHeight; 190 191 char string[256]; 192 strcpy(string, "Unknown"); 193 194 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 195 BPath path; 196 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 197 path.Append("libbe.so"); 198 199 BAppFileInfo appFileInfo; 200 version_info versionInfo; 201 BFile file; 202 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 203 && appFileInfo.SetTo(&file) == B_OK 204 && appFileInfo.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK 205 && versionInfo.short_info[0] != '\0') 206 strcpy(string, versionInfo.short_info); 207 } 208 209 // Add revision from uname() info 210 utsname unameInfo; 211 if (uname(&unameInfo) == 0) { 212 long revision; 213 if (sscanf(unameInfo.version, "r%ld", &revision) == 1) { 214 char version[16]; 215 snprintf(version, sizeof(version), "%ld", revision); 216 strlcat(string, " (Revision ", sizeof(string)); 217 strlcat(string, version, sizeof(string)); 218 strlcat(string, ")", sizeof(string)); 219 } 220 } 221 222 stringView = new BStringView(r, "ostext", string); 223 fInfoView->AddChild(stringView); 224 stringView->ResizeToPreferred(); 225 226 // CPU count, type and clock speed 227 r.OffsetBy(0, textHeight * 1.5); 228 r.bottom = r.top + labelHeight; 229 230 if (systemInfo.cpu_count > 1) 231 sprintf(string, "%ld Processors:", systemInfo.cpu_count); 232 else 233 strcpy(string, "Processor:"); 234 235 stringView = new BStringView(r, "cpulabel", string); 236 stringView->SetFont(be_bold_font); 237 fInfoView->AddChild(stringView); 238 stringView->ResizeToPreferred(); 239 240 BString cpuType; 241 cpuType << get_cpu_vendor_string(systemInfo.cpu_type) 242 << " " << get_cpu_model_string(&systemInfo); 243 244 r.OffsetBy(0, labelHeight); 245 r.bottom = r.top + textHeight; 246 stringView = new BStringView(r, "cputext", cpuType.String()); 247 fInfoView->AddChild(stringView); 248 stringView->ResizeToPreferred(); 249 250 r.OffsetBy(0, textHeight); 251 r.bottom = r.top + textHeight; 252 253 int32 clockSpeed = get_rounded_cpu_speed(); 254 if (clockSpeed < 1000) 255 sprintf(string,"%ld MHz", clockSpeed); 256 else 257 sprintf(string,"%.2f GHz", clockSpeed / 1000.0f); 258 259 stringView = new BStringView(r, "mhztext", string); 260 fInfoView->AddChild(stringView); 261 stringView->ResizeToPreferred(); 262 263 // RAM 264 r.OffsetBy(0, textHeight * 1.5); 265 r.bottom = r.top + labelHeight; 266 stringView = new BStringView(r, "ramlabel", "Memory:"); 267 stringView->SetFont(be_bold_font); 268 fInfoView->AddChild(stringView); 269 stringView->ResizeToPreferred(); 270 271 r.OffsetBy(0, labelHeight); 272 r.bottom = r.top + textHeight; 273 274 fMemView = new BStringView(r, "ramtext", ""); 275 fInfoView->AddChild(fMemView); 276 fMemView->SetText(MemUsageToString(string, sizeof(string), &systemInfo)); 277 278 // Kernel build time/date 279 r.OffsetBy(0, textHeight * 1.5); 280 r.bottom = r.top + labelHeight; 281 stringView = new BStringView(r, "kernellabel", "Kernel:"); 282 stringView->SetFont(be_bold_font); 283 fInfoView->AddChild(stringView); 284 stringView->ResizeToPreferred(); 285 286 r.OffsetBy(0, labelHeight); 287 r.bottom = r.top + textHeight; 288 289 snprintf(string, sizeof(string), "%s %s", 290 systemInfo.kernel_build_date, systemInfo.kernel_build_time); 291 292 stringView = new BStringView(r, "kerneltext", string); 293 fInfoView->AddChild(stringView); 294 stringView->ResizeToPreferred(); 295 296 // Uptime 297 r.OffsetBy(0, textHeight * 1.5); 298 r.bottom = r.top + labelHeight; 299 stringView = new BStringView(r, "uptimelabel", "Time Running:"); 300 stringView->SetFont(be_bold_font); 301 fInfoView->AddChild(stringView); 302 stringView->ResizeToPreferred(); 303 304 r.OffsetBy(0, labelHeight); 305 r.bottom = r.top + textHeight; 306 307 fUptimeView = new BStringView(r, "uptimetext", ""); 308 fInfoView->AddChild(fUptimeView); 309 // string width changes, so we don't do ResizeToPreferred() 310 311 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 312 313 // Begin construction of the credits view 314 r = Bounds(); 315 r.left += fInfoView->Bounds().right + 1; 316 r.right -= B_V_SCROLL_BAR_WIDTH; 317 318 fCreditsView = new BTextView(r, "credits", 319 r.OffsetToCopy(0, 0).InsetByCopy(5, 5), B_FOLLOW_ALL); 320 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS ); 321 fCreditsView->SetStylable(true); 322 fCreditsView->MakeEditable(false); 323 fCreditsView->MakeSelectable(false); 324 fCreditsView->SetWordWrap(true); 325 326 BScrollView *creditsScroller = new BScrollView("creditsScroller", 327 fCreditsView, B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS, false, true, B_PLAIN_BORDER); 328 AddChild(creditsScroller); 329 330 BFont font(be_bold_font); 331 font.SetSize(font.Size() + 4); 332 333 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 334 fCreditsView->Insert("Haiku\n"); 335 336 font.SetSize(be_bold_font->Size()); 337 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 338 339 time_t time = ::time(NULL); 340 struct tm* tm = localtime(&time); 341 int32 year = tm->tm_year + 1900; 342 if (year < 2007) 343 year = 2007; 344 snprintf(string, sizeof(string), 345 "Copyright " B_UTF8_COPYRIGHT "2001-%ld Haiku, Inc.\n", year); 346 347 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 348 fCreditsView->Insert(string); 349 350 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 351 fCreditsView->Insert("http://haiku-os.org\n\n"); 352 353 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 354 fCreditsView->Insert("Team Leads:\n"); 355 356 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 357 fCreditsView->Insert( 358 "Axel Dörfler\n" 359 "Phil Greenway\n" 360 "Philippe Houdoin\n" 361 "Marcus Overhagen\n" 362 "Ingo Weinhold\n" 363 "Jonathan Yoder\n" 364 "\n"); 365 366 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 367 fCreditsView->Insert("Developers:\n"); 368 369 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 370 fCreditsView->Insert( 371 "Ithamar R. Adema\n" 372 "Bruno G. Albuquerque\n" 373 "Stephan Aßmus\n" 374 "Andrew Bachmann\n" 375 "Salvatore Benedetto\n" 376 "Stefano Ceccherini\n" 377 "Rudolf Cornelissen\n" 378 "Alexandre Deckner\n" 379 "Oliver Ruiz Dorantes\n" 380 "Jérôme Duval\n" 381 "Andre Alves Garzia\n" 382 "René Gollent\n" 383 "Karsten Heimrich\n" 384 "Euan Kirkhope\n" 385 "Waldemar Kornewald\n" 386 "Ryan Leavengood\n" 387 "Michael Lotz\n" 388 "David McPaul\n" 389 "Michael Pfeiffer\n" 390 "Niels Sascha Reedijk\n" 391 "Jonas Sundström\n" 392 "François Revol\n" 393 "Hugo Santos\n" 394 "Gerasim Troeglazov\n" 395 "Bryan Varner\n" 396 "Siarzhuk Zharski\n" 397 "\n"); 398 399 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 400 fCreditsView->Insert("Contributors:\n"); 401 402 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 403 fCreditsView->Insert( 404 "Andrea Anzani\n" 405 "Andre Braga\n" 406 "Bruce Cameron\n" 407 "Greg Crain\n" 408 "Tyler Dauwalder\n" 409 "John Drinkwater\n" 410 "Cian Duffy\n" 411 "Marc Flerackers\n" 412 "Daniel Furrer\n" 413 "Matthijs Hollemans\n" 414 "Morgan Howe\n" 415 "Erik Jaesler\n" 416 "Carwyn Jones\n" 417 "Maurice Kalinowski\n" 418 "Vasilis Kaoutsis\n" 419 "James Kim\n" 420 "Jan Klötzke\n" 421 "Marcin Konicki\n" 422 "Kurtis Kopf\n" 423 "Waldemar Kornewald\n" 424 "Tomáš Kučera\n" 425 "Luboš Kulič\n" 426 "Thomas Kurschel\n" 427 "Elad Lahav\n" 428 "Anthony Lee\n" 429 "Santiago Lema\n" 430 "Raynald Lesieur\n" 431 "Oscar Lesta\n" 432 "Jerome Leveque\n" 433 "Christof Lutteroth\n" 434 "Graham MacDonald\n" 435 "Jan Matějek\n" 436 "Brian Matzon\n" 437 "Christopher ML Zumwalt May\n" 438 "Andrew McCall\n" 439 "Michele (zuMi)\n" 440 "Marius Middelthon\n" 441 "Misza\n" 442 "Fredrik Modéen\n" 443 "MrSiggler\n" 444 "Alan Murta\n" 445 "Frans Van Nispen\n" 446 "Adi Oanca\n" 447 "Pahtz\n" 448 "Michael Paine\n" 449 "Michael Phipps\n" 450 "Jeremy Rand\n" 451 "Hartmut Reh\n" 452 "David Reid\n" 453 "Daniel Reinhold\n" 454 "Samuel Rodriguez Perez\n" 455 "Thomas Roell\n" 456 "Rafael Romo\n" 457 "Philippe Saint-Pierre\n" 458 "Reznikov Sergei\n" 459 "Zousar Shaker\n" 460 "Alexander G. M. Smith\n" 461 "Daniel Switkin\n" 462 "Atsushi Takamatsu\n" 463 "Oliver Tappe\n" 464 "James Urquhart\n" 465 "Jason Vandermark\n" 466 "Sandor Vroemisse\n" 467 "Denis Washington\n" 468 "Nathan Whitehorn\n" 469 "Michael Wilber\n" 470 "Ulrich Wimboeck\n" 471 "James Woodcock\n" // getpagesize() patch 472 "Artur Wyszynski\n" 473 "Gabe Yoder\n" 474 "Gerald Zajac\n" 475 "Łukasz Zemczak\n" 476 "JiSheng Zhang\n" 477 "\n" B_UTF8_ELLIPSIS " and probably some more we forgot to mention (sorry!)" 478 "\n\n"); 479 480 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 481 fCreditsView->Insert("Special Thanks To:\n"); 482 483 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 484 fCreditsView->Insert("Travis Geiselbrecht (and his NewOS kernel)\n"); 485 fCreditsView->Insert("Michael Phipps (project founder)\n\n"); 486 487 // copyrights for various projects we use 488 489 font.SetSize(be_bold_font->Size() + 4); 490 font.SetFace(B_BOLD_FACE); 491 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 492 fCreditsView->Insert("\nCopyrights\n\n"); 493 494 // GNU copyrights 495 AddCopyrightEntry("The GNU Project", 496 "Contains software from the GNU Project, " 497 "released under the GPL and LGPL licences:\n" 498 " - GNU C Library,\n" 499 " - GNU coretools, diffutils, findutils, gawk, bison, m4, make,\n" 500 " - Bourne Again Shell.\n" 501 "Copyright " B_UTF8_COPYRIGHT " The Free Software Foundation.", 502 "www.gnu.org"); 503 504 // FFMpeg copyrights 505 AddCopyrightEntry("FFMpeg libavcodec", 506 "Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.", 507 "www.ffmpeg.org"); 508 509 // AGG copyrights 510 AddCopyrightEntry("AntiGrain Geometry", 511 "Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).", 512 "www.antigrain.com"); 513 514 // PDFLib copyrights 515 AddCopyrightEntry("PDFLib", 516 "Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. " 517 "All rights reserved.\n" 518 "PDFlib and the PDFlib logo are registered trademarks of PDFlib GmbH.", 519 "www.pdflib.com"); 520 521 // FreeType copyrights 522 AddCopyrightEntry("FreeType2", 523 "Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 The FreeType" 524 " Project. All rights reserved.", 525 "www.freetype.org"); 526 527 // Mesa3D (http://www.mesa3d.org) copyrights 528 AddCopyrightEntry("Mesa", 529 "Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. " 530 "Mesa3D project. All rights reserved.", 531 "www.mesa3d.org"); 532 533 // SGI's GLU implementation copyrights 534 AddCopyrightEntry("GLU", 535 "Copyright " B_UTF8_COPYRIGHT " 1991-2000 Silicon Graphics, Inc. " 536 "SGI's Software FreeB license. All rights reserved."); 537 538 // GLUT implementation copyrights 539 AddCopyrightEntry("GLUT", 540 "Copyright " B_UTF8_COPYRIGHT " 1994-1997 Mark Kilgard. " 541 "All rights reserved.\n" 542 "Copyright " B_UTF8_COPYRIGHT " 1997 Be Inc.\n" 543 "Copyright " B_UTF8_COPYRIGHT " 1999 Jake Hamby."); 544 545 // OpenGroup & DEC (BRegion backend) copyright 546 AddCopyrightEntry("BRegion backend (XFree86)", 547 "Copyright " B_UTF8_COPYRIGHT " 1987, 1988, 1998 The Open Group.\n" 548 "Copyright " B_UTF8_COPYRIGHT " 1987, 1988 Digital Equipment Corporation, Maynard, Massachusetts.\n" 549 "All rights reserved."); 550 551 // Konatu font 552 AddCopyrightEntry("Konatu font", 553 "Copyright " B_UTF8_COPYRIGHT " 2002- MASUDA mitiya.\n" 554 "MIT license. All rights reserved."); 555 556 // expat copyrights 557 AddCopyrightEntry("expat", 558 "Copyright " B_UTF8_COPYRIGHT " 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper.\n" 559 "Copyright " B_UTF8_COPYRIGHT " 2001, 2002, 2003 Expat maintainers."); 560 561 // zlib copyrights 562 AddCopyrightEntry("zlib", 563 "Copyright " B_UTF8_COPYRIGHT " 1995-2004 Jean-loup Gailly and Mark Adler."); 564 565 // zip copyrights 566 AddCopyrightEntry("Info-ZIP", 567 "Copyright " B_UTF8_COPYRIGHT " 1990-2002 Info-ZIP. All rights reserved."); 568 569 // bzip2 copyrights 570 AddCopyrightEntry("bzip2", 571 "Copyright " B_UTF8_COPYRIGHT " 1996-2005 Julian R Seward. All rights reserved."); 572 573 // VIM copyrights 574 AddCopyrightEntry("Vi IMproved", 575 "Copyright " B_UTF8_COPYRIGHT " Bram Moolenaar et al."); 576 577 // lp_solve copyrights 578 // TODO: Fix! 579 AddCopyrightEntry("lp_solve", 580 "Copyright " B_UTF8_COPYRIGHT 581 " ??? (http://lpsolve.sourceforge.net/)."); 582 583 // OpenEXR copyrights 584 AddCopyrightEntry("OpenEXR", 585 "Copyright " B_UTF8_COPYRIGHT " 2002-2005, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC."); 586 587 // Bullet copyrights 588 AddCopyrightEntry("Bullet", 589 "Copyright " B_UTF8_COPYRIGHT " 2003-2008 Erwin Coumans", 590 "www.bulletphysics.com"); 591 592 // Build a list of installed applications and show their 593 // long version info. Well-behaved apps usually give 594 // copyright info there. 595 596 font.SetSize(be_bold_font->Size() + 4); 597 font.SetFace(B_BOLD_FACE); 598 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 599 fCreditsView->Insert("\nInstalled applications\n\n"); 600 601 BVolume bootVolume; 602 BVolumeRoster().GetBootVolume(&bootVolume); 603 fAppsQuery.SetVolume(&bootVolume); 604 if (fAppsQuery.SetPredicate("((BEOS:APP_SIG==\"**\")&&(name!=\"*.so\")&&(name!=\"*.rsrc\")&&" 605 "(BEOS:TYPE==\"application/x-vnd.Be-elfexecutable\"))") >= B_OK) { 606 fAppsQuery.Fetch(); 607 } 608 } 609 610 611 AboutView::~AboutView(void) 612 { 613 delete fScrollRunner; 614 } 615 616 617 void 618 AboutView::AttachedToWindow(void) 619 { 620 BView::AttachedToWindow(); 621 Window()->SetPulseRate(500000); 622 SetEventMask(B_POINTER_EVENTS); 623 } 624 625 626 void 627 AboutView::MouseDown(BPoint pt) 628 { 629 BRect r(92, 26, 105, 31); 630 if (r.Contains(pt)) { 631 printf("Easter Egg\n"); 632 PickRandomHaiku(); 633 } 634 635 if (Bounds().Contains(pt)) { 636 fLastActionTime = system_time(); 637 delete fScrollRunner; 638 fScrollRunner = NULL; 639 } 640 } 641 642 643 void 644 AboutView::FrameResized(float width, float height) 645 { 646 BRect r = fCreditsView->Bounds(); 647 r.OffsetTo(B_ORIGIN); 648 r.InsetBy(3, 3); 649 fCreditsView->SetTextRect(r); 650 } 651 652 653 void 654 AboutView::Draw(BRect update) 655 { 656 if (fLogo) 657 DrawBitmap(fLogo, fDrawPoint); 658 } 659 660 661 void 662 AboutView::Pulse(void) 663 { 664 char string[255]; 665 system_info info; 666 get_system_info(&info); 667 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 668 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 669 670 if (fScrollRunner == NULL && (system_time() > fLastActionTime + 10000000)) { 671 BMessage message(SCROLL_CREDITS_VIEW); 672 //fScrollRunner = new BMessageRunner(this, &message, 300000, -1); 673 } 674 } 675 676 677 void 678 AboutView::MessageReceived(BMessage *msg) 679 { 680 switch (msg->what) { 681 case SCROLL_CREDITS_VIEW: 682 { 683 BScrollBar *scrollBar = fCreditsView->ScrollBar(B_VERTICAL); 684 if (scrollBar == NULL) 685 break; 686 float max, min; 687 scrollBar->GetRange(&min, &max); 688 if (scrollBar->Value() < max) 689 fCreditsView->ScrollBy(0, 5); 690 691 break; 692 } 693 694 case READ_APP_QUERY_ENT: 695 { 696 BEntry ent; 697 if (fAppsQuery.GetNextEntry(&ent) < B_OK) { 698 fAppsQuery.Clear(); 699 fCreditsView->MakeSelectable(true); 700 break; 701 } 702 BFile file; 703 BPath path; 704 if (ent.Exists() && 705 ent.GetPath(&path) >= B_OK && 706 file.SetTo(&ent, B_READ_ONLY) >= B_OK) { 707 /* filter only apps */ 708 if (strncmp(path.Path(), "/boot/apps", 10) == 0) { 709 BAppFileInfo appFileInfo(&file); 710 uint32 flags; 711 version_info version; 712 if (appFileInfo.InitCheck() >= B_OK && 713 appFileInfo.GetAppFlags(&flags) >= B_OK && 714 appFileInfo.GetVersionInfo(&version, B_APP_VERSION_KIND) >= B_OK) { 715 //printf("AppFileInfo for %s :\n", path.Path()); 716 //printf("flags: %08x\n", flags); 717 BString name; 718 BString info; 719 name << path.Leaf(); 720 if (strlen(version.short_info) && 721 strcmp(version.short_info, path.Leaf())) 722 name << " (" << version.short_info << ")"; 723 /* 724 info << "\tVersion: "; 725 info << version.major << "."; 726 info << version.middle << "."; 727 info << version.minor; 728 char varieties[] = "dabgmf"; 729 if (version.variety > B_FINAL_VERSION) 730 info << "?"; 731 else 732 info << varieties[version.variety]; 733 info << version.internal; 734 info << "\n"; 735 */ 736 info << version.long_info; 737 AddCopyrightEntry(name.String(), info.String()); 738 739 } 740 } 741 } 742 // note for self: read next entry :) 743 BMessage m(READ_APP_QUERY_ENT); 744 BMessenger(this).SendMessage(&m); 745 break; 746 } 747 748 default: 749 BView::MessageReceived(msg); 750 break; 751 } 752 } 753 754 755 void 756 AboutView::AddCopyrightEntry(const char *name, const char *text, const char *url) 757 { 758 BFont font(be_bold_font); 759 //font.SetSize(be_bold_font->Size()); 760 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 761 762 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 763 fCreditsView->Insert(name); 764 fCreditsView->Insert("\n"); 765 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 766 fCreditsView->Insert(text); 767 fCreditsView->Insert("\n"); 768 if (url) { 769 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 770 fCreditsView->Insert(url); 771 fCreditsView->Insert("\n"); 772 } 773 fCreditsView->Insert("\n"); 774 } 775 776 void 777 AboutView::PickRandomHaiku() 778 { 779 BFile fortunes( 780 #ifdef __HAIKU__ 781 "/etc/fortunes/Haiku", 782 #else 783 "data/etc/fortunes/Haiku", 784 #endif 785 B_READ_ONLY); 786 struct stat st; 787 if (fortunes.InitCheck() < B_OK) 788 return; 789 if (fortunes.GetStat(&st) < B_OK) 790 return; 791 char *buff = (char *)malloc((size_t)st.st_size + 1); 792 if (!buff) 793 return; 794 buff[(size_t)st.st_size] = '\0'; 795 BList haikuList; 796 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 797 char *p = buff; 798 while (p && *p) { 799 char *e = strchr(p, '%'); 800 BString *s = new BString(p, e ? (e - p) : -1); 801 haikuList.AddItem(s); 802 p = e; 803 if (p && (*p == '%')) 804 p++; 805 if (p && (*p == '\n')) 806 p++; 807 } 808 } 809 free(buff); 810 if (haikuList.CountItems() < 1) 811 return; 812 BString *s = (BString *)haikuList.ItemAt(rand() % haikuList.CountItems()); 813 BFont font(be_bold_font); 814 font.SetSize(be_bold_font->Size()); 815 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 816 fCreditsView->SelectAll(); 817 fCreditsView->Delete(); 818 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 819 fCreditsView->Insert(s->String()); 820 fCreditsView->Insert("\n"); 821 while ((s = (BString *)haikuList.RemoveItem((int32)0))) { 822 delete s; 823 } 824 } 825 826 827 // #pragma mark - 828 829 830 static const char * 831 MemUsageToString(char string[], size_t size, system_info *info) 832 { 833 snprintf(string, size, "%d MB total, %d MB used (%d%%)", 834 int(info->max_pages / 256.0f + 0.5f), 835 int(info->used_pages / 256.0f + 0.5f), 836 int(100 * info->used_pages / info->max_pages)); 837 838 return string; 839 } 840 841 842 static const char * 843 UptimeToString(char string[], size_t size) 844 { 845 int64 days, hours, minutes, seconds, remainder; 846 int64 systime = system_time(); 847 848 days = systime / 86400000000LL; 849 remainder = systime % 86400000000LL; 850 851 hours = remainder / 3600000000LL; 852 remainder = remainder % 3600000000LL; 853 854 minutes = remainder / 60000000; 855 remainder = remainder % 60000000; 856 857 seconds = remainder / 1000000; 858 859 char *str = string; 860 if (days) { 861 str += snprintf(str, size, "%lld day%s",days, days > 1 ? "s" : ""); 862 } 863 if (hours) { 864 str += snprintf(str, size - strlen(string), "%s%lld hour%s", 865 str != string ? ", " : "", 866 hours, hours > 1 ? "s" : ""); 867 } 868 if (minutes) { 869 str += snprintf(str, size - strlen(string), "%s%lld minute%s", 870 str != string ? ", " : "", 871 minutes, minutes > 1 ? "s" : ""); 872 } 873 874 if (seconds || str == string) { 875 // Haiku would be well-known to boot very fast. 876 // Let's be ready to handle below minute uptime, zero second included ;-) 877 str += snprintf(str, size - strlen(string), "%s%lld second%s", 878 str != string ? ", " : "", 879 seconds, seconds > 1 ? "s" : ""); 880 } 881 882 return string; 883 } 884 885 886 int 887 main() 888 { 889 AboutApp app; 890 app.Run(); 891 return 0; 892 } 893 894