vfs: check userland buffers before reading them.
[haiku.git] / src / apps / pulse / NormalPulseView.cpp
blob14c112ea3206ab5ae57ea5ff56288ca48638fce5
1 //*****************************************************************************
2 //
3 // File: NormalPulseView.cpp
4 //
5 // Written by: Daniel Switkin
6 //
7 // Copyright 1999, Be Incorporated
8 //
9 //*****************************************************************************
12 #include "NormalPulseView.h"
13 #include "Common.h"
14 #include "Pictures"
16 #include <Catalog.h>
17 #include <Bitmap.h>
18 #include <Dragger.h>
19 #include <Window.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
25 #include <cpu_type.h>
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "NormalPulseView"
31 float
32 max_font_size(BFont font, const char* text, float maxSize, float maxWidth)
34 const float steps = 0.5f;
36 for (float size = maxSize; size > 4; size -= steps) {
37 font.SetSize(size);
38 if (font.StringWidth(text) <= maxWidth)
39 return size;
42 return 4;
46 // #pragma mark -
49 NormalPulseView::NormalPulseView(BRect rect)
50 : PulseView(rect, "NormalPulseView"),
51 fHasBrandLogo(false)
53 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
54 SetLowUIColor(ViewUIColor());
56 mode1->SetLabel(B_TRANSLATE("Mini mode"));
57 mode1->SetMessage(new BMessage(PV_MINI_MODE));
58 mode2->SetLabel(B_TRANSLATE("Deskbar mode"));
59 mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
61 DetermineVendorAndProcessor();
63 // Allocate progress bars and button pointers
64 system_info systemInfo;
65 get_system_info(&systemInfo);
66 fCpuCount = systemInfo.cpu_count;
67 fProgressBars = new ProgressBar *[fCpuCount];
68 fCpuButtons = new CPUButton *[fCpuCount];
70 // Set up the CPU activity bars and buttons
71 for (int x = 0; x < fCpuCount; x++) {
72 BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
73 PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
74 PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
75 char* str2 = (char *)B_TRANSLATE("CPU progress bar");
76 fProgressBars[x] = new ProgressBar(r, str2);
77 AddChild(fProgressBars[x]);
79 r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
80 CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7,
81 CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7);
82 char temp[4];
83 sprintf(temp, "%d", x + 1);
84 fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL);
85 AddChild(fCpuButtons[x]);
88 if (fCpuCount == 1) {
89 fProgressBars[0]->MoveBy(-3, 12);
90 fCpuButtons[0]->Hide();
95 NormalPulseView::~NormalPulseView()
97 delete fCpuLogo;
98 delete[] fCpuButtons;
99 delete[] fProgressBars;
103 void
104 NormalPulseView::CalculateFontSizes()
106 BFont font;
107 GetFont(&font);
109 fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
111 if (!fHasBrandLogo)
112 fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
116 void
117 NormalPulseView::DetermineVendorAndProcessor()
119 system_info sys_info;
120 get_system_info(&sys_info);
122 // Initialize logo
124 fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
125 unsigned char *logo = BlankLogo;
127 #if __POWERPC__
128 logo = PowerPCLogo;
129 #elif __INTEL__
130 uint32 topologyNodeCount = 0;
131 cpu_topology_node_info* topology = NULL;
133 get_cpu_topology_info(NULL, &topologyNodeCount);
134 if (topologyNodeCount != 0)
135 topology = new cpu_topology_node_info[topologyNodeCount];
136 get_cpu_topology_info(topology, &topologyNodeCount);
138 for (uint32 i = 0; i < topologyNodeCount; i++) {
139 if (topology[i].type == B_TOPOLOGY_PACKAGE) {
140 switch (topology[i].data.package.vendor) {
141 case B_CPU_VENDOR_INTEL:
142 logo = IntelLogo;
143 break;
145 case B_CPU_VENDOR_AMD:
146 logo = AmdLogo;
147 break;
149 default:
150 break;
153 break;
157 delete[] topology;
158 #endif
160 fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8);
161 fHasBrandLogo = (logo != BlankLogo);
163 get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
167 void
168 NormalPulseView::Draw(BRect rect)
170 PushState();
172 // Black frame
173 SetHighColor(0, 0, 0);
174 BRect frame = Bounds();
175 frame.right--;
176 frame.bottom--;
177 StrokeRect(frame);
179 // Bevelled edges
180 SetHighColor(255, 255, 255);
181 StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
182 StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
183 SetHighColor(80, 80, 80);
184 StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
185 StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
187 // Dividing line
188 SetHighColor(96, 96, 96);
189 StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
190 SetHighColor(255, 255, 255);
191 StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
193 // Processor picture
194 DrawBitmap(fCpuLogo, BPoint(10, 10));
196 #if __INTEL__
197 // Do nothing in the case of non-Intel CPUs - they already have a logo
198 if (!fHasBrandLogo) {
199 SetDrawingMode(B_OP_OVER);
200 SetHighColor(240, 240, 240);
201 SetFontSize(fVendorFontSize);
203 float width = StringWidth(fVendor);
204 MovePenTo(10 + (32 - width / 2), 30);
205 DrawString(fVendor);
207 #endif
209 // Draw processor type and speed
210 SetDrawingMode(B_OP_OVER);
211 SetHighColor(240, 240, 240);
213 SetFontSize(fProcessorFontSize);
214 float width = StringWidth(fProcessor);
215 MovePenTo(10 + (32 - width / 2), 48);
216 DrawString(fProcessor);
218 char buffer[64];
219 int32 cpuSpeed = get_rounded_cpu_speed();
220 if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0)
221 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f);
222 else
223 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed);
225 // We can't assume anymore that a CPU clock speed is always static.
226 // Let's compute the best font size for the CPU speed string each time...
227 BFont font;
228 GetFont(&font);
229 SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f));
230 width = StringWidth(buffer);
231 MovePenTo(10 + (32 - width / 2), 60);
232 DrawString(buffer);
234 PopState();
238 void
239 NormalPulseView::Pulse()
241 // Don't recalculate and redraw if this view is hidden
242 if (!IsHidden()) {
243 Update();
244 if (Window()->Lock()) {
245 // Set the value of each CPU bar
246 for (int x = 0; x < fCpuCount; x++) {
247 fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100));
250 Sync();
251 Window()->Unlock();
257 void
258 NormalPulseView::AttachedToWindow()
260 SetFont(be_bold_font);
261 CalculateFontSizes();
263 fPreviousTime = system_time();
265 BMessenger messenger(Window());
266 mode1->SetTarget(messenger);
267 mode2->SetTarget(messenger);
268 preferences->SetTarget(messenger);
269 about->SetTarget(messenger);
271 system_info sys_info;
272 get_system_info(&sys_info);
273 if (sys_info.cpu_count >= 2) {
274 for (unsigned int x = 0; x < sys_info.cpu_count; x++)
275 cpu_menu_items[x]->SetTarget(messenger);
280 void
281 NormalPulseView::UpdateColors(BMessage *message)
283 int32 color = message->FindInt32("color");
284 bool fade = message->FindBool("fade");
285 system_info sys_info;
286 get_system_info(&sys_info);
288 for (unsigned int x = 0; x < sys_info.cpu_count; x++) {
289 fProgressBars[x]->UpdateColors(color, fade);
290 fCpuButtons[x]->UpdateColors(color);