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 "elm_systray_watcher.h"
10 
11 #define OBJ       "/StatusNotifierWatcher"
12 #define BUS       "org.kde.StatusNotifierWatcher"
13 #define INTERFACE "org.kde.StatusNotifierWatcher"
14 
15 static Eina_Bool _elm_systray_watcher = EINA_FALSE;
16 
17 static Eldbus_Connection *_watcher_conn  = NULL;
18 static Eldbus_Object     *_watcher_obj   = NULL;
19 static Eldbus_Proxy      *_watcher_proxy = NULL;
20 
21 static void
_status_notifier_item_register_cb(void * data EINA_UNUSED,const Eldbus_Message * msg,Eldbus_Pending * pending EINA_UNUSED)22 _status_notifier_item_register_cb(void *data EINA_UNUSED,
23                                   const Eldbus_Message *msg,
24                                   Eldbus_Pending *pending EINA_UNUSED)
25 {
26    const char *errname, *errmsg;
27 
28    if (eldbus_message_error_get(msg, &errname, &errmsg))
29      ERR("Eldbus Error: %s %s", errname, errmsg);
30 }
31 
32 Eina_Bool
_elm_systray_watcher_status_notifier_item_register(const char * obj)33 _elm_systray_watcher_status_notifier_item_register(const char *obj)
34 {
35    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
36    EINA_SAFETY_ON_NULL_RETURN_VAL(_watcher_proxy, EINA_FALSE);
37 
38    if (!eldbus_proxy_call(_watcher_proxy, "RegisterStatusNotifierItem",
39                          _status_notifier_item_register_cb,
40                          NULL, -1, "s", obj))
41      {
42         ERR("Error sending message: "INTERFACE".RegisterStatusNotifierItem.");
43         return EINA_FALSE;
44      }
45 
46    return EINA_TRUE;
47 }
48 
49 static void
_release(void)50 _release(void)
51 {
52    if (_watcher_proxy)
53      {
54         eldbus_proxy_unref(_watcher_proxy);
55         _watcher_proxy = NULL;
56      }
57 
58    if (_watcher_obj)
59      {
60         eldbus_object_unref(_watcher_obj);
61         _watcher_obj = NULL;
62      }
63 }
64 
65 static void
_update(void)66 _update(void)
67 {
68    _release();
69 
70    _watcher_obj = eldbus_object_get(_watcher_conn, BUS, OBJ);
71    _watcher_proxy = eldbus_proxy_get(_watcher_obj, INTERFACE);
72 
73    ecore_event_add(ELM_EVENT_SYSTRAY_READY, NULL, NULL, NULL);
74 }
75 
76 static void
_name_owner_changed_cb(void * data EINA_UNUSED,const char * bus EINA_UNUSED,const char * old_id EINA_UNUSED,const char * new_id)77 _name_owner_changed_cb(void *data EINA_UNUSED,
78                        const char *bus EINA_UNUSED,
79                        const char *old_id EINA_UNUSED,
80                        const char *new_id)
81 {
82    if ((!new_id) || (*new_id == '\0'))
83      _release();
84    else
85      _update();
86 }
87 
88 Eina_Bool
_elm_systray_watcher_init(void)89 _elm_systray_watcher_init(void)
90 {
91    if (_elm_systray_watcher) return EINA_TRUE;
92 
93    if (!elm_need_eldbus()) return EINA_FALSE;
94 
95    _watcher_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
96 
97    eldbus_name_owner_changed_callback_add(_watcher_conn, BUS,
98                                          _name_owner_changed_cb, NULL,
99                                          EINA_TRUE);
100 
101    _elm_systray_watcher = EINA_TRUE;
102    return EINA_TRUE;
103 }
104 
105 void
_elm_systray_watcher_shutdown(void)106 _elm_systray_watcher_shutdown(void)
107 {
108    if (!_elm_systray_watcher) return;
109 
110    _elm_systray_watcher = EINA_FALSE;
111 
112    _release();
113 
114    eldbus_connection_unref(_watcher_conn);
115    _watcher_conn = NULL;
116 }
117