vfs: check userland buffers before reading them.
[haiku.git] / src / apps / pulse / PulseApp.cpp
blob75445e777198c5f7d435bd5bda4012738d40d0da
1 /*
2 * Copyright 2002-2005 Haiku
3 * Distributed under the terms of the MIT license.
5 * Updated by Sikosis (beos@gravity24hr.com)
7 * Copyright 1999, Be Incorporated. All Rights Reserved.
8 * This file may be used under the terms of the Be Sample Code License.
10 * Written by: Daniel Switkin
14 #include "PulseApp.h"
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <getopt.h>
21 #include <Alert.h>
22 #include <Catalog.h>
23 #include <Deskbar.h>
24 #include <Rect.h>
25 #include <TextView.h>
27 #include <syscalls.h>
29 #include "Common.h"
30 #include "PulseWindow.h"
31 #include "DeskbarPulseView.h"
33 #undef B_TRANSLATION_CONTEXT
34 #define B_TRANSLATION_CONTEXT "PulseApp"
37 PulseApp::PulseApp(int argc, char **argv)
38 : BApplication(APP_SIGNATURE)
40 prefs = new Prefs();
42 int mini = false, deskbar = false, normal = false;
43 uint32 framecolor = 0, activecolor = 0, idlecolor = 0;
45 while (1) {
46 int option_index = 0;
47 static struct option long_options[] = {
48 {"deskbar", 0, &deskbar, true},
49 {"width", 1, 0, 'w'},
50 {"framecolor", 1, 0, 0},
51 {"activecolor", 1, 0, 0},
52 {"idlecolor", 1, 0, 0},
53 {"mini", 0, &mini, true},
54 {"normal", 0, &normal, true},
55 {"help", 0, 0, 'h'},
56 {0,0,0,0}
58 int c = getopt_long(argc, argv, "hw:", long_options, &option_index);
59 if (c == -1)
60 break;
62 switch (c) {
63 case 0:
64 switch (option_index) {
65 case 2: /* framecolor */
66 case 3: /* activecolor */
67 case 4: /* idlecolor */
68 uint32 rgb = strtoul(optarg, NULL, 0);
69 rgb = rgb << 8;
70 rgb |= 0x000000ff;
72 switch (option_index) {
73 case 2:
74 framecolor = rgb;
75 break;
76 case 3:
77 activecolor = rgb;
78 break;
79 case 4:
80 idlecolor = rgb;
81 break;
83 break;
85 break;
86 case 'w':
87 prefs->deskbar_icon_width = atoi(optarg);
88 if (prefs->deskbar_icon_width < GetMinimumViewWidth())
89 prefs->deskbar_icon_width = GetMinimumViewWidth();
90 else if (prefs->deskbar_icon_width > 50) prefs->deskbar_icon_width = 50;
91 break;
92 case 'h':
93 case '?':
94 Usage();
95 break;
96 default:
97 printf("?? getopt returned character code 0%o ??\n", c);
98 break;
102 if (deskbar) {
103 prefs->window_mode = DESKBAR_MODE;
104 if (activecolor != 0)
105 prefs->deskbar_active_color = activecolor;
106 if (idlecolor != 0)
107 prefs->deskbar_idle_color = idlecolor;
108 if (framecolor != 0)
109 prefs->deskbar_frame_color = framecolor;
110 } else if (mini) {
111 prefs->window_mode = MINI_WINDOW_MODE;
112 if (activecolor != 0)
113 prefs->mini_active_color = activecolor;
114 if (idlecolor != 0)
115 prefs->mini_idle_color = idlecolor;
116 if (framecolor != 0)
117 prefs->mini_frame_color = framecolor;
118 } else if (normal)
119 prefs->window_mode = NORMAL_WINDOW_MODE;
121 prefs->Save();
122 BuildPulse();
126 void
127 PulseApp::BuildPulse()
129 // Remove this case for Deskbar add on API
131 // If loading the replicant fails, launch the app instead
132 // This allows having the replicant and the app open simultaneously
133 if (prefs->window_mode == DESKBAR_MODE && LoadInDeskbar()) {
134 PostMessage(new BMessage(B_QUIT_REQUESTED));
135 return;
136 } else if (prefs->window_mode == DESKBAR_MODE)
137 prefs->window_mode = NORMAL_WINDOW_MODE;
139 PulseWindow *pulseWindow = NULL;
141 if (prefs->window_mode == MINI_WINDOW_MODE)
142 pulseWindow = new PulseWindow(prefs->mini_window_rect);
143 else
144 pulseWindow = new PulseWindow(prefs->normal_window_rect);
146 pulseWindow->MoveOnScreen(B_MOVE_IF_PARTIALLY_OFFSCREEN);
147 pulseWindow->Show();
151 PulseApp::~PulseApp()
153 // Load the replicant after we save our preferences so they don't
154 // get overwritten by DeskbarPulseView's instance
155 prefs->Save();
156 if (prefs->window_mode == DESKBAR_MODE)
157 LoadInDeskbar();
159 delete prefs;
163 void
164 PulseApp::AboutRequested()
166 PulseApp::ShowAbout(true);
170 void
171 PulseApp::ShowAbout(bool asApplication)
173 // static version to be used in replicant mode
174 BString name;
175 if (asApplication)
176 name = B_TRANSLATE_SYSTEM_NAME("Pulse");
177 else
178 name = B_TRANSLATE("Pulse");
180 BString message = B_TRANSLATE(
181 "%s\n\nBy David Ramsey and Arve Hjønnevåg\n"
182 "Revised by Daniel Switkin\n");
183 message.ReplaceFirst("%s", name);
184 BAlert *alert = new BAlert(B_TRANSLATE("Info"),
185 message.String(), B_TRANSLATE("OK"));
187 BTextView* view = alert->TextView();
188 BFont font;
190 view->SetStylable(true);
191 view->GetFont(&font);
193 font.SetSize(18);
194 font.SetFace(B_BOLD_FACE);
195 view->SetFontAndColor(0, name.Length(), &font);
196 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
197 // Use the asynchronous version so we don't block the window's thread
198 alert->Go(NULL);
201 // #pragma mark -
204 /** Make sure we don't disable the last CPU - this is needed by
205 * descendants of PulseView for the popup menu and for CPUButton
206 * both as a replicant and not.
209 bool
210 LastEnabledCPU(unsigned int my_cpu)
212 system_info sys_info;
213 get_system_info(&sys_info);
214 if (sys_info.cpu_count == 1)
215 return true;
217 for (unsigned int x = 0; x < sys_info.cpu_count; x++) {
218 if (x == my_cpu)
219 continue;
220 if (_kern_cpu_enabled(x) == 1)
221 return false;
223 return true;
227 /** Ensure that the mini mode and deskbar mode always show an indicator
228 * for each CPU, at least one pixel wide.
232 GetMinimumViewWidth()
234 system_info sys_info;
235 get_system_info(&sys_info);
236 return (sys_info.cpu_count * 2) + 1;
240 void
241 Usage()
243 printf(B_TRANSLATE("Usage: Pulse [--mini] [-w width] [--width=width]\n"
244 "\t[--deskbar] [--normal] [--framecolor 0xrrggbb]\n"
245 "\t[--activecolor 0xrrggbb] [--idlecolor 0xrrggbb]\n"));
246 exit(0);
250 bool
251 LoadInDeskbar()
253 PulseApp *pulseapp = (PulseApp *)be_app;
254 BDeskbar *deskbar = new BDeskbar();
255 // Don't allow two copies in the Deskbar at once
256 if (deskbar->HasItem("DeskbarPulseView")) {
257 delete deskbar;
258 return false;
261 // Must be 16 pixels high, the width is retrieved from the Prefs class
262 int width = pulseapp->prefs->deskbar_icon_width;
263 int min_width = GetMinimumViewWidth();
264 if (width < min_width) {
265 pulseapp->prefs->deskbar_icon_width = min_width;
266 width = min_width;
269 BRect rect(0, 0, width - 1, 15);
270 DeskbarPulseView *replicant = new DeskbarPulseView(rect);
271 status_t err = deskbar->AddItem(replicant);
272 delete replicant;
273 delete deskbar;
274 if (err != B_OK) {
275 BString message;
276 snprintf(message.LockBuffer(512), 512,
277 B_TRANSLATE("Installing in Deskbar failed\n%s"), strerror(err));
278 message.UnlockBuffer();
279 BAlert *alert = new BAlert(B_TRANSLATE("Error"),
280 message.String(), B_TRANSLATE("OK"));
281 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
282 alert->Go(NULL);
283 return false;
286 return true;
291 main(int argc, char **argv)
293 PulseApp *pulseapp = new PulseApp(argc, argv);
294 pulseapp->Run();
295 delete pulseapp;
296 return 0;