Mercurial > pidgin
comparison src/gtkidle.c @ 11907:d2db6426c88a
[gaim-migrate @ 14198]
sf patch #1342817, from Evan Schoenberg
"As discussed in #gaim, this patch removes idle.c and replaces it
with gtkidle.c and gtkidle.h. The attached diff removes the idle
management from its various hiding places in connection.c, server.c,
and gaim.h. The plugins Changelog.API is appropriately updated.
The new gtkidle files are attached; idle.c should be removed from
CVS."
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 30 Oct 2005 23:00:47 +0000 |
parents | |
children | 73777ad45562 |
comparison
equal
deleted
inserted
replaced
11906:8913546c6a4e | 11907:d2db6426c88a |
---|---|
1 /* | |
2 * gaim | |
3 * | |
4 * Gaim 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. | |
7 * | |
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. | |
12 * | |
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. | |
17 * | |
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
23 #include "internal.h" | |
24 | |
25 #ifdef USE_SCREENSAVER | |
26 # ifndef _WIN32 | |
27 # include <X11/Xlib.h> | |
28 # include <X11/Xutil.h> | |
29 # include <X11/extensions/scrnsaver.h> | |
30 # include <gdk/gdkx.h> | |
31 # else | |
32 # include "idletrack.h" | |
33 # endif | |
34 #endif /* USE_SCREENSAVER */ | |
35 | |
36 #include "connection.h" | |
37 #include "debug.h" | |
38 #include "log.h" | |
39 #include "prefs.h" | |
40 #include "savedstatuses.h" | |
41 #include "signals.h" | |
42 | |
43 #define IDLEMARK 600 /* 10 minutes! */ | |
44 #define IDLE_CHECK_INTERVAL 20000 /* 20 seconds */ | |
45 | |
46 typedef enum | |
47 { | |
48 GAIM_IDLE_NOT_AWAY = 0, | |
49 GAIM_IDLE_AUTO_AWAY, | |
50 GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY | |
51 | |
52 } GaimAutoAwayState; | |
53 | |
54 #ifdef USE_SCREENSAVER | |
55 /** | |
56 * Get the number of seconds the user has been idle. In Unix-world | |
57 * this is based on the X Windows usage. In MS Windows this is based | |
58 * on keyboard/mouse usage. | |
59 * | |
60 * In Debian bug #271639, jwz says: | |
61 * | |
62 * Gaim should simply ask xscreensaver how long the user has been idle: | |
63 * % xscreensaver-command -time | |
64 * XScreenSaver 4.18: screen blanked since Tue Sep 14 14:10:45 2004 | |
65 * | |
66 * Or you can monitor the _SCREENSAVER_STATUS property on root window #0. | |
67 * Element 0 is the status (0, BLANK, LOCK), element 1 is the time_t since | |
68 * the last state change, and subsequent elements are which hack is running | |
69 * on the various screens: | |
70 * % xprop -f _SCREENSAVER_STATUS 32ac -root _SCREENSAVER_STATUS | |
71 * _SCREENSAVER_STATUS(INTEGER) = BLANK, 1095196626, 10, 237 | |
72 * | |
73 * See watch() in xscreensaver/driver/xscreensaver-command.c. | |
74 * | |
75 * @return The number of seconds the user has been idle. | |
76 */ | |
77 static int | |
78 get_idle_time_from_system() | |
79 { | |
80 #ifndef _WIN32 | |
81 static XScreenSaverInfo *mit_info = NULL; | |
82 int event_base, error_base; | |
83 if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) { | |
84 if (mit_info == NULL) { | |
85 mit_info = XScreenSaverAllocInfo(); | |
86 } | |
87 XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info); | |
88 return (mit_info->idle) / 1000; | |
89 } else | |
90 return 0; | |
91 #else | |
92 return (GetTickCount() - wgaim_get_lastactive()) / 1000; | |
93 #endif | |
94 } | |
95 #endif /* USE_SCREENSAVER */ | |
96 | |
97 /* | |
98 * This function should be called when you think your idle state | |
99 * may have changed. Maybe you're over the 10-minute mark and | |
100 * Gaim should start reporting idle time to the server. Maybe | |
101 * you've returned from being idle. Maybe your auto-away message | |
102 * should be set. | |
103 * | |
104 * There is no harm to calling this many many times, other than | |
105 * it will be kinda slow. This is called every 20 seconds by a | |
106 * timer set when an account logs in. It is also called when | |
107 * you send an IM, a chat, etc. | |
108 * | |
109 * This function has 3 sections. | |
110 * 1. Get your idle time. It will query XScreenSaver or Windows | |
111 * or get the Gaim idle time. Whatever. | |
112 * 2. Set or unset your auto-away message. | |
113 * 3. Report your current idle time to the IM server. | |
114 */ | |
115 gint | |
116 gaim_gtk_idle_check(gpointer data) | |
117 { | |
118 GaimConnection *gc = (GaimConnection *)data; | |
119 gboolean report_idle; | |
120 GaimAccount *account; | |
121 time_t t; | |
122 int idle_time; | |
123 | |
124 account = gaim_connection_get_account(gc); | |
125 | |
126 gaim_signal_emit(gaim_blist_get_handle(), "update-idle"); | |
127 | |
128 time(&t); | |
129 | |
130 report_idle = gaim_prefs_get_bool("/gaim/gtk/idle/report"); | |
131 | |
132 #ifdef USE_SCREENSAVER | |
133 idle_time = get_idle_time_from_system(); | |
134 #else | |
135 /* | |
136 * If Gaim wasn't built with xscreensaver support, then | |
137 * fallback to calculating our idle time based on when | |
138 * we last sent a message. | |
139 */ | |
140 idle_time = t - gc->last_sent_time; | |
141 #endif /* USE_SCREENSAVER */ | |
142 | |
143 /* Should we become auto-away? */ | |
144 if (gaim_prefs_get_bool("/core/away/away_when_idle") && | |
145 (idle_time > (60 * gaim_prefs_get_int("/core/away/mins_before_away"))) | |
146 && (!gc->is_auto_away)) | |
147 { | |
148 GaimPresence *presence; | |
149 | |
150 presence = gaim_account_get_presence(account); | |
151 | |
152 if (gaim_presence_is_available(presence)) | |
153 { | |
154 const char *idleaway_name; | |
155 GaimSavedStatus *saved_status; | |
156 | |
157 gaim_debug_info("idle", "Making %s auto-away\n", | |
158 gaim_account_get_username(account)); | |
159 | |
160 /* Mark our accounts "away" using the idleaway status */ | |
161 idleaway_name = gaim_prefs_get_string("/core/status/idleaway"); | |
162 saved_status = gaim_savedstatus_find(idleaway_name); | |
163 if (saved_status) | |
164 gaim_savedstatus_activate(saved_status); | |
165 | |
166 gc->is_auto_away = GAIM_IDLE_AUTO_AWAY; | |
167 } else { | |
168 gc->is_auto_away = GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY; | |
169 } | |
170 | |
171 /* Should we return from being auto-away? */ | |
172 } else if (gc->is_auto_away && | |
173 idle_time < 60 * gaim_prefs_get_int("/core/away/mins_before_away")) { | |
174 if (gc->is_auto_away == GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY) { | |
175 gc->is_auto_away = GAIM_IDLE_NOT_AWAY; | |
176 return TRUE; | |
177 } | |
178 gc->is_auto_away = GAIM_IDLE_NOT_AWAY; | |
179 | |
180 /* XXX STATUS AWAY CORE/UI */ | |
181 /* Need to set this connection to available here */ | |
182 } | |
183 | |
184 /* Deal with reporting idleness to the server, if appropriate */ | |
185 if (report_idle && idle_time >= IDLEMARK && !gc->is_idle) { | |
186 gaim_debug_info("idle", "Setting %s idle %d seconds\n", | |
187 gaim_account_get_username(account), idle_time); | |
188 serv_set_idle(gc, idle_time); | |
189 gc->is_idle = 1; | |
190 /* LOG system_log(log_idle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */ | |
191 } else if ((!report_idle || idle_time < IDLEMARK) && gc->is_idle) { | |
192 gaim_debug_info("idle", "Setting %s unidle\n", | |
193 gaim_account_get_username(account)); | |
194 gc->is_idle = 0; | |
195 serv_set_idle(gc, 0); | |
196 /* LOG system_log(log_unidle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */ | |
197 } | |
198 | |
199 return TRUE; | |
200 } | |
201 | |
202 static void | |
203 im_msg_sent_cb(GaimAccount *account, const char *receiver, | |
204 const char *message, void *data) | |
205 { | |
206 GaimConnection *gc = gaim_account_get_connection(account); | |
207 | |
208 /* After an IM is sent, check our idle time */ | |
209 gaim_gtk_idle_check(gc); | |
210 } | |
211 | |
212 static void | |
213 remove_idle_timer(GaimConnection *gc) | |
214 { | |
215 /* Remove any existing idle_timer */ | |
216 if (gc->idle_timer > 0) | |
217 gaim_timeout_remove(gc->idle_timer); | |
218 gc->idle_timer = 0; | |
219 } | |
220 | |
221 static void | |
222 connection_disconnected_cb(GaimConnection *gc, gpointer user_data) | |
223 { | |
224 remove_idle_timer(gc); | |
225 } | |
226 | |
227 static void | |
228 connection_connected_cb(GaimConnection *gc, gpointer user_data) | |
229 { | |
230 /* Now that we are connected, check for idleness every 20 seconds */ | |
231 remove_idle_timer(gc); | |
232 gc->idle_timer = gaim_timeout_add(IDLE_CHECK_INTERVAL, gaim_gtk_idle_check, gc); | |
233 | |
234 /* Immediately update our idleness, in case we connected while idle */ | |
235 gaim_gtk_idle_check(gc); | |
236 } | |
237 | |
238 void * | |
239 gaim_gtk_idle_get_handle() | |
240 { | |
241 static int handle; | |
242 | |
243 return &handle; | |
244 } | |
245 | |
246 void | |
247 gaim_gtk_idle_init() | |
248 { | |
249 gaim_signal_connect(gaim_conversations_get_handle(), "sent-im-msg", | |
250 gaim_gtk_idle_get_handle(), | |
251 GAIM_CALLBACK(im_msg_sent_cb), NULL); | |
252 | |
253 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
254 gaim_gtk_idle_get_handle(), | |
255 GAIM_CALLBACK(connection_connected_cb), NULL); | |
256 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
257 gaim_gtk_idle_get_handle(), | |
258 GAIM_CALLBACK(connection_disconnected_cb), NULL); | |
259 } | |
260 | |
261 void | |
262 gaim_gtk_idle_uninit() | |
263 { | |
264 gaim_signals_disconnect_by_handle(gaim_gtk_idle_get_handle()); | |
265 } |