]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/Xext/sleepuntil.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / Xext / sleepuntil.c
1 /*
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 $
4  *
5 Copyright (c) 1992  X Consortium
6
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:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
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.
23
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.
27  *
28  * Author:  Keith Packard, MIT X Consortium
29  */
30
31 /* dixsleep.c - implement millisecond timeouts for X clients */
32
33 #include "X.h"
34 #include "Xmd.h"
35 #include "misc.h"
36 #include "windowstr.h"
37 #include "dixstruct.h"
38 #include "pixmapstr.h"
39 #include "scrnintstr.h"
40
41 typedef struct _Sertafied {
42     struct _Sertafied   *next;
43     TimeStamp           revive;
44     ClientPtr           pClient;
45     XID                 id;
46     void                (*notifyFunc)(
47 #if NeedNestedPrototypes
48                         ClientPtr /* client */,
49                         pointer /* closure */
50 #endif
51                         );
52
53     pointer             closure;
54 } SertafiedRec, *SertafiedPtr;
55
56 static SertafiedPtr pPending;
57 static RESTYPE      SertafiedResType;
58 static Bool         BlockHandlerRegistered;
59 static int          SertafiedGeneration;
60
61 static void         ClientAwaken(
62 #if NeedFunctionPrototypes
63     ClientPtr /* client */,
64     pointer /* closure */
65 #endif
66 );
67 static int          SertafiedDelete(
68 #if NeedFunctionPrototypes
69     pointer /* value */,
70     XID /* id */
71 #endif
72 );
73 static void         SertafiedBlockHandler(
74 #if NeedFunctionPrototypes
75     pointer /* data */,
76     OSTimePtr /* wt */,
77     pointer /* LastSelectMask */
78 #endif
79 );
80 static void         SertafiedWakeupHandler(
81 #if NeedFunctionPrototypes
82     pointer /* data */,
83     int /* i */,
84     pointer /* LastSelectMask */
85 #endif
86 );
87
88 int
89 ClientSleepUntil (client, revive, notifyFunc, closure)
90     ClientPtr   client;
91     TimeStamp   *revive;
92     void        (*notifyFunc)();
93     pointer     closure;
94 {
95     SertafiedPtr        pRequest, pReq, pPrev;
96
97     if (SertafiedGeneration != serverGeneration)
98     {
99         SertafiedResType = CreateNewResourceType (SertafiedDelete);
100         if (!SertafiedResType)
101             return FALSE;
102         SertafiedGeneration = serverGeneration;
103         BlockHandlerRegistered = FALSE;
104     }
105     pRequest = (SertafiedPtr) xalloc (sizeof (SertafiedRec));
106     if (!pRequest)
107         return FALSE;
108     pRequest->pClient = client;
109     pRequest->revive = *revive;
110     pRequest->id = FakeClientID (client->index);
111     pRequest->closure = closure;
112     if (!BlockHandlerRegistered)
113     {
114         if (!RegisterBlockAndWakeupHandlers (SertafiedBlockHandler,
115                                              SertafiedWakeupHandler,
116                                              (pointer) 0))
117         {
118             xfree (pRequest);
119             return FALSE;
120         }
121         BlockHandlerRegistered = TRUE;
122     }
123     pRequest->notifyFunc = 0;
124     if (!AddResource (pRequest->id, SertafiedResType, (pointer) pRequest))
125         return FALSE;
126     if (!notifyFunc)
127         notifyFunc = ClientAwaken;
128     pRequest->notifyFunc = notifyFunc;
129     /* Insert into time-ordered queue, with earliest activation time coming first. */
130     pPrev = 0;
131     for (pReq = pPending; pReq; pReq = pReq->next)
132     {
133         if (CompareTimeStamps (pReq->revive, *revive) == LATER)
134             break;
135         pPrev = pReq;
136     }
137     if (pPrev)
138         pPrev->next = pRequest;
139     else
140         pPending = pRequest;
141     pRequest->next = pReq;
142     IgnoreClient (client);
143     return TRUE;
144 }
145
146 static void
147 ClientAwaken (client, closure)
148     ClientPtr   client;
149     pointer     closure;
150 {
151     if (!client->clientGone)
152         AttendClient (client);
153 }
154
155
156 static int
157 SertafiedDelete (value, id)
158     pointer value;
159     XID id;
160 {
161     SertafiedPtr        pRequest = (SertafiedPtr)value;
162     SertafiedPtr        pReq, pPrev;
163
164     pPrev = 0;
165     for (pReq = pPending; pReq; pPrev = pReq, pReq = pReq->next)
166         if (pReq == pRequest)
167         {
168             if (pPrev)
169                 pPrev->next = pReq->next;
170             else
171                 pPending = pReq->next;
172             break;
173         }
174     if (pRequest->notifyFunc)
175         (*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
176     xfree (pRequest);
177     return TRUE;
178 }
179
180 static void
181 SertafiedBlockHandler (data, wt, LastSelectMask)
182     pointer         data;               /* unused */
183     OSTimePtr       wt;                 /* wait time */
184     pointer         LastSelectMask;
185 {
186     SertafiedPtr            pReq, pNext;
187     unsigned long           newdelay, olddelay;
188     TimeStamp               now;
189
190     if (!pPending)
191         return;
192     now.milliseconds = GetTimeInMillis ();
193     now.months = currentTime.months;
194     if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
195         now.months++;
196     for (pReq = pPending; pReq; pReq = pNext)
197     {
198         pNext = pReq->next;
199         if (CompareTimeStamps (pReq->revive, now) == LATER)
200             break;
201         FreeResource (pReq->id, RT_NONE);
202
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().
206          */
207         AdjustWaitForDelay (wt, 0);
208     }
209     pReq = pPending;
210     if (!pReq)
211         return;
212     newdelay = pReq->revive.milliseconds - now.milliseconds;
213     AdjustWaitForDelay (wt, newdelay);
214 }
215
216 static void
217 SertafiedWakeupHandler (data, i, LastSelectMask)
218     pointer         data;
219     int             i;
220     pointer         LastSelectMask;
221 {
222     SertafiedPtr        pReq, pNext;
223     TimeStamp           now;
224
225     now.milliseconds = GetTimeInMillis ();
226     now.months = currentTime.months;
227     if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
228         now.months++;
229     for (pReq = pPending; pReq; pReq = pNext)
230     {
231         pNext = pReq->next;
232         if (CompareTimeStamps (pReq->revive, now) == LATER)
233             break;
234         FreeResource (pReq->id, RT_NONE);
235     }
236     if (!pPending)
237     {
238         RemoveBlockAndWakeupHandlers (SertafiedBlockHandler,
239                                       SertafiedWakeupHandler,
240                                       (pointer) 0);
241         BlockHandlerRegistered = FALSE;
242     }
243 }