~ubuntu-branches/ubuntu/trusty/modem-manager-gui/trusty-backports

« back to all changes in this revision

Viewing changes to src/ayatana.c

  • Committer: Package Import Robot
  • Author(s): Graham Inggs
  • Date: 2013-07-30 12:51:59 UTC
  • Revision ID: package-import@ubuntu.com-20130730125159-flzv882fhuzhmfmi
Tags: upstream-0.0.16
ImportĀ upstreamĀ versionĀ 0.0.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      ayatana.c
 
3
 *      
 
4
 *      Copyright 2013 Alex <alex@linuxonly.ru>
 
5
 *      
 
6
 *      This program is free software: you can redistribute it and/or modify
 
7
 *      it under the terms of the GNU General Public License as published by
 
8
 *      the Free Software Foundation; either version 3 of the License, or
 
9
 *      (at your option) any later version.
 
10
 *      
 
11
 *      This program is distributed in the hope that it will be useful,
 
12
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *      GNU General Public License for more details.
 
15
 *      
 
16
 *      You should have received a copy of the GNU General Public License
 
17
 *      along with this program. If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <glib/gi18n.h>
 
22
#include <gio/gio.h>
 
23
#include <gmodule.h>
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
#include <string.h>
 
27
 
 
28
#include "resources.h"
 
29
#include "ayatana.h"
 
30
 
 
31
static void mmgui_ayatana_indicator_server_clicked_signal(MessagingMenuApp *server, guint timestamp, gpointer user_data)
 
32
{
 
33
        mmgui_ayatana_t ayatana;
 
34
        
 
35
        ayatana = (mmgui_ayatana_t)user_data;
 
36
        
 
37
        if (ayatana == NULL) return;
 
38
        
 
39
        if (ayatana->eventcb != NULL) {
 
40
                (ayatana->eventcb)(MMGUI_AYATANA_EVENT_SERVER, ayatana, NULL, ayatana->userdata);
 
41
        }
 
42
}
 
43
 
 
44
static void mmgui_ayatana_indicator_client_clicked_signal(MessagingMenuApp *indicator, guint timestamp, gpointer user_data)
 
45
{
 
46
        mmgui_ayatana_t ayatana;
 
47
        
 
48
        ayatana = (mmgui_ayatana_t)user_data;
 
49
        
 
50
        if (ayatana == NULL) return;
 
51
        
 
52
        if (ayatana->eventcb != NULL) {
 
53
                (ayatana->eventcb)(MMGUI_AYATANA_EVENT_CLIENT, ayatana, NULL, ayatana->userdata);
 
54
        }
 
55
}
 
56
 
 
57
static void mmgui_ayatana_indicator_server_show_signal(IndicateServer *arg0, guint arg1, gpointer user_data)
 
58
{
 
59
        mmgui_ayatana_t ayatana;
 
60
        
 
61
        ayatana = (mmgui_ayatana_t)user_data;
 
62
        
 
63
        if (ayatana == NULL) return;
 
64
        
 
65
        if (ayatana->eventcb != NULL) {
 
66
                (ayatana->eventcb)(MMGUI_AYATANA_EVENT_SERVER, ayatana, NULL, ayatana->userdata);
 
67
        }
 
68
}
 
69
 
 
70
static void mmgui_ayatana_indicator_client_show_signal(IndicateServer *arg0, guint arg1, gpointer user_data)
 
71
{
 
72
        mmgui_ayatana_t ayatana;
 
73
        
 
74
        ayatana = (mmgui_ayatana_t)user_data;
 
75
        
 
76
        if (ayatana == NULL) return;
 
77
        
 
78
        if (ayatana->eventcb != NULL) {
 
79
                (ayatana->eventcb)(MMGUI_AYATANA_EVENT_CLIENT, ayatana, NULL, ayatana->userdata);
 
80
        }
 
81
}
 
82
 
 
83
static gchar *mmgui_ayatana_get_desktiop_file_id(gchar *filepath)
 
84
{
 
85
        guint pathlen, sym;
 
86
        
 
87
        if (filepath == NULL) return NULL;
 
88
        
 
89
        pathlen = strlen(filepath);
 
90
        
 
91
        if (pathlen == 0) return NULL;
 
92
        
 
93
        for (sym = pathlen; sym >= 0; sym--) {
 
94
                if (filepath[sym] == '/') {
 
95
                        break;
 
96
                }
 
97
        }
 
98
        
 
99
        return filepath+sym+1;
 
100
}
 
101
 
 
102
static gboolean mmgui_ayatana_setup_menu(mmgui_ayatana_t ayatana)
 
103
{
 
104
        if (ayatana == NULL) return FALSE;
 
105
        
 
106
        if (ayatana->library == MMGUI_AYATANA_LIB_MESSAGINGMENU) {
 
107
                /*setup server*/
 
108
                ayatana->backend.mmenu.server = (ayatana->backend.mmenu.messaging_menu_app_new)(mmgui_ayatana_get_desktiop_file_id(RESOURCE_DESKTOP_FILE));
 
109
                if (ayatana->backend.mmenu.server == NULL) {
 
110
                        return FALSE;
 
111
                }
 
112
                (ayatana->backend.mmenu.messaging_menu_app_register)(ayatana->backend.mmenu.server);
 
113
                g_signal_connect(G_OBJECT(ayatana->backend.mmenu.server), "activate-source", G_CALLBACK(mmgui_ayatana_indicator_server_clicked_signal), ayatana);
 
114
                return TRUE;
 
115
        } else if (ayatana->library == MMGUI_AYATANA_LIB_INDICATE) {
 
116
                /*setup server*/
 
117
                ayatana->backend.ind.server = (ayatana->backend.ind.indicate_server_ref_default)();
 
118
                if (ayatana->backend.ind.server == NULL) {
 
119
                        return FALSE;
 
120
                }
 
121
                (ayatana->backend.ind.indicate_server_set_type)(ayatana->backend.ind.server, "message.im");
 
122
                (ayatana->backend.ind.indicate_server_set_desktop_file)(ayatana->backend.ind.server, RESOURCE_DESKTOP_FILE);
 
123
                (ayatana->backend.ind.indicate_server_show)(ayatana->backend.ind.server);
 
124
                g_signal_connect(G_OBJECT(ayatana->backend.ind.server), "server-display", G_CALLBACK(mmgui_ayatana_indicator_server_show_signal), ayatana);
 
125
                /*setup client*/
 
126
                ayatana->backend.ind.client = (ayatana->backend.ind.indicate_indicator_new_with_server)(ayatana->backend.ind.server);
 
127
                if (ayatana->backend.ind.client != NULL) {
 
128
                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "subtype", "im");
 
129
                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "sender", _("Unread SMS"));
 
130
                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "draw_attention", "false");
 
131
                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "count", "");
 
132
                        (ayatana->backend.ind.indicate_indicator_show)(ayatana->backend.ind.client);
 
133
                        g_signal_connect(G_OBJECT(ayatana->backend.ind.client), "user-display", G_CALLBACK(mmgui_ayatana_indicator_client_show_signal), ayatana);
 
134
                }
 
135
                return TRUE;
 
136
        } else {
 
137
                return FALSE;
 
138
        }
 
139
}
 
140
 
 
141
static gboolean mmgui_ayatana_clean_menu(mmgui_ayatana_t ayatana)
 
142
{
 
143
        if (ayatana == NULL) return FALSE;
 
144
        
 
145
        if (ayatana->library == MMGUI_AYATANA_LIB_MESSAGINGMENU) {
 
146
                if (ayatana->backend.mmenu.server != NULL) {
 
147
                        (ayatana->backend.mmenu.messaging_menu_app_remove_source)(ayatana->backend.mmenu.server, "sms");
 
148
                        (ayatana->backend.mmenu.messaging_menu_app_unregister)(ayatana->backend.mmenu.server);
 
149
                }
 
150
                return TRUE;
 
151
        } else if (ayatana->library == MMGUI_AYATANA_LIB_INDICATE) {
 
152
                if (ayatana->backend.ind.server != NULL) {
 
153
                        if (ayatana->backend.ind.client != NULL) {
 
154
                                (ayatana->backend.ind.indicate_indicator_hide)(ayatana->backend.ind.client);
 
155
                                g_object_unref(G_OBJECT(ayatana->backend.ind.client));
 
156
                        }
 
157
                        (ayatana->backend.ind.indicate_server_hide)(ayatana->backend.ind.server);
 
158
                        g_object_unref(G_OBJECT(ayatana->backend.ind.server));
 
159
                }
 
160
                return TRUE;
 
161
        } else {
 
162
                return FALSE;
 
163
        }
 
164
}
 
165
 
 
166
mmgui_ayatana_t mmgui_ayatana_new(mmgui_libpaths_cache_t libcache, mmgui_ayatana_event_callback callback, gpointer userdata)
 
167
{
 
168
        mmgui_ayatana_t ayatana;
 
169
        gboolean libopened;
 
170
        
 
171
        ayatana = g_new0(struct _mmgui_ayatana, 1);
 
172
        
 
173
        /*Initialization*/
 
174
        ayatana->module = NULL;
 
175
        ayatana->library = MMGUI_AYATANA_LIB_NULL;
 
176
        ayatana->eventcb = callback;
 
177
        ayatana->userdata = userdata;
 
178
        
 
179
        /*Open module for libmessaging-menu*/
 
180
        ayatana->module = g_module_open(mmgui_libpaths_cache_get_library_name(libcache, "libmessaging-menu"), G_MODULE_BIND_LAZY);
 
181
        
 
182
        if (ayatana->module != NULL) {
 
183
                libopened = TRUE;
 
184
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_new", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_new));
 
185
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_register", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_register));
 
186
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_unregister", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_unregister));
 
187
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_append_source", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_append_source));
 
188
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_remove_source", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_remove_source));
 
189
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_set_source_count", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_set_source_count));
 
190
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_draw_attention", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_draw_attention));
 
191
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_remove_attention", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_remove_attention));
 
192
                libopened = libopened && g_module_symbol(ayatana->module, "messaging_menu_app_has_source", (gpointer *)&(ayatana->backend.mmenu.messaging_menu_app_has_source));
 
193
                /*Try to set up menu*/
 
194
                if (libopened) {
 
195
                        ayatana->library = MMGUI_AYATANA_LIB_MESSAGINGMENU;
 
196
                        if (!mmgui_ayatana_setup_menu(ayatana)) {
 
197
                                ayatana->library = MMGUI_AYATANA_LIB_NULL;
 
198
                        }
 
199
                }
 
200
                /*If some functions not exported or menu not set up, close library*/
 
201
                if ((!libopened) || (ayatana->library == MMGUI_AYATANA_LIB_NULL)) {
 
202
                        ayatana->backend.mmenu.messaging_menu_app_new = NULL;
 
203
                        ayatana->backend.mmenu.messaging_menu_app_register = NULL;
 
204
                        ayatana->backend.mmenu.messaging_menu_app_unregister = NULL;
 
205
                        ayatana->backend.mmenu.messaging_menu_app_append_source = NULL;
 
206
                        ayatana->backend.mmenu.messaging_menu_app_remove_source = NULL;
 
207
                        ayatana->backend.mmenu.messaging_menu_app_set_source_count = NULL;
 
208
                        ayatana->backend.mmenu.messaging_menu_app_draw_attention = NULL;
 
209
                        ayatana->backend.mmenu.messaging_menu_app_remove_attention = NULL;
 
210
                        /*Close module*/
 
211
                        g_module_close(ayatana->module);
 
212
                        ayatana->module = NULL;
 
213
                        ayatana->library = MMGUI_AYATANA_LIB_NULL;
 
214
                }
 
215
        }
 
216
        
 
217
        if ((ayatana->library == MMGUI_AYATANA_LIB_NULL) && (ayatana->module == NULL)) {
 
218
                /*Open module for libindicate*/
 
219
                ayatana->module = g_module_open(mmgui_libpaths_cache_get_library_name(libcache, "libindicate"), G_MODULE_BIND_LAZY);
 
220
                
 
221
                if (ayatana->module != NULL) {
 
222
                        libopened = TRUE;
 
223
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_server_ref_default", (gpointer *)&(ayatana->backend.ind.indicate_server_ref_default));
 
224
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_server_set_type", (gpointer *)&(ayatana->backend.ind.indicate_server_set_type));
 
225
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_server_set_desktop_file", (gpointer *)&(ayatana->backend.ind.indicate_server_set_desktop_file));
 
226
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_server_show", (gpointer *)&(ayatana->backend.ind.indicate_server_show));
 
227
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_server_hide", (gpointer *)&(ayatana->backend.ind.indicate_server_hide));
 
228
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_indicator_new_with_server", (gpointer *)&(ayatana->backend.ind.indicate_indicator_new_with_server));
 
229
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_indicator_set_property", (gpointer *)&(ayatana->backend.ind.indicate_indicator_set_property));
 
230
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_indicator_show", (gpointer *)&(ayatana->backend.ind.indicate_indicator_show));
 
231
                        libopened = libopened && g_module_symbol(ayatana->module, "indicate_indicator_hide", (gpointer *)&(ayatana->backend.ind.indicate_indicator_hide));
 
232
                        /*Try to set up menu*/
 
233
                        if (libopened) {
 
234
                                ayatana->library = MMGUI_AYATANA_LIB_INDICATE;
 
235
                                if (!mmgui_ayatana_setup_menu(ayatana)) {
 
236
                                        ayatana->library = MMGUI_AYATANA_LIB_NULL;
 
237
                                }
 
238
                        }
 
239
                        /*If some functions not exported or menu not set up, close library*/
 
240
                        if ((!libopened) || (ayatana->library == MMGUI_AYATANA_LIB_NULL)) {
 
241
                                ayatana->backend.ind.indicate_server_ref_default = NULL;
 
242
                                ayatana->backend.ind.indicate_server_set_type = NULL;
 
243
                                ayatana->backend.ind.indicate_server_set_desktop_file = NULL;
 
244
                                ayatana->backend.ind.indicate_server_show = NULL;
 
245
                                ayatana->backend.ind.indicate_server_hide = NULL;
 
246
                                ayatana->backend.ind.indicate_indicator_new_with_server = NULL;
 
247
                                ayatana->backend.ind.indicate_indicator_set_property = NULL;
 
248
                                ayatana->backend.ind.indicate_indicator_show = NULL;
 
249
                                ayatana->backend.ind.indicate_indicator_hide = NULL;
 
250
                                /*Close module*/
 
251
                                g_module_close(ayatana->module);
 
252
                                ayatana->module = NULL;
 
253
                                ayatana->library = MMGUI_AYATANA_LIB_NULL;
 
254
                        }
 
255
                }
 
256
        }
 
257
        
 
258
        if ((!libopened) || (ayatana->library == MMGUI_AYATANA_LIB_NULL)) {
 
259
                g_free(ayatana);
 
260
                return NULL;
 
261
        }
 
262
        
 
263
        return ayatana;
 
264
}
 
265
 
 
266
void mmgui_ayatana_close(mmgui_ayatana_t ayatana)
 
267
{
 
268
        if (ayatana == NULL) return;
 
269
        
 
270
        mmgui_ayatana_clean_menu(ayatana);
 
271
        
 
272
        if (ayatana->module != NULL) {
 
273
                g_module_close(ayatana->module);
 
274
        }
 
275
        
 
276
        g_free(ayatana);
 
277
}
 
278
 
 
279
void mmgui_ayatana_set_unread_messages_number(mmgui_ayatana_t ayatana, guint number)
 
280
{
 
281
        GFile *file;
 
282
        GIcon *icon;
 
283
        gchar numstr[32];
 
284
        
 
285
        if (ayatana == NULL) return;
 
286
        
 
287
        if (ayatana->library == MMGUI_AYATANA_LIB_MESSAGINGMENU) {
 
288
                if (ayatana->backend.mmenu.server != NULL) {
 
289
                        if ((ayatana->backend.mmenu.messaging_menu_app_has_source)(ayatana->backend.mmenu.server, "sms")) {
 
290
                                if (number > 0) {
 
291
                                        (ayatana->backend.mmenu.messaging_menu_app_set_source_count)(ayatana->backend.mmenu.server, "sms", number);
 
292
                                        (ayatana->backend.mmenu.messaging_menu_app_remove_attention)(ayatana->backend.mmenu.server, "sms");
 
293
                                } else {
 
294
                                        (ayatana->backend.mmenu.messaging_menu_app_remove_source)(ayatana->backend.mmenu.server, "sms");
 
295
                                }
 
296
                        } else {
 
297
                                if (number > 0) {
 
298
                                        file = g_file_new_for_path(RESOURCE_SMS_UNREAD);
 
299
                                        icon = g_file_icon_new(file);
 
300
                                        (ayatana->backend.mmenu.messaging_menu_app_append_source)(ayatana->backend.mmenu.server, "sms", icon, _("Unread messages"));
 
301
                                        (ayatana->backend.mmenu.messaging_menu_app_set_source_count)(ayatana->backend.mmenu.server, "sms", number);
 
302
                                        (ayatana->backend.mmenu.messaging_menu_app_draw_attention)(ayatana->backend.mmenu.server, "sms");
 
303
                                        g_signal_connect(G_OBJECT(ayatana->backend.mmenu.server), "activate-source::sms", G_CALLBACK(mmgui_ayatana_indicator_client_clicked_signal), ayatana);
 
304
                                        g_object_unref(icon);
 
305
                                        g_object_unref(file);
 
306
                                }
 
307
                        }
 
308
                }
 
309
        } else if (ayatana->library == MMGUI_AYATANA_LIB_INDICATE) {
 
310
                if (ayatana->backend.ind.server != NULL) {
 
311
                        if (ayatana->backend.ind.client != NULL) {
 
312
                                if (number > 0) {
 
313
                                        memset(numstr, 0, sizeof(numstr));
 
314
                                        snprintf(numstr, sizeof(numstr), "%u", number);
 
315
                                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "draw_attention", "true");
 
316
                                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "count", numstr);
 
317
                                } else {
 
318
                                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "draw_attention", "false");
 
319
                                        (ayatana->backend.ind.indicate_indicator_set_property)(ayatana->backend.ind.client, "count", "");
 
320
                                }
 
321
                        }
 
322
                }
 
323
        }
 
324
        
 
325
}