/* * Routines for dealing with the user being idle, or lack thereof. */ #include "gtkyahoo.h" #ifdef CAN_GET_X_IDLE_TIME #include #include #include #endif /* CAN_GET_X_IDLE_TIME */ static gint idle_timer_tag = 0; static int user_is_idle = 0; static int idle_debug = 0; /* Amount of time user is inactive before setting status to idle */ int idle_time = 300; static int idle_timer_callback(guint data); static gboolean can_get_system_idle_time = FALSE; uint system_unidle_check_interval = 5; /* check un-idleness every 5 seconds */ /* * Return the user's idle time, in seconds, as per the system. * If not supported, return that the user has been idle for a looooong time. */ static gint get_system_idle_time(void) { int secs = 365 * 24 * 60 * 60; /* defaults to something long */ if (can_get_system_idle_time) { #ifdef CAN_GET_X_IDLE_TIME XScreenSaverInfo X; XScreenSaverQueryInfo(gdk_display, DefaultRootWindow(gdk_display), &X); secs = X.idle/1000; #endif } return secs; } /* * Clear (stop) the idle timers. */ static void clear_idle_timers(void) { /* remove any timer currently running */ if (idle_timer_tag) { gtk_timeout_remove(idle_timer_tag); idle_timer_tag = 0; } } /* * Have the idle timer's callback called in the given number of seconds. */ static void reset_idle_timer(gint seconds) { clear_idle_timers(); if (idle_debug) printf("setting idle callback in %d seconds\n", seconds); idle_timer_tag = gtk_timeout_add(seconds * 1000, (void *) idle_timer_callback, NULL); } /* * Called when the user has been idle, but is now active. */ static void user_newly_active(void) { if (idle_debug) { printf("user is newly active (was %s)\n", user_is_idle ? "idle" : "NOT IDLE!"); } if (user_is_idle) { user_is_idle = 0; /* remove any timer currently running */ clear_idle_timers(); /* if the last status we sent was to make us idle, send another one - whichever the last one we manually chose was. */ if (connected && last_sent_status == YAHOO_STATUS_IDLE) { if (show_idle_messages) append_notify_msg("you are no longer idle"); if (last_user_status != YAHOO_STATUS_AVAILABLE) yahoo_cmd_set_back_mode(context, last_user_status, NULL); else yahoo_cmd_set_away_mode(context, last_user_status, NULL); last_sent_status = last_user_status; } } } /* * Called when the user has been active, but is now idle. */ static void user_newly_idle(void) { if (idle_debug) { printf("user is newly idle (was %s)\n", user_is_idle ? "IDLE!" : "not idle"); } user_is_idle = 1; /* only set idle if user is available */ if (last_user_status == YAHOO_STATUS_AVAILABLE) { /* callback called so indicate removal of the timeout event */ idle_timer_tag = 0; /* mark user as idle */ user_is_idle = 1; /* tell server we are idle */ if (last_sent_status != YAHOO_STATUS_IDLE) { last_sent_status = YAHOO_STATUS_IDLE; yahoo_cmd_set_away_mode(context, YAHOO_STATUS_IDLE, NULL); if (show_idle_messages) append_notify_msg("you are now idle"); } else { /* we recently set to idle */ if (idle_debug) printf("double idle. shouldn't get here\n"); } } } /* * Callback for the gtk timer used to check idleness. */ static int idle_timer_callback(guint data) { if (idle_debug) { printf("idle timer callback (%s idle; %s connected)\n", connected ? "is" : "not", user_is_idle ? "is" : "not"); } /* only handle if we're actually connected */ if (!connected) return TRUE; if (user_is_idle) { gint system_idle = get_system_idle_time(); if (system_idle < idle_time) user_newly_active(); return TRUE; } else { gint system_idle; /* * If we can't get the system idle time, we'll just have to wait for * some input, so turn off the callback and be done. */ if (!can_get_system_idle_time) { if (idle_debug) printf("can't get system idle time, so assume we're going idle now\n"); user_newly_idle(); return FALSE; } system_idle = get_system_idle_time(); /* * Let's check the system idle time, and if not yet idle long enough, * check to see how much time is left. */ if (system_idle < idle_time) { /* wait for the rest of the time we need to become idle */ reset_idle_timer(idle_time - system_idle); return TRUE; } user_newly_idle(); /* * Now should start a timer that checks to see if we've become * busy. */ reset_idle_timer(system_unidle_check_interval); return TRUE; } } /* * Called from the outside whenever we have user activity, to make us unidle * (or reset the idle timer) */ void have_user_activity(void) { if (user_is_idle) user_newly_active(); else reset_idle_timer(idle_time); } void start_idle_check(void) { #ifdef CAN_GET_X_IDLE_TIME { int dummy; if (XScreenSaverQueryExtension(gdk_display, &dummy, &dummy)) can_get_system_idle_time = TRUE; } #endif reset_idle_timer(idle_time); }