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