xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision d5cd5d63ff0ad395989db6cf4841a64d5b545d1d)
1 //****************************************************************************************
2 //
3 //	File:		NormalPulseView.cpp
4 //
5 //	Written by:	Daniel Switkin
6 //
7 //	Copyright 1999, Be Incorporated
8 //
9 //****************************************************************************************
10 
11 #include "NormalPulseView.h"
12 #include "Common.h"
13 #include "Pictures"
14 #include <interface/Bitmap.h>
15 #include <interface/Dragger.h>
16 #include <Window.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 
20 NormalPulseView::NormalPulseView(BRect rect) : PulseView(rect, "NormalPulseView") {
21 	rgb_color color = { 168, 168, 168, 0xff };
22 	SetViewColor(color);
23 	SetLowColor(color);
24 
25 	mode1->SetLabel("Mini Mode");
26 	mode1->SetMessage(new BMessage(PV_MINI_MODE));
27 	mode2->SetLabel("Deskbar Mode");
28 	mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
29 
30 	DetermineVendorAndProcessor();
31 
32 	// Allocate progress bars and button pointers
33 	system_info sys_info;
34 	get_system_info(&sys_info);
35 	progress_bars = new ProgressBar *[sys_info.cpu_count];
36 	cpu_buttons = new CPUButton *[sys_info.cpu_count];
37 
38 	// Set up the CPU activity bars and buttons
39 	for (int x = 0; x < sys_info.cpu_count; x++) {
40 		BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
41 			PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
42 			PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
43 		progress_bars[x] = new ProgressBar(r, "CPU Progress Bar");
44 		AddChild(progress_bars[x]);
45 
46 		r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
47 			CPUBUTTON_MLEFT + CPUBUTTON_WIDTH,
48 			CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT);
49 		char temp[4];
50 		sprintf(temp, "%d", x + 1);
51 		cpu_buttons[x] = new CPUButton(r, "CPUButton", temp, NULL);
52 		AddChild(cpu_buttons[x]);
53 
54 		//	If there is only 1 cpu it will be hidden below
55 		//	thus, no need to add the dragger as it will still
56 		//	be visible when replicants are turned on
57 		if (sys_info.cpu_count > 1) {
58 			BRect dragger_rect;
59 			dragger_rect = r;
60 			dragger_rect.top = dragger_rect.bottom;
61 			dragger_rect.left = dragger_rect.right;
62 			dragger_rect.bottom += 7;
63 			dragger_rect.right += 7;
64 			dragger_rect.OffsetBy(-1, -1);
65 			BDragger *dragger = new BDragger(dragger_rect, cpu_buttons[x], 0);
66 			AddChild(dragger);
67 		}
68 	}
69 
70 	if (sys_info.cpu_count == 1) {
71 		progress_bars[0]->MoveBy(-3, 12);
72 		cpu_buttons[0]->Hide();
73 	}
74 }
75 
76 int NormalPulseView::CalculateCPUSpeed() {
77 	system_info sys_info;
78 	get_system_info(&sys_info);
79 
80 	int target = sys_info.cpu_clock_speed / 1000000;
81 	int frac = target % 100;
82 	int delta = -frac;
83 	int at = 0;
84 	int freqs[] = { 100, 50, 25, 75, 33, 67, 20, 40, 60, 80, 10, 30, 70, 90 };
85 
86 	for (uint x = 0; x < sizeof(freqs) / sizeof(freqs[0]); x++) {
87 		int ndelta = freqs[x] - frac;
88 		if (abs(ndelta) < abs(delta)) {
89 			at = freqs[x];
90 			delta = ndelta;
91 		}
92 	}
93 	return target + delta;
94 }
95 
96 void NormalPulseView::DetermineVendorAndProcessor() {
97 	system_info sys_info;
98 	get_system_info(&sys_info);
99 
100 	// Initialize logos
101 	BRect r(0, 0, 63, 62);
102 	cpu_logo = new BBitmap(r, B_COLOR_8_BIT);
103 #if __POWERPC__
104 	cpu_logo->SetBits(Anim1, 11718, 0, B_COLOR_8_BIT);
105 #endif
106 #if __INTEL__
107 	if (sys_info.cpu_type < B_CPU_AMD_X86) {
108 		cpu_logo->SetBits(IntelLogo, 11718, 0, B_COLOR_8_BIT);
109 	} else {
110 		cpu_logo->SetBits(BlankLogo, 11718, 0, B_COLOR_8_BIT);
111 	}
112 #endif
113 
114 #if __INTEL__
115 	// Determine x86 vendor name - Intel just set for completeness
116 	switch (sys_info.cpu_type & B_CPU_X86_VENDOR_MASK) {
117 		case B_CPU_INTEL_X86:
118 			strcpy(vendor, "Intel");
119 			break;
120 		case B_CPU_AMD_X86:
121 			strcpy(vendor, "AMD");
122 			break;
123 		case B_CPU_CYRIX_X86:
124 			strcpy(vendor, "CYRIX");
125 			break;
126 		case B_CPU_IDT_X86:
127 			strcpy(vendor, "IDT");
128 			break;
129 		case B_CPU_RISE_X86:
130 			strcpy(vendor, "RISE");
131 			break;
132 		default:
133 			strcpy(vendor, "Unknown");
134 			break;
135 	}
136 #endif
137 
138 	// Determine CPU type
139 	switch(sys_info.cpu_type) {
140 #if __POWERPC__
141 		case B_CPU_PPC_603:
142 			strcpy(processor, "603");
143 			break;
144 		case B_CPU_PPC_603e:
145 			strcpy(processor, "603e");
146 			break;
147 		case B_CPU_PPC_750:
148 			strcpy(processor, "750");
149 			break;
150 		case B_CPU_PPC_604:
151 			strcpy(processor, "604");
152 			break;
153 		case B_CPU_PPC_604e:
154 			strcpy(processor, "604e");
155 			break;
156 #endif
157 
158 #if __INTEL__
159 		case B_CPU_X86:
160 			strcpy(processor, "Unknown x86");
161 			break;
162 		case B_CPU_INTEL_PENTIUM:
163 		case B_CPU_INTEL_PENTIUM75:
164 			strcpy(processor, "Pentium");
165 			break;
166 		case B_CPU_INTEL_PENTIUM_486_OVERDRIVE:
167 		case B_CPU_INTEL_PENTIUM75_486_OVERDRIVE:
168 			strcpy(processor, "Pentium OD");
169 			break;
170 		case B_CPU_INTEL_PENTIUM_MMX:
171 		case B_CPU_INTEL_PENTIUM_MMX_MODEL_8:
172 			strcpy(processor, "Pentium MMX");
173 			break;
174 		case B_CPU_INTEL_PENTIUM_PRO:
175 			strcpy(processor, "Pentium Pro");
176 			break;
177 		case B_CPU_INTEL_PENTIUM_II_MODEL_3:
178 		case B_CPU_INTEL_PENTIUM_II_MODEL_5:
179 			strcpy(processor, "Pentium II");
180 			break;
181 		case B_CPU_INTEL_CELERON:
182 			strcpy(processor, "Celeron");
183 			break;
184 		case B_CPU_INTEL_PENTIUM_III:
185 		case B_CPU_INTEL_PENTIUM_III_MODEL_8:
186 #ifdef OBOS_CPU_TYPES
187 		case B_CPU_INTEL_PENTIUM_III_MODEL_11:
188 #endif
189 			strcpy(processor, "Pentium III");
190 			break;
191 #ifdef OBOS_CPU_TYPES
192 		case B_CPU_INTEL_PENTIUM_IV:
193 		case B_CPU_INTEL_PENTIUM_IV_MODEL1:
194 		case B_CPU_INTEL_PENTIUM_IV_MODEL2:
195 		case B_CPU_INTEL_PENTIUM_IV_XEON:
196 			strcpy(processor, "Pentium IV");
197 			break;
198 #endif
199 		case B_CPU_AMD_K5_MODEL0:
200 		case B_CPU_AMD_K5_MODEL1:
201 		case B_CPU_AMD_K5_MODEL2:
202 		case B_CPU_AMD_K5_MODEL3:
203 			strcpy(processor, "K5");
204 			break;
205 		case B_CPU_AMD_K6_MODEL6:
206 		case B_CPU_AMD_K6_MODEL7:
207 			strcpy(processor, "K6");
208 			break;
209 		case B_CPU_AMD_K6_2:
210 			strcpy(processor, "K6-2");
211 			break;
212 		case B_CPU_AMD_K6_III:
213 #ifdef OBOS_CPU_TYPES
214 		case B_CPU_AMD_K6_III_MODEL2:
215 #endif
216 			strcpy(processor, "K6-III");
217 			break;
218 		case B_CPU_AMD_ATHLON_MODEL1:
219 #ifdef OBOS_CPU_TYPES
220 		case B_CPU_AMD_ATHLON_MODEL2:
221 		case B_CPU_AMD_ATHLON_THUNDERBIRD:
222 			strcpy(processor, "Athlon");
223 			break;
224 		case B_CPU_AMD_ATHLON_XP:
225 		case B_CPU_AMD_ATHLON_XP_MODEL2:
226 		case B_CPU_AMD_ATHLON_XP_MODEL3:
227 		case B_CPU_AMD_ATHLON_XP_MODEL_BARTON:
228 			strcpy(processor, "Athlon XP");
229 			break;
230 		case B_CPU_AMD_DURON:
231 			strcpy(processor, "Duron");
232 			break;
233 #endif
234 		case B_CPU_CYRIX_GXm:
235 			strcpy(processor, "GXm");
236 			break;
237 		case B_CPU_CYRIX_6x86MX:
238 			strcpy(processor, "6x86MX");
239 			break;
240 		case B_CPU_IDT_WINCHIP_C6:
241 			strcpy(processor, "WinChip C6");
242 			break;
243 		case B_CPU_IDT_WINCHIP_2:
244 			strcpy(processor, "WinChip 2");
245 			break;
246 		case B_CPU_RISE_mP6:
247 			strcpy(processor, "mP6");
248 			break;
249 #ifdef OBOS_CPU_TYPES
250 		case B_CPU_NATIONAL_GEODE_GX1:
251 			strcpy(processor, "Geode GX1");
252 			break;
253 #endif
254 #endif
255 		default:
256 			strcpy(processor, "Unknown");
257 			break;
258 	}
259 }
260 
261 void NormalPulseView::Draw(BRect rect) {
262 	PushState();
263 
264 	// Black frame
265 	SetHighColor(0, 0, 0);
266 	BRect frame = Bounds();
267 	frame.right--;
268 	frame.bottom--;
269 	StrokeRect(frame);
270 
271 	// Bevelled edges
272 	SetHighColor(255, 255, 255);
273 	StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
274 	StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
275 	SetHighColor(80, 80, 80);
276 	StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
277 	StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
278 
279 	// Dividing line
280 	SetHighColor(96, 96, 96);
281 	StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
282 	SetHighColor(255, 255, 255);
283 	StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
284 
285 	// Processor picture
286 	DrawBitmap(cpu_logo, BPoint(10, 10));
287 
288 #if __INTEL__
289 	// Do nothing in the case of Intel CPUs - they already have a logo
290 	if (strcmp(vendor, "Intel") != 0) {
291 		SetDrawingMode(B_OP_OVER);
292 		SetHighColor(240,240,240);
293 
294 		float width = StringWidth(vendor);
295 		MovePenTo(10 + (32 - width / 2), 30);
296 		DrawString(vendor);
297 	}
298 #endif
299 
300 	// Draw processor type and speed
301 	char buf[500];
302 	sprintf(buf, "%d MHz", CalculateCPUSpeed());
303 	SetDrawingMode(B_OP_OVER);
304 	SetHighColor(240, 240, 240);
305 
306 	float width = StringWidth(processor);
307 	MovePenTo(10 + (32 - width / 2), 48);
308 	DrawString(processor);
309 
310 	width = StringWidth(buf);
311 	MovePenTo(10 + (32 - width / 2), 60);
312 	DrawString(buf);
313 
314 	PopState();
315 }
316 
317 void NormalPulseView::Pulse() {
318 	// Don't recalculate and redraw if this view is hidden
319 	if (!IsHidden()) {
320 		Update();
321 		if (Window()->Lock()) {
322 			system_info sys_info;
323 			get_system_info(&sys_info);
324 
325 			// Set the value of each CPU bar
326 			for (int x = 0; x < sys_info.cpu_count; x++) {
327 				progress_bars[x]->Set(max_c(0, cpu_times[x] * 100));
328 			}
329 
330 			Sync();
331 			Window()->Unlock();
332 		}
333 	}
334 }
335 
336 void NormalPulseView::AttachedToWindow() {
337 	// Use a smaller font on x86 to accomodate longer processor names
338 	SetFont(be_bold_font);
339 #if __INTEL__
340 	SetFontSize(7);
341 #else
342 	SetFontSize(9);
343 #endif
344 	prev_time = system_time();
345 
346 	BMessenger messenger(Window());
347 	mode1->SetTarget(messenger);
348 	mode2->SetTarget(messenger);
349 	preferences->SetTarget(messenger);
350 	about->SetTarget(messenger);
351 
352 	system_info sys_info;
353 	get_system_info(&sys_info);
354 	if (sys_info.cpu_count >= 2) {
355 		for (int x = 0; x < sys_info.cpu_count; x++) {
356 			cpu_menu_items[x]->SetTarget(messenger);
357 		}
358 	}
359 }
360 
361 void NormalPulseView::UpdateColors(BMessage *message) {
362 	int32 color = message->FindInt32("color");
363 	bool fade = message->FindBool("fade");
364 	system_info sys_info;
365 	get_system_info(&sys_info);
366 
367 	for (int x = 0; x < sys_info.cpu_count; x++) {
368 		progress_bars[x]->UpdateColors(color, fade);
369 		cpu_buttons[x]->UpdateColors(color);
370 	}
371 }
372 
373 NormalPulseView::~NormalPulseView() {
374 	delete cpu_logo;
375 	delete cpu_buttons;
376 	delete progress_bars;
377 }
378