1 //***************************************************************************** 2 // 3 // File: NormalPulseView.cpp 4 // 5 // Written by: Daniel Switkin 6 // 7 // Copyright 1999, Be Incorporated 8 // 9 //***************************************************************************** 10 11 12 #include "NormalPulseView.h" 13 #include "Common.h" 14 #include "Pictures" 15 16 #include <Catalog.h> 17 #include <Bitmap.h> 18 #include <Dragger.h> 19 #include <IconUtils.h> 20 #include <Window.h> 21 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 26 #include <cpu_type.h> 27 28 #undef B_TRANSLATION_CONTEXT 29 #define B_TRANSLATION_CONTEXT "NormalPulseView" 30 31 32 float 33 max_font_size(BFont font, const char* text, float maxSize, float maxWidth) 34 { 35 const float steps = 0.5f; 36 37 for (float size = maxSize; size > 4; size -= steps) { 38 font.SetSize(size); 39 if (font.StringWidth(text) <= maxWidth) 40 return size; 41 } 42 43 return 4; 44 } 45 46 47 // #pragma mark - 48 49 50 NormalPulseView::NormalPulseView(BRect rect) 51 : PulseView(rect, "NormalPulseView"), 52 fBrandLogo(NULL) 53 { 54 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 55 SetLowUIColor(ViewUIColor()); 56 57 mode1->SetLabel(B_TRANSLATE("Mini mode")); 58 mode1->SetMessage(new BMessage(PV_MINI_MODE)); 59 mode2->SetLabel(B_TRANSLATE("Deskbar mode")); 60 mode2->SetMessage(new BMessage(PV_DESKBAR_MODE)); 61 62 DetermineVendorAndProcessor(); 63 64 // Allocate progress bars and button pointers 65 system_info systemInfo; 66 get_system_info(&systemInfo); 67 fCpuCount = systemInfo.cpu_count; 68 fProgressBars = new ProgressBar *[fCpuCount]; 69 fCpuButtons = new CPUButton *[fCpuCount]; 70 71 // Set up the CPU activity bars and buttons 72 for (int x = 0; x < fCpuCount; x++) { 73 BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x, 74 PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH, 75 PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT); 76 char* str2 = (char *)B_TRANSLATE("CPU progress bar"); 77 fProgressBars[x] = new ProgressBar(r, str2); 78 AddChild(fProgressBars[x]); 79 80 r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x, 81 CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7, 82 CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7); 83 char temp[4]; 84 snprintf(temp, sizeof(temp), "%hhd", int8(x + 1)); 85 fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL); 86 AddChild(fCpuButtons[x]); 87 } 88 89 if (fCpuCount == 1) { 90 fProgressBars[0]->MoveBy(-3, 12); 91 fCpuButtons[0]->Hide(); 92 } 93 } 94 95 96 NormalPulseView::~NormalPulseView() 97 { 98 delete fCpuLogo; 99 delete fBrandLogo; 100 delete[] fCpuButtons; 101 delete[] fProgressBars; 102 } 103 104 105 void 106 NormalPulseView::CalculateFontSizes() 107 { 108 BFont font; 109 GetFont(&font); 110 111 fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f); 112 113 if (fBrandLogo == NULL) 114 fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f); 115 } 116 117 118 void 119 NormalPulseView::DetermineVendorAndProcessor() 120 { 121 system_info sys_info; 122 get_system_info(&sys_info); 123 124 // Initialize logo 125 126 fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8); 127 fCpuLogo->SetBits(BlankLogo, fCpuLogo->BitsLength(), 0, B_CMAP8); 128 129 const unsigned char* logo = NULL; 130 size_t logoSize = 0; 131 uint32 topologyNodeCount = 0; 132 cpu_topology_node_info* topology = NULL; 133 134 get_cpu_topology_info(NULL, &topologyNodeCount); 135 if (topologyNodeCount != 0) 136 topology = new cpu_topology_node_info[topologyNodeCount]; 137 get_cpu_topology_info(topology, &topologyNodeCount); 138 139 for (uint32 i = 0; i < topologyNodeCount; i++) { 140 if (topology[i].type == B_TOPOLOGY_PACKAGE) { 141 switch (topology[i].data.package.vendor) { 142 case B_CPU_VENDOR_AMD: 143 logo = kAmdLogo; 144 logoSize = sizeof(kAmdLogo); 145 break; 146 147 case B_CPU_VENDOR_CYRIX: 148 logo = kCyrixLogo; 149 logoSize = sizeof(kCyrixLogo); 150 break; 151 152 case B_CPU_VENDOR_INTEL: 153 logo = kIntelLogo; 154 logoSize = sizeof(kIntelLogo); 155 break; 156 157 case B_CPU_VENDOR_MOTOROLA: 158 logo = kPowerPCLogo; 159 logoSize = sizeof(kPowerPCLogo); 160 break; 161 162 case B_CPU_VENDOR_VIA: 163 logo = kViaLogo; 164 logoSize = sizeof(kViaLogo); 165 break; 166 167 default: 168 break; 169 } 170 171 break; 172 } 173 } 174 175 delete[] topology; 176 177 if (logo != NULL) { 178 fBrandLogo = new BBitmap(BRect(0, 0, 47, 47), B_RGBA32); 179 if (BIconUtils::GetVectorIcon(logo, logoSize, fBrandLogo) != B_OK) { 180 delete fBrandLogo; 181 fBrandLogo = NULL; 182 } 183 } else 184 fBrandLogo = NULL; 185 186 get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor)); 187 } 188 189 190 void 191 NormalPulseView::Draw(BRect rect) 192 { 193 PushState(); 194 195 SetDrawingMode(B_OP_OVER); 196 // Processor picture 197 DrawBitmap(fCpuLogo, BPoint(10, 10)); 198 199 if (fBrandLogo != NULL) { 200 DrawBitmap(fBrandLogo, BPoint(18, 17)); 201 } else { 202 SetHighColor(240, 240, 240); 203 SetFontSize(fVendorFontSize); 204 205 float width = StringWidth(fVendor); 206 MovePenTo(10 + (32 - width / 2), 30); 207 DrawString(fVendor); 208 } 209 210 // Draw processor type and speed 211 SetHighColor(240, 240, 240); 212 213 SetFontSize(fProcessorFontSize); 214 float width = StringWidth(fProcessor); 215 MovePenTo(10 + (32 - width / 2), 55); 216 DrawString(fProcessor); 217 218 char buffer[64]; 219 int32 cpuSpeed = get_rounded_cpu_speed(); 220 if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0) 221 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f); 222 else 223 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed); 224 225 // We can't assume anymore that a CPU clock speed is always static. 226 // Let's compute the best font size for the CPU speed string each time... 227 BFont font; 228 GetFont(&font); 229 SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f)); 230 width = StringWidth(buffer); 231 MovePenTo(10 + (32 - width / 2), 64); 232 DrawString(buffer); 233 234 PopState(); 235 } 236 237 238 void 239 NormalPulseView::Pulse() 240 { 241 // Don't recalculate and redraw if this view is hidden 242 if (!IsHidden()) { 243 Update(); 244 if (Window()->Lock()) { 245 // Set the value of each CPU bar 246 for (int x = 0; x < fCpuCount; x++) { 247 fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100)); 248 } 249 250 Sync(); 251 Window()->Unlock(); 252 } 253 } 254 } 255 256 257 void 258 NormalPulseView::AttachedToWindow() 259 { 260 SetFont(be_bold_font); 261 CalculateFontSizes(); 262 263 fPreviousTime = system_time(); 264 265 BMessenger messenger(Window()); 266 mode1->SetTarget(messenger); 267 mode2->SetTarget(messenger); 268 preferences->SetTarget(messenger); 269 about->SetTarget(messenger); 270 271 system_info sys_info; 272 get_system_info(&sys_info); 273 if (sys_info.cpu_count >= 2) { 274 for (unsigned int x = 0; x < sys_info.cpu_count; x++) 275 cpu_menu_items[x]->SetTarget(messenger); 276 } 277 } 278 279 280 void 281 NormalPulseView::UpdateColors(BMessage *message) 282 { 283 int32 color = message->FindInt32("color"); 284 bool fade = message->FindBool("fade"); 285 system_info sys_info; 286 get_system_info(&sys_info); 287 288 for (unsigned int x = 0; x < sys_info.cpu_count; x++) { 289 fProgressBars[x]->UpdateColors(color, fade); 290 fCpuButtons[x]->UpdateColors(color); 291 } 292 } 293 294