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