2 * $XConsortium: sleepuntil.c,v 1.5 94/04/17 20:32:57 dpw Exp $
3 * $XFree86: xc/programs/Xserver/Xext/sleepuntil.c,v 3.0 1996/05/06 05:55:34 dawes Exp $
5 Copyright (c) 1992 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
28 * Author: Keith Packard, MIT X Consortium
31 /* dixsleep.c - implement millisecond timeouts for X clients */
36 #include "windowstr.h"
37 #include "dixstruct.h"
38 #include "pixmapstr.h"
39 #include "scrnintstr.h"
41 typedef struct _Sertafied {
42 struct _Sertafied *next;
47 #if NeedNestedPrototypes
48 ClientPtr /* client */,
54 } SertafiedRec, *SertafiedPtr;
56 static SertafiedPtr pPending;
57 static RESTYPE SertafiedResType;
58 static Bool BlockHandlerRegistered;
59 static int SertafiedGeneration;
61 static void ClientAwaken(
62 #if NeedFunctionPrototypes
63 ClientPtr /* client */,
67 static int SertafiedDelete(
68 #if NeedFunctionPrototypes
73 static void SertafiedBlockHandler(
74 #if NeedFunctionPrototypes
77 pointer /* LastSelectMask */
80 static void SertafiedWakeupHandler(
81 #if NeedFunctionPrototypes
84 pointer /* LastSelectMask */
89 ClientSleepUntil (client, revive, notifyFunc, closure)
95 SertafiedPtr pRequest, pReq, pPrev;
97 if (SertafiedGeneration != serverGeneration)
99 SertafiedResType = CreateNewResourceType (SertafiedDelete);
100 if (!SertafiedResType)
102 SertafiedGeneration = serverGeneration;
103 BlockHandlerRegistered = FALSE;
105 pRequest = (SertafiedPtr) xalloc (sizeof (SertafiedRec));
108 pRequest->pClient = client;
109 pRequest->revive = *revive;
110 pRequest->id = FakeClientID (client->index);
111 pRequest->closure = closure;
112 if (!BlockHandlerRegistered)
114 if (!RegisterBlockAndWakeupHandlers (SertafiedBlockHandler,
115 SertafiedWakeupHandler,
121 BlockHandlerRegistered = TRUE;
123 pRequest->notifyFunc = 0;
124 if (!AddResource (pRequest->id, SertafiedResType, (pointer) pRequest))
127 notifyFunc = ClientAwaken;
128 pRequest->notifyFunc = notifyFunc;
129 /* Insert into time-ordered queue, with earliest activation time coming first. */
131 for (pReq = pPending; pReq; pReq = pReq->next)
133 if (CompareTimeStamps (pReq->revive, *revive) == LATER)
138 pPrev->next = pRequest;
141 pRequest->next = pReq;
142 IgnoreClient (client);
147 ClientAwaken (client, closure)
151 if (!client->clientGone)
152 AttendClient (client);
157 SertafiedDelete (value, id)
161 SertafiedPtr pRequest = (SertafiedPtr)value;
162 SertafiedPtr pReq, pPrev;
165 for (pReq = pPending; pReq; pPrev = pReq, pReq = pReq->next)
166 if (pReq == pRequest)
169 pPrev->next = pReq->next;
171 pPending = pReq->next;
174 if (pRequest->notifyFunc)
175 (*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
181 SertafiedBlockHandler (data, wt, LastSelectMask)
182 pointer data; /* unused */
183 OSTimePtr wt; /* wait time */
184 pointer LastSelectMask;
186 SertafiedPtr pReq, pNext;
187 unsigned long newdelay, olddelay;
192 now.milliseconds = GetTimeInMillis ();
193 now.months = currentTime.months;
194 if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
196 for (pReq = pPending; pReq; pReq = pNext)
199 if (CompareTimeStamps (pReq->revive, now) == LATER)
201 FreeResource (pReq->id, RT_NONE);
203 /* AttendClient() may have been called via the resource delete
204 * function so a client may have input to be processed and so
205 * set delay to 0 to prevent blocking in WaitForSomething().
207 AdjustWaitForDelay (wt, 0);
212 newdelay = pReq->revive.milliseconds - now.milliseconds;
213 AdjustWaitForDelay (wt, newdelay);
217 SertafiedWakeupHandler (data, i, LastSelectMask)
220 pointer LastSelectMask;
222 SertafiedPtr pReq, pNext;
225 now.milliseconds = GetTimeInMillis ();
226 now.months = currentTime.months;
227 if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
229 for (pReq = pPending; pReq; pReq = pNext)
232 if (CompareTimeStamps (pReq->revive, now) == LATER)
234 FreeResource (pReq->id, RT_NONE);
238 RemoveBlockAndWakeupHandlers (SertafiedBlockHandler,
239 SertafiedWakeupHandler,
241 BlockHandlerRegistered = FALSE;