1 //**************************************************************************************** 2 // 3 // File: PulseView.cpp 4 // 5 // Written by: David Ramsey and Daniel Switkin 6 // 7 // Copyright 1999, Be Incorporated 8 // 9 //**************************************************************************************** 10 11 #include "PulseView.h" 12 #include "Common.h" 13 #include "PulseApp.h" 14 #include <interface/Alert.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <string.h> 18 19 PulseView::PulseView(BRect rect, const char *name) : 20 BView(rect, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_PULSE_NEEDED | B_FRAME_EVENTS) { 21 22 popupmenu = NULL; 23 cpu_menu_items = NULL; 24 25 // Don't init the menus for the DeskbarPulseView, because this instance 26 // will only be used to archive the replicant 27 if (strcmp(name, "DeskbarPulseView") != 0) { 28 Init(); 29 } 30 } 31 32 // This version will be used by the instantiated replicant 33 PulseView::PulseView(BMessage *message) : BView(message) { 34 SetResizingMode(B_FOLLOW_ALL_SIDES); 35 SetFlags(B_WILL_DRAW | B_PULSE_NEEDED); 36 37 popupmenu = NULL; 38 cpu_menu_items = NULL; 39 Init(); 40 } 41 42 void PulseView::Init() { 43 popupmenu = new BPopUpMenu("PopUpMenu", false, false, B_ITEMS_IN_COLUMN); 44 popupmenu->SetFont(be_plain_font); 45 mode1 = new BMenuItem("", NULL, 0, 0); 46 mode2 = new BMenuItem("", NULL, 0, 0); 47 preferences = new BMenuItem("Preferences...", new BMessage(PV_PREFERENCES), 0, 0); 48 about = new BMenuItem("About...", new BMessage(PV_ABOUT), 0, 0); 49 50 popupmenu->AddItem(mode1); 51 popupmenu->AddItem(mode2); 52 popupmenu->AddSeparatorItem(); 53 54 system_info sys_info; 55 get_system_info(&sys_info); 56 57 // Only add menu items to control CPUs on an SMP machine 58 if (sys_info.cpu_count >= 2) { 59 cpu_menu_items = new BMenuItem *[sys_info.cpu_count]; 60 char temp[20]; 61 for (int x = 0; x < sys_info.cpu_count; x++) { 62 sprintf(temp, "CPU %d", x + 1); 63 BMessage *message = new BMessage(PV_CPU_MENU_ITEM); 64 message->AddInt32("which", x); 65 cpu_menu_items[x] = new BMenuItem(temp, message, 0, 0); 66 popupmenu->AddItem(cpu_menu_items[x]); 67 } 68 popupmenu->AddSeparatorItem(); 69 } 70 71 popupmenu->AddItem(preferences); 72 popupmenu->AddItem(about); 73 } 74 75 void PulseView::MouseDown(BPoint point) { 76 BPoint cursor; 77 uint32 buttons; 78 MakeFocus(true); 79 GetMouse(&cursor, &buttons, true); 80 81 if (buttons & B_SECONDARY_MOUSE_BUTTON) { 82 ConvertToScreen(&point); 83 // Use the asynchronous version so we don't interfere with 84 // the window responding to Pulse() events 85 popupmenu->Go(point, true, false, true); 86 } 87 } 88 89 void PulseView::Update() { 90 system_info sys_info; 91 get_system_info(&sys_info); 92 bigtime_t now = system_time(); 93 94 // Calculate work done since last call to Update() for each CPU 95 for (int x = 0; x < sys_info.cpu_count; x++) { 96 double cpu_time = (double)(sys_info.cpu_infos[x].active_time - prev_active[x]) / (now - prev_time); 97 prev_active[x] = sys_info.cpu_infos[x].active_time; 98 if (cpu_time < 0) cpu_time = 0; 99 if (cpu_time > 1) cpu_time = 1; 100 cpu_times[x] = cpu_time; 101 102 if (sys_info.cpu_count >= 2) { 103 if (!_kget_cpu_state_(x) && cpu_menu_items[x]->IsMarked()) 104 cpu_menu_items[x]->SetMarked(false); 105 if (_kget_cpu_state_(x) && !cpu_menu_items[x]->IsMarked()) 106 cpu_menu_items[x]->SetMarked(true); 107 } 108 } 109 prev_time = now; 110 } 111 112 void PulseView::ChangeCPUState(BMessage *message) { 113 int which = message->FindInt32("which"); 114 115 if (!LastEnabledCPU(which)) { 116 _kset_cpu_state_(which, (int)!cpu_menu_items[which]->IsMarked()); 117 } else { 118 BAlert *alert = new BAlert(NULL, "You can't disable the last active CPU.", "OK"); 119 alert->Go(NULL); 120 } 121 } 122 123 PulseView::~PulseView() { 124 if (popupmenu != NULL) delete popupmenu; 125 if (cpu_menu_items != NULL) delete cpu_menu_items; 126 } 127