aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/mi/mieq.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
committermarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
commit3562e78743202e43aec8727005182a2558117eca (patch)
tree8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/mi/mieq.c
downloadvcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz
vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2
vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip
Checked in the following released items:
xkeyboard-config-1.4.tar.gz ttf-bitstream-vera-1.10.tar.gz font-alias-1.0.1.tar.gz font-sun-misc-1.0.0.tar.gz font-sun-misc-1.0.0.tar.gz font-sony-misc-1.0.0.tar.gz font-schumacher-misc-1.0.0.tar.gz font-mutt-misc-1.0.0.tar.gz font-misc-misc-1.0.0.tar.gz font-misc-meltho-1.0.0.tar.gz font-micro-misc-1.0.0.tar.gz font-jis-misc-1.0.0.tar.gz font-isas-misc-1.0.0.tar.gz font-dec-misc-1.0.0.tar.gz font-daewoo-misc-1.0.0.tar.gz font-cursor-misc-1.0.0.tar.gz font-arabic-misc-1.0.0.tar.gz font-winitzki-cyrillic-1.0.0.tar.gz font-misc-cyrillic-1.0.0.tar.gz font-cronyx-cyrillic-1.0.0.tar.gz font-screen-cyrillic-1.0.1.tar.gz font-xfree86-type1-1.0.1.tar.gz font-adobe-utopia-type1-1.0.1.tar.gz font-ibm-type1-1.0.0.tar.gz font-bitstream-type1-1.0.0.tar.gz font-bitstream-speedo-1.0.0.tar.gz font-bh-ttf-1.0.0.tar.gz font-bh-type1-1.0.0.tar.gz font-bitstream-100dpi-1.0.0.tar.gz font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz font-bh-100dpi-1.0.0.tar.gz font-adobe-utopia-100dpi-1.0.1.tar.gz font-adobe-100dpi-1.0.0.tar.gz font-util-1.0.1.tar.gz font-bitstream-75dpi-1.0.0.tar.gz font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz font-adobe-utopia-75dpi-1.0.1.tar.gz font-bh-75dpi-1.0.0.tar.gz bdftopcf-1.0.1.tar.gz font-adobe-75dpi-1.0.0.tar.gz mkfontscale-1.0.6.tar.gz openssl-0.9.8k.tar.gz bigreqsproto-1.0.2.tar.gz xtrans-1.2.2.tar.gz resourceproto-1.0.2.tar.gz inputproto-1.4.4.tar.gz compositeproto-0.4.tar.gz damageproto-1.1.0.tar.gz zlib-1.2.3.tar.gz xkbcomp-1.0.5.tar.gz freetype-2.3.9.tar.gz pthreads-w32-2-8-0-release.tar.gz pixman-0.12.0.tar.gz kbproto-1.0.3.tar.gz evieext-1.0.2.tar.gz fixesproto-4.0.tar.gz recordproto-1.13.2.tar.gz randrproto-1.2.2.tar.gz scrnsaverproto-1.1.0.tar.gz renderproto-0.9.3.tar.gz xcmiscproto-1.1.2.tar.gz fontsproto-2.0.2.tar.gz xextproto-7.0.3.tar.gz xproto-7.0.14.tar.gz libXdmcp-1.0.2.tar.gz libxkbfile-1.0.5.tar.gz libfontenc-1.0.4.tar.gz libXfont-1.3.4.tar.gz libX11-1.1.5.tar.gz libXau-1.0.4.tar.gz libxcb-1.1.tar.gz xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/mi/mieq.c')
-rw-r--r--xorg-server/mi/mieq.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/xorg-server/mi/mieq.c b/xorg-server/mi/mieq.c
new file mode 100644
index 000000000..803724708
--- /dev/null
+++ b/xorg-server/mi/mieq.c
@@ -0,0 +1,261 @@
+/*
+ *
+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
+ *
+ */
+
+#if HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# define NEED_EVENTS
+# include <X11/X.h>
+# include <X11/Xmd.h>
+# include <X11/Xproto.h>
+# include "misc.h"
+# include "windowstr.h"
+# include "pixmapstr.h"
+# include "inputstr.h"
+# include "mi.h"
+# include "mipointer.h"
+# include "scrnintstr.h"
+# include <X11/extensions/XI.h>
+# include <X11/extensions/XIproto.h>
+# include "extinit.h"
+# include "exglobals.h"
+
+#ifdef DPMSExtension
+# include "dpmsproc.h"
+# define DPMS_SERVER
+# include <X11/extensions/dpms.h>
+#endif
+
+#define QUEUE_SIZE 512
+
+typedef struct _Event {
+ xEvent event[7];
+ int nevents;
+ ScreenPtr pScreen;
+ DeviceIntPtr pDev; /* device this event _originated_ from */
+} EventRec, *EventPtr;
+
+typedef struct _EventQueue {
+ HWEventQueueType head, tail; /* long for SetInputCheck */
+ CARD32 lastEventTime; /* to avoid time running backwards */
+ int lastMotion; /* device ID if last event motion? */
+ EventRec events[QUEUE_SIZE]; /* static allocation for signals */
+ ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
+ ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
+ mieqHandler handlers[128]; /* custom event handler */
+} EventQueueRec, *EventQueuePtr;
+
+static EventQueueRec miEventQueue;
+
+Bool
+mieqInit(void)
+{
+ int i;
+
+ miEventQueue.head = miEventQueue.tail = 0;
+ miEventQueue.lastEventTime = GetTimeInMillis ();
+ miEventQueue.lastMotion = FALSE;
+ miEventQueue.pEnqueueScreen = screenInfo.screens[0];
+ miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
+ for (i = 0; i < 128; i++)
+ miEventQueue.handlers[i] = NULL;
+ 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(DeviceIntPtr pDev, xEvent *e)
+{
+ unsigned int oldtail = miEventQueue.tail, newtail;
+ int isMotion = 0;
+ deviceValuator *v = (deviceValuator *) e;
+ EventPtr laste = &miEventQueue.events[(oldtail - 1) %
+ QUEUE_SIZE];
+ deviceKeyButtonPointer *lastkbp = (deviceKeyButtonPointer *)
+ &laste->event[0];
+
+ if (e->u.u.type == MotionNotify)
+ isMotion = inputInfo.pointer->id;
+ else if (e->u.u.type == DeviceMotionNotify)
+ isMotion = pDev->id;
+
+ /* We silently steal valuator events: just tack them on to the last
+ * motion event they need to be attached to. Sigh. */
+ if (e->u.u.type == DeviceValuator) {
+ if (laste->nevents > 6) {
+ ErrorF("[mi] mieqEnqueue: more than six valuator events; dropping.\n");
+ return;
+ }
+ if (oldtail == miEventQueue.head ||
+ !(lastkbp->type == DeviceMotionNotify ||
+ lastkbp->type == DeviceButtonPress ||
+ lastkbp->type == DeviceButtonRelease ||
+ lastkbp->type == ProximityIn ||
+ lastkbp->type == ProximityOut) ||
+ ((lastkbp->deviceid & DEVICE_BITS) !=
+ (v->deviceid & DEVICE_BITS))) {
+ ErrorF("[mi] mieqEnequeue: out-of-order valuator event; dropping.\n");
+ return;
+ }
+ memcpy(&(laste->event[laste->nevents++]), e, sizeof(xEvent));
+ return;
+ }
+
+ if (isMotion && isMotion == miEventQueue.lastMotion &&
+ oldtail != miEventQueue.head) {
+ oldtail = (oldtail - 1) % QUEUE_SIZE;
+ }
+ else {
+ static int stuck = 0;
+ newtail = (oldtail + 1) % QUEUE_SIZE;
+ /* Toss events which come in late. Usually this means your server's
+ * stuck in an infinite loop somewhere, but SIGIO is still getting
+ * handled. */
+ if (newtail == miEventQueue.head) {
+ ErrorF("[mi] EQ overflowing. The server is probably stuck "
+ "in an infinite loop.\n");
+ if (!stuck) {
+ xorg_backtrace();
+ stuck = 1;
+ }
+ return;
+ }
+ stuck = 0;
+ miEventQueue.tail = newtail;
+ }
+
+ memcpy(&(miEventQueue.events[oldtail].event[0]), e, sizeof(xEvent));
+ miEventQueue.events[oldtail].nevents = 1;
+
+ /* 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[0].u.keyButtonPointer.time =
+ miEventQueue.lastEventTime;
+
+ miEventQueue.lastEventTime =
+ miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time;
+ miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
+ miEventQueue.events[oldtail].pDev = pDev;
+
+ miEventQueue.lastMotion = isMotion;
+}
+
+void
+mieqSwitchScreen(ScreenPtr pScreen, Bool fromDIX)
+{
+ miEventQueue.pEnqueueScreen = pScreen;
+ if (fromDIX)
+ miEventQueue.pDequeueScreen = pScreen;
+}
+
+void
+mieqSetHandler(int event, mieqHandler handler)
+{
+ if (handler && miEventQueue.handlers[event])
+ ErrorF("mieq: warning: overriding existing handler %p with %p for "
+ "event %d\n", miEventQueue.handlers[event], handler, event);
+
+ miEventQueue.handlers[event] = handler;
+}
+
+/* Call this from ProcessInputEvents(). */
+void
+mieqProcessInputEvents(void)
+{
+ EventRec *e = NULL;
+ int x = 0, y = 0;
+ DeviceIntPtr dev = NULL;
+
+ while (miEventQueue.head != miEventQueue.tail) {
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
+#ifdef DPMSExtension
+ else if (DPMSPowerLevel != DPMSModeOn)
+ SetScreenSaverTimer();
+
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(serverClient, DPMSModeOn);
+#endif
+
+ e = &miEventQueue.events[miEventQueue.head];
+ /* Assumption - screen switching can only occur on motion events. */
+ miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE;
+
+ if (e->pScreen != miEventQueue.pDequeueScreen) {
+ miEventQueue.pDequeueScreen = e->pScreen;
+ x = e->event[0].u.keyButtonPointer.rootX;
+ y = e->event[0].u.keyButtonPointer.rootY;
+ NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
+ }
+ else {
+ /* If someone's registered a custom event handler, let them
+ * steal it. */
+ if (miEventQueue.handlers[e->event->u.u.type]) {
+ miEventQueue.handlers[e->event->u.u.type](miEventQueue.pDequeueScreen->myNum,
+ e->event, dev,
+ e->nevents);
+ return;
+ }
+
+ /* If this is a core event, make sure our keymap, et al, is
+ * changed to suit. */
+ if (e->event[0].u.u.type == KeyPress ||
+ e->event[0].u.u.type == KeyRelease) {
+ SwitchCoreKeyboard(e->pDev);
+ dev = inputInfo.keyboard;
+ }
+ else if (e->event[0].u.u.type == MotionNotify ||
+ e->event[0].u.u.type == ButtonPress ||
+ e->event[0].u.u.type == ButtonRelease) {
+ SwitchCorePointer(e->pDev);
+ dev = inputInfo.pointer;
+ }
+ else {
+ dev = e->pDev;
+ }
+
+ dev->public.processInputProc(e->event, dev, e->nevents);
+ }
+ }
+}