~ubuntu-branches/ubuntu/vivid/gnome-color-manager/vivid

« back to all changes in this revision

Viewing changes to .pc/01-libnotify_0.7.patch/src/gcm-session.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2011-08-02 04:53:11 UTC
  • mfrom: (2.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110802045311-2mdo1cwq6mqtt1fh
Tags: 2.32.0-2
* debian/watch: Track .bz2 tarballs.
* Bump debhelper compatibility level to 8.
* Update for libnotify 0.7. (Closes: #630272)
  - Bump Build-Depends on libnotify-dev to (>= 0.7.0).
  - Add debian/patches/01-libnotify_0.7.patch.

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) 2007-2010 Richard Hughes <richard@hughsie.com>
 
4
 *
 
5
 * Licensed under the GNU General Public License Version 2
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (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
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <glib/gi18n.h>
 
25
#include <dbus/dbus-glib.h>
 
26
#include <gtk/gtk.h>
 
27
#include <locale.h>
 
28
#include <gconf/gconf-client.h>
 
29
#include <libnotify/notify.h>
 
30
 
 
31
#include "egg-debug.h"
 
32
#include "gcm-dbus.h"
 
33
#include "gcm-client.h"
 
34
#include "gcm-device.h"
 
35
#include "gcm-utils.h"
 
36
#include "org.gnome.ColorManager.h"
 
37
 
 
38
static GMainLoop *loop = NULL;
 
39
static GConfClient *gconf_client = NULL;
 
40
 
 
41
#define GCM_DBUS_SERVICE                "org.gnome.ColorManager"
 
42
#define GCM_DBUS_INTERFACE              "org.gnome.ColorManager"
 
43
#define GCM_DBUS_PATH                   "/org/gnome/ColorManager"
 
44
#define GCM_SESSION_IDLE_EXIT           60 /* seconds */
 
45
#define GCM_SESSION_NOTIFY_TIMEOUT      30000 /* ms */
 
46
 
 
47
/**
 
48
 * gcm_session_object_register:
 
49
 * @connection: What we want to register to
 
50
 * @object: The GObject we want to register
 
51
 *
 
52
 * Return value: success
 
53
 **/
 
54
static gboolean
 
55
gcm_session_object_register (DBusGConnection *connection, GObject *object)
 
56
{
 
57
        DBusGProxy *bus_proxy = NULL;
 
58
        GError *error = NULL;
 
59
        guint request_name_result;
 
60
        gboolean ret;
 
61
 
 
62
        /* connect to the bus */
 
63
        bus_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
 
64
                                               DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
 
65
 
 
66
        /* get our name */
 
67
        ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
 
68
                                 G_TYPE_STRING, GCM_DBUS_SERVICE,
 
69
                                 G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
 
70
                                              DBUS_NAME_FLAG_REPLACE_EXISTING |
 
71
                                              DBUS_NAME_FLAG_DO_NOT_QUEUE,
 
72
                                 G_TYPE_INVALID,
 
73
                                 G_TYPE_UINT, &request_name_result,
 
74
                                 G_TYPE_INVALID);
 
75
        if (ret == FALSE) {
 
76
                /* abort as the DBUS method failed */
 
77
                egg_warning ("RequestName failed: %s", error->message);
 
78
                g_error_free (error);
 
79
                return FALSE;
 
80
        }
 
81
 
 
82
        /* free the bus_proxy */
 
83
        g_object_unref (G_OBJECT (bus_proxy));
 
84
 
 
85
        /* already running */
 
86
        if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
 
87
                return FALSE;
 
88
 
 
89
        dbus_g_object_type_install_info (GCM_TYPE_DBUS, &dbus_glib_gcm_dbus_object_info);
 
90
        dbus_g_error_domain_register (GCM_DBUS_ERROR, NULL, GCM_DBUS_TYPE_ERROR);
 
91
        dbus_g_connection_register_g_object (connection, GCM_DBUS_PATH, object);
 
92
 
 
93
        return TRUE;
 
94
}
 
95
 
 
96
/**
 
97
 * gcm_session_check_idle_cb:
 
98
 **/
 
99
static gboolean
 
100
gcm_session_check_idle_cb (GcmDbus *dbus)
 
101
{
 
102
        guint idle;
 
103
 
 
104
        /* get the idle time */
 
105
        idle = gcm_dbus_get_idle_time (dbus);
 
106
        if (idle > GCM_SESSION_IDLE_EXIT) {
 
107
                egg_debug ("exiting loop as idle");
 
108
                g_main_loop_quit (loop);
 
109
                return FALSE;
 
110
        }
 
111
        /* continue to poll */
 
112
        return TRUE;
 
113
}
 
114
 
 
115
/**
 
116
 * gcm_session_notify_cb:
 
117
 **/
 
118
static void
 
119
gcm_session_notify_cb (NotifyNotification *notification, gchar *action, gpointer user_data)
 
120
{
 
121
        gboolean ret;
 
122
        GError *error = NULL;
 
123
 
 
124
        if (g_strcmp0 (action, "display") == 0) {
 
125
                gconf_client_set_int (gconf_client, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, 0, NULL);
 
126
        } else if (g_strcmp0 (action, "printer") == 0) {
 
127
                gconf_client_set_int (gconf_client, GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD, 0, NULL);
 
128
        } else if (g_strcmp0 (action, "recalibrate") == 0) {
 
129
                ret = g_spawn_command_line_async ("gcm-prefs", &error);
 
130
                if (!ret) {
 
131
                        egg_warning ("failed to spawn: %s", error->message);
 
132
                        g_error_free (error);
 
133
                }
 
134
        }
 
135
}
 
136
 
 
137
/**
 
138
 * gcm_session_notify_recalibrate:
 
139
 **/
 
140
static gboolean
 
141
gcm_session_notify_recalibrate (const gchar *title, const gchar *message, GcmDeviceKind kind)
 
142
{
 
143
        gboolean ret;
 
144
        GError *error = NULL;
 
145
        NotifyNotification *notification;
 
146
 
 
147
        /* show a bubble */
 
148
        notification = notify_notification_new (title, message, GCM_STOCK_ICON, NULL);
 
149
        notify_notification_set_timeout (notification, GCM_SESSION_NOTIFY_TIMEOUT);
 
150
        notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
 
151
 
 
152
        /* TRANSLATORS: button: this is to open GCM */
 
153
        notify_notification_add_action (notification, "recalibrate", _("Recalibrate now"), gcm_session_notify_cb, NULL, NULL);
 
154
 
 
155
        /* TRANSLATORS: button: this is to ignore the recalibrate notifications */
 
156
        notify_notification_add_action (notification, gcm_device_kind_to_string (kind), _("Ignore"), gcm_session_notify_cb, NULL, NULL);
 
157
 
 
158
        ret = notify_notification_show (notification, &error);
 
159
        if (!ret) {
 
160
                egg_warning ("failed to show notification: %s", error->message);
 
161
                g_error_free (error);
 
162
        }
 
163
        return ret;
 
164
}
 
165
 
 
166
/**
 
167
 * gcm_session_notify_device:
 
168
 **/
 
169
static void
 
170
gcm_session_notify_device (GcmDevice *device)
 
171
{
 
172
        gchar *message;
 
173
        const gchar *title;
 
174
        GcmDeviceKind kind;
 
175
        glong since;
 
176
        GTimeVal timeval;
 
177
        gint threshold;
 
178
 
 
179
        /* get current time */
 
180
        g_get_current_time (&timeval);
 
181
 
 
182
        /* TRANSLATORS: this is when the device has not been recalibrated in a while */
 
183
        title = _("Recalibration required");
 
184
 
 
185
        /* check we care */
 
186
        kind = gcm_device_get_kind (device);
 
187
        if (kind == GCM_DEVICE_KIND_DISPLAY) {
 
188
 
 
189
                /* get from GConf */
 
190
                threshold = gconf_client_get_int (gconf_client, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, NULL);
 
191
 
 
192
                /* TRANSLATORS: this is when the display has not been recalibrated in a while */
 
193
                message = g_strdup_printf (_("The display '%s' should be recalibrated soon."), gcm_device_get_title (device));
 
194
        } else {
 
195
 
 
196
                /* get from GConf */
 
197
                threshold = gconf_client_get_int (gconf_client, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, NULL);
 
198
 
 
199
                /* TRANSLATORS: this is when the printer has not been recalibrated in a while */
 
200
                message = g_strdup_printf (_("The printer '%s' should be recalibrated soon."), gcm_device_get_title (device));
 
201
        }
 
202
 
 
203
        /* check if we need to notify */
 
204
        since = timeval.tv_sec - gcm_device_get_modified_time (device);
 
205
        if (threshold > since)
 
206
                gcm_session_notify_recalibrate (title, message, kind);
 
207
        g_free (message);
 
208
}
 
209
 
 
210
/**
 
211
 * gcm_session_added_cb:
 
212
 **/
 
213
static void
 
214
gcm_session_added_cb (GcmClient *client, GcmDevice *device, gpointer user_data)
 
215
{
 
216
        GcmDeviceKind kind;
 
217
        const gchar *profile;
 
218
        gchar *basename = NULL;
 
219
 
 
220
        /* check we care */
 
221
        kind = gcm_device_get_kind (device);
 
222
        if (kind != GCM_DEVICE_KIND_DISPLAY &&
 
223
            kind != GCM_DEVICE_KIND_PRINTER)
 
224
                return;
 
225
 
 
226
        /* ensure we have a profile */
 
227
        profile = gcm_device_get_profile_filename (device);
 
228
        if (profile == NULL) {
 
229
                egg_debug ("no profile set for %s", gcm_device_get_id (device));
 
230
                goto out;
 
231
        }
 
232
 
 
233
        /* ensure it's a profile generated by us */
 
234
        basename = g_path_get_basename (profile);
 
235
        if (!g_str_has_prefix (basename, "GCM")) {
 
236
                egg_debug ("not a GCM profile for %s: %s", gcm_device_get_id (device), profile);
 
237
                goto out;
 
238
        }
 
239
 
 
240
        /* handle device */
 
241
        gcm_session_notify_device (device);
 
242
out:
 
243
        g_free (basename);
 
244
}
 
245
 
 
246
/**
 
247
 * main:
 
248
 **/
 
249
int
 
250
main (int argc, char *argv[])
 
251
{
 
252
        gboolean no_timed_exit = FALSE;
 
253
        GcmDbus *dbus = NULL;
 
254
        GOptionContext *context;
 
255
        GError *error = NULL;
 
256
        gboolean ret;
 
257
        guint retval = 0;
 
258
        DBusGConnection *connection;
 
259
        GcmClient *client = NULL;
 
260
 
 
261
        const GOptionEntry options[] = {
 
262
                { "no-timed-exit", '\0', 0, G_OPTION_ARG_NONE, &no_timed_exit,
 
263
                  _("Do not exit after the request has been processed"), NULL },
 
264
                { NULL}
 
265
        };
 
266
 
 
267
        setlocale (LC_ALL, "");
 
268
 
 
269
        bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
 
270
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
271
        textdomain (GETTEXT_PACKAGE);
 
272
 
 
273
        if (! g_thread_supported ())
 
274
                g_thread_init (NULL);
 
275
        dbus_g_thread_init ();
 
276
        g_type_init ();
 
277
        notify_init ("gnome-color-manager");
 
278
 
 
279
        /* TRANSLATORS: program name, a session wide daemon to watch for updates and changing system state */
 
280
        g_set_application_name (_("Color Management"));
 
281
        context = g_option_context_new (NULL);
 
282
        g_option_context_set_summary (context, _("Color Management D-Bus Service"));
 
283
        g_option_context_add_main_entries (context, options, NULL);
 
284
        g_option_context_add_group (context, egg_debug_get_option_group ());
 
285
        g_option_context_add_group (context, gtk_get_option_group (TRUE));
 
286
        g_option_context_parse (context, &argc, &argv, NULL);
 
287
        g_option_context_free (context);
 
288
 
 
289
        gtk_init (&argc, &argv);
 
290
 
 
291
        /* get the settings */
 
292
        gconf_client = gconf_client_get_default ();
 
293
 
 
294
        /* monitor devices as they are added */
 
295
        client = gcm_client_new ();
 
296
        g_signal_connect (client, "added", G_CALLBACK (gcm_session_added_cb), NULL);
 
297
 
 
298
        /* create new objects */
 
299
        dbus = gcm_dbus_new ();
 
300
        loop = g_main_loop_new (NULL, FALSE);
 
301
 
 
302
        /* get the bus */
 
303
        connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 
304
        if (error) {
 
305
                egg_warning ("%s", error->message);
 
306
                g_error_free (error);
 
307
                retval = 1;
 
308
                goto out;
 
309
        }
 
310
 
 
311
        /* try to register */
 
312
        ret = gcm_session_object_register (connection, G_OBJECT (dbus));
 
313
        if (!ret) {
 
314
                egg_warning ("failed to replace running instance.");
 
315
                retval = 1;
 
316
                goto out;
 
317
        }
 
318
 
 
319
        /* only timeout if we have specified iton the command line */
 
320
        if (!no_timed_exit)
 
321
                g_timeout_add_seconds (5, (GSourceFunc) gcm_session_check_idle_cb, dbus);
 
322
 
 
323
        /* wait */
 
324
        g_main_loop_run (loop);
 
325
out:
 
326
        g_object_unref (gconf_client);
 
327
        g_object_unref (client);
 
328
        g_main_loop_unref (loop);
 
329
        g_object_unref (dbus);
 
330
        return retval;
 
331
}
 
332