xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
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 			strcpy(processor, "Pentium III");
186 			break;
187 		case B_CPU_AMD_K5_MODEL0:
188 		case B_CPU_AMD_K5_MODEL1:
189 		case B_CPU_AMD_K5_MODEL2:
190 		case B_CPU_AMD_K5_MODEL3:
191 			strcpy(processor, "K5");
192 			break;
193 		case B_CPU_AMD_K6_MODEL6:
194 		case B_CPU_AMD_K6_MODEL7:
195 			strcpy(processor, "K6");
196 			break;
197 		case B_CPU_AMD_K6_2:
198 			strcpy(processor, "K6-2");
199 			break;
200 		case B_CPU_AMD_K6_III:
201 			strcpy(processor, "K6-III");
202 			break;
203 		case B_CPU_AMD_ATHLON_MODEL1:
204 			strcpy(processor, "Athlon");
205 			break;
206 		case B_CPU_CYRIX_GXm:
207 			strcpy(processor, "GXm");
208 			break;
209 		case B_CPU_CYRIX_6x86MX:
210 			strcpy(processor, "6x86MX");
211 			break;
212 		case B_CPU_IDT_WINCHIP_C6:
213 			strcpy(processor, "WinChip C6");
214 			break;
215 		case B_CPU_IDT_WINCHIP_2:
216 			strcpy(processor, "WinChip 2");
217 			break;
218 		case B_CPU_RISE_mP6:
219 			strcpy(processor, "mP6");
220 			break;
221 #endif
222 		default:
223 			strcpy(processor, "Unknown");
224 			break;
225 	}
226 }
227 
228 void NormalPulseView::Draw(BRect rect) {
229 	PushState();
230 
231 	// Black frame
232 	SetHighColor(0, 0, 0);
233 	BRect frame = Bounds();
234 	frame.right--;
235 	frame.bottom--;
236 	StrokeRect(frame);
237 
238 	// Bevelled edges
239 	SetHighColor(255, 255, 255);
240 	StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
241 	StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
242 	SetHighColor(80, 80, 80);
243 	StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
244 	StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
245 
246 	// Dividing line
247 	SetHighColor(96, 96, 96);
248 	StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
249 	SetHighColor(255, 255, 255);
250 	StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
251 
252 	// Processor picture
253 	DrawBitmap(cpu_logo, BPoint(10, 10));
254 
255 #if __INTEL__
256 	// Do nothing in the case of Intel CPUs - they already have a logo
257 	if (strcmp(vendor, "Intel") != 0) {
258 		SetDrawingMode(B_OP_OVER);
259 		SetHighColor(240,240,240);
260 
261 		float width = StringWidth(vendor);
262 		MovePenTo(10 + (32 - width / 2), 30);
263 		DrawString(vendor);
264 	}
265 #endif
266 
267 	// Draw processor type and speed
268 	char buf[500];
269 	sprintf(buf, "%d MHz", CalculateCPUSpeed());
270 	SetDrawingMode(B_OP_OVER);
271 	SetHighColor(240, 240, 240);
272 
273 	float width = StringWidth(processor);
274 	MovePenTo(10 + (32 - width / 2), 48);
275 	DrawString(processor);
276 
277 	width = StringWidth(buf);
278 	MovePenTo(10 + (32 - width / 2), 60);
279 	DrawString(buf);
280 
281 	PopState();
282 }
283 
284 void NormalPulseView::Pulse() {
285 	// Don't recalculate and redraw if this view is hidden
286 	if (!IsHidden()) {
287 		Update();
288 		if (Window()->Lock()) {
289 			system_info sys_info;
290 			get_system_info(&sys_info);
291 
292 			// Set the value of each CPU bar
293 			for (int x = 0; x < sys_info.cpu_count; x++) {
294 				progress_bars[x]->Set(max_c(0, cpu_times[x] * 100));
295 			}
296 
297 			Sync();
298 			Window()->Unlock();
299 		}
300 	}
301 }
302 
303 void NormalPulseView::AttachedToWindow() {
304 	// Use a smaller font on x86 to accomodate longer processor names
305 	SetFont(be_bold_font);
306 #if __INTEL__
307 	SetFontSize(7);
308 #else
309 	SetFontSize(9);
310 #endif
311 	prev_time = system_time();
312 
313 	BMessenger messenger(Window());
314 	mode1->SetTarget(messenger);
315 	mode2->SetTarget(messenger);
316 	preferences->SetTarget(messenger);
317 	about->SetTarget(messenger);
318 
319 	system_info sys_info;
320 	get_system_info(&sys_info);
321 	if (sys_info.cpu_count >= 2) {
322 		for (int x = 0; x < sys_info.cpu_count; x++) {
323 			cpu_menu_items[x]->SetTarget(messenger);
324 		}
325 	}
326 }
327 
328 void NormalPulseView::UpdateColors(BMessage *message) {
329 	int32 color = message->FindInt32("color");
330 	bool fade = message->FindBool("fade");
331 	system_info sys_info;
332 	get_system_info(&sys_info);
333 
334 	for (int x = 0; x < sys_info.cpu_count; x++) {
335 		progress_bars[x]->UpdateColors(color, fade);
336 		cpu_buttons[x]->UpdateColors(color);
337 	}
338 }
339 
340 NormalPulseView::~NormalPulseView() {
341 	delete cpu_logo;
342 	delete cpu_buttons;
343 	delete progress_bars;
344 }
345