~ubuntu-branches/ubuntu/quantal/cairo-dock-plug-ins/quantal-201208191523

« back to all changes in this revision

Viewing changes to Status-Notifier/src/applet-host.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-10 00:05:57 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810000557-pfxoz5w7hbyclcqh
Tags: 2.2.0~0beta4-0ubuntu1
* New Upstream Version (LP: #614625)
* Fixed a few bugs on LP:
 - LP: #483963: Dustbin applet does not display trashes on all volumes
 - LP: #485159: Some apps have problem with Systray
 - LP: #500677: ~/.xsession-errors is too much used by CD
 - LP: #500979: Shortcuts: the order gets messed up
 - LP: #521531: Mail: crashes on Maildir
 - LP: #519915: GTG: create a new applet to control GTG
 - LP: #526138: GMenu doesn't handle desktop file exec strings properly
 - LP: #531317: CMake: Added an error if the prefix of 'cairo-dock-plugins'
                 is not the same 'cairo-dock-core'
 - LP: #531319: CMake: check the version of 'cairo-dock' when building
                 'cairo-dock-plugins'
 - LP: #537115: Click at the position where icon lavel was, the icon
                 and dock still receive the event
 - LP: #537943: Terminal applet shortkey behaviour
 - LP: #538637: Trash applet doesn't create .trashinfo files on XFCE
 - More details on the 'ChangeLog' file
* debian/rules:
 - Autotools has been replaced by CMake
 - cdbs is now used.
* debian/copyright:
 - Updated with the new applets
* debian/control:
 - Autotools has been replaced by CMake
 - Added libcurl4-gnutls-dev, libindicator-dev, libdbusmenu-glib-dev
   libido-0.1-dev, libical-dev, libdbusmenu-gtk-dev as Build-deps
 - Bump Standard-Version to 3.9.1
 - Wget is required for dnd2share applet
 - Added the exact realease for 'cairo-dock-dev' in order to prevent any
    build error if this package is not already available (thx to didrocks)
* debian/cairo-dock-plug-ins*.install:
 - All sonames are now installed into lib32 or lib64 (lib*)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
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 <stdlib.h>
 
21
#include <string.h>
 
22
#include <sys/types.h>
 
23
#include <unistd.h>
 
24
 
 
25
#include "applet-struct.h"
 
26
#include "applet-host.h"
 
27
 
 
28
#define CD_STATUS_NOTIFIER_ITEM_IFACE "org.kde.StatusNotifierItem"
 
29
#define CD_STATUS_NOTIFIER_ITEM_OBJ "/StatusNotifierItem"
 
30
#define CD_STATUS_NOTIFIER_HOST_ADDR "org.kde.StatusNotifierHost"
 
31
#define CD_STATUS_NOTIFIER_WATCHER_ADDR "org.kde.StatusNotifierWatcher"
 
32
#define CD_STATUS_NOTIFIER_WATCHER_OBJ "/StatusNotifierWatcher"
 
33
#define CD_STATUS_NOTIFIER_WATCHER_IFACE "org.kde.StatusNotifierWatcher"
 
34
 
 
35
static void cd_free_tooltip (CDToolTip *pToolTip);
 
36
static void cd_free_item_data (CDStatusNotifierItemData *pItemData);
 
37
static Icon *cd_satus_notifier_create_item_icon (const gchar *cService);
 
38
 
 
39
 
 
40
G_DEFINE_TYPE(statusNotifierHostObject, cd_satus_notifier_host, G_TYPE_OBJECT);
 
41
 
 
42
static void cd_satus_notifier_host_class_init(statusNotifierHostObjectClass *klass)
 
43
{
 
44
        cd_message("");
 
45
}
 
46
static void cd_satus_notifier_host_init (statusNotifierHostObject *pMainObject)
 
47
{
 
48
        cd_message("");
 
49
        
 
50
        // Initialise the DBus connection
 
51
        pMainObject->connection = cairo_dock_get_session_connection ();
 
52
        
 
53
        //dbus_g_object_type_install_info(cd_satus_notifier_host_get_type(), &dbus_glib_cd_satus_notifier_host_object_info);
 
54
        
 
55
        // Register DBUS path
 
56
        dbus_g_connection_register_g_object(pMainObject->connection, "/org/kde/StatusNotifierHost", G_OBJECT(pMainObject));
 
57
}
 
58
 
 
59
 
 
60
static CDCategoryEnum _find_category (const gchar *cCategory)
 
61
{
 
62
        if (!cCategory)
 
63
                return CD_CATEGORY_APPLICATION_STATUS;
 
64
        if (*cCategory == 'A')
 
65
                return CD_CATEGORY_APPLICATION_STATUS;
 
66
        if (*cCategory == 'C')
 
67
                return CD_CATEGORY_COMMUNICATIONS;
 
68
        if (*cCategory == 'S')
 
69
                return CD_CATEGORY_SYSTEM_SERVICES;
 
70
        if (*cCategory == 'H')
 
71
                return CD_CATEGORY_HARDWARE;
 
72
        return CD_CATEGORY_APPLICATION_STATUS;
 
73
}
 
74
 
 
75
static CDStatusEnum _find_status (const gchar *cStatus)
 
76
{
 
77
        if (!cStatus)
 
78
                return CD_STATUS_ACTIVE;
 
79
        if (*cStatus == 'N')
 
80
                return CD_STATUS_NEEDS_ATTENTION;
 
81
        if (*cStatus == 'A')
 
82
                return CD_STATUS_ACTIVE;
 
83
        if (*cStatus == 'P')
 
84
                return CD_STATUS_PASSIVE;
 
85
        return CD_STATUS_ACTIVE;
 
86
}
 
87
 
 
88
static CDToolTip *_make_tooltip_from_dbus_struct (GValueArray *pToolTipTab)
 
89
{
 
90
        CDToolTip *pToolTip = NULL;
 
91
        if (pToolTipTab)
 
92
        {
 
93
                pToolTip = g_new0 (CDToolTip, 1);
 
94
                GValue *v = &pToolTipTab->values[0];
 
95
                if (v && G_VALUE_HOLDS_STRING (v))
 
96
                        pToolTip->cIconName = g_strdup (g_value_get_string (v));
 
97
                v = &pToolTipTab->values[2];
 
98
                if (v && G_VALUE_HOLDS_STRING (v))
 
99
                        pToolTip->cTitle = g_strdup (g_value_get_string (v));
 
100
                v = &pToolTipTab->values[3];
 
101
                if (v && G_VALUE_HOLDS_STRING (v))
 
102
                        pToolTip->cMessage = g_strdup (g_value_get_string (v));
 
103
                if (pToolTip->cMessage != NULL)
 
104
                {
 
105
                        if (strncmp (pToolTip->cMessage, "<qt>", 4) == 0)
 
106
                        {
 
107
                                gchar *str = pToolTip->cMessage;
 
108
                                int n = strlen (str);
 
109
                                *(str + n - 5) = '\0';
 
110
                                pToolTip->cMessage = g_strdup (str+4);
 
111
                                g_free (str);
 
112
                        }
 
113
                        /// remplacer <br/> pas \n
 
114
                        
 
115
                        /// virer les <nobr> et </nobr>
 
116
                        
 
117
                        /// virer les <img src=...> et </img>
 
118
                        
 
119
                }
 
120
        }
 
121
        return pToolTip;
 
122
}
 
123
 
 
124
static void _show_item_tooltip (Icon *pIcon, CDStatusNotifierItemData *pItemData)
 
125
{
 
126
        gchar *cText = g_strdup_printf ("<b>%s</b>\n%s", pItemData->pToolTip->cTitle, pItemData->pToolTip->cMessage);
 
127
        cairo_dock_show_temporary_dialog_with_icon (cText, pIcon, CAIRO_CONTAINER (myIcon->pSubDock), 4000, pItemData->pToolTip->cIconName);
 
128
        g_free (cText);
 
129
}
 
130
 
 
131
static void _show_item_status (Icon *pIcon, CDStatusNotifierItemData *pItemData)
 
132
{
 
133
        switch (pItemData->iStatus)
 
134
        {
 
135
                case CD_STATUS_PASSIVE :
 
136
                        pIcon->fAlpha = 0.5;
 
137
                        cairo_dock_stop_icon_attention (pIcon, myIcon->pSubDock);
 
138
                        cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
139
                break;
 
140
                case CD_STATUS_ACTIVE :
 
141
                default:
 
142
                        pIcon->fAlpha = 1.;
 
143
                        cairo_dock_stop_icon_attention (pIcon, myIcon->pSubDock);
 
144
                        cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
145
                break;
 
146
                case CD_STATUS_NEEDS_ATTENTION:
 
147
                        pIcon->fAlpha = 1.;
 
148
                        cairo_dock_request_icon_attention (pIcon, myIcon->pSubDock, "rotate", 60);
 
149
                break;
 
150
        }
 
151
}
 
152
 
 
153
 
 
154
static void on_new_item (DBusGProxy *proxy_watcher, const gchar *cService, CairoDockModuleInstance *myApplet)
 
155
{
 
156
        CD_APPLET_ENTER;
 
157
        g_print ("new item : '%s'\n", cService);
 
158
        
 
159
        Icon *pIcon = cd_satus_notifier_create_item_icon (cService);
 
160
        CD_APPLET_LEAVE_IF_FAIL (pIcon != NULL);
 
161
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
162
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
163
        
 
164
        cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
165
        
 
166
        if (myIcon->pSubDock)
 
167
                cairo_dock_insert_icon_in_dock (pIcon, myIcon->pSubDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
 
168
        else
 
169
        {
 
170
                CD_APPLET_LOAD_MY_ICONS_LIST (g_list_copy (myData.pIcons), NULL, "Caroussel", NULL);
 
171
        }
 
172
        
 
173
        if (pItemData->iStatus != CD_STATUS_ACTIVE)
 
174
                _show_item_status (pIcon, pItemData);
 
175
        
 
176
        CD_APPLET_LEAVE ();
 
177
}
 
178
 
 
179
static void on_removed_item (DBusGProxy *proxy_watcher, const gchar *cService, CairoDockModuleInstance *myApplet)
 
180
{
 
181
        CD_APPLET_ENTER;
 
182
        g_print ("item removed : '%s'\n", cService);
 
183
        
 
184
        gchar *str = strchr (cService, '/');
 
185
        if (str)
 
186
                *str = '\0';
 
187
        
 
188
        Icon *pIcon = cd_satus_notifier_find_icon_from_service (cService);
 
189
        CD_APPLET_LEAVE_IF_FAIL (pIcon != NULL);
 
190
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
191
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
192
        
 
193
        myData.pIcons = g_list_remove (myData.pIcons, pIcon);
 
194
        if (myIcon->pSubDock)
 
195
                cairo_dock_detach_icon_from_dock (pIcon, myIcon->pSubDock, TRUE);
 
196
        
 
197
        cd_free_item_data (pItemData);
 
198
        CD_APPLET_SET_MY_ICON_DATA (pIcon, NULL);
 
199
        cairo_dock_free_icon (pIcon);
 
200
        
 
201
        cairo_dock_update_dock_size (myIcon->pSubDock);
 
202
        
 
203
        CD_APPLET_LEAVE ();
 
204
}
 
205
 
 
206
static void on_new_item_title (DBusGProxy *proxy_item, Icon *pIcon)
 
207
{
 
208
        CD_APPLET_ENTER;
 
209
        g_print ("%s ()\n", __func__);
 
210
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
211
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
212
        
 
213
        gchar *cTitle = cairo_dock_dbus_get_property_as_string (pItemData->pProxyProps, CD_STATUS_NOTIFIER_ITEM_IFACE, "Title");
 
214
        cairo_dock_set_icon_name (cTitle, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
215
        g_free (cTitle);
 
216
        
 
217
        CD_APPLET_LEAVE ();
 
218
}
 
219
 
 
220
static void on_new_item_icon (DBusGProxy *proxy_item, Icon *pIcon)
 
221
{
 
222
        CD_APPLET_ENTER;
 
223
        g_print ("%s ()\n", __func__);
 
224
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
225
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
226
        
 
227
        gchar *cIconName = cairo_dock_dbus_get_property_as_string (pItemData->pProxyProps, CD_STATUS_NOTIFIER_ITEM_IFACE, "IconName");
 
228
        cairo_t *pIconContext = cairo_create (pIcon->pIconBuffer);
 
229
        cairo_dock_set_image_on_icon (pIconContext, pItemData->cAttentionIconName, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
230
        cairo_destroy (pIconContext);
 
231
        g_free (cIconName);
 
232
        
 
233
        CD_APPLET_LEAVE ();
 
234
}
 
235
 
 
236
static void on_new_item_attention_icon (DBusGProxy *proxy_item, Icon *pIcon)
 
237
{
 
238
        CD_APPLET_ENTER;
 
239
        g_print ("%s ()\n", __func__);
 
240
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
241
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
242
        
 
243
        g_free (pItemData->cAttentionIconName);
 
244
        pItemData->cAttentionIconName = cairo_dock_dbus_get_property_as_string (pItemData->pProxyProps, CD_STATUS_NOTIFIER_ITEM_IFACE, "AttentionIconName");
 
245
        if (pIcon->bIsDemandingAttention && pIcon->pIconBuffer)
 
246
        {
 
247
                cairo_t *pIconContext = cairo_create (pIcon->pIconBuffer);
 
248
                cairo_dock_set_image_on_icon (pIconContext, pItemData->cAttentionIconName, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
249
                cairo_destroy (pIconContext);
 
250
        }
 
251
        
 
252
        CD_APPLET_LEAVE ();
 
253
}
 
254
 
 
255
static void on_new_item_overlay_icon (DBusGProxy *proxy_item, Icon *pIcon)
 
256
{
 
257
        CD_APPLET_ENTER;
 
258
        g_print ("%s ()\n", __func__);
 
259
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
260
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
261
        
 
262
        g_free (pItemData->cOverlayIconName);
 
263
        pItemData->cOverlayIconName = cairo_dock_dbus_get_property_as_string (pItemData->pProxyProps, CD_STATUS_NOTIFIER_ITEM_IFACE, "OverlayIconName");
 
264
        if (pIcon->pIconBuffer)
 
265
        {
 
266
                cairo_t *pIconContext = cairo_create (pIcon->pIconBuffer);
 
267
                cairo_dock_set_image_on_icon (pIconContext, pIcon->cFileName, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
268
                cairo_destroy (pIconContext);
 
269
                
 
270
                if (pItemData->cOverlayIconName != NULL)
 
271
                {
 
272
                        CairoEmblem *pEmblem = cairo_dock_make_emblem (pItemData->cOverlayIconName, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
273
                        cairo_dock_set_emblem_position (pEmblem, CAIRO_DOCK_EMBLEM_MIDDLE);
 
274
                        cairo_dock_draw_emblem_on_icon (pEmblem, pIcon, CAIRO_CONTAINER (myIcon->pSubDock));
 
275
                        cairo_dock_free_emblem (pEmblem);
 
276
                }
 
277
        }
 
278
        
 
279
        CD_APPLET_LEAVE ();
 
280
}
 
281
 
 
282
static void on_new_item_tooltip (DBusGProxy *proxy_item, Icon *pIcon)
 
283
{
 
284
        CD_APPLET_ENTER;
 
285
        g_print ("%s ()\n", __func__);
 
286
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
287
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
288
        
 
289
        cairo_dock_remove_dialog_if_any (pIcon);
 
290
        cd_free_tooltip (pItemData->pToolTip);
 
291
        pItemData->pToolTip = NULL;
 
292
        
 
293
        GValueArray *pToolTipTab = cairo_dock_dbus_get_property_as_boxed (pItemData->pProxyProps, CD_STATUS_NOTIFIER_ITEM_IFACE, "ToolTip");
 
294
        if (pToolTipTab)
 
295
        {
 
296
                pItemData->pToolTip = _make_tooltip_from_dbus_struct (pToolTipTab);
 
297
                
 
298
                if (pItemData->pToolTip && pItemData->pToolTip->cMessage != NULL)
 
299
                        _show_item_tooltip (pIcon, pItemData);
 
300
        }
 
301
        
 
302
        CD_APPLET_LEAVE ();
 
303
}
 
304
 
 
305
static void on_new_item_status (DBusGProxy *proxy_item, const gchar *cStatus, Icon *pIcon)
 
306
{
 
307
        CD_APPLET_ENTER;
 
308
        g_print ("%s (%s)\n", __func__, cStatus);
 
309
        CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
310
        CD_APPLET_LEAVE_IF_FAIL (pItemData != NULL);
 
311
        
 
312
        pItemData->iStatus = _find_status (cStatus);
 
313
        _show_item_status (pIcon, pItemData);
 
314
        
 
315
        CD_APPLET_LEAVE ();
 
316
}
 
317
 
 
318
 
 
319
static int _compare_items (const CDStatusNotifierItemData *i1, const CDStatusNotifierItemData *i2)
 
320
{
 
321
        if (!i1)
 
322
                return -1;
 
323
        if (!i2)
 
324
                return 1;
 
325
        return (i1->iCategory < i2->iCategory ? -1 : (i1->iCategory > i2->iCategory ? 1 : 0));
 
326
}
 
327
static Icon *cd_satus_notifier_create_item_icon (const gchar *cService)
 
328
{
 
329
        gchar *str = strchr (cService, '/');
 
330
        if (str)
 
331
                *str = '\0';
 
332
        g_print (" + item '%s' on the bus\n", cService);
 
333
        
 
334
        //\_________________ get the properties of the item.
 
335
        DBusGProxy *pProxyItemProp = cairo_dock_create_new_session_proxy (
 
336
                cService,
 
337
                "/StatusNotifierItem",
 
338
                "org.freedesktop.DBus.Properties");
 
339
        if (pProxyItemProp == NULL)
 
340
                return NULL;
 
341
        
 
342
        g_print ("getting properties ...\n");
 
343
        GHashTable *hProps = cairo_dock_dbus_get_all_properties (pProxyItemProp, CD_STATUS_NOTIFIER_ITEM_IFACE);
 
344
        if (hProps == NULL)
 
345
                return NULL;
 
346
        
 
347
        GValue *v;
 
348
        const gchar *cId = NULL;
 
349
        v = g_hash_table_lookup (hProps, "Id");
 
350
        if (v && G_VALUE_HOLDS_STRING (v))
 
351
        {
 
352
                cId = g_value_get_string (v);
 
353
        }
 
354
        g_print ("  ID '%s\n", cId);
 
355
        
 
356
        const gchar *cTitle = NULL;
 
357
        v = g_hash_table_lookup (hProps, "Title");  // -> cName
 
358
        if (v && G_VALUE_HOLDS_STRING (v))
 
359
        {
 
360
                cTitle = g_value_get_string (v);
 
361
        }
 
362
        g_print ("  Title '%s\n", cTitle);
 
363
        
 
364
        const gchar *cCategory = NULL;
 
365
        v = g_hash_table_lookup (hProps, "Category");  // (ApplicationStatus, Communications, SystemServices, Hardware) -> fOrder
 
366
        if (v && G_VALUE_HOLDS_STRING (v))
 
367
        {
 
368
                cCategory = g_value_get_string (v);
 
369
        }
 
370
        g_print ("  Category '%s'\n", cCategory);
 
371
        
 
372
        const gchar *cStatus = NULL;
 
373
        v = g_hash_table_lookup (hProps, "Category");  // (Passive, Active, NeedsAttention) -> demands attention
 
374
        if (v && G_VALUE_HOLDS_STRING (v))
 
375
        {
 
376
                cStatus = g_value_get_string (v);
 
377
        }
 
378
        g_print ("  Status '%s'\n", cStatus);
 
379
        
 
380
        v = g_hash_table_lookup (hProps, "WindowId");
 
381
        guint iWindowId = 0;
 
382
        if (v && G_VALUE_HOLDS_UINT(v))
 
383
        {
 
384
                iWindowId = g_value_get_uint (v);
 
385
        }
 
386
        g_print ("  WindowId '%d'\n", iWindowId);
 
387
        
 
388
        const gchar *cIconName = NULL;
 
389
        v = g_hash_table_lookup (hProps, "IconName");  // -> cIFileName
 
390
        if (v && G_VALUE_HOLDS_STRING (v))
 
391
        {
 
392
                cIconName = g_value_get_string (v);
 
393
        }
 
394
        g_print ("  IconName '%s'\n", cIconName);
 
395
        
 
396
        const gchar *cIconThemePath = NULL;
 
397
        v = g_hash_table_lookup (hProps, "IconThemePath");
 
398
        if (v && G_VALUE_HOLDS_STRING (v))
 
399
        {
 
400
                cIconThemePath = g_value_get_string (v);
 
401
        }
 
402
        g_print ("  IconThemePath '%s'\n", cIconThemePath);
 
403
        
 
404
        const gchar *cOverlayIconName = NULL;
 
405
        v = g_hash_table_lookup (hProps, "OverlayIconName");  // -> emblem
 
406
        if (v && G_VALUE_HOLDS_STRING (v))
 
407
        {
 
408
                cOverlayIconName = g_value_get_string (v);
 
409
        }
 
410
        g_print ("  OverlayIconName '%s'\n", cOverlayIconName);
 
411
        
 
412
        const gchar *cAttentionIconName = NULL;
 
413
        v = g_hash_table_lookup (hProps, "AttentionIconName");  // -> keep for demands of attention
 
414
        if (v && G_VALUE_HOLDS_STRING (v))
 
415
        {
 
416
                cAttentionIconName = g_value_get_string (v);
 
417
        }
 
418
        g_print ("  AttentionIconName '%s'\n", cAttentionIconName);
 
419
        
 
420
        const gchar *cAttentionMovieName = NULL;
 
421
        v = g_hash_table_lookup (hProps, "AttentionMovieName");  // -> idem
 
422
        if (v && G_VALUE_HOLDS_STRING (v))
 
423
        {
 
424
                cAttentionMovieName = g_value_get_string (v);
 
425
        }
 
426
        g_print ("  AttentionMovieName '%s'\n", cAttentionMovieName);
 
427
        
 
428
        GValueArray *pToolTipTab = NULL;
 
429
        v = g_hash_table_lookup (hProps, "ToolTip");
 
430
        if (v && G_VALUE_HOLDS_BOXED (v))
 
431
        {
 
432
                pToolTipTab = g_value_get_boxed (v);
 
433
        }
 
434
        
 
435
        g_print ("creating the icon...\n");
 
436
        DBusGProxy *pProxyItem = cairo_dock_create_new_session_proxy (
 
437
                cService,
 
438
                "/StatusNotifierItem",
 
439
                CD_STATUS_NOTIFIER_ITEM_IFACE);
 
440
        if (pProxyItem == NULL)
 
441
                return NULL;
 
442
        
 
443
        //\_________________ create a new item.
 
444
        CDStatusNotifierItemData *pItemData = g_new0 (CDStatusNotifierItemData, 1);
 
445
        pItemData->cService = g_strdup (cService);
 
446
        pItemData->pProxyProps = pProxyItemProp;
 
447
        pItemData->pProxy = pProxyItem;
 
448
        pItemData->cId = g_strdup (cId);
 
449
        pItemData->iWindowId = iWindowId;
 
450
        pItemData->iCategory = _find_category (cCategory);
 
451
        pItemData->iStatus = _find_status (cStatus);
 
452
        pItemData->cIconThemePath = g_strdup (cIconThemePath);
 
453
        pItemData->cAttentionIconName = g_strdup (cAttentionIconName);
 
454
        pItemData->cAttentionMovieName = g_strdup (cAttentionMovieName);
 
455
        pItemData->cOverlayIconName = g_strdup (cOverlayIconName);
 
456
        if (pToolTipTab)
 
457
        {
 
458
                pItemData->pToolTip = _make_tooltip_from_dbus_struct (pToolTipTab);
 
459
        }
 
460
        
 
461
        //\_________________ create a new associated icon.
 
462
        Icon *pIcon = cairo_dock_create_dummy_launcher (g_strdup (cTitle),
 
463
                g_strdup (cIconName),
 
464
                g_strdup ("none"),
 
465
                NULL,
 
466
                pItemData->iCategory);
 
467
        CD_APPLET_SET_MY_ICON_DATA (pIcon, pItemData);
 
468
        
 
469
        myData.pIcons = g_list_insert_sorted (myData.pIcons, pIcon, (GCompareFunc)_compare_items);
 
470
        
 
471
        //\_________________ track any changes in the item.
 
472
        dbus_g_proxy_add_signal(pProxyItem, "NewTitle",
 
473
                G_TYPE_INVALID);
 
474
        dbus_g_proxy_connect_signal(pProxyItem, "NewTitle",
 
475
                G_CALLBACK(on_new_item_title), myApplet, NULL);
 
476
        
 
477
        dbus_g_proxy_add_signal(pProxyItem, "NewIcon",
 
478
                G_TYPE_INVALID);
 
479
        dbus_g_proxy_connect_signal(pProxyItem, "NewIcon",
 
480
                G_CALLBACK(on_new_item_icon), myApplet, NULL);
 
481
        
 
482
        dbus_g_proxy_add_signal(pProxyItem, "NewAttentionIcon",
 
483
                G_TYPE_INVALID);
 
484
        dbus_g_proxy_connect_signal(pProxyItem, "NewAttentionIcon",
 
485
                G_CALLBACK(on_new_item_attention_icon), myApplet, NULL);
 
486
        
 
487
        dbus_g_proxy_add_signal(pProxyItem, "NewOverlayIcon",
 
488
                G_TYPE_INVALID);
 
489
        dbus_g_proxy_connect_signal(pProxyItem, "NewOverlayIcon",
 
490
                G_CALLBACK(on_new_item_overlay_icon), myApplet, NULL);
 
491
        
 
492
        dbus_g_proxy_add_signal(pProxyItem, "NewToolTip",
 
493
                G_TYPE_INVALID);
 
494
        dbus_g_proxy_connect_signal(pProxyItem, "NewToolTip",
 
495
                G_CALLBACK(on_new_item_tooltip), myApplet, NULL);
 
496
        
 
497
        dbus_g_proxy_add_signal(pProxyItem, "NewStatus",
 
498
                G_TYPE_STRING, G_TYPE_INVALID);
 
499
        dbus_g_proxy_connect_signal(pProxyItem, "NewStatus",
 
500
                G_CALLBACK(on_new_item_status), myApplet, NULL);
 
501
        
 
502
        g_print ("destroy props...\n");
 
503
        g_hash_table_destroy (hProps);
 
504
        return pIcon;
 
505
}
 
506
 
 
507
static void cd_free_tooltip (CDToolTip *pToolTip)
 
508
{
 
509
        if (pToolTip == NULL)
 
510
                return;
 
511
        g_free (pToolTip->cIconName);
 
512
        g_free (pToolTip->cTitle);
 
513
        g_free (pToolTip->cMessage);
 
514
        g_free (pToolTip);
 
515
}
 
516
 
 
517
static void cd_free_item_data (CDStatusNotifierItemData *pItemData)
 
518
{
 
519
        if (pItemData == NULL)
 
520
                return;
 
521
        if (pItemData->iSidPopupTooltip != 0)
 
522
                g_source_remove (pItemData->iSidPopupTooltip);
 
523
        g_object_unref (pItemData->pProxy);
 
524
        g_object_unref (pItemData->pProxyProps);
 
525
        g_free (pItemData->cService);
 
526
        g_free (pItemData->cId);
 
527
        g_free (pItemData->cAttentionIconName);
 
528
        g_free (pItemData->cAttentionMovieName);
 
529
        g_free (pItemData->cOverlayIconName);
 
530
        cd_free_tooltip (pItemData->pToolTip);
 
531
        g_free (pItemData);
 
532
}
 
533
 
 
534
 
 
535
 
 
536
void cd_satus_notifier_launch_service (void)
 
537
{
 
538
        g_return_if_fail (myData.pMainObject == NULL);
 
539
        g_type_init();
 
540
        
 
541
        // on cree l'objet distant principal.
 
542
        g_print ("satus-notifier : Lancement du service\n");
 
543
        pid_t pid = getpid ();
 
544
        ///myData.pMainObject = g_object_new (cd_satus_notifier_host_get_type(), NULL);  // appelle class_init() et init().
 
545
        
 
546
        // Register the service name no the bus.
 
547
        myData.cHostName = g_strdup_printf (CD_STATUS_NOTIFIER_HOST_ADDR"-%d", pid);
 
548
        g_print ("registering %s ...\n", myData.cHostName);
 
549
        cairo_dock_register_service_name (myData.cHostName);
 
550
        
 
551
        // get the watcher.
 
552
        g_print ("getting the watcher...\n");
 
553
        myData.pProxyWatcher = cairo_dock_create_new_session_proxy (
 
554
                CD_STATUS_NOTIFIER_WATCHER_ADDR,
 
555
                CD_STATUS_NOTIFIER_WATCHER_OBJ,
 
556
                CD_STATUS_NOTIFIER_WATCHER_IFACE);
 
557
        g_return_if_fail (myData.pProxyWatcher != NULL);
 
558
        
 
559
        // register to the watcher.
 
560
        g_print ("registering to the watcher...\n");
 
561
        GError *erreur = NULL;
 
562
        dbus_g_proxy_call (myData.pProxyWatcher, "RegisterStatusNotifierHost", &erreur,
 
563
                G_TYPE_STRING, myData.cHostName,
 
564
                G_TYPE_INVALID,
 
565
                G_TYPE_INVALID);
 
566
        if (erreur != NULL)
 
567
        {
 
568
                cd_warning ("couldn't find a Status Notifier Watcher (%s)\nYour system doesn't support Systray 2.0", erreur->message);
 
569
                g_error_free (erreur);
 
570
                return;
 
571
        }
 
572
        // connect to the signals.
 
573
        dbus_g_proxy_add_signal(myData.pProxyWatcher, "StatusNotifierItemRegistered",
 
574
                G_TYPE_STRING, G_TYPE_INVALID);
 
575
        dbus_g_proxy_connect_signal(myData.pProxyWatcher, "StatusNotifierItemRegistered",
 
576
                G_CALLBACK(on_new_item), myApplet, NULL);
 
577
        dbus_g_proxy_add_signal(myData.pProxyWatcher, "StatusNotifierItemUnregistered",
 
578
                G_TYPE_STRING, G_TYPE_INVALID);
 
579
        dbus_g_proxy_connect_signal(myData.pProxyWatcher, "StatusNotifierItemUnregistered",
 
580
                G_CALLBACK(on_removed_item), myApplet, NULL);
 
581
        
 
582
        // get the items.
 
583
        DBusGProxy *pProxyWatcherProps = cairo_dock_create_new_session_proxy (
 
584
                CD_STATUS_NOTIFIER_WATCHER_ADDR,
 
585
                CD_STATUS_NOTIFIER_WATCHER_OBJ,
 
586
                "org.freedesktop.DBus.Properties");
 
587
        gchar **cItemsName = cairo_dock_dbus_get_property_as_string_list (pProxyWatcherProps, CD_STATUS_NOTIFIER_WATCHER_IFACE, "RegisteredStatusNotifierItems");
 
588
        g_object_unref (pProxyWatcherProps);
 
589
        
 
590
        // create all the icons.
 
591
        if (cItemsName != NULL)
 
592
        {
 
593
                int i;
 
594
                for (i = 0; cItemsName[i] != NULL; i ++)
 
595
                {
 
596
                        cd_satus_notifier_create_item_icon (cItemsName[i]);
 
597
                }
 
598
                g_strfreev (cItemsName);
 
599
                
 
600
                CD_APPLET_LOAD_MY_ICONS_LIST (g_list_copy (myData.pIcons), NULL, "Caroussel", NULL);
 
601
        }
 
602
}
 
603
 
 
604
void cd_satus_notifier_stop_service (void)
 
605
{
 
606
        if (myData.pMainObject = NULL)
 
607
                return;
 
608
        g_object_unref (myData.pMainObject);
 
609
        g_object_unref (myData.pProxyWatcher);
 
610
        
 
611
        Icon *pIcon = NULL;
 
612
        GList *ic;
 
613
        for (ic = myData.pIcons; ic != NULL; ic = ic->next)
 
614
        {
 
615
                pIcon = ic->data;
 
616
                CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
617
                cd_free_item_data (pItemData);
 
618
                CD_APPLET_SET_MY_ICON_DATA (pIcon, NULL);
 
619
        }
 
620
        g_list_free (myData.pIcons);
 
621
        CD_APPLET_DELETE_MY_ICONS_LIST;
 
622
}
 
623
 
 
624
Icon * cd_satus_notifier_find_icon_from_service (const gchar *cService)
 
625
{
 
626
        Icon *pIcon = NULL;
 
627
        GList *ic;
 
628
        for (ic = myData.pIcons; ic != NULL; ic = ic->next)
 
629
        {
 
630
                pIcon = ic->data;
 
631
                CDStatusNotifierItemData *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
632
                if (pItemData && pItemData->cService && strcmp (pItemData->cService, cService) == 0)
 
633
                        return pIcon;
 
634
        }
 
635
        return NULL;
 
636
}
 
637