summaryrefslogtreecommitdiff
path: root/src/lib/elementary/elm_systray.c
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2016-03-23 12:56:14 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-03-23 13:24:41 -0700
commitc2a1c49ab2042f559b28e840e54feb8494888e0e (patch)
treec6eb110b7c479499854eede9d0c3ab0a80c9a11a /src/lib/elementary/elm_systray.c
parent9340855597e7e465435c69b6278650346688da14 (diff)
elementary: move all legacy files to their expected new location.
Diffstat (limited to 'src/lib/elementary/elm_systray.c')
-rw-r--r--src/lib/elementary/elm_systray.c518
1 files changed, 518 insertions, 0 deletions
diff --git a/src/lib/elementary/elm_systray.c b/src/lib/elementary/elm_systray.c
new file mode 100644
index 0000000000..45ca4696da
--- /dev/null
+++ b/src/lib/elementary/elm_systray.c
@@ -0,0 +1,518 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6
7#include "elm_priv.h"
8
9#include "Eo.h"
10
11#include "elm_systray_watcher.h"
12
13EAPI int ELM_EVENT_SYSTRAY_READY = 0;
14
15typedef struct _Elm_Systray_Private_Data
16{
17 Elm_Systray_Category cat;
18 Elm_Systray_Status status;
19
20 const char *att_icon_name;
21 const char *icon_name;
22 const char *icon_theme_path;
23 const char *id;
24 const char *title;
25 const char *menu;
26 const Eo *menu_obj;
27} Elm_Systray_Private_Data;
28
29static Elm_Systray_Private_Data _item = {
30 .cat = ELM_SYSTRAY_CATEGORY_APP_STATUS,
31 .status = ELM_SYSTRAY_STATUS_ACTIVE,
32 .att_icon_name = NULL,
33 .icon_name = NULL,
34 .icon_theme_path = NULL,
35 .id = NULL,
36 .title = NULL,
37 .menu = NULL,
38 .menu_obj = NULL
39};
40
41#define OBJ_PATH "/org/ayatana/NotificationItem/StatusNotifierItem"
42#define INTERFACE "org.kde.StatusNotifierItem"
43
44static Eina_Bool _elm_need_systray = EINA_FALSE;
45
46static Eldbus_Connection *_conn = NULL;
47static Eldbus_Service_Interface *_iface = NULL;
48
49static const char *_Elm_Systray_Cat_Str[] = {
50 [ELM_SYSTRAY_CATEGORY_APP_STATUS] = "ApplicationStatus",
51 [ELM_SYSTRAY_CATEGORY_COMMUNICATIONS] = "Communications",
52 [ELM_SYSTRAY_CATEGORY_SYS_SERVICES] = "SystemServices",
53 [ELM_SYSTRAY_CATEGORY_HARDWARE] = "Hardware",
54 [ELM_SYSTRAY_CATEGORY_OTHER] = "Other"
55};
56
57static const char *_Elm_Systray_Status_Str[] = {
58 [ELM_SYSTRAY_STATUS_ACTIVE] = "Active",
59 [ELM_SYSTRAY_STATUS_PASSIVE] = "Passive",
60 [ELM_SYSTRAY_STATUS_ATTENTION] = "NeedsAttention"
61};
62
63// =============================================================================
64// org.kde.StatusNotifierItem Service
65// =============================================================================
66// =============================================================================
67// Methods
68// =============================================================================
69static Eldbus_Message *
70_empty_method(const Eldbus_Service_Interface *iface EINA_UNUSED,
71 const Eldbus_Message *msg)
72{
73 return eldbus_message_method_return_new(msg);
74}
75
76static const Eldbus_Method methods[] = {
77 {
78 "Scroll",
79 ELDBUS_ARGS({"i", "delta"}, {"s", "orientation"}),
80 NULL,
81 _empty_method,
82 0
83 },
84 {
85 "SecondaryActivate",
86 ELDBUS_ARGS({"i", "x"}, {"i", "y"}),
87 NULL,
88 _empty_method,
89 0
90 },
91 {
92 "XAyatanaSecondaryActivate",
93 ELDBUS_ARGS({"u", "timestamp"}),
94 NULL,
95 _empty_method,
96 0
97 },
98 { NULL, NULL, NULL, NULL, 0 }
99};
100
101// =============================================================================
102// Signals
103// =============================================================================
104typedef enum _Elm_Systray_Service_Signals
105{
106 ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON,
107 ELM_SYSTRAY_SIGNAL_NEWICON,
108 ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
109 ELM_SYSTRAY_SIGNAL_NEWSTATUS,
110 ELM_SYSTRAY_SIGNAL_NEWTITLE,
111 ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL
112} Elm_Systray_Service_Signals;
113
114#define _elm_systray_signal_emit(sig, ...) \
115 eldbus_service_signal_emit(_iface, sig, __VA_ARGS__)
116
117static const Eldbus_Signal signals[] = {
118 [ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON] = {
119 "NewAttentionIcon", NULL, 0
120 },
121 [ELM_SYSTRAY_SIGNAL_NEWICON] = {
122 "NewIcon", NULL, 0
123 },
124 [ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH] = {
125 "NewIconThemePath", ELDBUS_ARGS({"s", "icon_theme_path"}), 0
126 },
127 [ELM_SYSTRAY_SIGNAL_NEWSTATUS] = {
128 "NewStatus", ELDBUS_ARGS({"s", "status"}), 0
129 },
130 [ELM_SYSTRAY_SIGNAL_NEWTITLE] = {
131 "NewTitle", NULL, 0
132 },
133 [ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL] = {
134 "XAyatanaNewLabel", ELDBUS_ARGS({"s", "label"}, {"s", "guide"}), 0
135 },
136 { NULL, NULL, 0 }
137};
138
139// =============================================================================
140// Properties
141// =============================================================================
142static Eina_Bool
143_prop_str_empty_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
144 const char *propname EINA_UNUSED,
145 Eldbus_Message_Iter *iter,
146 const Eldbus_Message *request_msg EINA_UNUSED,
147 Eldbus_Message **error EINA_UNUSED)
148{
149 eldbus_message_iter_basic_append(iter, 's', "");
150
151 return EINA_TRUE;
152}
153
154static Eina_Bool
155_prop_attention_icon_name_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
156 const char *propname EINA_UNUSED,
157 Eldbus_Message_Iter *iter,
158 const Eldbus_Message *request_msg EINA_UNUSED,
159 Eldbus_Message **error EINA_UNUSED)
160{
161 const char *s = _item.att_icon_name ? _item.att_icon_name : "";
162
163 eldbus_message_iter_basic_append(iter, 's', s);
164
165 return EINA_TRUE;
166}
167
168static Eina_Bool
169_prop_category_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
170 const char *propname EINA_UNUSED,
171 Eldbus_Message_Iter *iter,
172 const Eldbus_Message *request_msg EINA_UNUSED,
173 Eldbus_Message **error EINA_UNUSED)
174{
175 eldbus_message_iter_basic_append(iter, 's', _Elm_Systray_Cat_Str[_item.cat]);
176
177 return EINA_TRUE;
178}
179
180static Eina_Bool
181_prop_icon_name_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
182 const char *propname EINA_UNUSED,
183 Eldbus_Message_Iter *iter,
184 const Eldbus_Message *request_msg EINA_UNUSED,
185 Eldbus_Message **error EINA_UNUSED)
186{
187 const char *s = _item.icon_name ? _item.icon_name : "";
188
189 eldbus_message_iter_basic_append(iter, 's', s);
190
191 return EINA_TRUE;
192}
193
194static Eina_Bool
195_prop_icon_theme_path_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
196 const char *propname EINA_UNUSED,
197 Eldbus_Message_Iter *iter,
198 const Eldbus_Message *request_msg EINA_UNUSED,
199 Eldbus_Message **error EINA_UNUSED)
200{
201 const char *s = _item.icon_theme_path ? _item.icon_theme_path : "";
202
203 eldbus_message_iter_basic_append(iter, 's', s);
204
205 return EINA_TRUE;
206}
207
208static Eina_Bool
209_prop_id_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
210 const char *propname EINA_UNUSED,
211 Eldbus_Message_Iter *iter,
212 const Eldbus_Message *request_msg EINA_UNUSED,
213 Eldbus_Message **error EINA_UNUSED)
214{
215 const char *s = _item.id ? _item.id : "";
216
217 eldbus_message_iter_basic_append(iter, 's', s);
218
219 return EINA_TRUE;
220}
221
222static Eina_Bool
223_prop_menu_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
224 const char *propname EINA_UNUSED,
225 Eldbus_Message_Iter *iter,
226 const Eldbus_Message *request_msg EINA_UNUSED,
227 Eldbus_Message **error EINA_UNUSED)
228{
229 const char *s = _item.menu ? _item.menu : "/";
230
231 eldbus_message_iter_basic_append(iter, 'o', s);
232
233 return EINA_TRUE;
234}
235
236static Eina_Bool
237_prop_status_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
238 const char *propname EINA_UNUSED,
239 Eldbus_Message_Iter *iter,
240 const Eldbus_Message *request_msg EINA_UNUSED,
241 Eldbus_Message **error EINA_UNUSED)
242{
243 eldbus_message_iter_basic_append(iter, 's',
244 _Elm_Systray_Status_Str[_item.status]);
245
246 return EINA_TRUE;
247}
248
249static Eina_Bool
250_prop_title_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
251 const char *propname EINA_UNUSED,
252 Eldbus_Message_Iter *iter,
253 const Eldbus_Message *request_msg EINA_UNUSED,
254 Eldbus_Message **error EINA_UNUSED)
255{
256 const char *s = _item.title ? _item.title : "";
257
258 eldbus_message_iter_basic_append(iter, 's', s);
259
260 return EINA_TRUE;
261}
262
263static Eina_Bool
264_prop_xayatana_orderindex_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
265 const char *propname EINA_UNUSED,
266 Eldbus_Message_Iter *iter,
267 const Eldbus_Message *request_msg EINA_UNUSED,
268 Eldbus_Message **error EINA_UNUSED)
269{
270 eldbus_message_iter_basic_append(iter, 'u', 0);
271
272 return EINA_TRUE;
273}
274
275static const Eldbus_Property properties[] = {
276 { "AttentionAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
277 { "AttentionIconName", "s", _prop_attention_icon_name_get, NULL, 0 },
278 { "Category", "s", _prop_category_get, NULL, 0 },
279 { "IconAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
280 { "IconName", "s", _prop_icon_name_get, NULL, 0 },
281 { "IconThemePath", "s", _prop_icon_theme_path_get, NULL, 0 },
282 { "Id", "s", _prop_id_get, NULL, 0 },
283 { "Menu", "o", _prop_menu_get, NULL, 0 },
284 { "Status", "s", _prop_status_get, NULL, 0 },
285 { "Title", "s", _prop_title_get, NULL, 0 },
286 { "XAyatanaLabelGuide", "s", _prop_str_empty_get, NULL, 0 },
287 { "XAyatanaLabel", "s", _prop_str_empty_get, NULL, 0 },
288 { "XAyatanaOrderingIndex", "u", _prop_xayatana_orderindex_get, NULL, 0 },
289 { NULL, NULL, NULL, NULL, 0 }
290};
291
292static const Eldbus_Service_Interface_Desc _iface_desc = {
293 INTERFACE, methods, signals, properties, NULL, NULL
294};
295// =============================================================================
296
297static void
298_menu_died(void *data EINA_UNUSED,
299 Evas *e EINA_UNUSED,
300 Evas_Object *obj EINA_UNUSED,
301 void *event_info EINA_UNUSED)
302{
303 _item.menu_obj = NULL;
304
305 eina_stringshare_replace(&(_item.menu), NULL);
306
307 eldbus_service_property_changed(_iface, "Menu");
308}
309
310EOLIAN static void
311_elm_systray_category_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, Elm_Systray_Category cat)
312{
313 if (_item.cat == cat) return;
314
315 _item.cat = cat;
316 eldbus_service_property_changed(_iface, "Category");
317}
318
319EOLIAN static Elm_Systray_Category
320_elm_systray_category_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
321{
322 return _item.cat;
323}
324
325EOLIAN static void
326_elm_systray_status_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, Elm_Systray_Status st)
327{
328 if (_item.status == st) return;
329
330 _item.status = st;
331 eldbus_service_property_changed(_iface, "Status");
332 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWSTATUS,
333 _Elm_Systray_Status_Str[_item.status]);
334}
335
336EOLIAN static Elm_Systray_Status
337_elm_systray_status_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
338{
339 return _item.status;
340}
341
342EOLIAN static void
343_elm_systray_att_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *att_icon_name)
344{
345 if (!eina_stringshare_replace(&(_item.att_icon_name), att_icon_name)) return;
346
347 eldbus_service_property_changed(_iface, "AttentionIconName");
348 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON, NULL);
349}
350
351EOLIAN static const char*
352_elm_systray_att_icon_name_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
353{
354 return _item.att_icon_name;
355}
356
357EOLIAN static void
358_elm_systray_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *icon_name)
359{
360 if (!eina_stringshare_replace(&(_item.icon_name), icon_name)) return;
361
362 eldbus_service_property_changed(_iface, "IconName");
363 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICON, NULL);
364}
365
366EOLIAN static const char*
367_elm_systray_icon_name_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
368{
369 return _item.icon_name;
370}
371
372EOLIAN static void
373_elm_systray_icon_theme_path_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *icon_theme_path)
374{
375 if (!eina_stringshare_replace(&(_item.icon_theme_path), icon_theme_path))
376 return;
377
378 eldbus_service_property_changed(_iface, "IconThemePath");
379 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
380 _item.icon_theme_path);
381}
382
383EOLIAN static const char*
384_elm_systray_icon_theme_path_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
385{
386 return _item.icon_theme_path;
387}
388
389EOLIAN static void
390_elm_systray_id_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *id)
391{
392 if (!eina_stringshare_replace(&(_item.id), id)) return;
393
394 eldbus_service_property_changed(_iface, "Id");
395}
396
397EOLIAN static const char*
398_elm_systray_id_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
399{
400 return _item.id;
401}
402
403EOLIAN static void
404_elm_systray_title_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *title)
405{
406 if (!eina_stringshare_replace(&(_item.title), title)) return;
407
408 eldbus_service_property_changed(_iface, "Title");
409 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWTITLE, NULL);
410}
411
412EOLIAN static const char*
413_elm_systray_title_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
414{
415 return _item.title;
416}
417
418EOLIAN static void
419_elm_systray_menu_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const Eo *menu_obj)
420{
421 const char *menu = NULL;
422
423 if (_item.menu_obj == menu_obj) return;
424
425 if (menu_obj)
426 {
427 menu = _elm_dbus_menu_register((Eo *) menu_obj);
428 evas_object_event_callback_add((Evas_Object *) menu_obj,
429 EVAS_CALLBACK_DEL, _menu_died, NULL);
430 }
431
432 eina_stringshare_replace(&(_item.menu), menu);
433
434 if (_item.menu_obj)
435 evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
436 EVAS_CALLBACK_DEL, _menu_died, NULL);
437
438 _item.menu_obj = menu_obj;
439
440 eldbus_service_property_changed(_iface, "Menu");
441}
442
443EOLIAN static const Eo*
444_elm_systray_menu_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
445{
446 return _item.menu_obj;
447}
448
449EOLIAN static Eina_Bool
450_elm_systray_register(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
451{
452 if (!_elm_need_systray) return EINA_FALSE;
453
454 return _elm_systray_watcher_status_notifier_item_register(OBJ_PATH);
455}
456
457EAPI Eina_Bool
458elm_need_systray(void)
459{
460 if (_elm_need_systray) return EINA_TRUE;
461
462 if (!elm_need_eldbus()) return EINA_FALSE;
463
464 if (!ELM_EVENT_SYSTRAY_READY)
465 ELM_EVENT_SYSTRAY_READY = ecore_event_type_new();
466
467 if (!_elm_systray_watcher_init()) return EINA_FALSE;
468
469 _conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
470 if (!_conn) goto err;
471
472 _iface = eldbus_service_interface_register(_conn, OBJ_PATH, &_iface_desc);
473 if (!_iface) goto err;
474
475 _elm_need_systray = EINA_TRUE;
476 return EINA_TRUE;
477
478err:
479 if (_conn)
480 {
481 eldbus_connection_unref(_conn);
482 _conn = NULL;
483 }
484
485 _elm_systray_watcher_shutdown();
486 return EINA_FALSE;
487}
488
489void
490_elm_unneed_systray(void)
491{
492 if (!_elm_need_systray) return;
493
494 _elm_need_systray = EINA_FALSE;
495
496 eldbus_service_interface_unregister(_iface);
497
498 eldbus_connection_unref(_conn);
499
500 _elm_systray_watcher_shutdown();
501
502 eina_stringshare_del(_item.att_icon_name);
503 eina_stringshare_del(_item.icon_name);
504 eina_stringshare_del(_item.icon_theme_path);
505 eina_stringshare_del(_item.id);
506 eina_stringshare_del(_item.title);
507 eina_stringshare_del(_item.menu);
508
509 if (_item.menu_obj)
510 {
511 evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
512 EVAS_CALLBACK_DEL, _menu_died,
513 NULL);
514 _item.menu_obj = NULL;
515 }
516}
517
518#include "elm_systray.eo.c"