xref: /haiku/src/servers/bluetooth/DeskbarReplicant.cpp (revision a5a3b2d9a3d95cbae71eaf371708c73a1780ac0d)
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 	AdoptParentColors();
121 
122 	SetLowColor(ViewColor());
123 }
124 
125 
126 void
127 DeskbarReplicant::Draw(BRect updateRect)
128 {
129 	if (!fIcon) {
130 		/* At least display something... */
131 		rgb_color lowColor = LowColor();
132 		SetLowColor(0, 113, 187, 255);
133 		FillRoundRect(Bounds().InsetBySelf(3.f, 0.f), 5.f, 7.f, B_SOLID_LOW);
134 		SetLowColor(lowColor);
135 	} else {
136 		SetDrawingMode(B_OP_ALPHA);
137 		DrawBitmap(fIcon);
138 		SetDrawingMode(B_OP_COPY);
139 	}
140 }
141 
142 
143 void
144 DeskbarReplicant::MessageReceived(BMessage* msg)
145 {
146 	switch (msg->what) {
147 		case kMsgShowBluetoothServerConsole:
148 			_ShowBluetoothServerConsole();
149 			break;
150 
151 		case kMsgOpenBluetoothPreferences:
152 			_OpenBluetoothPreferences();
153 			break;
154 
155 		case kMsgQuitBluetoothServer:
156 			_QuitBluetoothServer();
157 			break;
158 
159 		default:
160 			BView::MessageReceived(msg);
161 	}
162 }
163 
164 
165 void
166 DeskbarReplicant::MouseDown(BPoint where)
167 {
168 	BPoint point;
169 	uint32 buttons;
170 	GetMouse(&point, &buttons);
171 	if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) {
172 		return;
173 	}
174 
175 	BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
176 
177 	menu->AddItem(new BMenuItem("Settings" B_UTF8_ELLIPSIS,
178 		new BMessage(kMsgOpenBluetoothPreferences)));
179 
180 	// TODO show list of known/paired devices
181 
182 	/* The code below is for development purposes only, but doesn't
183 	 * hurt to be enabled as long as in alpha state.
184 	 */
185 	menu->AddSeparatorItem();
186 
187 	menu->AddItem(new BMenuItem("Show server console" B_UTF8_ELLIPSIS,
188 		new BMessage(kMsgShowBluetoothServerConsole)));
189 
190 	menu->AddItem(new BMenuItem("Stop server",
191 		new BMessage(kMsgQuitBluetoothServer)));
192 
193 	menu->SetTargetForItems(this);
194 	ConvertToScreen(&point);
195 	menu->Go(point, true, true, true);
196 }
197 
198 
199 void
200 DeskbarReplicant::_OpenBluetoothPreferences()
201 {
202 	status_t status = be_roster->Launch(BLUETOOTH_APP_SIGNATURE);
203 	if (status < B_OK) {
204 		_ShowErrorAlert("Launching the Bluetooth preflet failed.", status);
205 	}
206 }
207 
208 
209 void
210 DeskbarReplicant::_ShowBluetoothServerConsole()
211 {
212 	if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
213 		return;
214 	}
215 	status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
216 		BT_MSG_SERVER_SHOW_CONSOLE);
217 	if (status < B_OK) {
218 		_ShowErrorAlert("Showing the Bluetooth server console failed.", status);
219 	}
220 }
221 
222 
223 void
224 DeskbarReplicant::_QuitBluetoothServer()
225 {
226 	if (!be_roster->IsRunning(BLUETOOTH_SIGNATURE)) {
227 		return;
228 	}
229 	status_t status = BMessenger(BLUETOOTH_SIGNATURE).SendMessage(
230 		B_QUIT_REQUESTED);
231 	if (status < B_OK) {
232 		_ShowErrorAlert("Stopping the Bluetooth server failed.", status);
233 	}
234 }
235 
236 
237 void
238 DeskbarReplicant::_ShowErrorAlert(BString msg, status_t status)
239 {
240 	msg << "\n\nError: " << strerror(status);
241 	BAlert* alert = new BAlert("Bluetooth error", msg.String(), "OK");
242 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
243 	alert->Go(NULL);
244 }
245 
246 //	#pragma mark -
247 
248 
249 extern "C" _EXPORT BView *
250 instantiate_deskbar_item(void)
251 {
252 	return new DeskbarReplicant(BRect(0, 0, 15, 15),
253 		B_FOLLOW_LEFT | B_FOLLOW_TOP);
254 }
255 
256 //	#pragma mark -
257 
258 
259 status_t
260 our_image(image_info& image)
261 {
262 	int32 cookie = 0;
263 	while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
264 		if ((char *)our_image >= (char *)image.text
265 			&& (char *)our_image <= (char *)image.text + image.text_size)
266 			return B_OK;
267 	}
268 
269 	return B_ERROR;
270 }
271