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
29PulseView::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
43PulseView::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
52void 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
87void 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
101void 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
124void 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
138PulseView::~PulseView() {
139	if (popupmenu != NULL) delete popupmenu;
140	if (cpu_menu_items != NULL) delete cpu_menu_items;
141}
142
143