pidgin/gtkidle.c

changeset 38578
c81f0a8301fe
parent 35455
216a37403c5b
child 38580
775bba9b53df
equal deleted inserted replaced
38542:b0c4ad7949de 38578:c81f0a8301fe
24 #include "gtkidle.h" 24 #include "gtkidle.h"
25 25
26 #ifdef HAVE_IOKIT 26 #ifdef HAVE_IOKIT
27 # include <CoreFoundation/CoreFoundation.h> 27 # include <CoreFoundation/CoreFoundation.h>
28 # include <IOKit/IOKitLib.h> 28 # include <IOKit/IOKitLib.h>
29 #else 29 #elif defined _WIN32
30 # ifdef USE_SCREENSAVER 30 # include "gtkwin32dep.h"
31 # ifdef _WIN32 31 #endif
32 # include "gtkwin32dep.h"
33 # else
34 /* We're on X11 and not MacOS X with IOKit. */
35 # include <X11/Xlib.h>
36 # include <X11/Xutil.h>
37 # include <X11/extensions/scrnsaver.h>
38 # include <gdk/gdkx.h>
39 # endif /* !_WIN32 */
40 # endif /* USE_SCREENSAVER */
41 #endif /* !HAVE_IOKIT */
42 32
43 #include "idle.h" 33 #include "idle.h"
34
35 #if !defined(HAVE_IOKIT) && !defined(_WIN32)
36 typedef struct {
37 gchar *bus_name;
38 gchar *object_path;
39 gchar *iface_name;
40 } PidginDBusScreenSaverInfo;
41
42 static const PidginDBusScreenSaverInfo screensavers[] = {
43 {
44 "org.freedesktop.ScreenSaver",
45 "/org/freedesktop/ScreenSaver",
46 "org.freedesktop.ScreenSaver"
47 }, {
48 "org.gnome.ScreenSaver",
49 "/org/gnome/ScreenSaver",
50 "org.gnome.ScreenSaver"
51 }, {
52 "org.kde.ScreenSaver",
53 "/org/kde/ScreenSaver",
54 "org.kde.ScreenSaver"
55 },
56 { NULL, NULL, NULL}
57 };
58 #endif /* !HAVE_IOKIT && !_WIN32 */
44 59
45 /* 60 /*
46 * pidgin_get_time_idle: 61 * pidgin_get_time_idle:
47 * 62 *
48 * Get the number of seconds the user has been idle. In Unix-world 63 * Get the number of seconds the user has been idle. In Unix-world
49 * this is based on the X Windows usage. In MS Windows this is 64 * this is based on the DBus ScreenSaver interfaces. In MS Windows this
50 * based on keyboard/mouse usage information obtained from the OS. 65 * is based on keyboard/mouse usage information obtained from the OS.
51 * In MacOS X, this is based on keyboard/mouse usage information 66 * In MacOS X, this is based on keyboard/mouse usage information
52 * obtained from the OS, if configure detected IOKit. Otherwise, 67 * obtained from the OS, if configure detected IOKit. Otherwise,
53 * MacOS X is handled as a case of X Windows. 68 * MacOS X is handled as a case of Unix.
54 *
55 * In Debian bug #271639, jwz says:
56 *
57 * Purple should simply ask xscreensaver how long the user has been idle:
58 * % xscreensaver-command -time
59 * XScreenSaver 4.18: screen blanked since Tue Sep 14 14:10:45 2004
60 *
61 * Or you can monitor the _SCREENSAVER_STATUS property on root window #0.
62 * Element 0 is the status (0, BLANK, LOCK), element 1 is the time_t since
63 * the last state change, and subsequent elements are which hack is running
64 * on the various screens:
65 * % xprop -f _SCREENSAVER_STATUS 32ac -root _SCREENSAVER_STATUS
66 * _SCREENSAVER_STATUS(INTEGER) = BLANK, 1095196626, 10, 237
67 *
68 * See watch() in xscreensaver/driver/xscreensaver-command.c.
69 * 69 *
70 * Returns: The number of seconds the user has been idle. 70 * Returns: The number of seconds the user has been idle.
71 */ 71 */
72 #if defined(USE_SCREENSAVER) || defined(HAVE_IOKIT)
73 static time_t 72 static time_t
74 pidgin_get_time_idle(void) 73 pidgin_get_time_idle(void)
75 { 74 {
76 # ifdef HAVE_IOKIT 75 # ifdef HAVE_IOKIT
77 /* Query the IOKit API */ 76 /* Query the IOKit API */
99 # else 98 # else
100 # ifdef _WIN32 99 # ifdef _WIN32
101 /* Query Windows */ 100 /* Query Windows */
102 return (GetTickCount() - winpidgin_get_lastactive()) / 1000; 101 return (GetTickCount() - winpidgin_get_lastactive()) / 1000;
103 # else 102 # else
104 /* We're on X11 and not MacOS X with IOKit. */ 103 static const PidginDBusScreenSaverInfo *info = screensavers;
104 GApplication *app;
105 GDBusConnection *conn;
106 GVariant *reply = NULL;
107 guint32 active_time = 0;
108 GError *error = NULL;
105 109
106 /* Query xscreensaver */ 110 app = g_application_get_default();
107 static XScreenSaverInfo *mit_info = NULL;
108 static int has_extension = -1;
109 int event_base, error_base;
110 111
111 if (has_extension == -1) 112 if (app == NULL) {
112 has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), 113 purple_debug_error("gtkidle",
113 &event_base, &error_base); 114 "Unable to retrieve GApplication");
115 return 0;
116 }
114 117
115 if (has_extension) 118 conn = g_application_get_dbus_connection(app);
116 {
117 if (mit_info == NULL)
118 mit_info = XScreenSaverAllocInfo();
119 119
120 XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), 120 if (conn == NULL) {
121 GDK_ROOT_WINDOW(), mit_info); 121 purple_debug_misc("gtkidle",
122 return (mit_info->idle) / 1000; 122 "GApplication lacking DBus connection. "
123 "Skip checking ScreenSaver interface");
124 return 0;
123 } 125 }
124 else 126
127 while (reply == NULL && info->bus_name != NULL) {
128 reply = g_dbus_connection_call_sync(conn,
129 info->bus_name, info->object_path,
130 info->iface_name, "GetActiveTime",
131 NULL, G_VARIANT_TYPE("(u)"),
132 G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000,
133 NULL, &error);
134
135 if (reply != NULL) {
136 break;
137 }
138
139 if (g_error_matches(error, G_DBUS_ERROR,
140 G_DBUS_ERROR_NOT_SUPPORTED)) {
141 purple_debug_info("gtkidle",
142 "Querying idle time on '%s' "
143 "unsupported. Trying the next one",
144 info->bus_name);
145 } else if (g_error_matches(error, G_DBUS_ERROR,
146 G_DBUS_ERROR_NAME_HAS_NO_OWNER)) {
147 purple_debug_info("gtkidle",
148 "Querying idle time on '%s' "
149 "not found. Trying the next one",
150 info->bus_name);
151 } else {
152 purple_debug_error("gtkidle",
153 "Querying idle time on '%s' "
154 "error: %s", info->bus_name,
155 error->message);
156 }
157
158 g_clear_error(&error);
159 ++info;
160 }
161
162 if (reply == NULL) {
163 purple_debug_warning("gtkidle",
164 "Failed to query ScreenSaver active time: "
165 "No working ScreenSaver interfaces");
125 return 0; 166 return 0;
167 }
168
169 g_variant_get(reply, "(u)", &active_time);
170 g_variant_unref(reply);
171
172 return active_time;
126 # endif /* !_WIN32 */ 173 # endif /* !_WIN32 */
127 # endif /* !HAVE_IOKIT */ 174 # endif /* !HAVE_IOKIT */
128 } 175 }
129 #endif /* USE_SCREENSAVER || HAVE_IOKIT */
130 176
131 static PurpleIdleUiOps ui_ops = 177 static PurpleIdleUiOps ui_ops =
132 { 178 {
133 #if defined(USE_SCREENSAVER) || defined(HAVE_IOKIT)
134 pidgin_get_time_idle, 179 pidgin_get_time_idle,
135 #else
136 NULL,
137 #endif /* USE_SCREENSAVER || HAVE_IOKIT */
138 NULL, 180 NULL,
139 NULL, 181 NULL,
140 NULL, 182 NULL,
141 NULL 183 NULL
142 }; 184 };

mercurial