xref: /haiku/src/apps/pulse/PulseApp.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 /*
2  * Copyright 2002-2005 Haiku
3  * Distributed under the terms of the MIT license.
4  *
5  * Updated by Sikosis (beos@gravity24hr.com)
6  *
7  * Copyright 1999, Be Incorporated. All Rights Reserved.
8  * This file may be used under the terms of the Be Sample Code License.
9  *
10  * Written by:	Daniel Switkin
11  */
12 
13 
14 #include "PulseApp.h"
15 #include "Common.h"
16 #include "PulseWindow.h"
17 #include "DeskbarPulseView.h"
18 
19 #include <Alert.h>
20 #include <Rect.h>
21 #include <Deskbar.h>
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <getopt.h>
27 
28 
29 PulseApp::PulseApp(int argc, char **argv)
30 	: BApplication(APP_SIGNATURE)
31 {
32 	prefs = new Prefs();
33 
34 	int mini = false, deskbar = false, normal = false;
35 	uint32 framecolor = 0, activecolor = 0, idlecolor = 0;
36 
37 	while (1) {
38 		int option_index = 0;
39 		static struct option long_options[] = {
40 			{"deskbar", 0, &deskbar, true},
41 			{"width", 1, 0, 'w'},
42 			{"framecolor", 1, 0, 0},
43 			{"activecolor", 1, 0, 0},
44 			{"idlecolor", 1, 0, 0},
45 			{"mini", 0, &mini, true},
46 			{"normal", 0, &normal, true},
47 			{"help", 0, 0, 'h'},
48 			{0,0,0,0}
49 		};
50 		int c = getopt_long(argc, argv, "hw:", long_options, &option_index);
51 		if (c == -1)
52 			break;
53 
54 		switch (c) {
55 			case 0:
56 				switch (option_index) {
57 					case 2: /* framecolor */
58 					case 3: /* activecolor */
59 					case 4: /* idlecolor */
60 						uint32 rgb = strtoul(optarg, NULL, 0);
61 						rgb = rgb << 8;
62 						rgb |= 0x000000ff;
63 
64 						switch (option_index) {
65 							case 2:
66 								framecolor = rgb;
67 								break;
68 							case 3:
69 								activecolor = rgb;
70 								break;
71 							case 4:
72 								idlecolor = rgb;
73 								break;
74 						}
75 						break;
76 				}
77 				break;
78 			case 'w':
79 				prefs->deskbar_icon_width = atoi(optarg);
80 				if (prefs->deskbar_icon_width < GetMinimumViewWidth())
81 					prefs->deskbar_icon_width = GetMinimumViewWidth();
82 				else if (prefs->deskbar_icon_width > 50) prefs->deskbar_icon_width = 50;
83 				break;
84 			case 'h':
85 			case '?':
86 				Usage();
87 				break;
88 			default:
89 				printf("?? getopt returned character code 0%o ??\n", c);
90 				break;
91 		}
92 	}
93 
94 	if (deskbar) {
95 		prefs->window_mode = DESKBAR_MODE;
96 		if (activecolor != 0)
97 			prefs->deskbar_active_color = activecolor;
98 		if (idlecolor != 0)
99 			prefs->deskbar_idle_color = idlecolor;
100 		if (framecolor != 0)
101 			prefs->deskbar_frame_color = framecolor;
102 	} else if (mini) {
103 		prefs->window_mode = MINI_WINDOW_MODE;
104 		if (activecolor != 0)
105 			prefs->mini_active_color = activecolor;
106 		if (idlecolor != 0)
107 			prefs->mini_idle_color = idlecolor;
108 		if (framecolor != 0)
109 			prefs->mini_frame_color = framecolor;
110 	} else if (normal)
111 		prefs->window_mode = NORMAL_WINDOW_MODE;
112 
113 	prefs->Save();
114 	BuildPulse();
115 }
116 
117 
118 void
119 PulseApp::BuildPulse()
120 {
121 	// Remove this case for Deskbar add on API
122 
123 	// If loading the replicant fails, launch the app instead
124 	// This allows having the replicant and the app open simultaneously
125 	if (prefs->window_mode == DESKBAR_MODE && LoadInDeskbar()) {
126 		PostMessage(new BMessage(B_QUIT_REQUESTED));
127 		return;
128 	} else
129 		prefs->window_mode = NORMAL_WINDOW_MODE;
130 
131 	PulseWindow *pulseWindow = NULL;
132 
133 	if (prefs->window_mode == MINI_WINDOW_MODE)
134 		pulseWindow = new PulseWindow(prefs->mini_window_rect);
135 	else
136 		pulseWindow = new PulseWindow(prefs->normal_window_rect);
137 
138 	pulseWindow->MoveOnScreen();
139 	pulseWindow->Show();
140 }
141 
142 
143 PulseApp::~PulseApp()
144 {
145 	// Load the replicant after we save our preferences so they don't
146 	// get overwritten by DeskbarPulseView's instance
147 	prefs->Save();
148 	if (prefs->window_mode == DESKBAR_MODE)
149 		LoadInDeskbar();
150 
151 	delete prefs;
152 }
153 
154 
155 //	#pragma mark -
156 
157 
158 /** Make sure we don't disable the last CPU - this is needed by
159  *	descendants of PulseView for the popup menu and for CPUButton
160  *	both as a replicant and not.
161  */
162 
163 bool
164 LastEnabledCPU(int my_cpu)
165 {
166 	system_info sys_info;
167 	get_system_info(&sys_info);
168 	if (sys_info.cpu_count == 1)
169 		return true;
170 
171 	for (int x = 0; x < sys_info.cpu_count; x++) {
172 		if (x == my_cpu)
173 			continue;
174 		if (_kget_cpu_state_(x) == 1)
175 			return false;
176 	}
177 	return true;
178 }
179 
180 
181 /**	Ensure that the mini mode and deskbar mode always show an indicator
182  *	for each CPU, at least one pixel wide.
183  */
184 
185 int
186 GetMinimumViewWidth()
187 {
188 	system_info sys_info;
189 	get_system_info(&sys_info);
190 	return (sys_info.cpu_count * 2) + 1;
191 }
192 
193 
194 void
195 Usage()
196 {
197 	printf("Usage: Pulse [--mini] [-w width] [--width=width]\n"
198 	       "\t[--deskbar] [--normal] [--framecolor 0xrrggbb]\n"
199 	       "\t[--activecolor 0xrrggbb] [--idlecolor 0xrrggbb]\n");
200 	exit(0);
201 }
202 
203 
204 bool
205 LoadInDeskbar()
206 {
207 	PulseApp *pulseapp = (PulseApp *)be_app;
208 	BDeskbar *deskbar = new BDeskbar();
209 	// Don't allow two copies in the Deskbar at once
210 	if (deskbar->HasItem("DeskbarPulseView")) {
211 		delete deskbar;
212 		return false;
213 	}
214 
215 	// Must be 16 pixels high, the width is retrieved from the Prefs class
216 	int width = pulseapp->prefs->deskbar_icon_width;
217 	int min_width = GetMinimumViewWidth();
218 	if (width < min_width) {
219 		pulseapp->prefs->deskbar_icon_width = min_width;
220 		width = min_width;
221 	}
222 
223 	BRect rect(0, 0, width - 1, 15);
224 	DeskbarPulseView *replicant = new DeskbarPulseView(rect);
225 	status_t err = deskbar->AddItem(replicant);
226 	delete replicant;
227 	delete deskbar;
228 	if (err != B_OK) {
229 		BAlert *alert = new BAlert(NULL, strerror(err), "OK");
230 		alert->Go(NULL);
231 		return false;
232 	}
233 
234 	return true;
235 }
236 
237 
238 int
239 main(int argc, char **argv)
240 {
241 	PulseApp *pulseapp = new PulseApp(argc, argv);
242 	pulseapp->Run();
243 	delete pulseapp;
244 	return 0;
245 }
246