]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mi/mieq.c
0f338de3ebf0de004dc5f973854e54c6491427f0
[rdpsrv] / Xserver / programs / Xserver / mi / mieq.c
1 /*
2  * $XConsortium: mieq.c,v 1.8 94/11/02 15:59:29 kaleb Exp $
3  *
4 Copyright (c) 1990  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26  *
27  * Author:  Keith Packard, MIT X Consortium
28  */
29
30 /*
31  * mieq.c
32  *
33  * Machine independent event queue
34  *
35  */
36
37 # define NEED_EVENTS
38 # include   "X.h"
39 # include   "Xmd.h"
40 # include   "Xproto.h"
41 # include   "misc.h"
42 # include   "windowstr.h"
43 # include   "pixmapstr.h"
44 # include   "inputstr.h"
45 # include   "mi.h"
46 # include   "scrnintstr.h"
47
48 #define QUEUE_SIZE  256
49
50 typedef struct _Event {
51     xEvent      event;
52     ScreenPtr   pScreen;
53 } EventRec, *EventPtr;
54
55 typedef struct _EventQueue {
56     HWEventQueueType    head, tail;         /* long for SetInputCheck */
57     CARD32      lastEventTime;      /* to avoid time running backwards */
58     Bool        lastMotion;
59     EventRec    events[QUEUE_SIZE]; /* static allocation for signals */
60     DevicePtr   pKbd, pPtr;         /* device pointer, to get funcs */
61     ScreenPtr   pEnqueueScreen;     /* screen events are being delivered to */
62     ScreenPtr   pDequeueScreen;     /* screen events are being dispatched to */
63 } EventQueueRec, *EventQueuePtr;
64
65 static EventQueueRec miEventQueue;
66
67 Bool
68 mieqInit (pKbd, pPtr)
69     DevicePtr   pKbd, pPtr;
70 {
71     miEventQueue.head = miEventQueue.tail = 0;
72     miEventQueue.lastEventTime = GetTimeInMillis ();
73     miEventQueue.pKbd = pKbd;
74     miEventQueue.pPtr = pPtr;
75     miEventQueue.lastMotion = FALSE;
76     miEventQueue.pEnqueueScreen = screenInfo.screens[0];
77     miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
78     SetInputCheck (&miEventQueue.head, &miEventQueue.tail);
79     return TRUE;
80 }
81
82 /*
83  * Must be reentrant with ProcessInputEvents.  Assumption: mieqEnqueue
84  * will never be interrupted.  If this is called from both signal
85  * handlers and regular code, make sure the signal is suspended when
86  * called from regular code.
87  */
88
89 void
90 mieqEnqueue (e)
91     xEvent      *e;
92 {
93     HWEventQueueType    oldtail, newtail, prevtail;
94     Bool    isMotion;
95
96     oldtail = miEventQueue.tail;
97     isMotion = e->u.u.type == MotionNotify;
98     if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head)
99     {
100         if (oldtail == 0)
101             oldtail = QUEUE_SIZE;
102         oldtail = oldtail - 1;
103     }
104     else
105     {
106         newtail = oldtail + 1;
107         if (newtail == QUEUE_SIZE)
108             newtail = 0;
109         /* Toss events which come in late */
110         if (newtail == miEventQueue.head)
111             return;
112         miEventQueue.tail = newtail;
113     }
114     miEventQueue.lastMotion = isMotion;
115     miEventQueue.events[oldtail].event = *e;
116     /*
117      * Make sure that event times don't go backwards - this
118      * is "unnecessary", but very useful
119      */
120     if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
121         miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
122     {
123         miEventQueue.events[oldtail].event.u.keyButtonPointer.time =
124             miEventQueue.lastEventTime;
125     }
126     miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
127 }
128
129 void
130 mieqSwitchScreen (pScreen, fromDIX)
131     ScreenPtr   pScreen;
132     Bool        fromDIX;
133 {
134     miEventQueue.pEnqueueScreen = pScreen;
135     if (fromDIX)
136         miEventQueue.pDequeueScreen = pScreen;
137 }
138
139 /*
140  * Call this from ProcessInputEvents()
141  */
142
143 mieqProcessInputEvents ()
144 {
145     EventRec    *e;
146     int         x, y;
147     xEvent      xe;
148
149     while (miEventQueue.head != miEventQueue.tail)
150     {
151         extern int  screenIsSaved;
152
153         if (screenIsSaved == SCREEN_SAVER_ON)
154             SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
155
156         e = &miEventQueue.events[miEventQueue.head];
157         /*
158          * Assumption - screen switching can only occur on motion events
159          */
160         if (e->pScreen != miEventQueue.pDequeueScreen)
161         {
162             miEventQueue.pDequeueScreen = e->pScreen;
163             x = e->event.u.keyButtonPointer.rootX;
164             y = e->event.u.keyButtonPointer.rootY;
165             if (miEventQueue.head == QUEUE_SIZE - 1)
166                 miEventQueue.head = 0;
167             else
168                 ++miEventQueue.head;
169             NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
170         }
171         else
172         {
173             xe = e->event;
174             if (miEventQueue.head == QUEUE_SIZE - 1)
175                 miEventQueue.head = 0;
176             else
177                 ++miEventQueue.head;
178             switch (xe.u.u.type) 
179             {
180             case KeyPress:
181             case KeyRelease:
182                 (*miEventQueue.pKbd->processInputProc)
183                                 (&xe, (DeviceIntPtr)miEventQueue.pKbd, 1);
184                 break;
185             default:
186                 (*miEventQueue.pPtr->processInputProc)
187                                 (&xe, (DeviceIntPtr)miEventQueue.pPtr, 1);
188                 break;
189             }
190         }
191     }
192 }