xref: /haiku/src/servers/bluetooth/DeskbarReplicant.cpp (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Weirauch, dev@m-phasis.de
7  */
8 
9 
10 #include "DeskbarReplicant.h"
11 
12 #include <Alert.h>
13 #include <Application.h>
14 #include <Bitmap.h>
15 #include <Deskbar.h>
16 #include <IconUtils.h>
17 #include <MenuItem.h>
18 #include <Message.h>
19 #include <PopUpMenu.h>
20 #include <Resources.h>
21 #include <Roster.h>
22 #include <String.h>
23 
24 #include <bluetoothserver_p.h>
25 
26 extern "C" _EXPORT BView *instantiate_deskbar_item(void);
27 status_t our_image(image_info& image);
28 
29 const uint32 kMsgShowBluetoothServerConsole = 'sbtc';
30 const uint32 kMsgOpenBluetoothPreferences = 'obtp';
31 const uint32 kMsgQuitBluetoothServer = 'qbts';
32 
33 const char* kDeskbarItemName = "BluetoothServerReplicant";
34 const char* kClassName = "DeskbarReplicant";
35 
36 //	#pragma mark -
37 
38 
39 DeskbarReplicant::DeskbarReplicant(BRect frame, int32 resizingMode)
40 	: BView(frame, kDeskbarItemName, resizingMode,
41 		B_WILL_DRAW | B_FRAME_EVENTS)
42 {
43 	_Init();
44 }
45 
46 
47 DeskbarReplicant::DeskbarReplicant(BMessage* archive)
48 	: BView(archive)
49 {
50 	_Init();
51 }
52 
53 
54 DeskbarReplicant::~DeskbarReplicant()
55 {
56 }
57 
58 
59 void
60 DeskbarReplicant::_Init()
61 {
62 	fIcon = NULL;
63 
64 	image_info info;
65 	if (our_image(info) != B_OK)
66 		return;
67 
68 	BFile file(info.name, B_READ_ONLY);
69 	if (file.InitCheck() < B_OK)
70 		return;
71 
72 	BResources resources(&file);
73 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
74 	if (resources.InitCheck() < B_OK)
75 		return;
76 #endif
77 
78 	size_t size;
79 	const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE,
80 		"BEOS:ICON", &size);
81 	if (data != NULL) {
82 		BBitmap* icon = new BBitmap(Bounds(), B_RGBA32);
83 		if (icon->InitCheck() == B_OK
84 			&& BIconUtils::GetVectorIcon((const uint8 *)data,
85 				size, icon) == B_OK) {
86 			fIcon = icon;
87 		} else
88 			delete icon;
89 	}
90 }
91 
92 
93 DeskbarReplicant *
94 DeskbarReplicant::Instantiate(BMessage* archive)
95 {
96 	if (!validate_instantiation(archive, kClassName))
97 		return NULL;
98 
99 	return new DeskbarReplicant(archive);
100 }
101 
102 
103 status_t
104 DeskbarReplicant::Archive(BMessage* archive, bool deep) const
105 {
106 	status_t status = BView::Archive(archive, deep);
107 	if (status == B_OK)
108 		status = archive->AddString("add_on", BLUETOOTH_SIGNATURE);
109 	if (status == B_OK)
110 		status = archive->AddString("class", kClassName);
111 
112 	return status;
113 }
114 
115 
116 void
117 DeskbarReplicant::AttachedToWindow()
118 {
119 	BView::AttachedToWindow();
120 	if (Parent())
121 		SetViewColor(Parent()->ViewColor());
122 	else
123 		SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
124 
125 	SetLowColor(ViewColor());
126 }
127 
128 
129 void
130 DeskbarReplicant::Draw(BRect updateRect)
131 {
132 	if (!fIcon) {
133 		/* At least display something... */
134 		rgb_color lowColor = LowColor();
135 		SetLowColor(0, 113, 187, 255);
136 		FillRoundRect(Bounds().InsetBySelf(3.f, 0.f), 5.f, 7.f, B_SOLID_LOW);
137 		SetLowColor(lowColor);
138 	} else {
139 		SetDrawingMode(B_OP_ALPHA);
140 		DrawBitmap(fIcon);
141 		SetDrawingMode(B_OP_COPY);
142 	}
143 }
144 
145 
146 void
147 DeskbarReplicant::MessageReceived(BMessage* msg)
148 {
149 	switch (msg->what) {
150 		case kMsgShowBluetoothServerConsole:
151 			_ShowBluetoothServerConsole();
152 			break;
153 
154 		case kMsgOpenBluetoothPreferences:
155 			_OpenBluetoothPreferences();
156 			break;
157 
158 		case kMsgQuitBluetoothServer:
159 			_QuitBluetoothServer();
160 			break;
161 
162 		default:
163 			BView::MessageReceived(msg);
164 	}
165 }
166 
167 
168 void
169 DeskbarReplicant::MouseDown(BPoint where)
170 {
171 	BPoint point;
172 	uint32 buttons;
173 	GetMouse(&point, &buttons);
174 	if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) {
175 		return;
176 	}
177 
178 	BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
179 
180 	menu->AddItem(new BMenuItem("Open Preferences"B_UTF8_ELLIPSIS,
181 		new BMessage(kMsgOpenBluetoothPreferences)));
182 
183 	// TODO show list of known/paired devices
184 
185 	/* The code below is for development purposes only, but doesn't
186 	 * hurt to be enabled as long as in alpha state.
187 	 */
188 	menu->AddSeparatorItem();
189 
190 	menu->AddItem(new BMenuItem("Show Server Console" B_UTF8_ELLIPSIS,
191 		new BMessage(kMsgShowBluetoothServerConsole)));
192 
193 	menu->AddItem(new BMenuItem("Stop Server",
194 		new BMessage(kMsgQuitBluetoothServer)));
195 
196 	menu->SetTargetForItems(this);
197 	ConvertToScreen(&point);
198 	menu->Go(point, true, true, true);
199 }
200 
201 
202 void
203 DeskbarReplicant::_OpenBluetoothPreferences()
204 {
205 	status_t status = be_roster->Launch(BLUETOOTH_APP_SIGNATURE);
206 	if (status < B_OK) {
207 		_ShowErrorAlert("Launching the Bluetooth preflet failed.", status);
208 	}
209 }
210 
211 
212 void
213 DeskbarReplicant::_ShowBluetoothServerConsole()
214 {
215 	if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
216 		return;
217 	}
218 	status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
219 		BT_MSG_SERVER_SHOW_CONSOLE);
220 	if (status < B_OK) {
221 		_ShowErrorAlert("Showing the Bluetooth Server Console failed.", status);
222 	}
223 }
224 
225 
226 void
227 DeskbarReplicant::_QuitBluetoothServer()
228 {
229 	if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
230 		return;
231 	}
232 	status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
233 		B_QUIT_REQUESTED);
234 	if (status < B_OK) {
235 		_ShowErrorAlert("Stopping the Bluetooth Server failed.", status);
236 	}
237 }
238 
239 
240 void
241 DeskbarReplicant::_ShowErrorAlert(BString msg, status_t status)
242 {
243 	msg << "\n\nError: " << strerror(status);
244 	BAlert* alert = new BAlert("Bluetooth Error", msg.String(), "Ok");
245 	alert->Go(NULL);
246 }
247 
248 //	#pragma mark -
249 
250 
251 extern "C" _EXPORT BView *
252 instantiate_deskbar_item(void)
253 {
254 	return new DeskbarReplicant(BRect(0, 0, 15, 15),
255 		B_FOLLOW_LEFT | B_FOLLOW_TOP);
256 }
257 
258 //	#pragma mark -
259 
260 
261 status_t
262 our_image(image_info& image)
263 {
264 	int32 cookie = 0;
265 	while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
266 		if ((char *)our_image >= (char *)image.text
267 			&& (char *)our_image <= (char *)image.text + image.text_size)
268 			return B_OK;
269 	}
270 
271 	return B_ERROR;
272 }
273