Replace functions which called once with their bodies
[pidgin-git.git] / pidgin / gtkidle.c
blobc47dbe967659143c7c85dc7c71ad0b4e4b06980e
1 /*
2 * pidgin
4 * Pidgin is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
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.
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.
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 02111-1301 USA
23 #include "internal.h"
24 #include "gtkidle.h"
26 #ifdef HAVE_IOKIT
27 /* HAVE_UNISTD_H must have a value, see
28 * https://forums.developer.apple.com/thread/86887
30 # ifdef HAVE_UNISTD_H
31 # undef HAVE_UNISTD_H
32 # define HAVE_UNISTD_H 1
33 # else
34 # define HAVE_UNISTD_H 0
35 # endif
37 # include <CoreFoundation/CoreFoundation.h>
38 # include <IOKit/IOKitLib.h>
39 #elif defined (_WIN32)
40 # include "win32/gtkwin32dep.h"
41 #endif
43 #include "idle.h"
45 #if !defined(HAVE_IOKIT) && !defined(_WIN32)
46 typedef struct {
47 gchar *bus_name;
48 gchar *object_path;
49 gchar *iface_name;
50 } PidginDBusScreenSaverInfo;
52 static const PidginDBusScreenSaverInfo screensavers[] = {
54 "org.freedesktop.ScreenSaver",
55 "/org/freedesktop/ScreenSaver",
56 "org.freedesktop.ScreenSaver"
57 }, {
58 "org.gnome.ScreenSaver",
59 "/org/gnome/ScreenSaver",
60 "org.gnome.ScreenSaver"
61 }, {
62 "org.kde.ScreenSaver",
63 "/org/kde/ScreenSaver",
64 "org.kde.ScreenSaver"
67 #endif /* !HAVE_IOKIT && !_WIN32 */
70 * pidgin_get_time_idle:
72 * Get the number of seconds the user has been idle. In Unix-world
73 * this is based on the DBus ScreenSaver interfaces. In MS Windows this
74 * is based on keyboard/mouse usage information obtained from the OS.
75 * In MacOS X, this is based on keyboard/mouse usage information
76 * obtained from the OS, if configure detected IOKit. Otherwise,
77 * MacOS X is handled as a case of Unix.
79 * Returns: The number of seconds the user has been idle.
81 static time_t
82 pidgin_get_time_idle(void)
84 # ifdef HAVE_IOKIT
85 /* Query the IOKit API */
86 double idleSeconds = -1;
87 io_iterator_t iter = 0;
88 if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
89 io_registry_entry_t entry = IOIteratorNext(iter);
90 if (entry) {
91 CFMutableDictionaryRef dict = NULL;
92 kern_return_t status;
93 status = IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0);
94 if (status == KERN_SUCCESS) {
95 CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
96 if (obj) {
97 int64_t nanoseconds = 0;
98 if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) {
99 idleSeconds = (double) nanoseconds / NSEC_PER_SEC;
102 CFRelease(dict);
104 IOObjectRelease(entry);
106 IOObjectRelease(iter);
108 return idleSeconds;
109 # else
110 # ifdef _WIN32
111 /* Query Windows */
112 return (GetTickCount() - winpidgin_get_lastactive()) / 1000;
113 # else
114 static guint idx = 0;
115 GApplication *app;
116 GDBusConnection *conn;
117 GVariant *reply = NULL;
118 guint32 active_time = 0;
119 GError *error = NULL;
121 app = g_application_get_default();
123 if (app == NULL) {
124 purple_debug_error("gtkidle",
125 "Unable to retrieve GApplication");
126 return 0;
129 conn = g_application_get_dbus_connection(app);
131 if (conn == NULL) {
132 purple_debug_misc("gtkidle",
133 "GApplication lacking DBus connection. "
134 "Skip checking ScreenSaver interface");
135 return 0;
138 for (; idx < G_N_ELEMENTS(screensavers); ++idx) {
139 const PidginDBusScreenSaverInfo *info = &screensavers[idx];
141 reply = g_dbus_connection_call_sync(conn,
142 info->bus_name, info->object_path,
143 info->iface_name, "GetActiveTime",
144 NULL, G_VARIANT_TYPE("(u)"),
145 G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000,
146 NULL, &error);
148 if (reply != NULL) {
149 break;
152 if (g_error_matches(error, G_DBUS_ERROR,
153 G_DBUS_ERROR_NOT_SUPPORTED)) {
154 purple_debug_info("gtkidle",
155 "Querying idle time on '%s' "
156 "unsupported. Trying the next one",
157 info->bus_name);
158 } else if (g_error_matches(error, G_DBUS_ERROR,
159 G_DBUS_ERROR_NAME_HAS_NO_OWNER)) {
160 purple_debug_info("gtkidle",
161 "Querying idle time on '%s' "
162 "not found. Trying the next one",
163 info->bus_name);
164 } else {
165 purple_debug_error("gtkidle",
166 "Querying idle time on '%s' "
167 "error: %s", info->bus_name,
168 error->message);
171 g_clear_error(&error);
174 if (reply == NULL) {
175 purple_debug_warning("gtkidle",
176 "Failed to query ScreenSaver active time: "
177 "No working ScreenSaver interfaces");
178 return 0;
181 g_variant_get(reply, "(u)", &active_time);
182 g_variant_unref(reply);
184 return active_time;
185 # endif /* !_WIN32 */
186 # endif /* !HAVE_IOKIT */
189 static PurpleIdleUiOps ui_ops =
191 pidgin_get_time_idle,
192 NULL,
193 NULL,
194 NULL,
195 NULL
198 PurpleIdleUiOps *
199 pidgin_idle_get_ui_ops()
201 return &ui_ops;