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