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