summaryrefslogtreecommitdiff
path: root/mi/mieq.c
diff options
context:
space:
mode:
Diffstat (limited to 'mi/mieq.c')
-rw-r--r--mi/mieq.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/mi/mieq.c b/mi/mieq.c
new file mode 100644
index 000000000..02b35160c
--- /dev/null
+++ b/mi/mieq.c
@@ -0,0 +1,191 @@
+/*
+ * $Xorg: mieq.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $
+ *
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+ *
+ * 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;
+ }
+ }
+ }
+}