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