comparison src/idle.c @ 10319:32e7baa81e03

[gaim-migrate @ 11526] Some cleanup/documentation/me getting familiar with idle handling. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 05 Dec 2004 18:57:57 +0000
parents bdec08a8fc5b
children 3232e1a33899
comparison
equal deleted inserted replaced
10318:fcadde998ba9 10319:32e7baa81e03
39 #include "prefs.h" 39 #include "prefs.h"
40 #include "signals.h" 40 #include "signals.h"
41 41
42 #define IDLEMARK 600 /* 10 minutes! */ 42 #define IDLEMARK 600 /* 10 minutes! */
43 43
44 gint check_idle(gpointer data) 44 typedef enum
45 { 45 {
46 GAIM_IDLE_NOT_AWAY = 0,
47 GAIM_IDLE_AUTO_AWAY,
48 GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY
49
50 } GaimAutoAwayState;
51
52 #ifdef USE_SCREENSAVER
53 /**
54 * Get the number of seconds the user has been idle. In Unix-world
55 * this is based on the X Windows usage. In MS Windows this is based
56 * on keyboard/mouse usage.
57 *
58 * In Debian bug #271639, jwz says:
59 *
60 * Gaim should simply ask xscreensaver how long the user has been idle:
61 * % xscreensaver-command -time
62 * XScreenSaver 4.18: screen blanked since Tue Sep 14 14:10:45 2004
63 *
64 * Or you can monitor the _SCREENSAVER_STATUS property on root window #0.
65 * Element 0 is the status (0, BLANK, LOCK), element 1 is the time_t since
66 * the last state change, and subsequent elements are which hack is running
67 * on the various screens:
68 * % xprop -f _SCREENSAVER_STATUS 32ac -root _SCREENSAVER_STATUS
69 * _SCREENSAVER_STATUS(INTEGER) = BLANK, 1095196626, 10, 237
70 *
71 * See watch() in xscreensaver/driver/xscreensaver-command.c.
72 *
73 * @return The number of seconds the user has been idle.
74 */
75 static int
76 get_idle_time_from_system()
77 {
78 #ifndef _WIN32
79 static XScreenSaverInfo *mit_info = NULL;
80 int event_base, error_base;
81 if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) {
82 if (mit_info == NULL) {
83 mit_info = XScreenSaverAllocInfo();
84 }
85 XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
86 return (mit_info->idle) / 1000;
87 } else
88 return 0;
89 #else
90 return (GetTickCount() - wgaim_get_lastactive()) / 1000;
91 #endif
92 }
93 #endif /* USE_SCREENSAVER */
94
95 /*
96 * This function should be called when you think your idle state
97 * may have changed. Maybe you're over the 10-minute mark and
98 * Gaim should start reporting idle time to the server. Maybe
99 * you've returned from being idle. Maybe your auto-away message
100 * should be set.
101 *
102 * There is no harm to calling this many many times, other than
103 * it will be kinda slow. This is called every 20 seconds by a
104 * timer set when an account logs in. It is also called when
105 * you send an IM, a chat, etc.
106 *
107 * This function has 3 sections.
108 * 1. Get your idle time. It will query XScreenSaver or Windows
109 * or get the Gaim idle time. Whatever.
110 * 2. Set or unset your auto-away message.
111 * 3. Report your current idle time to the IM server.
112 */
113 gint
114 check_idle(gpointer data)
115 {
116 GaimConnection *gc = data;
46 const char *report_idle; 117 const char *report_idle;
47 GaimConnection *gc = data;
48 GaimAccount *account; 118 GaimAccount *account;
49 time_t t; 119 time_t t;
120 int idle_time;
121
122 account = gaim_connection_get_account(gc);
123
124 gaim_signal_emit(gaim_blist_get_handle(), "update-idle");
125
126 time(&t);
127
128 report_idle = gaim_prefs_get_string("/gaim/gtk/idle/reporting_method");
129
50 #ifdef USE_SCREENSAVER 130 #ifdef USE_SCREENSAVER
51 #ifndef _WIN32 131 if (report_idle != NULL && !strcmp(report_idle, "system"))
52 static XScreenSaverInfo *mit_info = NULL; 132 idle_time = get_idle_time_from_system();
53 #endif 133 else
54 #endif
55 int idle_time;
56
57 account = gaim_connection_get_account(gc);
58
59 gaim_signal_emit(gaim_blist_get_handle(), "update-idle");
60
61 time(&t);
62
63 report_idle = gaim_prefs_get_string("/gaim/gtk/idle/reporting_method");
64
65 #ifdef USE_SCREENSAVER
66 if (report_idle != NULL && !strcmp(report_idle, "system")) {
67 #ifndef _WIN32
68 int event_base, error_base;
69 if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) {
70 if (mit_info == NULL) {
71 mit_info = XScreenSaverAllocInfo();
72 }
73 XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
74 idle_time = (mit_info->idle) / 1000;
75 } else
76 idle_time = 0;
77 #else
78 idle_time = (GetTickCount() - wgaim_get_lastactive()) / 1000;
79 #endif
80 } else
81 #endif /* USE_SCREENSAVER */ 134 #endif /* USE_SCREENSAVER */
82 idle_time = t - gc->last_sent_time; 135 idle_time = t - gc->last_sent_time;
83 136
137 /* Should be become auto-away? */
84 if (gaim_prefs_get_bool("/core/away/away_when_idle") && 138 if (gaim_prefs_get_bool("/core/away/away_when_idle") &&
85 (idle_time > (60 * gaim_prefs_get_int("/core/away/mins_before_away"))) 139 (idle_time > (60 * gaim_prefs_get_int("/core/away/mins_before_away")))
86 && (!gc->is_auto_away)) 140 && (!gc->is_auto_away))
87 { 141 {
88 GaimPresence *presence; 142 GaimPresence *presence;
89 143
90 presence = gaim_account_get_presence(account); 144 presence = gaim_account_get_presence(account);
91 145
92 if (gaim_presence_is_available(presence)) 146 if (gaim_presence_is_available(presence))
93 { 147 {
94 /* XXX CORE/UI
95 struct away_message *default_away = NULL;
96 GSList *l;
97 */
98 const char *default_name; 148 const char *default_name;
99 149
150 gaim_debug_info("idle", "Making %s auto-away\n",
151 gaim_account_get_username(account));
152
100 default_name = gaim_prefs_get_string("/core/away/default_message"); 153 default_name = gaim_prefs_get_string("/core/away/default_message");
101 /* XXX CORE/UI 154
102 for(l = away_messages; l; l = l->next) { 155 /* XXX STATUS AWAY CORE/UI */
103 if(!strcmp(default_name, ((struct away_message *)l->data)->name)) { 156 /* Need to set the default_name away message for this connection here */
104 default_away = l->data; 157
105 break; 158 gc->is_auto_away = GAIM_IDLE_AUTO_AWAY;
106 } 159 } else {
107 } 160 gc->is_auto_away = GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY;
108 161 }
109 if(!default_away && away_messages) 162
110 default_away = away_messages->data; 163 /* Should we return from being auto-away? */
111 */
112
113 gaim_debug(GAIM_DEBUG_INFO, "idle",
114 "Making %s away automatically\n",
115 gaim_account_get_username(account));
116
117 /* XXX CORE/UI
118 if (g_list_length(gaim_connections_get_all()) == 1)
119 do_away_message(NULL, default_away);
120 else if (default_away)
121 serv_set_away(gc, GAIM_AWAY_CUSTOM, default_away->message);
122 */
123
124 gc->is_auto_away = 1;
125 } else
126 gc->is_auto_away = 2;
127 } else if (gc->is_auto_away && 164 } else if (gc->is_auto_away &&
128 idle_time < 60 * gaim_prefs_get_int("/core/away/mins_before_away")) { 165 idle_time < 60 * gaim_prefs_get_int("/core/away/mins_before_away")) {
129 if (gc->is_auto_away == 2) { 166 if (gc->is_auto_away == GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY) {
130 gc->is_auto_away = 0; 167 gc->is_auto_away = GAIM_IDLE_NOT_AWAY;
131 return TRUE; 168 return TRUE;
132 } 169 }
133 gc->is_auto_away = 0; 170 gc->is_auto_away = GAIM_IDLE_NOT_AWAY;
134 171
135 /* XXX CORE/UI 172 /* XXX STATUS AWAY CORE/UI */
136 if (awaymessage == NULL) { 173 /* Need to set this connection to available here */
137 gaim_debug(GAIM_DEBUG_INFO, "idle",
138 "Removing auto-away message for %s\n", gaim_account_get_username(account));
139 serv_set_away(gc, GAIM_AWAY_CUSTOM, NULL);
140 } else {
141 if (g_list_length(gaim_connections_get_all()) == 1)
142 do_im_back(0, 0);
143 else {
144 gaim_debug(GAIM_DEBUG_INFO, "idle",
145 "Replacing auto-away with global for %s\n",
146 gaim_account_get_username(account));
147 serv_set_away(gc, GAIM_AWAY_CUSTOM, awaymessage->message);
148 }
149 }
150 */
151 } 174 }
152 175
153 176 /*
154 /* If we're not reporting idle times to the server, still use Gaim 177 * If we're not reporting idle times to the server, still use Gaim
155 usage for auto-away, but quit here so we don't report to the 178 * usage for auto-away, but quit here so we don't report to the
156 server */ 179 * server.
157 180 *
181 * Hmm. What if _while_ we're idle we toggle the pref for reporting
182 * idle time to the server? We would never become unidle...
183 */
158 if (report_idle != NULL && !strcmp(report_idle, "none")) 184 if (report_idle != NULL && !strcmp(report_idle, "none"))
159 return TRUE; 185 return TRUE;
160 186
161 if (idle_time >= IDLEMARK && !gc->is_idle) { 187 if (idle_time >= IDLEMARK && !gc->is_idle) {
162 gaim_debug(GAIM_DEBUG_INFO, "idle", "Setting %s idle %d seconds\n", 188 gaim_debug_info("idle", "Setting %s idle %d seconds\n",
163 gaim_account_get_username(account), idle_time); 189 gaim_account_get_username(account), idle_time);
164 serv_set_idle(gc, idle_time); 190 serv_set_idle(gc, idle_time);
165 gc->is_idle = 1; 191 gc->is_idle = 1;
166 /* LOG system_log(log_idle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */ 192 /* LOG system_log(log_idle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */
167 } else if (idle_time < IDLEMARK && gc->is_idle) { 193 } else if (idle_time < IDLEMARK && gc->is_idle) {
168 gaim_debug(GAIM_DEBUG_INFO, "idle", "Setting %s unidle\n", 194 gaim_debug_info("idle", "Setting %s unidle\n",
169 gaim_account_get_username(account)); 195 gaim_account_get_username(account));
170 serv_touch_idle(gc); 196 serv_touch_idle(gc);
171 /* LOG system_log(log_unidle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */ 197 /* LOG system_log(log_unidle, gc, NULL, OPT_LOG_BUDDY_IDLE | OPT_LOG_MY_SIGNON); */
172 } 198 }
173 199