Added abs_time_t structure to the server protocol, and added a dump
routine for it that displays the relative timeout to make timeout
values easier to interpret.

diff --git a/server/protocol.def b/server/protocol.def
index a3db385..b27788b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -167,6 +167,13 @@
     /* char title[...]; */
 } startup_info_t;
 
+/* structure for absolute timeouts */
+typedef struct
+{
+    int            sec;      /* seconds since Unix epoch */
+    int            usec;     /* microseconds */
+} abs_time_t;
+
 /* structure returned in the list of window properties */
 typedef struct
 {
@@ -486,8 +493,7 @@
 @REQ(select)
     int          flags;        /* wait flags (see below) */
     void*        cookie;       /* magic cookie to return to client */
-    int          sec;          /* absolute timeout */
-    int          usec;         /* absolute timeout */
+    abs_time_t   timeout;      /* absolute timeout */
     VARARG(handles,handles);   /* handles to select on */
 @END
 #define SELECT_ALL           1
@@ -1426,8 +1432,7 @@
 /* Set a waitable timer */
 @REQ(set_timer)
     obj_handle_t handle;        /* handle to the timer */
-    int          sec;           /* next expiration absolute time */
-    int          usec;          /* next expiration absolute time */
+    abs_time_t   expire;        /* next expiration absolute time */
     int          period;        /* timer period in ms */
     void*        callback;      /* callback function */
     void*        arg;           /* callback argument */
diff --git a/server/thread.c b/server/thread.c
index 0db0ada..ad310c9 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -373,7 +373,7 @@
 }
 
 /* build the thread wait structure */
-static int wait_on( int count, struct object *objects[], int flags, int sec, int usec )
+static int wait_on( int count, struct object *objects[], int flags, const abs_time_t *timeout )
 {
     struct thread_wait *wait;
     struct wait_queue_entry *entry;
@@ -388,8 +388,8 @@
     current->wait = wait;
     if (flags & SELECT_TIMEOUT)
     {
-        wait->timeout.tv_sec = sec;
-        wait->timeout.tv_usec = usec;
+        wait->timeout.tv_sec  = timeout->sec;
+        wait->timeout.tv_usec = timeout->usec;
     }
 
     for (i = 0, entry = wait->queues; i < count; i++, entry++)
@@ -518,7 +518,7 @@
 
 /* select on a list of handles */
 static void select_on( int count, void *cookie, const obj_handle_t *handles,
-                       int flags, int sec, int usec )
+                       int flags, const abs_time_t *timeout )
 {
     int ret, i;
     struct object *objects[MAXIMUM_WAIT_OBJECTS];
@@ -535,7 +535,7 @@
     }
 
     if (i < count) goto done;
-    if (!wait_on( count, objects, flags, sec, usec )) goto done;
+    if (!wait_on( count, objects, flags, timeout )) goto done;
 
     if ((ret = check_wait( current )) != -1)
     {
@@ -963,7 +963,7 @@
 DECL_HANDLER(select)
 {
     int count = get_req_data_size() / sizeof(int);
-    select_on( count, req->cookie, get_req_data(), req->flags, req->sec, req->usec );
+    select_on( count, req->cookie, get_req_data(), req->flags, &req->timeout );
 }
 
 /* queue an APC for a thread */
diff --git a/server/timer.c b/server/timer.c
index 4ca7793..85cf080 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -131,7 +131,7 @@
 }
 
 /* set the timer expiration and period */
-static void set_timer( struct timer *timer, int sec, int usec, int period,
+static void set_timer( struct timer *timer, const abs_time_t *expire, int period,
                        void *callback, void *arg )
 {
     cancel_timer( timer );
@@ -140,7 +140,7 @@
         period = 0;  /* period doesn't make any sense for a manual timer */
         timer->signaled = 0;
     }
-    if (!sec && !usec)
+    if (!expire->sec && !expire->usec)
     {
         /* special case: use now + period as first expiration */
         gettimeofday( &timer->when, 0 );
@@ -148,8 +148,8 @@
     }
     else
     {
-        timer->when.tv_sec  = sec;
-        timer->when.tv_usec = usec;
+        timer->when.tv_sec  = expire->sec;
+        timer->when.tv_usec = expire->usec;
     }
     timer->period       = period;
     timer->callback     = callback;
@@ -220,7 +220,7 @@
     if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
                                                  TIMER_MODIFY_STATE, &timer_ops )))
     {
-        set_timer( timer, req->sec, req->usec, req->period, req->callback, req->arg );
+        set_timer( timer, &req->expire, req->period, req->callback, req->arg );
         release_object( timer );
     }
 }
diff --git a/server/trace.c b/server/trace.c
index 2110883..9f46615 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -59,6 +59,29 @@
     fputc( '}', stderr );
 }
 
+static void dump_abs_time( const abs_time_t *time )
+{
+    struct timeval tv;
+    int secs, usecs;
+
+    if (!time->sec && !time->usec)
+    {
+        fprintf( stderr, "0" );
+        return;
+    }
+    gettimeofday( &tv, NULL );
+    secs = time->sec - tv.tv_sec;
+    if ((usecs = time->usec - tv.tv_usec) < 0)
+    {
+        usecs += 1000000;
+        secs--;
+    }
+    if (secs > 0 || (secs == 0 && usecs >= 0))
+        fprintf( stderr, "%d.%06d (+%d.%06d)", time->sec, time->usec, secs, usecs );
+    else
+        fprintf( stderr, "%d.%06d (-%d.%06d)", time->sec, time->usec, abs(secs+1), 1000000-usecs );
+}
+
 static void dump_rectangle( const rectangle_t *rect )
 {
     fprintf( stderr, "{%d,%d;%d,%d}",
@@ -684,8 +707,9 @@
 {
     fprintf( stderr, " flags=%d,", req->flags );
     fprintf( stderr, " cookie=%p,", req->cookie );
-    fprintf( stderr, " sec=%d,", req->sec );
-    fprintf( stderr, " usec=%d,", req->usec );
+    fprintf( stderr, " timeout=" );
+    dump_abs_time( &req->timeout );
+    fprintf( stderr, "," );
     fprintf( stderr, " handles=" );
     dump_varargs_handles( cur_size );
 }
@@ -1662,8 +1686,9 @@
 static void dump_set_timer_request( const struct set_timer_request *req )
 {
     fprintf( stderr, " handle=%p,", req->handle );
-    fprintf( stderr, " sec=%d,", req->sec );
-    fprintf( stderr, " usec=%d,", req->usec );
+    fprintf( stderr, " expire=" );
+    dump_abs_time( &req->expire );
+    fprintf( stderr, "," );
     fprintf( stderr, " period=%d,", req->period );
     fprintf( stderr, " callback=%p,", req->callback );
     fprintf( stderr, " arg=%p", req->arg );