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