[comp.windows.x] Timing Out a User - problems with XChangeProperty

lcp@ibism.UUCP (Larry Poleshuck) (02/21/91)

I need to know when a user has not touched the keyboard or mouse for more than
n minutes so I can time them out (force them to re-enter their password).  They must be timed out even if the application is updating various windows automatically (in a WorkProc).  I wanted to do this without checking every X event.  Thanks to an idea from someone at DEC I am using the following technique.

I have a timeout (XtAddTimeOut) which goes off every minute.  The timeout proc in turn calls XChangeProperty in order to change the property of a private Atom.
I establish an event handler for PropertyChange events.  In that event handler, I can look at the event.xproperty.time field which gives the server time.  I am told that the server clock is incremented only upon external stimuli, such as keyboard or mouse events and therefore if the user hasn't touched the keyboard or mouse, then event.xproperty.time will be unchanged.

Two questions:

1)  Is this a good way to handle my problem?  Can I rely on this feature of the server clock?  I am currently using Xsun server, but can see this application running on other servers.

2)  For some reason my event handler never gets executed.  I have included pieces of my code.  startUserTimeout is called from my application.  userTimeout is the 1 minute timer routine.  HandleTimeoutEvent is the event handler which should but doesn't get the changeProperty events.  Is there something else I should be doing in order to sensitize my application to these events?

Thanks in advance for any help.


userTimeout.C =================

static char sccs_id[] = "%Z% %Q% %M% %I% %G% %Z%";

extern "C"
    {
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xatom.h>
#include <stdlib.h>
    }

/*
 * userTimeout will time the user out in the event that the keyboard and
 * mouse is not touched in a fixed period of time.  the strategy is to
 * modify a user property every minute.  in a event handler for property
 * change, we look at the timestamp.  The timestamp of the event is the
 * server timestamp which gets updated only when user input has occurred.
 * so if the timestamp  has not changed since last time, we assume
 * that no user input has occurred.
 *
 */
static int userTimeoutPeriod;     // how often we check for activity
static int userTimeoutInterval;   // how long inactivity can be
static void (*userTimeoutProc)(); // what to do when we timeout
static Display* display = 0;
static Window window = 0;
static Atom property;

extern "C" XChangeProperty(Display* display, Window window, Atom property,
	Atom type, int format, int mode, unsigned char *data, int nelements);
extern "C" XSetSelectionOwner(Display* d, Atom s, Window o, Time t);

static void timeoutTimer(Widget w)
    {
    // by now the window has been created, get the window and display
    if (window == 0)
	{
	window = XtWindow(w);
 	}
    
    // change the property
    XChangeProperty(display, window, property, XA_STRING, 8, 
	    PropModeAppend,
	    (unsigned char*)"" /* the actual data is insignificant */,
	    0  /* number of elements */ );

    XtAddTimeOut(userTimeoutInterval,
	         (XtTimerCallbackProc) timeoutTimer,
		 (caddr_t) w );
    }
    

static void HandleTimeoutEvent (Widget, caddr_t, XEvent* event)
    {
    // only if this is a propertyNotify event and the changed atom
    // is our "property"
    if (event->xproperty.type == PropertyNotify && 
	    event->xproperty.atom == property)
	{
	printf("time = %d\n", event->xproperty.time);
	}
    }

void startUserTimeout(Widget w, int timeoutInterval, int timeoutPeriod,
		void (*proc)())
    {
    userTimeoutInterval = timeoutInterval;
    userTimeoutPeriod = timeoutPeriod;
    userTimeoutProc = proc;
    display = XtDisplay(w);
    property = XInternAtom(display, "USER_TIMEOUT_ATOM", False);

    // add an event handler for changes to properties
    XtAddRawEventHandler(w, PropertyChangeMask, False, 
				(XtEventHandler)HandleTimeoutEvent, 0);

    // add a timeout which changes the property which is handled
    // by previous handler
    XtAddTimeOut(timeoutInterval,
	         (XtTimerCallbackProc) timeoutTimer,
		 (caddr_t) w );
    }

   

-- 

Larry Poleshuck
Citibank
111 Wall Street
New York, NY  10043

Phone:  212-657-7709
Fax:    212-825-8607
E-Mail: uunet!ibism!lcp