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 rgb_color color = { 168, 168, 168, 0xff }; 54 SetViewColor(color); 55 SetLowColor(color); 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 sprintf(temp, "%d", 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[] fCpuButtons; 100 delete[] fProgressBars; 101 } 102 103 104 void 105 NormalPulseView::CalculateFontSizes() 106 { 107 BFont font; 108 GetFont(&font); 109 110 fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f); 111 112 if (!fHasBrandLogo) 113 fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f); 114 } 115 116 117 void 118 NormalPulseView::DetermineVendorAndProcessor() 119 { 120 system_info sys_info; 121 get_system_info(&sys_info); 122 123 // Initialize logo 124 125 fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8); 126 unsigned char *logo = BlankLogo; 127 128 #if __POWERPC__ 129 logo = PowerPCLogo; 130 #endif 131 #if __INTEL__ 132 uint32 topologyNodeCount = 0; 133 cpu_topology_node_info* topology = NULL; 134 135 get_cpu_topology_info(NULL, &topologyNodeCount); 136 if (topologyNodeCount != 0) 137 topology = new cpu_topology_node_info[topologyNodeCount]; 138 get_cpu_topology_info(topology, &topologyNodeCount); 139 140 for (uint32 i = 0; i < topologyNodeCount; i++) { 141 if (topology[i].type == B_TOPOLOGY_PACKAGE) { 142 switch (topology[i].data.package.vendor) { 143 case B_CPU_VENDOR_INTEL: 144 logo = IntelLogo; 145 break; 146 147 case B_CPU_VENDOR_AMD: 148 logo = AmdLogo; 149 break; 150 151 default: 152 break; 153 } 154 155 break; 156 } 157 } 158 159 delete[] topology; 160 #endif 161 162 fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8); 163 fHasBrandLogo = (logo != BlankLogo); 164 165 get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor)); 166 } 167 168 169 void 170 NormalPulseView::Draw(BRect rect) 171 { 172 PushState(); 173 174 // Black frame 175 SetHighColor(0, 0, 0); 176 BRect frame = Bounds(); 177 frame.right--; 178 frame.bottom--; 179 StrokeRect(frame); 180 181 // Bevelled edges 182 SetHighColor(255, 255, 255); 183 StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1)); 184 StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1)); 185 SetHighColor(80, 80, 80); 186 StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom)); 187 StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom)); 188 189 // Dividing line 190 SetHighColor(96, 96, 96); 191 StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1)); 192 SetHighColor(255, 255, 255); 193 StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2)); 194 195 // Processor picture 196 DrawBitmap(fCpuLogo, BPoint(10, 10)); 197 198 #if __INTEL__ 199 // Do nothing in the case of non-Intel CPUs - they already have a logo 200 if (!fHasBrandLogo) { 201 SetDrawingMode(B_OP_OVER); 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 #endif 210 211 // Draw processor type and speed 212 SetDrawingMode(B_OP_OVER); 213 SetHighColor(240, 240, 240); 214 215 SetFontSize(fProcessorFontSize); 216 float width = StringWidth(fProcessor); 217 MovePenTo(10 + (32 - width / 2), 48); 218 DrawString(fProcessor); 219 220 char buffer[64]; 221 int32 cpuSpeed = get_rounded_cpu_speed(); 222 if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0) 223 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f); 224 else 225 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed); 226 227 // We can't assume anymore that a CPU clock speed is always static. 228 // Let's compute the best font size for the CPU speed string each time... 229 BFont font; 230 GetFont(&font); 231 SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f)); 232 width = StringWidth(buffer); 233 MovePenTo(10 + (32 - width / 2), 60); 234 DrawString(buffer); 235 236 PopState(); 237 } 238 239 240 void 241 NormalPulseView::Pulse() 242 { 243 // Don't recalculate and redraw if this view is hidden 244 if (!IsHidden()) { 245 Update(); 246 if (Window()->Lock()) { 247 // Set the value of each CPU bar 248 for (int x = 0; x < fCpuCount; x++) { 249 fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100)); 250 } 251 252 Sync(); 253 Window()->Unlock(); 254 } 255 } 256 } 257 258 259 void 260 NormalPulseView::AttachedToWindow() 261 { 262 SetFont(be_bold_font); 263 CalculateFontSizes(); 264 265 fPreviousTime = system_time(); 266 267 BMessenger messenger(Window()); 268 mode1->SetTarget(messenger); 269 mode2->SetTarget(messenger); 270 preferences->SetTarget(messenger); 271 about->SetTarget(messenger); 272 273 system_info sys_info; 274 get_system_info(&sys_info); 275 if (sys_info.cpu_count >= 2) { 276 for (unsigned int x = 0; x < sys_info.cpu_count; x++) 277 cpu_menu_items[x]->SetTarget(messenger); 278 } 279 } 280 281 282 void 283 NormalPulseView::UpdateColors(BMessage *message) 284 { 285 int32 color = message->FindInt32("color"); 286 bool fade = message->FindBool("fade"); 287 system_info sys_info; 288 get_system_info(&sys_info); 289 290 for (unsigned int x = 0; x < sys_info.cpu_count; x++) { 291 fProgressBars[x]->UpdateColors(color, fade); 292 fCpuButtons[x]->UpdateColors(color); 293 } 294 } 295 296