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 <Window.h> 20 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <string.h> 24 25 #include <cpu_type.h> 26 27 #undef B_TRANSLATION_CONTEXT 28 #define B_TRANSLATION_CONTEXT "NormalPulseView" 29 30 31 float 32 max_font_size(BFont font, const char* text, float maxSize, float maxWidth) 33 { 34 const float steps = 0.5f; 35 36 for (float size = maxSize; size > 4; size -= steps) { 37 font.SetSize(size); 38 if (font.StringWidth(text) <= maxWidth) 39 return size; 40 } 41 42 return 4; 43 } 44 45 46 // #pragma mark - 47 48 49 NormalPulseView::NormalPulseView(BRect rect) 50 : PulseView(rect, "NormalPulseView"), 51 fHasBrandLogo(false) 52 { 53 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 54 SetLowUIColor(ViewUIColor()); 55 56 mode1->SetLabel(B_TRANSLATE("Mini mode")); 57 mode1->SetMessage(new BMessage(PV_MINI_MODE)); 58 mode2->SetLabel(B_TRANSLATE("Deskbar mode")); 59 mode2->SetMessage(new BMessage(PV_DESKBAR_MODE)); 60 61 DetermineVendorAndProcessor(); 62 63 // Allocate progress bars and button pointers 64 system_info systemInfo; 65 get_system_info(&systemInfo); 66 fCpuCount = systemInfo.cpu_count; 67 fProgressBars = new ProgressBar *[fCpuCount]; 68 fCpuButtons = new CPUButton *[fCpuCount]; 69 70 // Set up the CPU activity bars and buttons 71 for (int x = 0; x < fCpuCount; x++) { 72 BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x, 73 PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH, 74 PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT); 75 char* str2 = (char *)B_TRANSLATE("CPU progress bar"); 76 fProgressBars[x] = new ProgressBar(r, str2); 77 AddChild(fProgressBars[x]); 78 79 r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x, 80 CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7, 81 CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7); 82 char temp[4]; 83 snprintf(temp, sizeof(temp), "%hhd", x + 1); 84 fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL); 85 AddChild(fCpuButtons[x]); 86 } 87 88 if (fCpuCount == 1) { 89 fProgressBars[0]->MoveBy(-3, 12); 90 fCpuButtons[0]->Hide(); 91 } 92 } 93 94 95 NormalPulseView::~NormalPulseView() 96 { 97 delete fCpuLogo; 98 delete[] fCpuButtons; 99 delete[] fProgressBars; 100 } 101 102 103 void 104 NormalPulseView::CalculateFontSizes() 105 { 106 BFont font; 107 GetFont(&font); 108 109 fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f); 110 111 if (!fHasBrandLogo) 112 fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f); 113 } 114 115 116 void 117 NormalPulseView::DetermineVendorAndProcessor() 118 { 119 system_info sys_info; 120 get_system_info(&sys_info); 121 122 // Initialize logo 123 124 fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8); 125 unsigned char *logo = BlankLogo; 126 127 #if __POWERPC__ 128 logo = PowerPCLogo; 129 #elif __INTEL__ 130 uint32 topologyNodeCount = 0; 131 cpu_topology_node_info* topology = NULL; 132 133 get_cpu_topology_info(NULL, &topologyNodeCount); 134 if (topologyNodeCount != 0) 135 topology = new cpu_topology_node_info[topologyNodeCount]; 136 get_cpu_topology_info(topology, &topologyNodeCount); 137 138 for (uint32 i = 0; i < topologyNodeCount; i++) { 139 if (topology[i].type == B_TOPOLOGY_PACKAGE) { 140 switch (topology[i].data.package.vendor) { 141 case B_CPU_VENDOR_INTEL: 142 logo = IntelLogo; 143 break; 144 145 case B_CPU_VENDOR_AMD: 146 logo = AmdLogo; 147 break; 148 149 default: 150 break; 151 } 152 153 break; 154 } 155 } 156 157 delete[] topology; 158 #endif 159 160 fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8); 161 fHasBrandLogo = (logo != BlankLogo); 162 163 get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor)); 164 } 165 166 167 void 168 NormalPulseView::Draw(BRect rect) 169 { 170 PushState(); 171 172 // Black frame 173 SetHighColor(0, 0, 0); 174 BRect frame = Bounds(); 175 frame.right--; 176 frame.bottom--; 177 StrokeRect(frame); 178 179 // Bevelled edges 180 SetHighColor(255, 255, 255); 181 StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1)); 182 StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1)); 183 SetHighColor(80, 80, 80); 184 StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom)); 185 StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom)); 186 187 // Dividing line 188 SetHighColor(96, 96, 96); 189 StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1)); 190 SetHighColor(255, 255, 255); 191 StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2)); 192 193 // Processor picture 194 DrawBitmap(fCpuLogo, BPoint(10, 10)); 195 196 #if __INTEL__ 197 // Do nothing in the case of non-Intel CPUs - they already have a logo 198 if (!fHasBrandLogo) { 199 SetDrawingMode(B_OP_OVER); 200 SetHighColor(240, 240, 240); 201 SetFontSize(fVendorFontSize); 202 203 float width = StringWidth(fVendor); 204 MovePenTo(10 + (32 - width / 2), 30); 205 DrawString(fVendor); 206 } 207 #endif 208 209 // Draw processor type and speed 210 SetDrawingMode(B_OP_OVER); 211 SetHighColor(240, 240, 240); 212 213 SetFontSize(fProcessorFontSize); 214 float width = StringWidth(fProcessor); 215 MovePenTo(10 + (32 - width / 2), 48); 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), 60); 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