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 <Catalog.h> 23 #include <Deskbar.h> 24 #include <Locale.h> 25 #include <Rect.h> 26 27 #include <syscalls.h> 28 29 #include "Common.h" 30 #include "PulseWindow.h" 31 #include "DeskbarPulseView.h" 32 33 #undef B_TRANSLATE_CONTEXT 34 #define B_TRANSLATE_CONTEXT "PulseApp" 35 36 37 PulseApp::PulseApp(int argc, char **argv) 38 : BApplication(APP_SIGNATURE) 39 { 40 prefs = new Prefs(); 41 42 int mini = false, deskbar = false, normal = false; 43 uint32 framecolor = 0, activecolor = 0, idlecolor = 0; 44 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} 57 }; 58 int c = getopt_long(argc, argv, "hw:", long_options, &option_index); 59 if (c == -1) 60 break; 61 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; 71 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; 82 } 83 break; 84 } 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; 99 } 100 } 101 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; 120 121 prefs->Save(); 122 BuildPulse(); 123 } 124 125 126 void 127 PulseApp::BuildPulse() 128 { 129 // Remove this case for Deskbar add on API 130 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; 138 139 PulseWindow *pulseWindow = NULL; 140 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); 145 146 pulseWindow->MoveOnScreen(); 147 pulseWindow->Show(); 148 } 149 150 151 PulseApp::~PulseApp() 152 { 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(); 158 159 delete prefs; 160 } 161 162 163 // #pragma mark - 164 165 166 /** Make sure we don't disable the last CPU - this is needed by 167 * descendants of PulseView for the popup menu and for CPUButton 168 * both as a replicant and not. 169 */ 170 171 bool 172 LastEnabledCPU(int my_cpu) 173 { 174 system_info sys_info; 175 get_system_info(&sys_info); 176 if (sys_info.cpu_count == 1) 177 return true; 178 179 for (int x = 0; x < sys_info.cpu_count; x++) { 180 if (x == my_cpu) 181 continue; 182 if (_kern_cpu_enabled(x) == 1) 183 return false; 184 } 185 return true; 186 } 187 188 189 /** Ensure that the mini mode and deskbar mode always show an indicator 190 * for each CPU, at least one pixel wide. 191 */ 192 193 int 194 GetMinimumViewWidth() 195 { 196 system_info sys_info; 197 get_system_info(&sys_info); 198 return (sys_info.cpu_count * 2) + 1; 199 } 200 201 202 void 203 Usage() 204 { 205 printf(B_TRANSLATE("Usage: Pulse [--mini] [-w width] [--width=width]\n" 206 "\t[--deskbar] [--normal] [--framecolor 0xrrggbb]\n" 207 "\t[--activecolor 0xrrggbb] [--idlecolor 0xrrggbb]\n")); 208 exit(0); 209 } 210 211 212 bool 213 LoadInDeskbar() 214 { 215 PulseApp *pulseapp = (PulseApp *)be_app; 216 BDeskbar *deskbar = new BDeskbar(); 217 // Don't allow two copies in the Deskbar at once 218 if (deskbar->HasItem("DeskbarPulseView")) { 219 delete deskbar; 220 return false; 221 } 222 223 // Must be 16 pixels high, the width is retrieved from the Prefs class 224 int width = pulseapp->prefs->deskbar_icon_width; 225 int min_width = GetMinimumViewWidth(); 226 if (width < min_width) { 227 pulseapp->prefs->deskbar_icon_width = min_width; 228 width = min_width; 229 } 230 231 BRect rect(0, 0, width - 1, 15); 232 DeskbarPulseView *replicant = new DeskbarPulseView(rect); 233 status_t err = deskbar->AddItem(replicant); 234 delete replicant; 235 delete deskbar; 236 if (err != B_OK) { 237 BAlert *alert = new BAlert(NULL, strerror(err), B_TRANSLATE("OK")); 238 alert->Go(NULL); 239 return false; 240 } 241 242 return true; 243 } 244 245 246 int 247 main(int argc, char **argv) 248 { 249 PulseApp *pulseapp = new PulseApp(argc, argv); 250 pulseapp->Run(); 251 delete pulseapp; 252 return 0; 253 } 254