X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fmi%2Fmieq.c;fp=Xserver%2Fprograms%2FXserver%2Fmi%2Fmieq.c;h=0f338de3ebf0de004dc5f973854e54c6491427f0;hp=0000000000000000000000000000000000000000;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hpb=e3340a110a3b01756b8e67531395a33b40a17d37;ds=sidebyside diff --git a/Xserver/programs/Xserver/mi/mieq.c b/Xserver/programs/Xserver/mi/mieq.c new file mode 100644 index 0000000..0f338de --- /dev/null +++ b/Xserver/programs/Xserver/mi/mieq.c @@ -0,0 +1,192 @@ +/* + * $XConsortium: mieq.c,v 1.8 94/11/02 15:59:29 kaleb Exp $ + * +Copyright (c) 1990 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + * + * Author: Keith Packard, MIT X Consortium + */ + +/* + * mieq.c + * + * Machine independent event queue + * + */ + +# define NEED_EVENTS +# include "X.h" +# include "Xmd.h" +# include "Xproto.h" +# include "misc.h" +# include "windowstr.h" +# include "pixmapstr.h" +# include "inputstr.h" +# include "mi.h" +# include "scrnintstr.h" + +#define QUEUE_SIZE 256 + +typedef struct _Event { + xEvent event; + ScreenPtr pScreen; +} EventRec, *EventPtr; + +typedef struct _EventQueue { + HWEventQueueType head, tail; /* long for SetInputCheck */ + CARD32 lastEventTime; /* to avoid time running backwards */ + Bool lastMotion; + EventRec events[QUEUE_SIZE]; /* static allocation for signals */ + DevicePtr pKbd, pPtr; /* device pointer, to get funcs */ + ScreenPtr pEnqueueScreen; /* screen events are being delivered to */ + ScreenPtr pDequeueScreen; /* screen events are being dispatched to */ +} EventQueueRec, *EventQueuePtr; + +static EventQueueRec miEventQueue; + +Bool +mieqInit (pKbd, pPtr) + DevicePtr pKbd, pPtr; +{ + miEventQueue.head = miEventQueue.tail = 0; + miEventQueue.lastEventTime = GetTimeInMillis (); + miEventQueue.pKbd = pKbd; + miEventQueue.pPtr = pPtr; + miEventQueue.lastMotion = FALSE; + miEventQueue.pEnqueueScreen = screenInfo.screens[0]; + miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen; + SetInputCheck (&miEventQueue.head, &miEventQueue.tail); + return TRUE; +} + +/* + * Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue + * will never be interrupted. If this is called from both signal + * handlers and regular code, make sure the signal is suspended when + * called from regular code. + */ + +void +mieqEnqueue (e) + xEvent *e; +{ + HWEventQueueType oldtail, newtail, prevtail; + Bool isMotion; + + oldtail = miEventQueue.tail; + isMotion = e->u.u.type == MotionNotify; + if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head) + { + if (oldtail == 0) + oldtail = QUEUE_SIZE; + oldtail = oldtail - 1; + } + else + { + newtail = oldtail + 1; + if (newtail == QUEUE_SIZE) + newtail = 0; + /* Toss events which come in late */ + if (newtail == miEventQueue.head) + return; + miEventQueue.tail = newtail; + } + miEventQueue.lastMotion = isMotion; + miEventQueue.events[oldtail].event = *e; + /* + * Make sure that event times don't go backwards - this + * is "unnecessary", but very useful + */ + if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime && + miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) + { + miEventQueue.events[oldtail].event.u.keyButtonPointer.time = + miEventQueue.lastEventTime; + } + miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen; +} + +void +mieqSwitchScreen (pScreen, fromDIX) + ScreenPtr pScreen; + Bool fromDIX; +{ + miEventQueue.pEnqueueScreen = pScreen; + if (fromDIX) + miEventQueue.pDequeueScreen = pScreen; +} + +/* + * Call this from ProcessInputEvents() + */ + +mieqProcessInputEvents () +{ + EventRec *e; + int x, y; + xEvent xe; + + while (miEventQueue.head != miEventQueue.tail) + { + extern int screenIsSaved; + + if (screenIsSaved == SCREEN_SAVER_ON) + SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset); + + e = &miEventQueue.events[miEventQueue.head]; + /* + * Assumption - screen switching can only occur on motion events + */ + if (e->pScreen != miEventQueue.pDequeueScreen) + { + miEventQueue.pDequeueScreen = e->pScreen; + x = e->event.u.keyButtonPointer.rootX; + y = e->event.u.keyButtonPointer.rootY; + if (miEventQueue.head == QUEUE_SIZE - 1) + miEventQueue.head = 0; + else + ++miEventQueue.head; + NewCurrentScreen (miEventQueue.pDequeueScreen, x, y); + } + else + { + xe = e->event; + if (miEventQueue.head == QUEUE_SIZE - 1) + miEventQueue.head = 0; + else + ++miEventQueue.head; + switch (xe.u.u.type) + { + case KeyPress: + case KeyRelease: + (*miEventQueue.pKbd->processInputProc) + (&xe, (DeviceIntPtr)miEventQueue.pKbd, 1); + break; + default: + (*miEventQueue.pPtr->processInputProc) + (&xe, (DeviceIntPtr)miEventQueue.pPtr, 1); + break; + } + } + } +}