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