xref: /haiku/src/apps/aboutsystem/AboutSystem.cpp (revision 93a78ecaa45114d68952d08c4778f073515102f2)
1 /*
2  * Copyright (c) 2005-2007, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Author:
6  *		DarkWyrm <bpmagic@columbus.rr.com>
7  */
8 
9 
10 #include <AppFileInfo.h>
11 #include <Application.h>
12 #include <Bitmap.h>
13 #include <File.h>
14 #include <FindDirectory.h>
15 #include <Font.h>
16 #include <MessageRunner.h>
17 #include <Messenger.h>
18 #include <OS.h>
19 #include <Path.h>
20 #include <Resources.h>
21 #include <Screen.h>
22 #include <ScrollView.h>
23 #include <String.h>
24 #include <TextView.h>
25 #include <TranslationUtils.h>
26 #include <StringView.h>
27 #include <View.h>
28 #include <Window.h>
29 
30 #include <cpu_type.h>
31 
32 #include <stdio.h>
33 #include <time.h>
34 #include <sys/utsname.h>
35 
36 
37 #define SCROLL_CREDITS_VIEW 'mviv'
38 
39 
40 static const char *UptimeToString(char string[], size_t size);
41 static const char *MemUsageToString(char string[], size_t size);
42 
43 
44 class AboutApp : public BApplication {
45 	public:
46 		AboutApp(void);
47 };
48 
49 class AboutWindow : public BWindow {
50 	public:
51 				AboutWindow(void);
52 		bool	QuitRequested(void);
53 };
54 
55 class AboutView : public BView {
56 	public:
57 				AboutView(const BRect &r);
58 				~AboutView(void);
59 
60 		virtual void AttachedToWindow();
61 		virtual void Pulse();
62 
63 		virtual void FrameResized(float width, float height);
64 		virtual void Draw(BRect update);
65 		virtual void MessageReceived(BMessage *msg);
66 		virtual void MouseDown(BPoint pt);
67 
68 	private:
69 		BStringView		*fMemView;
70 		BStringView		*fUptimeView;
71 		BView			*fInfoView;
72 		BTextView		*fCreditsView;
73 
74 		BBitmap			*fLogo;
75 
76 		BPoint			fDrawPoint;
77 
78 		bigtime_t		fLastActionTime;
79 		BMessageRunner	*fScrollRunner;
80 };
81 
82 
83 //	#pragma mark -
84 
85 
86 AboutApp::AboutApp(void)
87 	: BApplication("application/x-vnd.Haiku-About")
88 {
89 	AboutWindow *window = new AboutWindow();
90 	window->Show();
91 }
92 
93 
94 //	#pragma mark -
95 
96 
97 AboutWindow::AboutWindow()
98 	: BWindow(BRect(0, 0, 500, 300), "About This System", B_TITLED_WINDOW,
99 			B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
100 {
101 	AddChild(new AboutView(Bounds()));
102 
103 	MoveTo((BScreen().Frame().Width() - Bounds().Width()) / 2,
104 		(BScreen().Frame().Height() - Bounds().Height()) / 2 );
105 }
106 
107 
108 bool
109 AboutWindow::QuitRequested()
110 {
111 	be_app->PostMessage(B_QUIT_REQUESTED);
112 	return true;
113 }
114 
115 
116 AboutView::AboutView(const BRect &rect)
117 	: BView(rect, "aboutview", B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED),
118 	fLastActionTime(system_time()),
119 	fScrollRunner(NULL)
120 {
121 	fLogo = BTranslationUtils::GetBitmap('PNG ', "haikulogo.png");
122 	if (fLogo) {
123 		fDrawPoint.x = (225-fLogo->Bounds().Width()) / 2;
124 		fDrawPoint.y = 0;
125 	}
126 
127 	// Begin Construction of System Information controls
128 
129 	font_height height;
130 	float labelHeight, textHeight;
131 
132 	system_info systemInfo;
133 	get_system_info(&systemInfo);
134 
135 	be_plain_font->GetHeight(&height);
136 	textHeight = height.ascent + height.descent + height.leading;
137 
138 	be_bold_font->GetHeight(&height);
139 	labelHeight = height.ascent + height.descent + height.leading;
140 
141 	BRect r(0, 0, 225, Bounds().bottom);
142 	if (fLogo)
143 		r.OffsetBy(0, fLogo->Bounds().Height());
144 
145 	fInfoView = new BView(r, "infoview", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_WILL_DRAW);
146 	fInfoView->SetViewColor(235, 235, 235);
147 	AddChild(fInfoView);
148 
149 	// Add all the various labels for system infomation
150 
151 	BStringView *stringView;
152 
153 	// OS Version
154 	r.Set(5, 5, 224, labelHeight + 5);
155 	stringView = new BStringView(r, "oslabel", "Version:");
156 	stringView->SetFont(be_bold_font);
157 	fInfoView->AddChild(stringView);
158 	stringView->ResizeToPreferred();
159 
160 	// we update "labelHeight" to the actual height of the string view
161 	labelHeight = stringView->Bounds().Height();
162 
163 	r.OffsetBy(0, labelHeight);
164 	r.bottom = r.top + textHeight;
165 
166 	char string[256];
167 	strcpy(string, "Unknown");
168 
169 	// the version is stored in the BEOS:APP_VERSION attribute of libbe.so
170 	BPath path;
171 	if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) {
172 		path.Append("libbe.so");
173 
174 		BAppFileInfo appFileInfo;
175 		version_info versionInfo;
176 		BFile file;
177 		if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK
178 			&& appFileInfo.SetTo(&file) == B_OK
179 			&& appFileInfo.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK
180 			&& versionInfo.short_info[0] != '\0')
181 			strcpy(string, versionInfo.short_info);
182 	}
183 
184 	// Add revision from uname() info
185 	utsname unameInfo;
186 	if (uname(&unameInfo) == 0) {
187 		long revision;
188 		if (sscanf(unameInfo.version, "r%ld", &revision) == 1) {
189 			char version[16];
190 			snprintf(version, sizeof(version), "%ld", revision);
191 			strlcat(string, " (Revision ", sizeof(string));
192 			strlcat(string, version, sizeof(string));
193 			strlcat(string, ")", sizeof(string));
194 		}
195 	}
196 
197 	stringView = new BStringView(r, "ostext", string);
198 	fInfoView->AddChild(stringView);
199 	stringView->ResizeToPreferred();
200 
201 	// CPU count, type and clock speed
202 	r.OffsetBy(0, textHeight * 1.5);
203 	r.bottom = r.top + labelHeight;
204 
205 	if (systemInfo.cpu_count > 1)
206 		sprintf(string, "%ld Processors:", systemInfo.cpu_count);
207 	else
208 		strcpy(string, "Processor:");
209 
210 	stringView = new BStringView(r, "cpulabel", string);
211 	stringView->SetFont(be_bold_font);
212 	fInfoView->AddChild(stringView);
213 	stringView->ResizeToPreferred();
214 
215 
216 	BString cpuType;
217 	cpuType << get_cpu_vendor_string(systemInfo.cpu_type)
218 		<< " " << get_cpu_model_string(&systemInfo);
219 
220 	r.OffsetBy(0, labelHeight);
221 	r.bottom = r.top + textHeight;
222 	stringView = new BStringView(r, "cputext", cpuType.String());
223 	fInfoView->AddChild(stringView);
224 	stringView->ResizeToPreferred();
225 
226 	r.OffsetBy(0, textHeight);
227 	r.bottom = r.top + textHeight;
228 
229 	int32 clockSpeed = get_rounded_cpu_speed();
230 	if (clockSpeed < 1000)
231 		sprintf(string,"%ld MHz", clockSpeed);
232 	else
233 		sprintf(string,"%.2f GHz", clockSpeed / 1000.0f);
234 
235 	stringView = new BStringView(r, "mhztext", string);
236 	fInfoView->AddChild(stringView);
237 	stringView->ResizeToPreferred();
238 
239 	// RAM
240 	r.OffsetBy(0, textHeight * 1.5);
241 	r.bottom = r.top + labelHeight;
242 	stringView = new BStringView(r, "ramlabel", "Memory:");
243 	stringView->SetFont(be_bold_font);
244 	fInfoView->AddChild(stringView);
245 	stringView->ResizeToPreferred();
246 
247 	r.OffsetBy(0, labelHeight);
248 	r.bottom = r.top + textHeight;
249 
250 	fMemView = new BStringView(r, "ramtext", "");
251 	fInfoView->AddChild(fMemView);
252 	//fMemView->ResizeToPreferred();
253 
254 	fMemView->SetText(MemUsageToString(string, sizeof(string)));
255 
256 	// Kernel build time/date
257 	r.OffsetBy(0, textHeight * 1.5);
258 	r.bottom = r.top + labelHeight;
259 	stringView = new BStringView(r, "kernellabel", "Kernel:");
260 	stringView->SetFont(be_bold_font);
261 	fInfoView->AddChild(stringView);
262 	stringView->ResizeToPreferred();
263 
264 	r.OffsetBy(0, labelHeight);
265 	r.bottom = r.top + textHeight;
266 
267 	snprintf(string, sizeof(string), "%s %s",
268 		systemInfo.kernel_build_date, systemInfo.kernel_build_time);
269 
270 	stringView = new BStringView(r, "kerneltext", string);
271 	fInfoView->AddChild(stringView);
272 	stringView->ResizeToPreferred();
273 
274 	// Uptime
275 	r.OffsetBy(0, textHeight * 1.5);
276 	r.bottom = r.top + labelHeight;
277 	stringView = new BStringView(r, "uptimelabel", "Time Running:");
278 	stringView->SetFont(be_bold_font);
279 	fInfoView->AddChild(stringView);
280 	stringView->ResizeToPreferred();
281 
282 	r.OffsetBy(0, labelHeight);
283 	r.bottom = r.top + textHeight;
284 
285 	fUptimeView = new BStringView(r, "uptimetext", "");
286 	fInfoView->AddChild(fUptimeView);
287 	// string width changes, so we don't do ResizeToPreferred()
288 
289 	fUptimeView->SetText(UptimeToString(string, sizeof(string)));
290 
291 	// Begin construction of the credits view
292 	r = Bounds();
293 	r.left += fInfoView->Bounds().right + 1;
294 	r.right -= B_V_SCROLL_BAR_WIDTH;
295 
296 	fCreditsView = new BTextView(r, "credits",
297 		r.OffsetToCopy(0, 0).InsetByCopy(5, 5), B_FOLLOW_ALL);
298 	fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS );
299 	fCreditsView->SetStylable(true);
300 	fCreditsView->MakeEditable(false);
301 	fCreditsView->SetWordWrap(true);
302 
303 	BScrollView *creditsScroller = new BScrollView("creditsScroller",
304 		fCreditsView, B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS, false, true, B_PLAIN_BORDER);
305 	AddChild(creditsScroller);
306 
307 	rgb_color darkgrey = { 100, 100, 100, 255 };
308 	rgb_color haikuGreen = { 42, 131, 36, 255 };
309 	rgb_color haikuOrange = { 255, 69, 0, 255 };
310 	rgb_color haikuYellow = { 255, 176, 0, 255 };
311 	rgb_color linkBlue = { 80, 80, 200, 255 };
312 
313 	BFont font(be_bold_font);
314 	font.SetSize(font.Size() + 4);
315 
316 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuGreen);
317 	fCreditsView->Insert("Haiku\n");
318 
319 	font.SetSize(be_bold_font->Size());
320 	font.SetFace(B_BOLD_FACE | B_ITALIC_FACE);
321 
322 	time_t time = ::time(NULL);
323 	struct tm* tm = localtime(&time);
324 	int32 year = tm->tm_year + 1900;
325 	if (year < 2007)
326 		year = 2007;
327 	snprintf(string, sizeof(string),
328 		"Copyright " B_UTF8_COPYRIGHT "2001-%ld Haiku, Inc.\n", year);
329 
330 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
331 	fCreditsView->Insert(string);
332 
333 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
334 	fCreditsView->Insert("http://haiku-os.org\n\n");
335 
336 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
337 	fCreditsView->Insert("Team Leads:\n");
338 
339 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
340 	fCreditsView->Insert(
341 		"Axel Dörfler\n"
342 		"Phil Greenway\n"
343 		"Philippe Houdoin\n"
344 		"Waldemar Kornewald\n"
345 		"Marcus Overhagen\n"
346 		"Michael Pfeiffer\n"
347 		"Ingo Weinhold\n"
348 		"Jonathan Yoder\n"
349 		"\n");
350 
351 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
352 	fCreditsView->Insert("Developers:\n");
353 
354 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
355 	fCreditsView->Insert(
356 		"Ithamar R. Adema\n"
357 		"Stephan Aßmus\n"
358 		"Andrew Bachmann\n"
359 		"Stefano Ceccherini\n"
360 		"Rudolf Cornelissen\n"
361 		"Jérôme Duval\n"
362 		"Waldemar Kornewald\n"
363 		"Ryan Leavengood\n"
364 		"Michael Lotz\n"
365 		"Niels Reedijk\n"
366 		"François Revol\n"
367 		"Hugo Santos\n"
368 		"Bryan Varner\n"
369 		"Siarzhuk Zharski\n"
370 		"\n");
371 
372 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
373 	fCreditsView->Insert("Contributors:\n");
374 
375 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
376 	fCreditsView->Insert(
377 		"Bruno G. Albuquerque\n"
378 		"Andrea Anzani\n"
379 		"Bruce Cameron\n"
380 		"Greg Crain\n"
381 		"Tyler Dauwalder\n"
382 		"Oliver Ruiz Dorantes\n"
383 		"John Drinkwater\n"
384 		"Cian Duffy\n"
385 		"Marc Flerackers\n"
386 		"Daniel Furrer\n"
387 		"Troeglazov Gerasim\n"
388 		"Matthijs Hollemans\n"
389 		"Morgan Howe\n"
390 		"Erik Jaesler\n"
391 		"Carwyn Jones\n"
392 		"Vasilis Kaoutsis\n"
393 		"Euan Kirkhope\n"
394 		"Jan Klötzke\n"
395 		"Marcin Konicki\n"
396 		"Kurtis Kopf\n"
397 		"Thomas Kurschel\n"
398 		"Elad Lahav\n"
399 		"Santiago Lema\n"
400 		"Oscar Lesta\n"
401 		"Jerome Leveque\n"
402 		"Graham MacDonald\n"
403 		"Brian Matzon\n"
404 		"Christopher ML Zumwalt May\n"
405 		"Andrew McCall\n"
406 		"David McPaul\n"
407 		"Michele (zuMi)\n"
408 		"Misza\n"
409 		"MrSiggler\n"
410 		"Alan Murta\n"
411 		"Frans Van Nispen\n"
412 		"Adi Oanca\n"
413 		"Pahtz\n"
414 		"Michael Paine\n"
415 		"Michael Phipps\n"
416 		"Jeremy Rand\n"
417 		"Hartmut Reh\n"
418 		"David Reid\n"
419 		"Daniel Reinhold\n"
420 		"Samuel Rodriguez Perez\n"
421 		"Thomas Roell\n"
422 		"Rafael Romo\n"
423 		"Reznikov Sergei\n"
424 		"Zousar Shaker\n"
425 		"Jonas Sundström\n"
426 		"Daniel Switkin\n"
427 		"Atsushi Takamatsu\n"
428 		"Oliver Tappe\n"
429 		"Jason Vandermark\n"
430 		"Sandor Vroemisse\n"
431 		"Nathan Whitehorn\n"
432 		"Michael Wilber\n"
433 		"Ulrich Wimboeck\n"
434 		"Gabe Yoder\n"
435 		"Gerald Zajac\n"
436 		"Łukasz Zemczak\n"
437 		"\n" B_UTF8_ELLIPSIS " and probably some more we forgot to mention (sorry!)"
438 		"\n\n");
439 
440 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
441 	fCreditsView->Insert("Special Thanks To:\n");
442 
443 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
444 	fCreditsView->Insert("Travis Geiselbrecht (and his NewOS kernel)\n");
445 	fCreditsView->Insert("Michael Phipps (project founder)\n\n");
446 
447 	font.SetSize(be_bold_font->Size() + 4);
448 	font.SetFace(B_BOLD_FACE);
449 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuGreen);
450 	fCreditsView->Insert("\nCopyrights\n\n");
451 
452 	font.SetSize(be_bold_font->Size());
453 	font.SetFace(B_BOLD_FACE | B_ITALIC_FACE);
454 
455 	// GNU copyrights
456 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
457 	fCreditsView->Insert("The GNU Project\n");
458 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
459 	fCreditsView->Insert("Contains software from the GNU Project, "
460 		"released under the GPL and LGPL licences:\n");
461 	fCreditsView->Insert("	- GNU C Library,\n");
462 	fCreditsView->Insert("	- GNU coretools, diffutils, findutils, gawk, bison, m4, make,\n");
463 	fCreditsView->Insert("	- Bourne Again Shell.\n");
464 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " The Free Software Foundation.\n");
465 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
466 	fCreditsView->Insert("www.gnu.org\n\n");
467 
468 	// FFMpeg copyrights
469 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
470 	fCreditsView->Insert("FFMpeg libavcodec\n");
471 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
472 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.\n");
473 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
474 	fCreditsView->Insert("www.ffmpeg.org\n\n");
475 
476 	// AGG copyrights
477 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
478 	fCreditsView->Insert("AntiGrain Geometry\n");
479 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
480 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).\n");
481 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
482 	fCreditsView->Insert("www.antigrain.com\n\n");
483 
484 	// PDFLib copyrights
485 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
486 	fCreditsView->Insert("PDFLib\n");
487 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
488 	fCreditsView->Insert(
489 		"Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. "
490 		"All rights reserved.\n"
491 		"PDFlib and the PDFlib logo are registered trademarks of PDFlib GmbH.\n");
492 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
493 	fCreditsView->Insert("www.pdflib.com\n\n");
494 
495 	// FreeType copyrights
496 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
497 	fCreditsView->Insert("FreeType2\n");
498 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
499 	fCreditsView->Insert("Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 The FreeType"
500 		" Project.  All rights reserved.\n");
501 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
502 	fCreditsView->Insert("www.freetype.org\n\n");
503 
504 	// Mesa3D (http://www.mesa3d.org) copyrights
505 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
506 	fCreditsView->Insert("Mesa\n");
507 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
508 	fCreditsView->Insert(
509 		"Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. "
510 		"Mesa3D project.  All rights reserved.\n");
511 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
512 	fCreditsView->Insert("www.mesa3d.org\n\n");
513 
514 	// SGI's GLU implementation copyrights
515 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
516 	fCreditsView->Insert("GLU\n");
517 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
518 	fCreditsView->Insert(
519 		"Copyright " B_UTF8_COPYRIGHT " 1991-2000 Silicon Graphics, Inc. "
520 		"SGI's Software FreeB license.  All rights reserved.\n\n");
521 
522 	// GLUT implementation copyrights
523 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
524 	fCreditsView->Insert("GLUT\n");
525 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
526 	fCreditsView->Insert(
527 		"Copyright " B_UTF8_COPYRIGHT " 1994-1997 Mark Kilgard. "
528 		"All rights reserved.\n"
529 		"Copyright " B_UTF8_COPYRIGHT " 1997 Be Inc.\n"
530 		"Copyright " B_UTF8_COPYRIGHT " 1999 Jake Hamby. \n\n");
531 
532 	// Konatu font
533 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
534 	fCreditsView->Insert("Konatu font\n");
535 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
536 	fCreditsView->Insert(
537 		"Copyright " B_UTF8_COPYRIGHT " 2002- MASUDA mitiya.\n"
538 		"MIT license. All rights reserved.\n\n");
539 
540 	// expat copyrights
541 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
542 	fCreditsView->Insert("expat\n");
543 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
544 	fCreditsView->Insert(
545 		"Copyright " B_UTF8_COPYRIGHT " 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper.\n"
546 		"Copyright " B_UTF8_COPYRIGHT " 2001, 2002, 2003 Expat maintainers.\n\n");
547 
548 	// zlib copyrights
549 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
550 	fCreditsView->Insert("zlib\n");
551 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
552 	fCreditsView->Insert(
553 		"Copyright " B_UTF8_COPYRIGHT " 1995-2004 Jean-loup Gailly and Mark Adler.\n\n");
554 
555 	// zip copyrights
556 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
557 	fCreditsView->Insert("Info-ZIP\n");
558 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
559 	fCreditsView->Insert(
560 		"Copyright " B_UTF8_COPYRIGHT " 1990-2002 Info-ZIP. All rights reserved.\n\n");
561 
562 	// bzip2 copyrights
563 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
564 	fCreditsView->Insert("bzip2\n");
565 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
566 	fCreditsView->Insert(
567 		"Copyright " B_UTF8_COPYRIGHT " 1996-2005 Julian R Seward. All rights reserved.\n\n");
568 
569 	// VIM copyrights
570 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
571 	fCreditsView->Insert("Vi IMproved\n");
572 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
573 	fCreditsView->Insert(
574 		"Copyright " B_UTF8_COPYRIGHT " Bram Moolenaar et al.\n\n");
575 
576 }
577 
578 
579 AboutView::~AboutView(void)
580 {
581 	delete fScrollRunner;
582 }
583 
584 
585 void
586 AboutView::AttachedToWindow(void)
587 {
588 	BView::AttachedToWindow();
589 	Window()->SetPulseRate(500000);
590 	SetEventMask(B_POINTER_EVENTS);
591 }
592 
593 
594 void
595 AboutView::MouseDown(BPoint pt)
596 {
597 	BRect r(92, 26, 105, 31);
598 	if (r.Contains(pt))
599 		printf("Easter Egg\n");
600 
601 	if (Bounds().Contains(pt)) {
602 		fLastActionTime = system_time();
603 		delete fScrollRunner;
604 		fScrollRunner = NULL;
605 	}
606 }
607 
608 
609 void
610 AboutView::FrameResized(float width, float height)
611 {
612 	BRect r = fCreditsView->Bounds();
613 	r.OffsetTo(B_ORIGIN);
614 	r.InsetBy(3, 3);
615 	fCreditsView->SetTextRect(r);
616 }
617 
618 
619 void
620 AboutView::Draw(BRect update)
621 {
622 	if (fLogo)
623 		DrawBitmap(fLogo, fDrawPoint);
624 }
625 
626 
627 void
628 AboutView::Pulse(void)
629 {
630 	char string[255];
631 
632 	fUptimeView->SetText(UptimeToString(string, sizeof(string)));
633 	fMemView->SetText(MemUsageToString(string, sizeof(string)));
634 
635 	if (fScrollRunner == NULL && (system_time() > fLastActionTime + 10000000)) {
636 		BMessage message(SCROLL_CREDITS_VIEW);
637 		//fScrollRunner = new BMessageRunner(this, &message, 300000, -1);
638 	}
639 }
640 
641 
642 void
643 AboutView::MessageReceived(BMessage *msg)
644 {
645 	switch (msg->what) {
646 		case SCROLL_CREDITS_VIEW:
647 		{
648 			BScrollBar *scrollBar = fCreditsView->ScrollBar(B_VERTICAL);
649 			if (scrollBar == NULL)
650 				break;
651 			float max, min;
652 			scrollBar->GetRange(&min, &max);
653 			if (scrollBar->Value() < max)
654 				fCreditsView->ScrollBy(0, 5);
655 
656 			break;
657 		}
658 
659 		default:
660 			BView::MessageReceived(msg);
661 			break;
662 	}
663 }
664 
665 
666 //	#pragma mark -
667 
668 
669 static const char *
670 MemUsageToString(char string[], size_t size)
671 {
672 	system_info systemInfo;
673 
674 	if (get_system_info(&systemInfo) < B_OK)
675 		return "Unknown";
676 
677 	snprintf(string, size, "%d MB total, %d MB used (%d%%)",
678 			int(systemInfo.max_pages / 256.0f + 0.5f),
679 			int(systemInfo.used_pages / 256.0f + 0.5f),
680 			int(100 * systemInfo.used_pages / systemInfo.max_pages));
681 
682 	return string;
683 }
684 
685 
686 static const char *
687 UptimeToString(char string[], size_t size)
688 {
689 	int64 days, hours, minutes, seconds, remainder;
690 	int64 systime = system_time();
691 
692 	days = systime / 86400000000LL;
693 	remainder = systime % 86400000000LL;
694 
695 	hours = remainder / 3600000000LL;
696 	remainder = remainder % 3600000000LL;
697 
698 	minutes = remainder / 60000000;
699 	remainder = remainder % 60000000;
700 
701 	seconds = remainder / 1000000;
702 
703 	char *str = string;
704 	if (days) {
705 		str += snprintf(str, size, "%lld day%s",days, days > 1 ? "s" : "");
706 	}
707 	if (hours) {
708 		str += snprintf(str, size - strlen(string), "%s%lld hour%s",
709 				str != string ? ", " : "",
710 				hours, hours > 1 ? "s" : "");
711 	}
712 	if (minutes) {
713 		str += snprintf(str, size - strlen(string), "%s%lld minute%s",
714 				str != string ? ", " : "",
715 				minutes, minutes > 1 ? "s" : "");
716 	}
717 
718 	if (seconds || str == string) {
719 		// Haiku would be well-known to boot very fast.
720 		// Let's be ready to handle below minute uptime, zero second included ;-)
721 		str += snprintf(str, size - strlen(string), "%s%lld second%s",
722 				str != string ? ", " : "",
723 				seconds, seconds > 1 ? "s" : "");
724 	}
725 
726 	return string;
727 }
728 
729 
730 int
731 main()
732 {
733 	AboutApp app;
734 	app.Run();
735 	return 0;
736 }
737 
738