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
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
27 /* HAVE_UNISTD_H must have a value, see
28 * https://forums.developer.apple.com/thread/86887
32 # define HAVE_UNISTD_H 1
34 # define HAVE_UNISTD_H 0
37 # include <CoreFoundation/CoreFoundation.h>
38 # include <IOKit/IOKitLib.h>
39 #elif defined (_WIN32)
40 # include "win32/gtkwin32dep.h"
45 #if !defined(HAVE_IOKIT) && !defined(_WIN32)
50 } PidginDBusScreenSaverInfo
;
52 static const PidginDBusScreenSaverInfo screensavers
[] = {
54 "org.freedesktop.ScreenSaver",
55 "/org/freedesktop/ScreenSaver",
56 "org.freedesktop.ScreenSaver"
58 "org.gnome.ScreenSaver",
59 "/org/gnome/ScreenSaver",
60 "org.gnome.ScreenSaver"
62 "org.kde.ScreenSaver",
63 "/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.
82 pidgin_get_time_idle(void)
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
);
91 CFMutableDictionaryRef dict
= NULL
;
93 status
= IORegistryEntryCreateCFProperties(entry
, &dict
, kCFAllocatorDefault
, 0);
94 if (status
== KERN_SUCCESS
) {
95 CFNumberRef obj
= CFDictionaryGetValue(dict
, CFSTR("HIDIdleTime"));
97 int64_t nanoseconds
= 0;
98 if (CFNumberGetValue(obj
, kCFNumberSInt64Type
, &nanoseconds
)) {
99 idleSeconds
= (double) nanoseconds
/ NSEC_PER_SEC
;
104 IOObjectRelease(entry
);
106 IOObjectRelease(iter
);
112 return (GetTickCount() - winpidgin_get_lastactive()) / 1000;
114 static guint idx
= 0;
116 GDBusConnection
*conn
;
117 GVariant
*reply
= NULL
;
118 guint32 active_time
= 0;
119 GError
*error
= NULL
;
121 app
= g_application_get_default();
124 purple_debug_error("gtkidle",
125 "Unable to retrieve GApplication");
129 conn
= g_application_get_dbus_connection(app
);
132 purple_debug_misc("gtkidle",
133 "GApplication lacking DBus connection. "
134 "Skip checking ScreenSaver interface");
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,
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",
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",
165 purple_debug_error("gtkidle",
166 "Querying idle time on '%s' "
167 "error: %s", info
->bus_name
,
171 g_clear_error(&error
);
175 purple_debug_warning("gtkidle",
176 "Failed to query ScreenSaver active time: "
177 "No working ScreenSaver interfaces");
181 g_variant_get(reply
, "(u)", &active_time
);
182 g_variant_unref(reply
);
185 # endif /* !_WIN32 */
186 # endif /* !HAVE_IOKIT */
189 static PurpleIdleUiOps ui_ops
=
191 pidgin_get_time_idle
,
199 pidgin_idle_get_ui_ops()