xref: /haiku/src/apps/pulse/PulseView.cpp (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
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