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