xref: /haiku/src/apps/aboutsystem/AboutSystem.cpp (revision 14e3d1b5768e7110b3d5c0855833267409b71dbb)
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 		"Stephan Aßmus\n"
357 		"Andrew Bachmann\n"
358 		"Stefano Ceccherini\n"
359 		"Rudolf Cornelissen\n"
360 		"Jérôme Duval\n"
361 		"Waldemar Kornewald\n"
362 		"Thomas Kurschel\n"
363 		"Ryan Leavengood\n"
364 		"Michael Lotz\n"
365 		"Niels Reedijk\n"
366 		"Hugo Santos\n"
367 		"Bryan Varner\n"
368 		"\n");
369 
370 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
371 	fCreditsView->Insert("Contributors:\n");
372 
373 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
374 	fCreditsView->Insert(
375 		"Bruno G. Albuquerque\n"
376 		"Andrea Anzani\n"
377 		"Bruce Cameron\n"
378 		"Greg Crain\n"
379 		"Tyler Dauwalder\n"
380 		"Oliver Ruiz Dorantes\n"
381 		"John Drinkwater\n"
382 		"Cian Duffy\n"
383 		"Marc Flerackers\n"
384 		"Daniel Furrer\n"
385 		"Troeglazov Gerasim\n"
386 		"Matthijs Hollemans\n"
387 		"Morgan Howe\n"
388 		"Erik Jaesler\n"
389 		"Carwyn Jones\n"
390 		"Vasilis Kaoutsis\n"
391 		"Euan Kirkhope\n"
392 		"Marcin Konicki\n"
393 		"Kurtis Kopf\n"
394 		"Elad Lahav\n"
395 		"Santiago Lema\n"
396 		"Oscar Lesta\n"
397 		"Jerome Leveque\n"
398 		"Graham MacDonald\n"
399 		"Jorge G. Mare\n"
400 		"Brian Matzon\n"
401 		"Christopher ML Zumwalt May\n"
402 		"Andrew McCall\n"
403 		"David McPaul\n"
404 		"Misza\n"
405 		"MrSiggler\n"
406 		"Alan Murta\n"
407 		"Frans Van Nispen\n"
408 		"Adi Oanca\n"
409 		"Pahtz\n"
410 		"Michael Paine\n"
411 		"Michael Phipps\n"
412 		"Jeremy Rand\n"
413 		"Hartmut Reh\n"
414 		"David Reid\n"
415 		"Daniel Reinhold\n"
416 		"François Revol\n"
417 		"Samuel Rodriguez Perez\n"
418 		"Thomas Roell\n"
419 		"Rafael Romo\n"
420 		"Reznikov Sergei\n"
421 		"Zousar Shaker\n"
422 		"Jonas Sundström\n"
423 		"Daniel Switkin\n"
424 		"Atsushi Takamatsu\n"
425 		"Oliver Tappe\n"
426 		"Jason Vandermark\n"
427 		"Sandor Vroemisse\n"
428 		"Nathan Whitehorn\n"
429 		"Michael Wilber\n"
430 		"Ulrich Wimboeck\n"
431 		"Gabe Yoder\n"
432 		"Łukasz Zemczak\n"
433 		"Siarzhuk Zharski\n"
434 		"\n" B_UTF8_ELLIPSIS " and probably some more we forgot to mention (sorry!)"
435 		"\n\n");
436 
437 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuOrange);
438 	fCreditsView->Insert("Special Thanks To:\n");
439 
440 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
441 	fCreditsView->Insert("Travis Geiselbrecht (and his NewOS kernel)\n");
442 	fCreditsView->Insert("Michael Phipps (project founder)\n\n");
443 
444 	font.SetSize(be_bold_font->Size() + 4);
445 	font.SetFace(B_BOLD_FACE);
446 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuGreen);
447 	fCreditsView->Insert("\nCopyrights\n\n");
448 
449 	font.SetSize(be_bold_font->Size());
450 	font.SetFace(B_BOLD_FACE | B_ITALIC_FACE);
451 
452 	// GNU copyrights
453 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
454 	fCreditsView->Insert("The GNU Project\n");
455 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
456 	fCreditsView->Insert("Contains software from the GNU Project, "
457 		"released under the GPL and LGPL licences:\n");
458 	fCreditsView->Insert("	- GNU C Library,\n");
459 	fCreditsView->Insert("	- GNU coretools, diffutils, findutils, gawk, bison, m4, make,\n");
460 	fCreditsView->Insert("	- Bourne Again Shell.\n");
461 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " The Free Software Foundation.\n");
462 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
463 	fCreditsView->Insert("www.gnu.org\n\n");
464 
465 	// FFMpeg copyrights
466 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
467 	fCreditsView->Insert("FFMpeg libavcodec\n");
468 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
469 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.\n");
470 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
471 	fCreditsView->Insert("www.ffmpeg.org\n\n");
472 
473 	// AGG copyrights
474 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
475 	fCreditsView->Insert("AntiGrain Geometry\n");
476 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
477 	fCreditsView->Insert("Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).\n");
478 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
479 	fCreditsView->Insert("www.antigrain.com\n\n");
480 
481 	// PDFLib copyrights
482 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
483 	fCreditsView->Insert("PDFLib\n");
484 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
485 	fCreditsView->Insert(
486 		"Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. "
487 		"All rights reserved.\n"
488 		"PDFlib and the PDFlib logo are registered trademarks of PDFlib GmbH.\n");
489 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
490 	fCreditsView->Insert("www.pdflib.com\n\n");
491 
492 	// FreeType copyrights
493 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
494 	fCreditsView->Insert("FreeType2\n");
495 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
496 	fCreditsView->Insert("Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 The FreeType"
497 		" Project.  All rights reserved.\n");
498 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
499 	fCreditsView->Insert("www.freetype.org\n\n");
500 
501 	// Mesa3D (http://www.mesa3d.org) copyrights
502 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
503 	fCreditsView->Insert("Mesa\n");
504 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
505 	fCreditsView->Insert(
506 		"Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. "
507 		"Mesa3D project.  All rights reserved.\n");
508 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &linkBlue);
509 	fCreditsView->Insert("www.mesa3d.org\n\n");
510 
511 	// SGI's GLU implementation copyrights
512 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
513 	fCreditsView->Insert("GLU\n");
514 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
515 	fCreditsView->Insert(
516 		"Copyright " B_UTF8_COPYRIGHT " 1991-2000 Silicon Graphics, Inc. "
517 		"SGI's Software FreeB license.  All rights reserved.\n\n");
518 
519 	// GLUT implementation copyrights
520 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
521 	fCreditsView->Insert("GLUT\n");
522 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
523 	fCreditsView->Insert(
524 		"Copyright " B_UTF8_COPYRIGHT " 1994-1997 Mark Kilgard. "
525 		"All rights reserved.\n"
526 		"Copyright " B_UTF8_COPYRIGHT " 1997 Be Inc.\n"
527 		"Copyright " B_UTF8_COPYRIGHT " 1999 Jake Hamby. \n\n");
528 
529 	// Konatu font
530 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
531 	fCreditsView->Insert("Konatu font\n");
532 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
533 	fCreditsView->Insert(
534 		"Copyright " B_UTF8_COPYRIGHT " 2002- MASUDA mitiya.\n"
535 		"MIT license. All rights reserved.\n\n");
536 
537 	// expat copyrights
538 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
539 	fCreditsView->Insert("expat\n");
540 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
541 	fCreditsView->Insert(
542 		"Copyright " B_UTF8_COPYRIGHT " 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper.\n"
543 		"Copyright " B_UTF8_COPYRIGHT " 2001, 2002, 2003 Expat maintainers.\n\n");
544 
545 	// zlib copyrights
546 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
547 	fCreditsView->Insert("zlib\n");
548 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
549 	fCreditsView->Insert(
550 		"Copyright " B_UTF8_COPYRIGHT " 1995-2004 Jean-loup Gailly and Mark Adler.\n\n");
551 
552 	// zip copyrights
553 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
554 	fCreditsView->Insert("Info-ZIP\n");
555 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
556 	fCreditsView->Insert(
557 		"Copyright " B_UTF8_COPYRIGHT " 1990-2002 Info-ZIP. All rights reserved.\n\n");
558 
559 	// bzip2 copyrights
560 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
561 	fCreditsView->Insert("bzip2\n");
562 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
563 	fCreditsView->Insert(
564 		"Copyright " B_UTF8_COPYRIGHT " 1996-2005 Julian R Seward. All rights reserved.\n\n");
565 
566 	// VIM copyrights
567 	fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &haikuYellow);
568 	fCreditsView->Insert("Vi IMproved\n");
569 	fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &darkgrey);
570 	fCreditsView->Insert(
571 		"Copyright " B_UTF8_COPYRIGHT " Bram Moolenaar et al.\n\n");
572 
573 }
574 
575 
576 AboutView::~AboutView(void)
577 {
578 	delete fScrollRunner;
579 }
580 
581 
582 void
583 AboutView::AttachedToWindow(void)
584 {
585 	BView::AttachedToWindow();
586 	Window()->SetPulseRate(500000);
587 	SetEventMask(B_POINTER_EVENTS);
588 }
589 
590 
591 void
592 AboutView::MouseDown(BPoint pt)
593 {
594 	BRect r(92, 26, 105, 31);
595 	if (r.Contains(pt))
596 		printf("Easter Egg\n");
597 
598 	if (Bounds().Contains(pt)) {
599 		fLastActionTime = system_time();
600 		delete fScrollRunner;
601 		fScrollRunner = NULL;
602 	}
603 }
604 
605 
606 void
607 AboutView::FrameResized(float width, float height)
608 {
609 	BRect r = fCreditsView->Bounds();
610 	r.OffsetTo(B_ORIGIN);
611 	r.InsetBy(3, 3);
612 	fCreditsView->SetTextRect(r);
613 }
614 
615 
616 void
617 AboutView::Draw(BRect update)
618 {
619 	if (fLogo)
620 		DrawBitmap(fLogo, fDrawPoint);
621 }
622 
623 
624 void
625 AboutView::Pulse(void)
626 {
627 	char string[255];
628 
629 	fUptimeView->SetText(UptimeToString(string, sizeof(string)));
630 	fMemView->SetText(MemUsageToString(string, sizeof(string)));
631 
632 	if (fScrollRunner == NULL && (system_time() > fLastActionTime + 10000000)) {
633 		BMessage message(SCROLL_CREDITS_VIEW);
634 		//fScrollRunner = new BMessageRunner(this, &message, 300000, -1);
635 	}
636 }
637 
638 
639 void
640 AboutView::MessageReceived(BMessage *msg)
641 {
642 	switch (msg->what) {
643 		case SCROLL_CREDITS_VIEW:
644 		{
645 			BScrollBar *scrollBar = fCreditsView->ScrollBar(B_VERTICAL);
646 			if (scrollBar == NULL)
647 				break;
648 			float max, min;
649 			scrollBar->GetRange(&min, &max);
650 			if (scrollBar->Value() < max)
651 				fCreditsView->ScrollBy(0, 5);
652 
653 			break;
654 		}
655 
656 		default:
657 			BView::MessageReceived(msg);
658 			break;
659 	}
660 }
661 
662 
663 //	#pragma mark -
664 
665 
666 static const char *
667 MemUsageToString(char string[], size_t size)
668 {
669 	system_info systemInfo;
670 
671 	if (get_system_info(&systemInfo) < B_OK)
672 		return "Unknown";
673 
674 	snprintf(string, size, "%d MB total, %d MB used (%d%%)",
675 			int(systemInfo.max_pages / 256.0f + 0.5f),
676 			int(systemInfo.used_pages / 256.0f + 0.5f),
677 			int(100 * systemInfo.used_pages / systemInfo.max_pages));
678 
679 	return string;
680 }
681 
682 
683 static const char *
684 UptimeToString(char string[], size_t size)
685 {
686 	int64 days, hours, minutes, seconds, remainder;
687 	int64 systime = system_time();
688 
689 	days = systime / 86400000000LL;
690 	remainder = systime % 86400000000LL;
691 
692 	hours = remainder / 3600000000LL;
693 	remainder = remainder % 3600000000LL;
694 
695 	minutes = remainder / 60000000;
696 	remainder = remainder % 60000000;
697 
698 	seconds = remainder / 1000000;
699 
700 	char *str = string;
701 	if (days) {
702 		str += snprintf(str, size, "%lld day%s",days, days > 1 ? "s" : "");
703 	}
704 	if (hours) {
705 		str += snprintf(str, size - strlen(string), "%s%lld hour%s",
706 				str != string ? ", " : "",
707 				hours, hours > 1 ? "s" : "");
708 	}
709 	if (minutes) {
710 		str += snprintf(str, size - strlen(string), "%s%lld minute%s",
711 				str != string ? ", " : "",
712 				minutes, minutes > 1 ? "s" : "");
713 	}
714 
715 	if (seconds || str == string) {
716 		// Haiku would be well-known to boot very fast.
717 		// Let's be ready to handle below minute uptime, zero second included ;-)
718 		str += snprintf(str, size - strlen(string), "%s%lld second%s",
719 				str != string ? ", " : "",
720 				seconds, seconds > 1 ? "s" : "");
721 	}
722 
723 	return string;
724 }
725 
726 
727 int
728 main()
729 {
730 	AboutApp app;
731 	app.Run();
732 	return 0;
733 }
734 
735