changeset 1026:5bad25457843

[gaim-migrate @ 1036] X-Idle support. Thanks bryner and bmiller! Both of you guys sent me similar patches :) committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Thu, 26 Oct 2000 07:22:32 +0000
parents 84a5d80e52f1
children a375efb2884e
files ChangeLog acconfig.h configure.in src/aim.c src/gaim.h src/gaimrc.c src/idle.c src/prefs.c src/server.c
diffstat 9 files changed, 140 insertions(+), 667 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Oct 26 02:12:34 2000 +0000
+++ b/ChangeLog	Thu Oct 26 07:22:32 2000 +0000
@@ -6,6 +6,7 @@
 	* protocol plugins
 	* user configurable sounds
 	* scroll bar now functions properly in chat room user lists
+	* X-Idle support added (thanks bmiller and bryner)
 
 version 0.10.3 (10/09/2000):
 	* Segfault when viewing user info fixed
--- a/acconfig.h	Thu Oct 26 02:12:34 2000 +0000
+++ b/acconfig.h	Thu Oct 26 07:22:32 2000 +0000
@@ -6,6 +6,7 @@
 #undef HAVE_LIBSM
 #undef USE_APPLET
 #undef USE_GNOME
+#undef USE_SCREENSAVER
 #undef NO_MULTI
 #undef DEBUG
 #undef GAIM_PLUGINS
--- a/configure.in	Thu Oct 26 02:12:34 2000 +0000
+++ b/configure.in	Thu Oct 26 07:22:32 2000 +0000
@@ -49,6 +49,7 @@
 AC_ARG_ENABLE(plugins, [  --disable-plugins       compile with out plugin support],,enable_plugins=yes)
 AC_ARG_ENABLE(perl,    [  --disable-perl          compile without perl scripting],,enable_perl=yes)
 AC_ARG_ENABLE(debug,   [  --enable-debug          compile with debugging support],,enable_debug=no)
+AC_ARG_ENABLE(screensaver,   [  --disable-screensaver     compile without  X screensaver extension],enable_xss=no,enable_xss=yes)
 AM_CONDITIONAL(PLUGINS, test "x$enable_plugins" = "xyes")
 AC_ARG_ENABLE(,,,)
 
@@ -103,6 +104,29 @@
 	AC_PATH_PROG(gaimpath, gaim)
 fi
 
+dnl Check for XScreenSaver
+if test "x$enable_xss" = "xyes" ; then
+       XSS_LIBS="no"
+       XSS_HEADERS="no"
+       AC_CHECK_LIB(Xext, XScreenSaverRegister,[XSS_LIBS=""],[],[-lX11 -lXext -lm])
+       AC_CHECK_LIB(Xss, XScreenSaverRegister,[XSS_LIBS="-lXss"],[],[-lX11 -lXext -lm])
+       if test \! "$XSS_LIBS" = "no"; then
+               AC_CHECK_HEADER(X11/extensions/scrnsaver.h,[XSS_HEADERS="yes"])
+               if test "$XSS_HEADERS" = "yes"; then
+                       dnl Found the libs and the headers
+                       AC_DEFINE(USE_SCREENSAVER)
+                       LIBS="$LIBS $XSS_LIBS"
+               fi
+       else
+               XSS_LIBS=""
+       fi
+else
+       XSS_LIBS=""
+fi
+
+
+
+
 if test "x$enable_multi" != "xyes" ; then
 	AC_DEFINE(NO_MULTI)
 fi
--- a/src/aim.c	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/aim.c	Thu Oct 26 07:22:32 2000 +0000
@@ -170,6 +170,7 @@
 		aim_users = g_list_append(aim_users, u);
 	}
 	g_snprintf(u->password, sizeof u->password, "%s", password);
+	set_first_user(username);
 	save_prefs();
 	serv_login(u);
 }
--- a/src/gaim.h	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/gaim.h	Thu Oct 26 07:22:32 2000 +0000
@@ -72,9 +72,10 @@
 #define UC_NORMAL	8
 #define UC_UNAVAILABLE  16
 
-#define IDLE_NONE       0
-#define IDLE_GAIM       1
-#define IDLE_SYSTEM     2
+#define IDLE_NONE        0
+#define IDLE_GAIM        1
+#define IDLE_SYSTEM      2
+#define IDLE_SCREENSAVER 3
 
 #define WFLAG_SEND 1
 #define WFLAG_RECV 2
@@ -594,14 +595,15 @@
 extern void update_chat_button_pix();
 extern void update_im_button_pix();
 
-
-
 /* Functions in html.c */
 extern char *fix_url(char *);
 extern struct g_url parse_url(char *);
 extern char *grab_url(char *);
 extern gchar *strip_html(gchar *);
 
+/* Functions in idle.c */
+extern gint check_idle(struct gaim_connection *);
+
 /* Functions in util.c */
 extern char *normalize(const char *);
 extern int escape_text(char *);
--- a/src/gaimrc.c	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/gaimrc.c	Thu Oct 26 07:22:32 2000 +0000
@@ -763,7 +763,7 @@
 			sound_file[i] = NULL;
 		font_options = 0; 
         	sound_options = OPT_SOUND_LOGIN | OPT_SOUND_LOGOUT | OPT_SOUND_RECV | OPT_SOUND_SEND | OPT_SOUND_SILENT_SIGNON;
-        	report_idle = IDLE_GAIM;
+        	report_idle = IDLE_SCREENSAVER;
         	web_browser = BROWSER_NETSCAPE;
         	proxy_type = PROXY_NONE;
         
--- a/src/idle.c	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/idle.c	Thu Oct 26 07:22:32 2000 +0000
@@ -1,648 +1,84 @@
-#if 0
-//----------------------------------------------------------------------------
-// This is a somewhat modified kscreensaver.
-// The original copyright notice follows
-//
-//----------------------------------------------------------------------------
-//
-// KDE screensavers
-//
-// This module is a heavily modified xautolock.
-// The orignal copyright notice follows
-//
-
-/*****************************************************************************
+/*
+ * gaim
+ *
+ * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
  *
- * xautolock
- * =========
- *
- * Authors   :  S. De Troch (SDT) + M. Eyckmans (MCE)
- *
- * Date      :  22/07/90
- *
- * ---------------------------------------------------------------------------
- *
- * Copyright 1990, 1992-1995 by S. De Troch and MCE.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- * Permission to use, copy, modify and distribute this software and the
- * supporting documentation without fee is hereby granted, provided that
- *
- *  1 : Both the above copyright notice and this permission notice
- *      appear in all copies of both the software and the supporting
- *      documentation.
- *  2 : No financial profit is made out of it.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *****************************************************************************/
-
-
-
-/*
- *  Have a guess what this does...
- *  ==============================
- *
- *  Warning for swm & tvtwm users : xautolock should *not* be compiled
- *  with vroot.h, because it needs to know the real root window.
  */
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(hpux) || defined (__hpux)
-#ifndef _HPUX_SOURCE
-#define _HPUX_SOURCE
-#endif /* _HPUX_SOURCE */
-#endif /* hpux || __hpux */
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef VMS
-#include <ssdef.h>    
-#include <processes.h>  /* really needed? */
-#endif /* VMS */
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xresource.h>
-
-#include <time.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-
-#ifdef HAVE_SYS_M_WAIT_H
-#include <sys/m_wait.h>
-#endif 
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#include "../config.h"
 #endif
-#include <stdlib.h>
-
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-#include "gaim.h"
-
-void initAutoLock();
-void cleanupAutoLock();
-
-/*
- *  Usefull macros and customization stuff
- *  ======================================
- */
-#define PP(x)                      x
-
-#ifdef VMS
-#define ALL_OK                     1       /* for use by exit ()           */
-#define PROBLEMS                   SS$_ABORT 
-                                           /* for use by exit ()           */
-#else /* VMS */
-#define ALL_OK                     0       /* for use by exit ()           */
-#define PROBLEMS                   1       /* for use by exit ()           */
-#endif /* VMS */
-
-
-#define CREATION_DELAY             30      /* should be > 10 and
-                                              < min (45,(MIN_MINUTES*30))  */
-#define TIME_CHANGE_LIMIT         120      /* if the time changes by more
-                                              than x secs then we will
-                                              assume someone has changed
-                                              date or machine has suspended */
-
-
-#ifndef HasVFork
-#define vfork                      fork
-#endif /* HasVFork */
-
-#define Error0(str)                fprintf (stderr, str)
-#define SetTrigger(delta)          trigger = time ((time_t*) NULL) + delta
-
-static caddr_t                     ch_ptr;  /* this is dirty */
-#define Skeleton(t,s)              (ch_ptr = (Caddrt) malloc ((Unsigned) s), \
-                                      (ch_ptr == (Caddrt) NULL)              \
-                                    ? (Error0 ("Out of memory.\n"),          \
-                                       exit (PROBLEMS),                      \
-                                       /*NOTREACHED*/ (t*) NULL              \
-                                      )                                      \
-                                    : (t*) ch_ptr                            \
-                                   )                                         \
-
-#define New(tp)                    Skeleton (tp, sizeof (tp))
-
-
-
-/*
- *  New types
- *  =========
- */
-#if defined (apollo) || defined (news1800) 
-typedef int                        (*XErrorHandler) PP((Display*,
-                                                        XErrorEvent*));
-#endif /* apollo || news1800 */
-
-#if defined (news1800) || defined (sun386) 
-typedef int                        pid_t;
-#endif /* news1800  || sun386*/
-
-#ifdef VMS
-typedef long                       pid_t;
-#endif /* VMS */
-
-#define Void                       void     /* no typedef because of VAX */
-typedef int                        Int;
-typedef char                       Char;
-typedef char*                      String;
-typedef int                        Boolean;
-typedef caddr_t                    Caddrt;
-typedef unsigned int               Unsigned;
-typedef unsigned long              Huge;
-
-typedef struct QueueItem_
-        {
-          Window                   window;        /* as it says          */
-          time_t                   creationtime;  /* as it says          */
-          struct QueueItem_*       next;          /* as it says          */
-          struct QueueItem_*       prev;          /* as it says          */
-        } aQueueItem, *QueueItem;
-
-typedef struct Queue_
-        {
-          struct QueueItem_*       head;          /* as it says          */
-          struct QueueItem_*       tail;          /* as it says          */
-        } aQueue, *Queue;
-
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <aim.h>
 
-/*
- *  Function declarations
- *  =====================
- */
-#if defined(news1800) 
-extern Void*    malloc                PP((Unsigned));
-#endif /* news1800 */
- 
-static int      EvaluateCounter       PP((Display*));
-static int      QueryPointer          PP((Display*, int));
-static int      ProcessEvents         PP((Display*, Queue, int));
-static Queue    NewQueue              PP((Void));
-static Void     AddToQueue            PP((Queue, Window));
-static Void     ProcessQueue          PP((Queue, Display*, time_t));
-static Void     SelectEvents          PP((Display*, Window, Boolean));
-
-
-/*
- *  Global variables
- *  ================
- */
-static time_t        trigger = 0;            /* as it says                 */
-static time_t        time_limit = IDLE_REPORT_TIME;   /* as it says */
-
-/*
- *  Functions related to the window queue
- *  =====================================
- *
- *  Function for creating a new queue
- *  ---------------------------------
- */
-static Queue  NewQueue ()
-
-{
-  Queue  queue;  /* return value */
-
-  queue = New (aQueue);
-  queue->tail = New (aQueueItem);
-  queue->head = New (aQueueItem);
-
-  queue->tail->next = queue->head;
-  queue->head->prev = queue->tail;
-  queue->tail->prev = queue->head->next = (QueueItem) NULL;
-
-  return queue;
-}
-
-
-/*
- *  Function for adding an item to a queue
- *  --------------------------------------
- */
-static Void  AddToQueue (Queue queue, Window window)
-{
-  QueueItem  newq;  /* new item */
-
-  newq = New (aQueueItem);
-
-  newq->window = window;
-  newq->creationtime = time ((time_t*) NULL);
-  newq->next = queue->tail->next;
-  newq->prev = queue->tail;
-  queue->tail->next->prev = newq;
-  queue->tail->next = newq;
-}
-
-/*
- *  Function for processing those entries that are old enough
- *  ---------------------------------------------------------
- */
-static Void  ProcessQueue (Queue queue, Display *d, time_t age)
-{
-  QueueItem  current;  /* as it says */
-  time_t     now;      /* as it says */
-
-  time (&now);
-  current = queue->head->prev;
+#ifdef USE_SCREENSAVER
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/scrnsaver.h>
+#endif /* USE_SCREENSAVER */
 
-  while ( current->prev && current->creationtime + age < now )
-  {
-    SelectEvents (d, current->window, False);
-    current = current->prev;
-    free (current->next);
-  }
-
-  current->next = queue->head;
-  queue->head->prev = current;
-}
-
-
-static Void  FreeQueue( Queue queue )
-{
-  QueueItem  current;  /* as it says */
-
-  current = queue->head->prev;
-
-  while ( current->prev )
-  {
-	  current = current->prev;
-	  free(current->next);
-  }
-
-  free(current);
-  free(queue);
-}
-
-
-/*
- *  Functions related to (the lack of) user activity
- *  ================================================
- *
- *  Function for processing the event queue
- *  ---------------------------------------
- */
-static int  ProcessEvents (Display *d, Queue queue, int until_idle)
-{
-  XEvent  event;  /* as it says */
-
- /*
-  *  Read whatever is available for reading.
-  */
-  while (XPending (d))
-  {
-    if (XCheckMaskEvent (d, SubstructureNotifyMask, &event))
-    {
-      if ((event.type == CreateNotify) && until_idle)
-      {
-        AddToQueue (queue, event.xcreatewindow.window);
-      }
-    }
-    else
-    {
-      XNextEvent (d, &event);
-    }
-
-
-   /*
-    *  Reset the counter if and only if the event is a KeyPress
-    *  event *and* was not generated by XSendEvent ().
-    */
-    if ( event.type == KeyPress && !event.xany.send_event )
-    {
-      if (!until_idle)    /* We've become un-idle */
-	return 1;
-      SetTrigger (time_limit);
-    }
-  }
-
-
- /*
-  *  Check the window queue for entries that are older than
-  *  CREATION_DELAY seconds.
-  */
-  ProcessQueue (queue, d, (time_t) CREATION_DELAY);
-  return 0;
-}
+#include "multi.h"
+#include "gaim.h"
 
 
-/*
- *  Function for monitoring pointer movements
- *  -----------------------------------------
- */
-static int  QueryPointer (Display *d, int until_idle)
+gint check_idle(struct gaim_connection *gc)
 {
-  Window           dummy_w;            /* as it says                    */
-  Int              dummy_c;            /* as it says                    */
-  Unsigned         mask;               /* modifier mask                 */
-  Int              root_x;             /* as it says                    */
-  Int              root_y;             /* as it says                    */
-  Int              i;                  /* loop counter                  */
-  static Window    root;               /* root window the pointer is on */
-  static Screen*   screen;             /* screen the pointer is on      */
-  static Unsigned  prev_mask = 0;      /* as it says                    */
-  static Int       prev_root_x = -1;   /* as it says                    */
-  static Int       prev_root_y = -1;   /* as it says                    */
-  static Boolean   first_call = TRUE;  /* as it says                    */
-  
-  
-  /*
-   *  Have a guess...
-   */
-  if (first_call)
-    {
-      first_call = FALSE;
-      root = DefaultRootWindow (d);
-      screen = ScreenOfDisplay (d, DefaultScreen (d));
-    }
-  
-  
-  /*
-   *  Find out whether the pointer has moved. Using XQueryPointer for this
-   *  is gross, but it also is the only way never to mess up propagation
-   *  of pointer events.
-   *
-   *  Remark : Unlike XNextEvent(), XPending () doesn't notice if the
-   *           connection to the server is lost. For this reason, earlier
-   *           versions of xautolock periodically called XNoOp (). But
-   *           why not let XQueryPointer () do the job for us, since
-   *           we now call that periodically anyway?
-   */
-  if (!XQueryPointer (d, root, &root, &dummy_w, &root_x, &root_y,
-                      &dummy_c, &dummy_c, &mask))
-    {
-      /*
-       *  Pointer has moved to another screen, so let's find out which one.
-       */
-      for (i = -1; ++i < ScreenCount (d); ) 
-	{
-	  if (root == RootWindow (d, i)) 
-	    {
-	      screen = ScreenOfDisplay (d, i);
-	      break;
-	    }
-	}
-    }
-  
-  if (   root_x != prev_root_x
-	 || root_y != prev_root_y
-	 || mask != prev_mask
-	 )
-    {
-      prev_root_x = root_x;
-      prev_root_y = root_y;
-      prev_mask = mask;
-      SetTrigger (time_limit);
-      if (!until_idle)
-	return 1;
-    }
-  
-  return 0;
-  
-}
+	time_t t;
+#ifdef USE_SCREENSAVER
+	static XScreenSaverInfo *mit_info = NULL;
+	Display *d = XOpenDisplay((char*)NULL);
+	time_t idle_time;
+#endif
 
-/*
- *  Function for deciding whether to lock
- *  -------------------------------------
- */
-static int  EvaluateCounter (Display *d)
-{
-  time_t         now = 0;                /* as it says  */
-
- /*
-  *  Now trigger the notifier if required. 
-  */
-  time (&now);
-
- /*
-  *  Finally fire up the locker if time has come. 
-  */
-  if (now >= trigger)
-  {
-      SetTrigger (time_limit);
-	  return TRUE;
-  }
+        /* Not idle, really...  :) */
+        update_all_buddies();
 
-  return FALSE;
-}
-
-/*
- *  Function for selecting events on a tree of windows
- *  --------------------------------------------------
- */
-static Void  SelectEvents (Display *d, Window window, Boolean substructure_only)
-{
-  Window             root;              /* root window of this window */
-  Window             parent;            /* parent of this window      */
-  Window*            children;          /* children of this window    */
-  Unsigned           nof_children = 0;  /* number of children         */
-  Unsigned           i;                 /* loop counter               */
-  XWindowAttributes  attribs;           /* attributes of the window   */
-
-
- /*
-  *  Start by querying the server about parent and child windows.
-  */
-  if (!XQueryTree (d, window, &root, &parent, &children, &nof_children))
-  {
-    return;
-  }
-
+	plugin_event(event_blist_update, 0, 0, 0, 0);
+        
+	time(&t);
 
- /*
-  *  Build the appropriate event mask. The basic idea is that we don't
-  *  want to interfere with the normal event propagation mechanism if
-  *  we don't have to.
-  */
-  if (substructure_only)
-  {
-    XSelectInput (d, window, SubstructureNotifyMask);
-  }
-  else
-  {
-    if (parent == None)  /* the *real* rootwindow */
-    {
-      attribs.all_event_masks = 
-        attribs.do_not_propagate_mask = KeyPressMask;
-    }
-    else if (XGetWindowAttributes (d, window, &attribs) == 0)
-    {
-      return;
-    }
-
-    XSelectInput (d, window,   SubstructureNotifyMask
-                             | (  (  attribs.all_event_masks
-                                   | attribs.do_not_propagate_mask)
-                                & KeyPressMask));
-  }
-
-
- /*
-  *  Now do the same thing for all children.
-  */
-  for (i = 0; i < nof_children; ++i)
-  {
-    SelectEvents (d, children[i], substructure_only);
-  }
-
-  if (nof_children) XFree ((Char*) children);
-}
-
-
-int catchFalseAlarms( Display *d, XErrorEvent *x )
-{
-	return 0;
-}
-
-Queue  windowQueue;
-Window hiddenWin;        /* hidden window    */
-
-void initAutoLock()
-{
-  Display*              d;          /* display pointer  */
-  Window                r;          /* root window      */
-  Int                   s;          /* screen index     */
-  XSetWindowAttributes  attribs;    /* for dummy window */
-  int (*oldHandler)(Display *, XErrorEvent *);
-
-  d = GDK_DISPLAY();
-
-  oldHandler = XSetErrorHandler( catchFalseAlarms );
-  XSync (d, 0);
-
-  windowQueue = NewQueue ();
-
-  for (s = -1; ++s < ScreenCount (d); )
-  {
-    AddToQueue (windowQueue, r = RootWindowOfScreen (ScreenOfDisplay (d, s)));
-    SelectEvents (d, r, True);
-  }
+	if (report_idle == 0)
+                return TRUE;
+	/*
+	if (gc->is_idle) {
+		fprintf (stderr, "\tgc->is_idle\n");
+		return TRUE;
+	}
+	*/
 
- /*
-  *  Get ourselves a dummy window in order to allow display and/or
-  *  session managers etc. to use XKillClient() on us (e.g. xdm when
-  *  not using XDMCP).
-  * 
-  *  I'm not sure whether the window needs to be mapped for xdm, but
-  *  the default set up Sun uses for OpenWindows and olwm definitely
-  *  requires it to be mapped.
-  */
-  attribs.override_redirect = True;
-  hiddenWin = XCreateWindow (d, DefaultRootWindow (d), -100, -100, 1, 1, 0,
-                CopyFromParent, InputOnly, CopyFromParent, CWOverrideRedirect,
-				&attribs);
-
-  XMapWindow (d, hiddenWin );
-
-  XSetErrorHandler( oldHandler );
-}
-
-/*  I don't think this should be needed, but leaving the code here
-    in case I change my mind. */
-/*
-void cleanupAutoLock()
-{
-  int (*oldHandler)(Display *, XErrorEvent *);
-  oldHandler = XSetErrorHandler( catchFalseAlarms );
-
-  FreeQueue( windowQueue );
-  XDestroyWindow( GDK_DISPLAY(), hiddenWin );
-  XSetErrorHandler( oldHandler );
-}
-*/
-
-/*
- *  Main function
- *  -------------
- */
-void waitIdle( int timeout, int until_idle )
-{
-  Display*              d;          /* display pointer  */
-  int (*oldHandler)(Display *, XErrorEvent *);
-  time_t now, prev;
-
-  time_limit = timeout;
-
-  d = GDK_DISPLAY();
+#ifdef USE_SCREENSAVER
+	if (report_idle == IDLE_SCREENSAVER) {
+		if (mit_info == NULL) {
+			mit_info = XScreenSaverAllocInfo ();
+		}
+		XScreenSaverQueryInfo (d, DefaultRootWindow(d), mit_info);
+		idle_time = (mit_info->idle)/1000;
+	} else
+#endif /* USE_SCREENSAVER */
+		idle_time = t - gc->lastsent;
 
-  oldHandler = XSetErrorHandler( catchFalseAlarms );
-
-  SetTrigger (time_limit);
-
-  time(&prev);
+	if (idle_time > 600) { /* 10 minutes! */
+		serv_set_idle(gc, idle_time);
+		gc->is_idle = 1;
+        } else
+		serv_touch_idle(gc);
 
- /*
-  *  Main event loop.
-  */
-  while ( 1 )
-  {
-    if (ProcessEvents (d, windowQueue, until_idle))
-      break;
-    if (QueryPointer (d, until_idle))
-      break;
-    
-    if (until_idle) {
-      time(&now);
-      
-      if ((now > prev && now - prev > TIME_CHANGE_LIMIT) ||
-	  (prev > now && prev - now > TIME_CHANGE_LIMIT+1))
-	{
-	  /* the time has changed in one large jump.  This could be because the
-	     date was changed, or the machine was suspended.  We'll just
-	     reset the triger. */
-	  SetTrigger (time_limit);
-	}
-      
-      prev = now;
-      
-      if ( EvaluateCounter (d) )
-	break;
-    }
-
-    /*
-     *  It seems that, on some operating systems (VMS to name just one),
-     *  sleep () can be vastly inaccurate: sometimes 60 calls to sleep (1)
-     *  add up to only 30 seconds or even less of sleeping. Therefore,
-     *  as of patchlevel 9 we no longer rely on it for keeping track of
-     *  time. The only reason why we still call it, is to make  xautolock
-     *  (which after all uses a busy-form-of-waiting algorithm), less
-     *  processor hungry.
-     */
-    sleep (1);
-  }
-
-  XSetErrorHandler( oldHandler );
+	return TRUE;
 
 }
-
-void idle_main(pid_t gaimpid) {
-  initAutoLock();
-  while (1) {
-    waitIdle(IDLE_REPORT_TIME, 1);
-    kill(gaimpid, SIGALRM);
-    sleep(1);                /* Just to be safe */
-    waitIdle(1, 0);
-    kill(gaimpid, SIGALRM);
-  }
-}
-
-
-#endif
\ No newline at end of file
--- a/src/prefs.c	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/prefs.c	Thu Oct 26 07:22:32 2000 +0000
@@ -73,10 +73,33 @@
 	debugbutton = NULL;
 }
 
+static void set_idle(GtkWidget *w, int *data)
+{
+        report_idle = (int)data;
+	save_prefs();
+}
+
+static GtkWidget *idle_radio(char *label, int which, GtkWidget *box, GtkWidget *set)
+{
+	GtkWidget *opt;
+
+	if (!set)
+		opt = gtk_radio_button_new_with_label(NULL, label);
+	else
+		opt = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(set)), label);
+	gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
+	gtk_signal_connect(GTK_OBJECT(opt), "clicked", GTK_SIGNAL_FUNC(set_idle), (void *)which);
+	gtk_widget_show(opt);
+	if (report_idle == which)
+		gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(opt), TRUE);
+
+	return opt;
+}
+
 static void general_page()
 {
 	GtkWidget *parent;
-	GtkWidget *box;
+	GtkWidget *box, *box2;
 	GtkWidget *label;
 	GtkWidget *sep;
 	GtkWidget *idle;
@@ -117,8 +140,18 @@
 	gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 5);
 	gtk_widget_show(sep);
 
-	idle = gaim_button(_("Report Idle Times"), &report_idle, 1, box);
-	gtk_signal_connect(GTK_OBJECT(idle), "clicked", set_option, &report_idle);
+	box2 = gtk_hbox_new(FALSE, 5);
+	gtk_box_pack_start(GTK_BOX(box), box2, FALSE, FALSE, 5);
+	gtk_widget_show(box2);
+
+	label = gtk_label_new(_("Report Idle Times:"));
+	gtk_box_pack_start(GTK_BOX(box2), label, FALSE, FALSE, 5);
+	gtk_widget_show (label);
+	idle = idle_radio(_("None"), IDLE_NONE, box2, NULL);
+	idle = idle_radio(_("GAIM Use"), IDLE_GAIM, box2, idle);
+#ifdef USE_SCREENSAVER
+	idle = idle_radio(_("X Use"), IDLE_SCREENSAVER, box2, idle);
+#endif
 
 	gtk_widget_show(prefdialog);
 }
--- a/src/server.c	Thu Oct 26 02:12:34 2000 +0000
+++ b/src/server.c	Thu Oct 26 07:22:32 2000 +0000
@@ -31,6 +31,11 @@
 #include <unistd.h>
 #include <gtk/gtk.h>
 #include <aim.h>
+#ifdef USE_SCREENSAVER
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/scrnsaver.h>
+#endif /* USE_SCREENSAVER */
 extern int gaim_caps;
 #include "prpl.h"
 #include "multi.h"
@@ -65,7 +70,6 @@
         gc->idle_timer = -1;
 }
 
-
 void serv_touch_idle(struct gaim_connection *gc)
 {
 	/* Are we idle?  If so, not anymore */
@@ -76,35 +80,6 @@
         time(&gc->lastsent);
 }
 
-
-static gint check_idle(struct gaim_connection *gc)
-{
-	time_t t;
-
-        /* Not idle, really...  :) */
-        update_all_buddies();
-
-	plugin_event(event_blist_update, 0, 0, 0, 0);
-        
-	time(&t);
-
-	if (report_idle != IDLE_GAIM)
-                return TRUE;
-
-	
-	if (gc->is_idle)
-		return TRUE;
-
-	if ((t - gc->lastsent) > 600) { /* 15 minutes! */
-		serv_set_idle(gc, (int)t - gc->lastsent);
-		gc->is_idle = 1;
-        }
-
-	return TRUE;
-
-}
-
-
 void serv_finish_login(struct gaim_connection *gc)
 {
         char *buf;
@@ -382,13 +357,13 @@
 	serv_save_config();
 }
 
+
 void serv_set_idle(struct gaim_connection *g, int time)
 {
 	if (g->prpl && g->prpl->set_idle)
 		(*g->prpl->set_idle)(g, time);
 }
 
-
 void serv_warn(struct gaim_connection *g, char *name, int anon)
 {
 	if (g->prpl && g->prpl->warn)