vfs: check userland buffers before reading them.
[haiku.git] / src / kits / interface / Deskbar.cpp
blob0d1bc062d1b67b709889e0870687477d4e3ac09e
1 /*
2 * Copyright 2001-2017 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Jérôme Duval
7 * Axel Dörfler
8 * Jeremy Rand, jrand@magma.ca
9 * John Scipione, jscipione@gmail.com
13 #include <Deskbar.h>
14 #include <Messenger.h>
15 #include <Message.h>
16 #include <View.h>
17 #include <Rect.h>
18 #include <InterfaceDefs.h>
19 #include <Node.h>
21 #include <string.h>
24 // ToDo: in case the BDeskbar methods are called from a Deskbar add-on,
25 // they will currently deadlock most of the time (only those that do
26 // not need a reply will work).
27 // That should be fixed in the Deskbar itself, even if the Be API found
28 // a way around that (that doesn't work too well, BTW)
30 // The API in this file should be considered as part of OpenTracker - but
31 // should work with all versions of Tracker available for Haiku.
34 static const char* kDeskbarSignature = "application/x-vnd.Be-TSKB";
36 static const uint32 kMsgIsAlwaysOnTop = 'gtop';
37 static const uint32 kMsgAlwaysOnTop = 'stop';
38 static const uint32 kMsgIsAutoRaise = 'grse';
39 static const uint32 kMsgAutoRaise = 'srse';
40 static const uint32 kMsgIsAutoHide = 'ghid';
41 static const uint32 kMsgAutoHide = 'shid';
43 static const uint32 kMsgAddView = 'icon';
44 static const uint32 kMsgAddAddOn = 'adon';
45 static const uint32 kMsgHasItem = 'exst';
46 static const uint32 kMsgGetItemInfo = 'info';
47 static const uint32 kMsgCountItems = 'cwnt';
48 static const uint32 kMsgRemoveItem = 'remv';
49 static const uint32 kMsgLocation = 'gloc';
50 static const uint32 kMsgIsExpanded = 'gexp';
51 static const uint32 kMsgSetLocation = 'sloc';
52 static const uint32 kMsgExpand = 'sexp';
55 status_t
56 get_deskbar_frame(BRect* frame)
58 BMessenger deskbar(kDeskbarSignature);
60 status_t result;
62 BMessage request(B_GET_PROPERTY);
63 request.AddSpecifier("Frame");
64 request.AddSpecifier("Window", "Deskbar");
66 BMessage reply;
67 result = deskbar.SendMessage(&request, &reply);
68 if (result == B_OK)
69 result = reply.FindRect("result", frame);
71 return result;
75 // #pragma mark - BDeskbar
78 BDeskbar::BDeskbar()
80 fMessenger(new BMessenger(kDeskbarSignature))
85 BDeskbar::~BDeskbar()
87 delete fMessenger;
91 bool
92 BDeskbar::IsRunning() const
94 return fMessenger->IsValid();
98 // #pragma mark - Item querying methods
101 BRect
102 BDeskbar::Frame() const
104 BRect frame(0.0, 0.0, 0.0, 0.0);
105 get_deskbar_frame(&frame);
107 return frame;
111 deskbar_location
112 BDeskbar::Location(bool* _isExpanded) const
114 deskbar_location location = B_DESKBAR_RIGHT_TOP;
115 BMessage request(kMsgLocation);
116 BMessage reply;
118 if (_isExpanded)
119 *_isExpanded = true;
121 if (fMessenger->IsTargetLocal()) {
122 // ToDo: do something about this!
123 // (if we just ask the Deskbar in this case, we would deadlock)
124 return location;
127 if (fMessenger->SendMessage(&request, &reply) == B_OK) {
128 int32 value;
129 if (reply.FindInt32("location", &value) == B_OK)
130 location = static_cast<deskbar_location>(value);
132 if (_isExpanded && reply.FindBool("expanded", _isExpanded) != B_OK)
133 *_isExpanded = true;
136 return location;
140 status_t
141 BDeskbar::SetLocation(deskbar_location location, bool expanded)
143 BMessage request(kMsgSetLocation);
144 request.AddInt32("location", static_cast<int32>(location));
145 request.AddBool("expand", expanded);
147 return fMessenger->SendMessage(&request);
151 // #pragma mark - Other state methods
154 bool
155 BDeskbar::IsExpanded() const
157 BMessage request(kMsgIsExpanded);
158 BMessage reply;
159 bool isExpanded = true;
161 if (fMessenger->SendMessage(&request, &reply) == B_OK)
162 reply.FindBool("expanded", &isExpanded);
164 return isExpanded;
168 status_t
169 BDeskbar::Expand(bool expand)
171 BMessage request(kMsgExpand);
172 request.AddBool("expand", expand);
174 return fMessenger->SendMessage(&request);
178 bool
179 BDeskbar::IsAlwaysOnTop() const
181 BMessage request(kMsgIsAlwaysOnTop);
182 BMessage reply;
183 bool isAlwaysOnTop = false;
185 if (fMessenger->SendMessage(&request, &reply) == B_OK)
186 reply.FindBool("always on top", &isAlwaysOnTop);
188 return isAlwaysOnTop;
192 status_t
193 BDeskbar::SetAlwaysOnTop(bool alwaysOnTop)
195 BMessage request(kMsgAlwaysOnTop);
196 request.AddBool("always on top", alwaysOnTop);
198 return fMessenger->SendMessage(&request);
202 bool
203 BDeskbar::IsAutoRaise() const
205 BMessage request(kMsgIsAutoRaise);
206 BMessage reply;
207 bool isAutoRaise = false;
209 if (fMessenger->SendMessage(&request, &reply) == B_OK)
210 reply.FindBool("auto raise", &isAutoRaise);
212 return isAutoRaise;
216 status_t
217 BDeskbar::SetAutoRaise(bool autoRaise)
219 BMessage request(kMsgAutoRaise);
220 request.AddBool("auto raise", autoRaise);
222 return fMessenger->SendMessage(&request);
226 bool
227 BDeskbar::IsAutoHide() const
229 BMessage request(kMsgIsAutoHide);
230 BMessage reply;
231 bool isAutoHidden = false;
233 if (fMessenger->SendMessage(&request, &reply) == B_OK)
234 reply.FindBool("auto hide", &isAutoHidden);
236 return isAutoHidden;
240 status_t
241 BDeskbar::SetAutoHide(bool autoHide)
243 BMessage request(kMsgAutoHide);
244 request.AddBool("auto hide", autoHide);
246 return fMessenger->SendMessage(&request);
250 // #pragma mark - Item querying methods
253 status_t
254 BDeskbar::GetItemInfo(int32 id, const char** _name) const
256 if (_name == NULL)
257 return B_BAD_VALUE;
259 // Note: Be's implementation returns B_BAD_VALUE if *_name was NULL,
260 // not just if _name was NULL. This doesn't make much sense, so we
261 // do not imitate this behaviour.
263 BMessage request(kMsgGetItemInfo);
264 request.AddInt32("id", id);
266 BMessage reply;
267 status_t result = fMessenger->SendMessage(&request, &reply);
268 if (result == B_OK) {
269 const char* name;
270 result = reply.FindString("name", &name);
271 if (result == B_OK) {
272 *_name = strdup(name);
273 if (*_name == NULL)
274 result = B_NO_MEMORY;
278 return result;
282 status_t
283 BDeskbar::GetItemInfo(const char* name, int32* _id) const
285 if (name == NULL)
286 return B_BAD_VALUE;
288 BMessage request(kMsgGetItemInfo);
289 request.AddString("name", name);
291 BMessage reply;
292 status_t result = fMessenger->SendMessage(&request, &reply);
293 if (result == B_OK)
294 result = reply.FindInt32("id", _id);
296 return result;
300 bool
301 BDeskbar::HasItem(int32 id) const
303 BMessage request(kMsgHasItem);
304 request.AddInt32("id", id);
306 BMessage reply;
307 if (fMessenger->SendMessage(&request, &reply) == B_OK)
308 return reply.FindBool("exists");
310 return false;
314 bool
315 BDeskbar::HasItem(const char* name) const
317 BMessage request(kMsgHasItem);
318 request.AddString("name", name);
320 BMessage reply;
321 if (fMessenger->SendMessage(&request, &reply) == B_OK)
322 return reply.FindBool("exists");
324 return false;
328 uint32
329 BDeskbar::CountItems() const
331 BMessage request(kMsgCountItems);
332 BMessage reply;
334 if (fMessenger->SendMessage(&request, &reply) == B_OK)
335 return reply.FindInt32("count");
337 return 0;
341 // #pragma mark - Item querying methods
344 status_t
345 BDeskbar::AddItem(BView* view, int32* _id)
347 BMessage archive;
348 status_t result = view->Archive(&archive);
349 if (result < B_OK)
350 return result;
352 BMessage request(kMsgAddView);
353 request.AddMessage("view", &archive);
355 BMessage reply;
356 result = fMessenger->SendMessage(&request, &reply);
357 if (result == B_OK) {
358 if (_id != NULL)
359 result = reply.FindInt32("id", _id);
360 else
361 reply.FindInt32("error", &result);
364 return result;
368 status_t
369 BDeskbar::AddItem(entry_ref* addon, int32* _id)
371 BMessage request(kMsgAddAddOn);
372 request.AddRef("addon", addon);
374 BMessage reply;
375 status_t status = fMessenger->SendMessage(&request, &reply);
376 if (status == B_OK) {
377 if (_id != NULL)
378 status = reply.FindInt32("id", _id);
379 else
380 reply.FindInt32("error", &status);
383 return status;
387 status_t
388 BDeskbar::RemoveItem(int32 id)
390 BMessage request(kMsgRemoveItem);
391 request.AddInt32("id", id);
393 // ToDo: the Deskbar does not reply to this message, so we don't
394 // know if it really succeeded - we can just acknowledge that the
395 // message was sent to the Deskbar
397 return fMessenger->SendMessage(&request);
401 status_t
402 BDeskbar::RemoveItem(const char* name)
404 BMessage request(kMsgRemoveItem);
405 request.AddString("name", name);
407 // ToDo: the Deskbar does not reply to this message, so we don't
408 // know if it really succeeded - we can just acknowledge that the
409 // message was sent to the Deskbar
411 return fMessenger->SendMessage(&request);