1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3
* Copyright (C) 2007-2010 Richard Hughes <richard@hughsie.com>
5
* Licensed under the GNU General Public License Version 2
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.
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.
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.
24
#include <glib/gi18n.h>
25
#include <dbus/dbus-glib.h>
28
#include <gconf/gconf-client.h>
29
#include <libnotify/notify.h>
31
#include "egg-debug.h"
33
#include "gcm-client.h"
34
#include "gcm-device.h"
35
#include "gcm-utils.h"
36
#include "org.gnome.ColorManager.h"
38
static GMainLoop *loop = NULL;
39
static GConfClient *gconf_client = NULL;
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 */
48
* gcm_session_object_register:
49
* @connection: What we want to register to
50
* @object: The GObject we want to register
52
* Return value: success
55
gcm_session_object_register (DBusGConnection *connection, GObject *object)
57
DBusGProxy *bus_proxy = NULL;
59
guint request_name_result;
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);
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,
73
G_TYPE_UINT, &request_name_result,
76
/* abort as the DBUS method failed */
77
egg_warning ("RequestName failed: %s", error->message);
82
/* free the bus_proxy */
83
g_object_unref (G_OBJECT (bus_proxy));
86
if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
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);
97
* gcm_session_check_idle_cb:
100
gcm_session_check_idle_cb (GcmDbus *dbus)
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);
111
/* continue to poll */
116
* gcm_session_notify_cb:
119
gcm_session_notify_cb (NotifyNotification *notification, gchar *action, gpointer user_data)
122
GError *error = NULL;
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);
131
egg_warning ("failed to spawn: %s", error->message);
132
g_error_free (error);
138
* gcm_session_notify_recalibrate:
141
gcm_session_notify_recalibrate (const gchar *title, const gchar *message, GcmDeviceKind kind)
144
GError *error = NULL;
145
NotifyNotification *notification;
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);
152
/* TRANSLATORS: button: this is to open GCM */
153
notify_notification_add_action (notification, "recalibrate", _("Recalibrate now"), gcm_session_notify_cb, NULL, NULL);
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);
158
ret = notify_notification_show (notification, &error);
160
egg_warning ("failed to show notification: %s", error->message);
161
g_error_free (error);
167
* gcm_session_notify_device:
170
gcm_session_notify_device (GcmDevice *device)
179
/* get current time */
180
g_get_current_time (&timeval);
182
/* TRANSLATORS: this is when the device has not been recalibrated in a while */
183
title = _("Recalibration required");
186
kind = gcm_device_get_kind (device);
187
if (kind == GCM_DEVICE_KIND_DISPLAY) {
190
threshold = gconf_client_get_int (gconf_client, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, NULL);
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));
197
threshold = gconf_client_get_int (gconf_client, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, NULL);
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));
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);
211
* gcm_session_added_cb:
214
gcm_session_added_cb (GcmClient *client, GcmDevice *device, gpointer user_data)
217
const gchar *profile;
218
gchar *basename = NULL;
221
kind = gcm_device_get_kind (device);
222
if (kind != GCM_DEVICE_KIND_DISPLAY &&
223
kind != GCM_DEVICE_KIND_PRINTER)
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));
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);
241
gcm_session_notify_device (device);
250
main (int argc, char *argv[])
252
gboolean no_timed_exit = FALSE;
253
GcmDbus *dbus = NULL;
254
GOptionContext *context;
255
GError *error = NULL;
258
DBusGConnection *connection;
259
GcmClient *client = NULL;
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 },
267
setlocale (LC_ALL, "");
269
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
270
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
271
textdomain (GETTEXT_PACKAGE);
273
if (! g_thread_supported ())
274
g_thread_init (NULL);
275
dbus_g_thread_init ();
277
notify_init ("gnome-color-manager");
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);
289
gtk_init (&argc, &argv);
291
/* get the settings */
292
gconf_client = gconf_client_get_default ();
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);
298
/* create new objects */
299
dbus = gcm_dbus_new ();
300
loop = g_main_loop_new (NULL, FALSE);
303
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
305
egg_warning ("%s", error->message);
306
g_error_free (error);
311
/* try to register */
312
ret = gcm_session_object_register (connection, G_OBJECT (dbus));
314
egg_warning ("failed to replace running instance.");
319
/* only timeout if we have specified iton the command line */
321
g_timeout_add_seconds (5, (GSourceFunc) gcm_session_check_idle_cb, dbus);
324
g_main_loop_run (loop);
326
g_object_unref (gconf_client);
327
g_object_unref (client);
328
g_main_loop_unref (loop);
329
g_object_unref (dbus);