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