xref: /haiku/src/kits/interface/Deskbar.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
1 /*
2  * Copyright 2001-2005, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jeremy Rand (jrand@magma.ca)
7  *		Jérôme Duval
8  *		Axel Dörfler
9  */
10 
11 
12 #include <Deskbar.h>
13 #include <Messenger.h>
14 #include <Message.h>
15 #include <View.h>
16 #include <Rect.h>
17 #include <InterfaceDefs.h>
18 #include <Node.h>
19 
20 #include <string.h>
21 
22 // ToDo: in case the BDeskbar methods are called from a Deskbar add-on,
23 //	they will currently deadlock most of the time (only those that do
24 //	not need a reply will work).
25 //	That should be fixed in the Deskbar itself, even if the Be API found
26 //	a way around that (that doesn't work too well, BTW)
27 
28 // The API in this file should be considered as part of OpenTracker - but
29 // should work with all versions of Tracker available for Haiku.
30 
31 static const char *kDeskbarSignature = "application/x-vnd.Be-TSKB";
32 
33 static const uint32 kMsgAddView = 'icon';
34 static const uint32 kMsgAddAddOn = 'adon';
35 static const uint32 kMsgHasItem = 'exst';
36 static const uint32 kMsgGetItemInfo = 'info';
37 static const uint32 kMsgCountItems = 'cwnt';
38 static const uint32 kMsgRemoveItem = 'remv';
39 static const uint32 kMsgLocation = 'gloc';
40 static const uint32 kMsgIsExpanded = 'gexp';
41 static const uint32 kMsgSetLocation = 'sloc';
42 static const uint32 kMsgExpand = 'sexp';
43 
44 
45 status_t
46 get_deskbar_frame(BRect *frame)
47 {
48 	BMessenger deskbar(kDeskbarSignature);
49 
50 	status_t result;
51 
52 	BMessage request(B_GET_PROPERTY);
53 	request.AddSpecifier("Frame");
54 	request.AddSpecifier("Window", "Deskbar");
55 
56 	BMessage reply;
57 	result = deskbar.SendMessage(&request, &reply);
58 	if (result == B_OK)
59    		result = reply.FindRect("result", frame);
60 
61 	return result;
62 }
63 
64 
65 //	#pragma mark -
66 
67 
68 BDeskbar::BDeskbar()
69 	: fMessenger(new BMessenger(kDeskbarSignature))
70 {
71 }
72 
73 
74 BDeskbar::~BDeskbar()
75 {
76 	delete fMessenger;
77 }
78 
79 
80 bool
81 BDeskbar::IsRunning() const
82 {
83 	return fMessenger->IsValid();
84 }
85 
86 
87 BRect
88 BDeskbar::Frame() const
89 {
90 	BRect frame(0.0, 0.0, 0.0, 0.0);
91 	get_deskbar_frame(&frame);
92 
93 	return frame;
94 }
95 
96 
97 deskbar_location
98 BDeskbar::Location(bool *_isExpanded) const
99 {
100 	deskbar_location location = B_DESKBAR_RIGHT_TOP;
101 	BMessage request(kMsgLocation);
102 	BMessage reply;
103 
104 	if (_isExpanded)
105 		*_isExpanded = true;
106 
107 	if (fMessenger->IsTargetLocal()) {
108 		// ToDo: do something about this!
109 		// (if we just ask the Deskbar in this case, we would deadlock)
110 		return location;
111 	}
112 
113 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
114 		int32 value;
115 		if (reply.FindInt32("location", &value) == B_OK)
116 			location = static_cast<deskbar_location>(value);
117 
118 		if (_isExpanded
119 			&& reply.FindBool("expanded", _isExpanded) != B_OK)
120 			*_isExpanded = true;
121 	}
122 
123 	return location;
124 }
125 
126 
127 status_t
128 BDeskbar::SetLocation(deskbar_location location, bool expanded)
129 {
130 	BMessage request(kMsgSetLocation);
131 	request.AddInt32("location", static_cast<int32>(location));
132 	request.AddBool("expand", expanded);
133 
134 	return fMessenger->SendMessage(&request);
135 }
136 
137 
138 bool
139 BDeskbar::IsExpanded(void) const
140 {
141 	BMessage request(kMsgIsExpanded);
142 	BMessage reply;
143 	bool isExpanded;
144 
145 	if (fMessenger->SendMessage(&request, &reply) != B_OK
146 		|| reply.FindBool("expanded", &isExpanded) != B_OK)
147 		isExpanded = true;
148 
149 	return isExpanded;
150 }
151 
152 
153 status_t
154 BDeskbar::Expand(bool expand)
155 {
156 	BMessage request(kMsgExpand);
157 	request.AddBool("expand", expand);
158 
159 	return fMessenger->SendMessage(&request);
160 }
161 
162 
163 status_t
164 BDeskbar::GetItemInfo(int32 id, const char **_name) const
165 {
166 	if (_name == NULL)
167 		return B_BAD_VALUE;
168 
169 	// Note: Be's implementation returns B_BAD_VALUE if *_name was NULL,
170 	// not just if _name was NULL.  This doesn't make much sense, so we
171 	// do not imitate this behaviour.
172 
173 	BMessage request(kMsgGetItemInfo);
174 	request.AddInt32("id", id);
175 
176 	BMessage reply;
177 	status_t result = fMessenger->SendMessage(&request, &reply);
178 	if (result == B_OK) {
179 		const char *name;
180 		result = reply.FindString("name", &name);
181 		if (result == B_OK) {
182 			*_name = strdup(name);
183 			if (*_name == NULL)
184 				result = B_NO_MEMORY;
185 		}
186 	}
187 	return result;
188 }
189 
190 
191 status_t
192 BDeskbar::GetItemInfo(const char *name, int32 *_id) const
193 {
194 	if (name == NULL)
195 		return B_BAD_VALUE;
196 
197 	BMessage request(kMsgGetItemInfo);
198 	request.AddString("name", name);
199 
200 	BMessage reply;
201 	status_t result = fMessenger->SendMessage(&request, &reply);
202 	if (result == B_OK)
203 		result = reply.FindInt32("id", _id);
204 
205 	return result;
206 }
207 
208 
209 bool
210 BDeskbar::HasItem(int32 id) const
211 {
212 	BMessage request(kMsgHasItem);
213 	request.AddInt32("id", id);
214 
215 	BMessage reply;
216 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
217 		return reply.FindBool("exists");
218 
219 	return false;
220 }
221 
222 
223 bool
224 BDeskbar::HasItem(const char *name) const
225 {
226 	BMessage request(kMsgHasItem);
227 	request.AddString("name", name);
228 
229 	BMessage reply;
230 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
231 		return reply.FindBool("exists");
232 
233 	return false;
234 }
235 
236 
237 uint32
238 BDeskbar::CountItems(void) const
239 {
240 	BMessage request(kMsgCountItems);
241 	BMessage reply;
242 
243 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
244 		return reply.FindInt32("count");
245 
246 	return 0;
247 }
248 
249 
250 status_t
251 BDeskbar::AddItem(BView *view, int32 *_id)
252 {
253 	BMessage archive;
254 	status_t result = view->Archive(&archive);
255 	if (result < B_OK)
256 		return result;
257 
258 	BMessage request(kMsgAddView);
259 	request.AddMessage("view", &archive);
260 
261 	BMessage reply;
262 	result = fMessenger->SendMessage(&request, &reply);
263 	if (result == B_OK) {
264 		if (_id != NULL)
265 			result = reply.FindInt32("id", _id);
266 		else
267 			reply.FindInt32("error", &result);
268 	}
269 
270 	return result;
271 }
272 
273 
274 status_t
275 BDeskbar::AddItem(entry_ref *addon, int32 *_id)
276 {
277 	BMessage request(kMsgAddAddOn);
278 	request.AddRef("addon", addon);
279 
280 	BMessage reply;
281 	status_t status = fMessenger->SendMessage(&request, &reply);
282 	if (status == B_OK) {
283 		if (_id != NULL)
284 			status = reply.FindInt32("id", _id);
285 		else
286 			reply.FindInt32("error", &status);
287 	}
288 
289 	return status;
290 }
291 
292 
293 status_t
294 BDeskbar::RemoveItem(int32 id)
295 {
296 	BMessage request(kMsgRemoveItem);
297 	request.AddInt32("id", id);
298 
299 	// ToDo: the Deskbar does not reply to this message, so we don't
300 	// know if it really succeeded - we can just acknowledge that the
301 	// message was sent to the Deskbar
302 
303 	return fMessenger->SendMessage(&request);
304 }
305 
306 
307 status_t
308 BDeskbar::RemoveItem(const char *name)
309 {
310 	BMessage request(kMsgRemoveItem);
311 	request.AddString("name", name);
312 
313 	// ToDo: the Deskbar does not reply to this message, so we don't
314 	// know if it really succeeded - we can just acknowledge that the
315 	// message was sent to the Deskbar
316 
317 	return fMessenger->SendMessage(&request);
318 
319 }
320 
321