home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / server / sleepuntil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  5.4 KB  |  200 lines

  1. /*
  2.  * $XConsortium: sleepuntil.c,v 1.1 92/02/24 19:02:27 keith Exp $
  3.  *
  4.  * Copyright 1992 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, MIT X Consortium
  24.  */
  25.  
  26. /* dixsleep.c - implement millisecond timeouts for X clients */
  27.  
  28. #include "X.h"
  29. #include "Xmd.h"
  30. #include "misc.h"
  31. #include "windowstr.h"
  32. #include "dixstruct.h"
  33. #include "pixmapstr.h"
  34. #include "scrnintstr.h"
  35.  
  36. typedef struct _Sertafied {
  37.     struct _Sertafied    *next;
  38.     TimeStamp        revive;
  39.     ClientPtr        pClient;
  40.     XID            id;
  41.     void        (*notifyFunc)();
  42.     pointer        closure;
  43. } SertafiedRec, *SertafiedPtr;
  44.  
  45. static SertafiedPtr pPending;
  46. static RESTYPE        SertafiedResType;
  47. static Bool        BlockHandlerRegistered;
  48. static int        SertafiedGeneration;
  49. static void        WachetAuf();
  50. static void        SertafiedDelete();
  51. static void        SertafiedBlockHandler();
  52. static void        SertafiedWakeupHandler();
  53.  
  54. ClientSleepUntil (client, revive, notifyFunc, closure)
  55.     ClientPtr    client;
  56.     TimeStamp    *revive;
  57.     void    (*notifyFunc)();
  58.     pointer    closure;
  59. {
  60.     SertafiedPtr    pRequest, pReq, pPrev;
  61.  
  62.     if (SertafiedGeneration != serverGeneration)
  63.     {
  64.     SertafiedResType = CreateNewResourceType (SertafiedDelete);
  65.     if (!SertafiedResType)
  66.         return FALSE;
  67.     SertafiedGeneration = serverGeneration;
  68.     BlockHandlerRegistered = FALSE;
  69.     }
  70.     pRequest = (SertafiedPtr) xalloc (sizeof (SertafiedRec));
  71.     if (!pRequest)
  72.     return FALSE;
  73.     pRequest->pClient = client;
  74.     pRequest->revive = *revive;
  75.     pRequest->id = FakeClientID (client->index);
  76.     pRequest->closure = closure;
  77.     if (!BlockHandlerRegistered)
  78.     {
  79.     if (!RegisterBlockAndWakeupHandlers (SertafiedBlockHandler,
  80.                          SertafiedWakeupHandler,
  81.                          (pointer) 0))
  82.     {
  83.         xfree (pRequest);
  84.         return FALSE;
  85.     }
  86.     BlockHandlerRegistered = TRUE;
  87.     }
  88.     pRequest->notifyFunc = 0;
  89.     if (!AddResource (pRequest->id, SertafiedResType, (pointer) pRequest))
  90.     return FALSE;
  91.     if (!notifyFunc)
  92.     notifyFunc = WachetAuf;
  93.     pRequest->notifyFunc = notifyFunc;
  94.     /* Insert into time-ordered queue, with earliest activation time coming first. */
  95.     pPrev = 0;
  96.     for (pReq = pPending; pReq; pReq = pReq->next)
  97.     {
  98.     if (CompareTimeStamps (pReq->revive, *revive) == LATER)
  99.         break;
  100.     pPrev = pReq;
  101.     }
  102.     if (pPrev)
  103.     pPrev->next = pRequest;
  104.     else
  105.     pPending = pRequest;
  106.     pRequest->next = pReq;
  107.     IgnoreClient (client);
  108.     return TRUE;
  109. }
  110.  
  111. static void
  112. WachetAuf (client, closure)
  113.     ClientPtr    client;
  114.     pointer    closure;
  115. {
  116.     if (!client->clientGone)
  117.     AttendClient (client);
  118. }
  119.  
  120.  
  121. static void
  122. SertafiedDelete (pRequest)
  123.     SertafiedPtr    pRequest;
  124. {
  125.     SertafiedPtr    pReq, pPrev;
  126.  
  127.     pPrev = 0;
  128.     for (pReq = pPending; pReq; pReq = pReq->next)
  129.     if (pReq == pRequest)
  130.     {
  131.         if (pPrev)
  132.         pPrev->next = pReq->next;
  133.         else
  134.         pPending = pReq->next;
  135.         break;
  136.     }
  137.     if (pRequest->notifyFunc)
  138.     (*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
  139.     xfree (pRequest);
  140. }
  141.  
  142. static void
  143. SertafiedBlockHandler (data, wt, LastSelectMask)
  144.     pointer        data;        /* unused */
  145.     pointer        wt;            /* wait time */
  146.     long        *LastSelectMask;
  147. {
  148.     SertafiedPtr        pReq, pNext;
  149.     unsigned long        newdelay, olddelay;
  150.     TimeStamp            now;
  151.  
  152.     if (!pPending)
  153.     return;
  154.     now.milliseconds = GetTimeInMillis ();
  155.     now.months = currentTime.months;
  156.     if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
  157.     now.months++;
  158.     for (pReq = pPending; pReq; pReq = pNext)
  159.     {
  160.     pNext = pReq->next;
  161.     if (CompareTimeStamps (pReq->revive, now) == LATER)
  162.         break;
  163.     FreeResource (pReq->id, RT_NONE);
  164.     }
  165.     pReq = pPending;
  166.     if (!pReq)
  167.     return;
  168.     newdelay = pReq->revive.milliseconds - now.milliseconds;
  169.     AdjustWaitForDelay (wt, newdelay);
  170. }
  171.  
  172. static void
  173. SertafiedWakeupHandler (data, i, LastSelectMask)
  174.     pointer        data;
  175.     int            i;
  176.     long        *LastSelectMask;
  177. {
  178.     SertafiedPtr    pReq, pNext;
  179.     TimeStamp        now;
  180.  
  181.     now.milliseconds = GetTimeInMillis ();
  182.     now.months = currentTime.months;
  183.     if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
  184.     now.months++;
  185.     for (pReq = pPending; pReq; pReq = pNext)
  186.     {
  187.     pNext = pReq->next;
  188.     if (CompareTimeStamps (pReq->revive, now) == LATER)
  189.         break;
  190.     FreeResource (pReq->id, RT_NONE);
  191.     }
  192.     if (!pPending)
  193.     {
  194.     RemoveBlockAndWakeupHandlers (SertafiedBlockHandler,
  195.                       SertafiedWakeupHandler,
  196.                       (pointer) 0);
  197.     BlockHandlerRegistered = FALSE;
  198.     }
  199. }
  200.