vfs: check userland buffers before reading them.
[haiku.git] / src / apps / pulse / CPUButton.cpp
blob42701cfdf5e5ccbefad4eacef9ff5654b8f63d85
1 //*****************************************************************************
2 //
3 // File: CPUButton.cpp
4 //
5 // Written by: Daniel Switkin
6 //
7 // Copyright 1999, Be Incorporated
8 //
9 //*****************************************************************************
11 #include "CPUButton.h"
13 #include <stdlib.h>
14 #include <string.h>
16 #include <Alert.h>
17 #include <Catalog.h>
18 #include <Dragger.h>
19 #include <PopUpMenu.h>
20 #include <TextView.h>
21 #include <ViewPrivate.h>
23 #include <syscalls.h>
25 #include "PulseApp.h"
26 #include "PulseView.h"
27 #include "Common.h"
29 #undef B_TRANSLATION_CONTEXT
30 #define B_TRANSLATION_CONTEXT "CPUButton"
33 CPUButton::CPUButton(BRect rect, const char *name, const char *label, BMessage *message)
34 : BControl(rect, name, label, message, B_FOLLOW_NONE, B_WILL_DRAW)
36 SetValue(B_CONTROL_ON);
37 SetViewColor(B_TRANSPARENT_COLOR);
38 fReplicant = false;
40 _InitData();
44 CPUButton::CPUButton(BMessage *message)
45 : BControl(message)
47 fReplicant = true;
49 /* We remove the dragger if we are in deskbar */
50 if (CountChildren() > 1)
51 RemoveChild(ChildAt(1));
53 ResizeTo(CPUBUTTON_WIDTH, CPUBUTTON_HEIGHT);
55 _InitData();
59 CPUButton::~CPUButton()
64 void
65 CPUButton::_InitData()
67 fOffColor.red = fOffColor.green = fOffColor.blue = 184;
68 fOffColor.alpha = 255;
70 fCPU = atoi(Label()) - 1;
74 void
75 CPUButton::_AddDragger()
77 BRect rect(Bounds());
78 rect.top = rect.bottom - 7;
79 rect.left = rect.right - 7;
80 BDragger* dragger = new BDragger(rect, this,
81 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
82 AddChild(dragger);
86 //! Redraw the button depending on whether it's up or down
87 void
88 CPUButton::Draw(BRect rect)
90 bool value = (bool)Value();
91 SetHighColor(value ? fOnColor : fOffColor);
93 if (!fReplicant) {
94 SetLowColor(Parent()->LowColor());
95 FillRect(Bounds(), B_SOLID_LOW);
98 BRect bounds = Bounds();
99 if (fReplicant && !fReplicantInDeskbar) {
100 bounds.bottom -= 4;
101 bounds.right -= 4;
102 } else if (!fReplicant) {
103 bounds.bottom -= 7;
104 bounds.right -= 7;
106 BRect color_rect(bounds);
107 color_rect.InsetBy(2, 2);
108 if (value) {
109 color_rect.bottom -= 1;
110 color_rect.right -= 1;
112 FillRect(bounds);
114 if (value)
115 SetHighColor(80, 80, 80);
116 else
117 SetHighColor(255, 255, 255);
119 BPoint start(0, 0);
120 BPoint end(bounds.right, 0);
121 StrokeLine(start, end);
122 end.Set(0, bounds.bottom);
123 StrokeLine(start, end);
125 if (value)
126 SetHighColor(32, 32, 32);
127 else
128 SetHighColor(216, 216, 216);
130 start.Set(1, 1);
131 end.Set(bounds.right - 1, 1);
132 StrokeLine(start, end);
133 end.Set(1, bounds.bottom - 1);
134 StrokeLine(start, end);
136 if (value)
137 SetHighColor(216, 216, 216);
138 else
139 SetHighColor(80, 80, 80);
141 start.Set(bounds.left + 1, bounds.bottom - 1);
142 end.Set(bounds.right - 1, bounds.bottom - 1);
143 StrokeLine(start, end);
144 start.Set(bounds.right - 1, bounds.top + 1);
145 StrokeLine(start, end);
147 if (value)
148 SetHighColor(255, 255, 255);
149 else
150 SetHighColor(32, 32, 32);
152 start.Set(bounds.left, bounds.bottom);
153 end.Set(bounds.right, bounds.bottom);
154 StrokeLine(start, end);
155 start.Set(bounds.right, bounds.top);
156 StrokeLine(start, end);
158 if (value) {
159 SetHighColor(0, 0, 0);
160 start.Set(bounds.left + 2, bounds.bottom - 2);
161 end.Set(bounds.right - 2, bounds.bottom - 2);
162 StrokeLine(start, end);
163 start.Set(bounds.right - 2, bounds.top + 2);
164 StrokeLine(start, end);
167 // Try to keep the text centered
168 BFont font;
169 GetFont(&font);
170 int label_width = (int)font.StringWidth(Label());
171 int rect_width = bounds.IntegerWidth() - 1;
172 int rect_height = bounds.IntegerHeight();
173 font_height fh;
174 font.GetHeight(&fh);
175 int label_height = (int)fh.ascent;
176 int x_pos = (int)(((double)(rect_width - label_width) / 2.0) + 0.5);
177 int y_pos = (rect_height - label_height) / 2 + label_height;
179 MovePenTo(x_pos, y_pos);
180 SetHighColor(0, 0, 0);
181 SetDrawingMode(B_OP_OVER);
182 DrawString(Label());
186 //! Track the mouse without blocking the window
187 void
188 CPUButton::MouseDown(BPoint point)
190 BPoint mousePosition;
191 uint32 mouseButtons;
193 GetMouse(&mousePosition, &mouseButtons);
195 if ((B_PRIMARY_MOUSE_BUTTON & mouseButtons) != 0) {
196 SetValue(!Value());
197 SetTracking(true);
198 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
199 } else if ((B_SECONDARY_MOUSE_BUTTON & mouseButtons) != 0
200 && fReplicantInDeskbar) {
201 BPopUpMenu *menu = new BPopUpMenu(B_TRANSLATE("Deskbar menu"));
202 menu->AddItem(new BMenuItem(B_TRANSLATE("About Pulse" B_UTF8_ELLIPSIS),
203 new BMessage(B_ABOUT_REQUESTED)));
204 menu->AddSeparatorItem();
205 menu->AddItem(new BMenuItem(B_TRANSLATE("Remove replicant"),
206 new BMessage(kDeleteReplicant)));
207 menu->SetTargetForItems(this);
209 ConvertToScreen(&point);
210 menu->Go(point, true, true, true);
215 void
216 CPUButton::MouseUp(BPoint point)
218 if (IsTracking()) {
219 if (Bounds().Contains(point))
220 Invoke();
222 SetTracking(false);
227 void
228 CPUButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
230 if (IsTracking()) {
231 if (transit == B_ENTERED_VIEW || transit == B_EXITED_VIEW)
232 SetValue(!Value());
237 status_t
238 CPUButton::Invoke(BMessage *message)
240 if (!LastEnabledCPU(fCPU)) {
241 _kern_set_cpu_enabled(fCPU, Value());
242 } else {
243 BAlert *alert = new BAlert(B_TRANSLATE("Info"),
244 B_TRANSLATE("You can't disable the last active CPU."),
245 B_TRANSLATE("OK"));
246 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
247 alert->Go(NULL);
248 SetValue(!Value());
251 return B_OK;
255 CPUButton *
256 CPUButton::Instantiate(BMessage *data)
258 if (!validate_instantiation(data, "CPUButton"))
259 return NULL;
261 return new CPUButton(data);
265 status_t
266 CPUButton::Archive(BMessage *data, bool deep) const
268 BControl::Archive(data, deep);
269 data->AddString("add_on", APP_SIGNATURE);
270 data->AddString("class", "CPUButton");
271 return B_OK;
275 void
276 CPUButton::MessageReceived(BMessage *message)
278 switch (message->what) {
279 case B_ABOUT_REQUESTED: {
280 PulseApp::ShowAbout(false);
281 break;
283 case PV_REPLICANT_PULSE: {
284 // Make sure we're consistent with our CPU
285 if (_kern_cpu_enabled(fCPU) != Value() && !IsTracking())
286 SetValue(!Value());
287 break;
289 case kDeleteReplicant: {
290 Window()->PostMessage(kDeleteReplicant, this, NULL);
291 break;
293 default:
294 BControl::MessageReceived(message);
295 break;
300 void
301 CPUButton::UpdateColors(int32 color)
303 fOnColor.red = (color & 0xff000000) >> 24;
304 fOnColor.green = (color & 0x00ff0000) >> 16;
305 fOnColor.blue = (color & 0x0000ff00) >> 8;
306 Draw(Bounds());
310 void
311 CPUButton::AttachedToWindow()
313 SetTarget(this);
314 SetFont(be_plain_font);
315 SetFontSize(10);
317 fReplicantInDeskbar = false;
319 if (fReplicant) {
320 if (strcmp(Window()->Title(), B_TRANSLATE("Deskbar"))) {
321 // Make room for dragger
322 ResizeBy(4, 4);
324 _AddDragger();
325 } else
326 fReplicantInDeskbar = true;
328 Prefs *prefs = new Prefs();
329 UpdateColors(prefs->normal_bar_color);
330 delete prefs;
331 } else {
332 PulseApp *pulseapp = (PulseApp *)be_app;
333 UpdateColors(pulseapp->prefs->normal_bar_color);
334 _AddDragger();
337 BMessenger messenger(this);
338 fPulseRunner = new BMessageRunner(messenger, new BMessage(PV_REPLICANT_PULSE),
339 200000, -1);
343 void
344 CPUButton::DetachedFromWindow()
346 delete fPulseRunner;