~psusi/ubuntu/natty/gnome-power-manager/sleep

« back to all changes in this revision

Viewing changes to .pc/00git-port-to-libupower.patch/src/gpm-tray-icon.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-07-14 16:19:03 UTC
  • Revision ID: james.westby@ubuntu.com-20100714161903-ji5dlfcj32q854gc
Tags: 2.30.1-1ubuntu2
* Add 00git-port-to-libupower.patch: Port from libdevkit-power to
  libupower-glib, the former will go away soon.
* debian/control.in: Replace libdevkit-power-gobject-dev with
  libupower-glib-dev build dependency.
* 12-add-appindicators.patch: Update to upower port.
* Add 13-energy-star.patch: Change default timings to be Energy Star 5.0
  compliant, except for automatic suspend on AC (since that might be both
  inconvenient, and suspend might not work at all). (LP: #604635)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
 
4
 * Copyright (C) 2005-2009 Richard Hughes <richard@hughsie.com>
 
5
 *
 
6
 * Licensed under the GNU General Public License Version 2
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#  include <config.h>
 
25
#endif
 
26
 
 
27
#include <stdlib.h>
 
28
#include <stdio.h>
 
29
#include <time.h>
 
30
#include <errno.h>
 
31
 
 
32
#include <string.h>
 
33
#include <sys/time.h>
 
34
#include <sys/types.h>
 
35
#ifdef HAVE_UNISTD_H
 
36
#include <unistd.h>
 
37
#endif /* HAVE_UNISTD_H */
 
38
 
 
39
#include <glib/gi18n.h>
 
40
#include <gtk/gtk.h>
 
41
#include <gconf/gconf-client.h>
 
42
#include <devkit-power-gobject/devicekit-power.h>
 
43
 
 
44
#include "egg-debug.h"
 
45
 
 
46
#include "gpm-upower.h"
 
47
#include "gpm-engine.h"
 
48
#include "gpm-common.h"
 
49
#include "gpm-stock-icons.h"
 
50
#include "gpm-tray-icon.h"
 
51
 
 
52
static void     gpm_tray_icon_finalize   (GObject          *object);
 
53
 
 
54
#define GPM_TRAY_ICON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_TRAY_ICON, GpmTrayIconPrivate))
 
55
 
 
56
struct GpmTrayIconPrivate
 
57
{
 
58
        GConfClient             *conf;
 
59
        GpmEngine               *engine;
 
60
        GtkStatusIcon           *status_icon;
 
61
        gboolean                 show_actions;
 
62
};
 
63
 
 
64
G_DEFINE_TYPE (GpmTrayIcon, gpm_tray_icon, G_TYPE_OBJECT)
 
65
 
 
66
/**
 
67
 * gpm_tray_icon_enable_actions:
 
68
 **/
 
69
static void
 
70
gpm_tray_icon_enable_actions (GpmTrayIcon *icon, gboolean enabled)
 
71
{
 
72
        g_return_if_fail (GPM_IS_TRAY_ICON (icon));
 
73
        icon->priv->show_actions = enabled;
 
74
}
 
75
 
 
76
/**
 
77
 * gpm_tray_icon_show:
 
78
 * @enabled: If we should show the tray
 
79
 **/
 
80
static void
 
81
gpm_tray_icon_show (GpmTrayIcon *icon, gboolean enabled)
 
82
{
 
83
        g_return_if_fail (GPM_IS_TRAY_ICON (icon));
 
84
        gtk_status_icon_set_visible (icon->priv->status_icon, enabled);
 
85
}
 
86
 
 
87
/**
 
88
 * gpm_tray_icon_set_tooltip:
 
89
 * @tooltip: The tooltip text, e.g. "Batteries fully charged"
 
90
 **/
 
91
gboolean
 
92
gpm_tray_icon_set_tooltip (GpmTrayIcon *icon, const gchar *tooltip)
 
93
{
 
94
        g_return_val_if_fail (icon != NULL, FALSE);
 
95
        g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), FALSE);
 
96
        g_return_val_if_fail (tooltip != NULL, FALSE);
 
97
 
 
98
#if GTK_CHECK_VERSION(2,15,0)
 
99
        gtk_status_icon_set_tooltip_text (icon->priv->status_icon, tooltip);
 
100
#else
 
101
        gtk_status_icon_set_tooltip (icon->priv->status_icon, tooltip);
 
102
#endif
 
103
        return TRUE;
 
104
}
 
105
 
 
106
/**
 
107
 * gpm_tray_icon_get_status_icon:
 
108
 **/
 
109
GtkStatusIcon *
 
110
gpm_tray_icon_get_status_icon (GpmTrayIcon *icon)
 
111
{
 
112
        g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), NULL);
 
113
        return g_object_ref (icon->priv->status_icon);
 
114
}
 
115
 
 
116
/**
 
117
 * gpm_tray_icon_set_image_from_stock:
 
118
 * @filename: The icon name, e.g. GPM_STOCK_APP_ICON, or NULL to remove.
 
119
 *
 
120
 * Loads a pixmap from disk, and sets as the tooltip icon
 
121
 **/
 
122
gboolean
 
123
gpm_tray_icon_set_icon (GpmTrayIcon *icon, const gchar *filename)
 
124
{
 
125
        g_return_val_if_fail (icon != NULL, FALSE);
 
126
        g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), FALSE);
 
127
 
 
128
        if (filename != NULL) {
 
129
                egg_debug ("Setting icon to %s", filename);
 
130
                gtk_status_icon_set_from_icon_name (icon->priv->status_icon, filename);
 
131
 
 
132
                /* make sure that we are visible */
 
133
                gpm_tray_icon_show (icon, TRUE);
 
134
        } else {
 
135
                /* remove icon */
 
136
                egg_debug ("no icon will be displayed");
 
137
 
 
138
                /* make sure that we are hidden */
 
139
                gpm_tray_icon_show (icon, FALSE);
 
140
        }
 
141
        return TRUE;
 
142
}
 
143
 
 
144
/**
 
145
 * gpm_tray_icon_show_info_cb:
 
146
 **/
 
147
static void
 
148
gpm_tray_icon_show_info_cb (GtkMenuItem *item, gpointer data)
 
149
{
 
150
        gchar *path;
 
151
        const gchar *object_path;
 
152
 
 
153
        object_path = g_object_get_data (G_OBJECT (item), "object-path");
 
154
        path = g_strdup_printf ("%s/gnome-power-statistics --device %s", BINDIR, object_path);
 
155
        if (!g_spawn_command_line_async (path, NULL))
 
156
                egg_warning ("Couldn't execute command: %s", path);
 
157
        g_free (path);
 
158
}
 
159
 
 
160
/**
 
161
 * gpm_tray_icon_show_preferences_cb:
 
162
 * @action: A valid GtkAction
 
163
 **/
 
164
static void
 
165
gpm_tray_icon_show_preferences_cb (GtkMenuItem *item, gpointer data)
 
166
{
 
167
        const gchar *command = "gnome-power-preferences";
 
168
 
 
169
        if (g_spawn_command_line_async (command, NULL) == FALSE)
 
170
                egg_warning ("Couldn't execute command: %s", command);
 
171
}
 
172
 
 
173
/**
 
174
 * gpm_tray_icon_popup_cleared_cd:
 
175
 * @widget: The popup Gtkwidget
 
176
 *
 
177
 * We have to re-enable the tooltip when the popup is removed
 
178
 **/
 
179
static void
 
180
gpm_tray_icon_popup_cleared_cd (GtkWidget *widget, GpmTrayIcon *icon)
 
181
{
 
182
        g_return_if_fail (GPM_IS_TRAY_ICON (icon));
 
183
        egg_debug ("clear tray");
 
184
        g_object_ref_sink (widget);
 
185
        g_object_unref (widget);
 
186
}
 
187
 
 
188
/**
 
189
 * gpm_tray_icon_class_init:
 
190
 **/
 
191
static void
 
192
gpm_tray_icon_class_init (GpmTrayIconClass *klass)
 
193
{
 
194
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
195
 
 
196
        object_class->finalize = gpm_tray_icon_finalize;
 
197
        g_type_class_add_private (klass, sizeof (GpmTrayIconPrivate));
 
198
}
 
199
 
 
200
/**
 
201
 * gpm_tray_icon_add_device:
 
202
 **/
 
203
static guint
 
204
gpm_tray_icon_add_device (GpmTrayIcon *icon, GtkMenu *menu, const GPtrArray *array, DkpDeviceType type)
 
205
{
 
206
        guint i;
 
207
        guint added = 0;
 
208
        gchar *icon_name;
 
209
        gchar *label;
 
210
        GtkWidget *item;
 
211
        GtkWidget *image;
 
212
        const gchar *object_path;
 
213
        const gchar *desc;
 
214
        DkpDevice *device;
 
215
        DkpDeviceType type_tmp;
 
216
        gdouble percentage;
 
217
 
 
218
        /* find type */
 
219
        for (i=0;i<array->len;i++) {
 
220
                device = g_ptr_array_index (array, i);
 
221
 
 
222
                /* get device properties */
 
223
                g_object_get (device,
 
224
                              "type", &type_tmp,
 
225
                              "percentage", &percentage,
 
226
                              NULL);
 
227
 
 
228
                if (type != type_tmp)
 
229
                        continue;
 
230
 
 
231
                object_path = dkp_device_get_object_path (device);
 
232
                egg_debug ("adding device %s", object_path);
 
233
                added++;
 
234
 
 
235
                /* generate the label */
 
236
                desc = gpm_device_type_to_localised_text (type, 1);
 
237
                label = g_strdup_printf ("%s (%.1f%%)", desc, percentage);
 
238
                item = gtk_image_menu_item_new_with_label (label);
 
239
 
 
240
                /* generate the image */
 
241
                icon_name = gpm_upower_get_device_icon (device);
 
242
                image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
 
243
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 
244
                gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
 
245
 
 
246
                /* callback and add the the menu */
 
247
                g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (gpm_tray_icon_show_info_cb), icon);
 
248
                g_object_set_data (G_OBJECT (item), "object-path", (gpointer) object_path);
 
249
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
250
 
 
251
                g_free (icon_name);
 
252
                g_free (label);
 
253
        }
 
254
        return added;
 
255
}
 
256
 
 
257
/**
 
258
 * gpm_tray_icon_create_menu:
 
259
 *
 
260
 * Display the popup menu.
 
261
 **/
 
262
static void
 
263
gpm_tray_icon_create_menu (GpmTrayIcon *icon, guint32 timestamp)
 
264
{
 
265
        GtkMenu *menu = (GtkMenu*) gtk_menu_new ();
 
266
        GtkWidget *item;
 
267
        GtkWidget *image;
 
268
        guint dev_cnt = 0;
 
269
        GPtrArray *array;
 
270
 
 
271
        /* add all device types to the drop down menu */
 
272
        array = gpm_engine_get_devices (icon->priv->engine);
 
273
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_BATTERY);
 
274
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_UPS);
 
275
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_MOUSE);
 
276
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_KEYBOARD);
 
277
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_PDA);
 
278
        dev_cnt += gpm_tray_icon_add_device (icon, menu, array, DKP_DEVICE_TYPE_PHONE);
 
279
        g_ptr_array_unref (array);
 
280
 
 
281
        /* skip for things like live-cd's and GDM */
 
282
        if (0 && !icon->priv->show_actions)
 
283
                goto skip_prefs;
 
284
 
 
285
        /* only do the seporator if we have at least one device */
 
286
        if (dev_cnt != 0) {
 
287
                item = gtk_separator_menu_item_new ();
 
288
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
289
        }
 
290
 
 
291
        /* preferences */
 
292
        item = gtk_image_menu_item_new_with_mnemonic (_("_Preferences"));
 
293
        image = gtk_image_new_from_icon_name (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
 
294
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 
295
        g_signal_connect (G_OBJECT (item), "activate",
 
296
                          G_CALLBACK (gpm_tray_icon_show_preferences_cb), icon);
 
297
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
298
 
 
299
skip_prefs:
 
300
        /* show the menu */
 
301
        gtk_widget_show_all (GTK_WIDGET (menu));
 
302
        gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
 
303
                        gtk_status_icon_position_menu, icon->priv->status_icon,
 
304
                        1, timestamp);
 
305
 
 
306
        g_signal_connect (GTK_WIDGET (menu), "hide",
 
307
                          G_CALLBACK (gpm_tray_icon_popup_cleared_cd), icon);
 
308
}
 
309
 
 
310
/**
 
311
 * gpm_tray_icon_popup_menu_cb:
 
312
 *
 
313
 * Display the popup menu.
 
314
 **/
 
315
static void
 
316
gpm_tray_icon_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint32 timestamp, GpmTrayIcon *icon)
 
317
{
 
318
        egg_debug ("icon right clicked");
 
319
        gpm_tray_icon_create_menu (icon, timestamp);
 
320
}
 
321
 
 
322
 
 
323
/**
 
324
 * gpm_tray_icon_activate_cb:
 
325
 * @button: Which buttons are pressed
 
326
 *
 
327
 * Callback when the icon is clicked
 
328
 **/
 
329
static void
 
330
gpm_tray_icon_activate_cb (GtkStatusIcon *status_icon, GpmTrayIcon *icon)
 
331
{
 
332
        egg_debug ("icon left clicked");
 
333
        gpm_tray_icon_create_menu (icon, gtk_get_current_event_time());
 
334
}
 
335
 
 
336
/**
 
337
 * gpm_conf_gconf_key_changed_cb:
 
338
 *
 
339
 * We might have to do things when the gconf keys change; do them here.
 
340
 **/
 
341
static void
 
342
gpm_conf_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, GpmTrayIcon *icon)
 
343
{
 
344
        GConfValue *value;
 
345
        gboolean allowed_in_menu;
 
346
 
 
347
        value = gconf_entry_get_value (entry);
 
348
        if (value == NULL)
 
349
                return;
 
350
 
 
351
        if (strcmp (entry->key, GPM_CONF_UI_SHOW_ACTIONS) == 0) {
 
352
                allowed_in_menu = gconf_value_get_bool (value);
 
353
                gpm_tray_icon_enable_actions (icon, allowed_in_menu);
 
354
        }
 
355
}
 
356
 
 
357
/**
 
358
 * gpm_tray_icon_init:
 
359
 *
 
360
 * Initialise the tray object
 
361
 **/
 
362
static void
 
363
gpm_tray_icon_init (GpmTrayIcon *icon)
 
364
{
 
365
        gboolean allowed_in_menu;
 
366
 
 
367
        icon->priv = GPM_TRAY_ICON_GET_PRIVATE (icon);
 
368
 
 
369
        icon->priv->engine = gpm_engine_new ();
 
370
 
 
371
        icon->priv->conf = gconf_client_get_default ();
 
372
        /* watch gnome-power-manager keys */
 
373
        gconf_client_add_dir (icon->priv->conf, GPM_CONF_DIR,
 
374
                              GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
 
375
        gconf_client_notify_add (icon->priv->conf, GPM_CONF_DIR,
 
376
                                 (GConfClientNotifyFunc) gpm_conf_gconf_key_changed_cb,
 
377
                                 icon, NULL, NULL);
 
378
 
 
379
        icon->priv->status_icon = gtk_status_icon_new ();
 
380
        g_signal_connect_object (G_OBJECT (icon->priv->status_icon),
 
381
                                 "popup_menu",
 
382
                                 G_CALLBACK (gpm_tray_icon_popup_menu_cb),
 
383
                                 icon, 0);
 
384
        g_signal_connect_object (G_OBJECT (icon->priv->status_icon),
 
385
                                 "activate",
 
386
                                 G_CALLBACK (gpm_tray_icon_activate_cb),
 
387
                                 icon, 0);
 
388
 
 
389
        allowed_in_menu = gconf_client_get_bool (icon->priv->conf, GPM_CONF_UI_SHOW_ACTIONS, NULL);
 
390
        gpm_tray_icon_enable_actions (icon, allowed_in_menu);
 
391
}
 
392
 
 
393
/**
 
394
 * gpm_tray_icon_finalize:
 
395
 * @object: This TrayIcon class instance
 
396
 **/
 
397
static void
 
398
gpm_tray_icon_finalize (GObject *object)
 
399
{
 
400
        GpmTrayIcon *tray_icon;
 
401
 
 
402
        g_return_if_fail (object != NULL);
 
403
        g_return_if_fail (GPM_IS_TRAY_ICON (object));
 
404
 
 
405
        tray_icon = GPM_TRAY_ICON (object);
 
406
 
 
407
        g_object_unref (tray_icon->priv->status_icon);
 
408
        g_object_unref (tray_icon->priv->engine);
 
409
        g_return_if_fail (tray_icon->priv != NULL);
 
410
 
 
411
        G_OBJECT_CLASS (gpm_tray_icon_parent_class)->finalize (object);
 
412
}
 
413
 
 
414
/**
 
415
 * gpm_tray_icon_new:
 
416
 * Return value: A new TrayIcon object.
 
417
 **/
 
418
GpmTrayIcon *
 
419
gpm_tray_icon_new (void)
 
420
{
 
421
        GpmTrayIcon *tray_icon;
 
422
        tray_icon = g_object_new (GPM_TYPE_TRAY_ICON, NULL);
 
423
        return GPM_TRAY_ICON (tray_icon);
 
424
}
 
425