~indicator-applet-developers/indicator-session/trunk.0.1

« back to all changes in this revision

Viewing changes to src/indicator-sus.c

  • Committer: Ted Gould
  • Date: 2009-07-27 04:47:27 UTC
  • mfrom: (9.1.94 fusa.libindicator)
  • Revision ID: ted@canonical.com-20090727044727-m04ul5d8sxqt2pd4
Merging in the branch to port everything to libindicator and fleshing thigns out.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
#include <gtk/gtk.h>
3
 
 
4
 
GtkWidget *
5
 
get_menu_item (void)
6
 
{
7
 
        GtkWidget * mainmenu = gtk_menu_item_new();
8
 
 
9
 
        GtkWidget * hbox = gtk_hbox_new(FALSE, 3);
10
 
 
11
 
        GtkWidget * label = gtk_label_new("Ted Gould");
12
 
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3);
13
 
        gtk_widget_show(label);
14
 
 
15
 
        GtkWidget * icon = gtk_image_new_from_icon_name("gnome-logout",
16
 
                                                        GTK_ICON_SIZE_MENU);
17
 
        gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
18
 
        gtk_widget_show(icon);
19
 
 
20
 
        gtk_container_add(GTK_CONTAINER(mainmenu), hbox);
21
 
        gtk_widget_show(hbox);
22
 
 
23
 
        gtk_widget_show(mainmenu);
24
 
        return mainmenu;
25
 
}
 
3
#include <libdbusmenu-gtk/client.h>
 
4
 
 
5
#include <dbus/dbus-glib.h>
 
6
#include <dbus/dbus-glib-bindings.h>
 
7
 
 
8
#include <libindicator/indicator.h>
 
9
INDICATOR_SET_VERSION
 
10
INDICATOR_SET_NAME("users-status-session")
 
11
 
 
12
#include "dbus-shared-names.h"
 
13
#include "status-service-client.h"
 
14
 
 
15
static DbusmenuGtkClient * status_client = NULL;
 
16
static DbusmenuGtkClient * users_client = NULL;
 
17
static DbusmenuGtkClient * session_client = NULL;
 
18
 
 
19
static GtkMenu * main_menu = NULL;
 
20
 
 
21
static GtkWidget * status_separator = NULL;
 
22
static GtkWidget * users_separator = NULL;
 
23
#define SEPARATOR_SHOWN(sep) (sep != NULL && GTK_WIDGET_VISIBLE(sep))
 
24
static GtkWidget * loading_item = NULL;
 
25
 
 
26
static DBusGConnection * connection = NULL;
 
27
static DBusGProxy * proxy = NULL;
 
28
 
 
29
typedef enum {
 
30
        STATUS_SECTION,
 
31
        USERS_SECTION,
 
32
        SESSION_SECTION,
 
33
        END_OF_SECTIONS
 
34
} section_t;
 
35
 
 
36
static void child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section);
 
37
static guint status_menu_pos_offset (void);
 
38
static guint users_menu_pos_offset (void);
 
39
static guint session_menu_pos_offset (void);
 
40
 
 
41
GtkLabel *
 
42
get_label (void)
 
43
{
 
44
        GtkLabel * returnval = GTK_LABEL(gtk_label_new("Ted Gould"));
 
45
        gtk_widget_show(GTK_WIDGET(returnval));
 
46
        return returnval;
 
47
}
 
48
 
 
49
GtkImage *
 
50
get_icon (void)
 
51
{
 
52
        return NULL;
 
53
}
 
54
 
 
55
static void
 
56
child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section)
 
57
{
 
58
        DbusmenuGtkClient * client = NULL;
 
59
        gchar * errorstr = NULL;
 
60
        guint (*posfunc) (void) = NULL;
 
61
 
 
62
        switch (GPOINTER_TO_UINT(section)) {
 
63
                case STATUS_SECTION:
 
64
                        client = status_client;
 
65
                        errorstr = "Status";
 
66
                        posfunc = status_menu_pos_offset;
 
67
                        break;
 
68
                case USERS_SECTION:
 
69
                        client = users_client;
 
70
                        errorstr = "Users";
 
71
                        posfunc = users_menu_pos_offset;
 
72
                        break;
 
73
                case SESSION_SECTION:
 
74
                        client = session_client;
 
75
                        errorstr = "Session";
 
76
                        posfunc = session_menu_pos_offset;
 
77
                        break;
 
78
                default:
 
79
                        g_warning("Child Added called with an unknown position function!");
 
80
                        return;
 
81
        }
 
82
 
 
83
        position += posfunc();
 
84
        g_debug("SUS: Adding child: %d", position);
 
85
        GtkMenuItem * widget = dbusmenu_gtkclient_menuitem_get(client, child);
 
86
 
 
87
        if (widget == NULL) {
 
88
                g_warning("Had a menu item added to the %s menu, but yet it didn't have a GtkWidget with it.  Can't add that to a menu now can we?  You need to figure this @#$# out!", errorstr);
 
89
                return;
 
90
        }
 
91
 
 
92
        gtk_menu_insert(main_menu, GTK_WIDGET(widget), position);
 
93
        gtk_widget_show(GTK_WIDGET(widget));
 
94
 
 
95
        gtk_widget_hide(loading_item);
 
96
 
 
97
        return;
 
98
}
 
99
 
 
100
static void
 
101
child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, guint (*posfunc) (void))
 
102
{
 
103
 
 
104
 
 
105
}
 
106
 
 
107
 
 
108
/* Status Menu */
 
109
static guint
 
110
status_menu_pos_offset (void)
 
111
{
 
112
        return 0;
 
113
}
 
114
 
 
115
static void
 
116
status_menu_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, gpointer user_data)
 
117
{
 
118
        gtk_widget_show(GTK_WIDGET(status_separator));
 
119
        return;
 
120
}
 
121
 
 
122
static void
 
123
status_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data)
 
124
{
 
125
        if (g_list_length(dbusmenu_menuitem_get_children(root)) == 0) {
 
126
                gtk_widget_hide(GTK_WIDGET(status_separator));
 
127
        }
 
128
 
 
129
        return;
 
130
}
 
131
 
 
132
static void
 
133
status_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main)
 
134
{
 
135
        if (newroot == NULL) {
 
136
                gtk_widget_hide(GTK_WIDGET(status_separator));
 
137
                return;
 
138
        }
 
139
 
 
140
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED,   G_CALLBACK(child_added),           GUINT_TO_POINTER(STATUS_SECTION));
 
141
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(status_menu_added),     NULL);
 
142
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(status_menu_removed),   NULL);
 
143
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED,   G_CALLBACK(child_moved),           GUINT_TO_POINTER(STATUS_SECTION));
 
144
 
 
145
        GList * child = NULL;
 
146
        guint count = 0;
 
147
        for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) {
 
148
                child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(STATUS_SECTION));
 
149
        }
 
150
 
 
151
        if (count > 0) {
 
152
                gtk_widget_show(GTK_WIDGET(status_separator));
 
153
        }
 
154
 
 
155
        return;
 
156
}
 
157
 
 
158
static gboolean
 
159
build_status_menu (gpointer userdata)
 
160
{
 
161
        g_debug("Building Status Menu");
 
162
        guint returnval = 0;
 
163
        GError * error = NULL;
 
164
 
 
165
        if (proxy == NULL) {
 
166
                /* If we don't have DBus, let's stay in the idle loop */
 
167
                return TRUE;
 
168
        }
 
169
 
 
170
        if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_STATUS_DBUS_NAME, 0, &returnval, &error)) {
 
171
                g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" );
 
172
                g_error_free(error);
 
173
                return FALSE;
 
174
        }
 
175
 
 
176
        if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) {
 
177
                g_error("Return value isn't indicative of success: %d", returnval);
 
178
                return FALSE;
 
179
        }
 
180
 
 
181
        status_client = dbusmenu_gtkclient_new(INDICATOR_STATUS_DBUS_NAME, INDICATOR_STATUS_DBUS_OBJECT);
 
182
        g_signal_connect(G_OBJECT(status_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(status_menu_root_changed), main_menu);
 
183
 
 
184
        status_separator = gtk_separator_menu_item_new();
 
185
        gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), status_separator);
 
186
        gtk_widget_hide(status_separator); /* Should be default, I'm just being explicit.  $(%*#$ hide already!  */
 
187
 
 
188
        return FALSE;
 
189
}
 
190
 
 
191
/* Users menu */
 
192
 
 
193
static guint
 
194
users_menu_pos_offset (void)
 
195
{
 
196
        guint position = 0;
 
197
        if (SEPARATOR_SHOWN(status_separator)) {
 
198
                GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, status_separator);
 
199
                position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1;
 
200
        }
 
201
 
 
202
        return position;
 
203
}
 
204
 
 
205
static void
 
206
users_menu_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, gpointer user_data)
 
207
{
 
208
        gtk_widget_show(GTK_WIDGET(users_separator));
 
209
        return;
 
210
}
 
211
 
 
212
static void
 
213
users_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data)
 
214
{
 
215
        if (g_list_length(dbusmenu_menuitem_get_children(root)) == 0) {
 
216
                gtk_widget_hide(GTK_WIDGET(users_separator));
 
217
        }
 
218
 
 
219
        return;
 
220
}
 
221
 
 
222
static void
 
223
users_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main)
 
224
{
 
225
        if (newroot == NULL) {
 
226
                gtk_widget_hide(GTK_WIDGET(users_separator));
 
227
                return;
 
228
        }
 
229
 
 
230
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED,   G_CALLBACK(child_added),           GUINT_TO_POINTER(USERS_SECTION));
 
231
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(users_menu_added),      NULL);
 
232
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(users_menu_removed),    NULL);
 
233
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED,   G_CALLBACK(child_moved),           GUINT_TO_POINTER(USERS_SECTION));
 
234
 
 
235
        GList * child = NULL;
 
236
        guint count = 0;
 
237
        for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) {
 
238
                child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(USERS_SECTION));
 
239
        }
 
240
 
 
241
        if (count > 0) {
 
242
                gtk_widget_show(GTK_WIDGET(users_separator));
 
243
        }
 
244
 
 
245
        return;
 
246
}
 
247
 
 
248
static gboolean
 
249
build_users_menu (gpointer userdata)
 
250
{
 
251
        g_debug("Building Users Menu");
 
252
        guint returnval = 0;
 
253
        GError * error = NULL;
 
254
 
 
255
        if (proxy == NULL) {
 
256
                /* If we don't have DBus, let's stay in the idle loop */
 
257
                return TRUE;
 
258
        }
 
259
 
 
260
        if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_USERS_DBUS_NAME, 0, &returnval, &error)) {
 
261
                g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" );
 
262
                g_error_free(error);
 
263
                return FALSE;
 
264
        }
 
265
 
 
266
        if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) {
 
267
                g_error("Return value isn't indicative of success: %d", returnval);
 
268
                return FALSE;
 
269
        }
 
270
 
 
271
        users_client = dbusmenu_gtkclient_new(INDICATOR_USERS_DBUS_NAME, INDICATOR_USERS_DBUS_OBJECT);
 
272
        g_signal_connect(G_OBJECT(users_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(users_menu_root_changed), main_menu);
 
273
 
 
274
        users_separator = gtk_separator_menu_item_new();
 
275
        gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), users_separator);
 
276
        gtk_widget_hide(users_separator); /* Should be default, I'm just being explicit.  $(%*#$ hide already!  */
 
277
 
 
278
        return FALSE;
 
279
}
 
280
 
 
281
/* Session Menu Stuff */
 
282
 
 
283
static guint
 
284
session_menu_pos_offset (void)
 
285
{
 
286
        guint position = 0;
 
287
        if (SEPARATOR_SHOWN(users_separator)) {
 
288
                GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, users_separator);
 
289
                position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1;
 
290
        } else if (SEPARATOR_SHOWN(status_separator)) {
 
291
                GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, status_separator);
 
292
                position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1;
 
293
        }
 
294
 
 
295
        return position;
 
296
}
 
297
 
 
298
static void
 
299
session_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data)
 
300
{
 
301
        return;
 
302
}
 
303
 
 
304
static void
 
305
session_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main)
 
306
{
 
307
        if (newroot == NULL) {
 
308
                /* We're assuming this'll crash the least so it doesn't
 
309
                   hide a separator.  May be a bad choice. */
 
310
                return;
 
311
        }
 
312
 
 
313
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED,   G_CALLBACK(child_added),           GUINT_TO_POINTER(SESSION_SECTION));
 
314
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(session_menu_removed),  NULL);
 
315
        g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED,   G_CALLBACK(child_moved),           GUINT_TO_POINTER(SESSION_SECTION));
 
316
 
 
317
        GList * child = NULL;
 
318
        guint count = 0;
 
319
        for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) {
 
320
                child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(SESSION_SECTION));
 
321
        }
 
322
 
 
323
        return;
 
324
}
 
325
 
 
326
static gboolean
 
327
build_session_menu (gpointer userdata)
 
328
{
 
329
        g_debug("Building Session Menu");
 
330
        guint returnval = 0;
 
331
        GError * error = NULL;
 
332
 
 
333
        if (proxy == NULL) {
 
334
                /* If we don't have DBus, let's stay in the idle loop */
 
335
                return TRUE;
 
336
        }
 
337
 
 
338
        if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_SESSION_DBUS_NAME, 0, &returnval, &error)) {
 
339
                g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" );
 
340
                g_error_free(error);
 
341
                return FALSE;
 
342
        }
 
343
 
 
344
        if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) {
 
345
                g_error("Return value isn't indicative of success: %d", returnval);
 
346
                return FALSE;
 
347
        }
 
348
 
 
349
        session_client = dbusmenu_gtkclient_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT);
 
350
        g_signal_connect(G_OBJECT(session_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(session_menu_root_changed), main_menu);
 
351
 
 
352
        return FALSE;
 
353
}
 
354
 
 
355
/* Base menu stuff */
 
356
 
 
357
GtkMenu *
 
358
get_menu (void)
 
359
{
 
360
        connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
 
361
        proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
 
362
        if (proxy == NULL) {
 
363
                g_warning("Unable to get proxy for DBus itself.  Seriously.");
 
364
        }
 
365
 
 
366
        g_idle_add(build_status_menu, NULL);
 
367
        g_idle_add(build_users_menu, NULL);
 
368
        g_idle_add(build_session_menu, NULL);
 
369
 
 
370
        main_menu = GTK_MENU(gtk_menu_new());
 
371
        loading_item = gtk_menu_item_new_with_label("Loading...");
 
372
        gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item);
 
373
        gtk_widget_show(GTK_WIDGET(loading_item));
 
374
 
 
375
        return main_menu;
 
376
}
 
377
 
26
378