summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <Alan.Coopersmith@sun.com>2005-05-22 01:12:49 +0000
committerAlan Coopersmith <Alan.Coopersmith@sun.com>2005-05-22 01:12:49 +0000
commit62343f5162066f19ca6e62d1c85a4a40d45b3295 (patch)
tree801fac4154f316c82e9cb25997bbdc2fd6c81427
parenta8a61bbe22361b12d4a2dd511894987a338e3eef (diff)
Bugzilla #2800 <https://bugs.freedesktop.org/show_bug.cgi?id=2800> XevieXORG-6_8_99_8
extension crash with signal 11 on keyboard Bugzilla #1205 <https://bugs.freedesktop.org/show_bug.cgi?id=1205> Xevie client receives two KeyPress events on consumed keys when XKB is enabled Patch #2223 <https://bugs.freedesktop.org/attachment.cgi?id=2223> Fixes for both of these and some other Xevie bugs (Derek Wang - Sun Microsystems)
-rw-r--r--Xext/xevie.c356
-rw-r--r--dix/devices.c25
-rw-r--r--dix/events.c156
-rw-r--r--dix/main.c1
-rw-r--r--dix/privates.c38
-rw-r--r--hw/xfree86/loader/dixsym.c8
-rw-r--r--xkb/xkbActions.c61
7 files changed, 607 insertions, 38 deletions
diff --git a/Xext/xevie.c b/Xext/xevie.c
index 48b11f640..947e39f3a 100644
--- a/Xext/xevie.c
+++ b/Xext/xevie.c
@@ -1,6 +1,6 @@
/************************************************************
-Copyright 2003 Sun Microsystems, Inc.
+Copyright 2003-2005 Sun Microsystems, Inc.
All rights reserved.
@@ -30,6 +30,7 @@ or other dealings in this Software without prior written authorization
of the copyright holder.
************************************************************/
+/* $XdotOrg: $ */
#define NEED_REPLIES
#define NEED_EVENTS
@@ -45,6 +46,10 @@ of the copyright holder.
#include <X11/extensions/Xeviestr.h>
#include <X11/Xfuncproto.h>
#include "input.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "cursorstr.h"
+#include <X11/extensions/XKBsrv.h>
#include "../os/osdep.h"
@@ -66,6 +71,12 @@ DeviceIntPtr xeviemouse = NULL;
Mask xevieMask = 0;
int xevieEventSent = 0;
int xevieKBEventSent = 0;
+static unsigned int xevieServerGeneration;
+static int xevieDevicePrivateIndex;
+static Bool xevieModifiersOn = FALSE;
+
+#define XEVIEINFO(dev) ((xevieDeviceInfoPtr)dev->devPrivates[xevieDevicePrivateIndex].ptr)
+
Mask xevieFilters[128] =
{
NoSuchEvent, /* 0 */
@@ -77,18 +88,53 @@ Mask xevieFilters[128] =
PointerMotionMask /* MotionNotify (initial state) */
};
+typedef struct {
+ ProcessInputProc processInputProc;
+ ProcessInputProc realInputProc;
+ DeviceUnwrapProc unwrapProc;
+} xevieDeviceInfoRec, *xevieDeviceInfoPtr;
+
+typedef struct {
+ CARD32 time;
+ KeyClassPtr keyc;
+} xevieKeycQueueRec, *xevieKeycQueuePtr;
+
+#define KEYC_QUEUE_SIZE 100
+xevieKeycQueueRec keycq[KEYC_QUEUE_SIZE] = {0, NULL};
+static int keycqHead = 0, keycqTail = 0;
+
+static int ProcDispatch (ClientPtr), SProcDispatch (ClientPtr);
+static void ResetProc (ExtensionEntry*);
+
+static int ErrorBase;
+
+static Bool XevieStart(void);
static void XevieEnd(int clientIndex);
static void XevieClientStateCallback(CallbackListPtr *pcbl, pointer nulldata,
- pointer calldata);
+ pointer calldata);
static void XevieServerGrabStateCallback(CallbackListPtr *pcbl,
- pointer nulldata,
- pointer calldata);
+ pointer nulldata,
+ pointer calldata);
+
+static Bool XevieAdd(DeviceIntPtr device, pointer data);
+static void XevieWrap(DeviceIntPtr device, ProcessInputProc proc);
+static Bool XevieRemove(DeviceIntPtr device, pointer data);
+static void doSendEvent(xEvent *xE, DeviceIntPtr device);
+static void XeviePointerProcessInputProc(xEvent *xE, DeviceIntPtr dev,
+ int count);
+static void XevieKbdProcessInputProc(xEvent *xE, DeviceIntPtr dev, int count);
void
XevieExtensionInit ()
{
ExtensionEntry* extEntry;
+ if (serverGeneration != xevieServerGeneration) {
+ if ((xevieDevicePrivateIndex = AllocateDevicePrivateIndex()) == -1)
+ return;
+ xevieServerGeneration = serverGeneration;
+ }
+
if (!AddCallback(&ServerGrabCallback,XevieServerGrabStateCallback,NULL))
return;
@@ -147,10 +193,25 @@ int ProcStart (client)
xevieFlag = 1;
rep.pad1 = 1;
xevieClientIndex = client->index;
+ if(!keycq[0].time ) {
+ int i;
+ for(i=0; i<KEYC_QUEUE_SIZE; i++) {
+ keycq[i].keyc = xalloc(sizeof(KeyClassRec));
+ keycq[i].keyc->xkbInfo = xalloc(sizeof(XkbSrvInfoRec));
+ }
+ }
} else
return BadAlloc;
} else
return BadAccess;
+ if (!noXkbExtension) {
+ if (!XevieStart()) {
+ DeleteCallback(&ClientStateCallback,XevieClientStateCallback,NULL);
+ return BadAlloc;
+ }
+ }
+
+ xevieModifiersOn = FALSE;
rep.type = X_Reply;
rep.sequence_number = client->sequence;
@@ -164,7 +225,13 @@ int ProcEnd (client)
{
xXevieEndReply rep;
- XevieEnd(xevieClientIndex);
+ if (xevieFlag) {
+ if (client->index != xevieClientIndex)
+ return BadAccess;
+
+ DeleteCallback(&ClientStateCallback,XevieClientStateCallback,NULL);
+ XevieEnd(xevieClientIndex);
+ }
rep.type = X_Reply;
rep.sequence_number = client->sequence;
@@ -182,6 +249,9 @@ int ProcSend (client)
OsCommPtr oc;
static unsigned char lastDetail = 0, lastType = 0;
+ if (client->index != xevieClientIndex)
+ return BadAccess;
+
xE = (xEvent *)&stuff->event;
rep.type = X_Reply;
rep.sequence_number = client->sequence;
@@ -191,16 +261,19 @@ int ProcSend (client)
case KeyPress:
case KeyRelease:
xevieKBEventSent = 1;
-#ifdef XKB
if(noXkbExtension)
-#endif
CoreProcessKeyboardEvent (xE, xeviekb, 1);
+ else
+ doSendEvent(xE, inputInfo.keyboard);
break;
case ButtonPress:
case ButtonRelease:
case MotionNotify:
xevieEventSent = 1;
- CoreProcessPointerEvent(xE, xeviemouse, 1);
+ if(noXkbExtension)
+ CoreProcessPointerEvent(xE, xeviemouse, 1);
+ else
+ doSendEvent(xE, inputInfo.pointer);
break;
default:
break;
@@ -217,6 +290,9 @@ int ProcSelectInput (client)
REQUEST (xXevieSelectInputReq);
xXevieSelectInputReply rep;
+ if (client->index != xevieClientIndex)
+ return BadAccess;
+
xevieMask = (long)stuff->event_mask;
rep.type = X_Reply;
rep.sequence_number = client->sequence;
@@ -335,11 +411,154 @@ int SProcDispatch (client)
return BadRequest;
}
}
+/*======================================================*/
+
+#define WRAP_INPUTPROC(dev,store,inputProc) \
+ store->processInputProc = dev->public.processInputProc; \
+ dev->public.processInputProc = inputProc; \
+ store->realInputProc = dev->public.realInputProc; \
+ dev->public.realInputProc = inputProc;
+
+#define COND_WRAP_INPUTPROC(dev,store,inputProc) \
+ if (dev->public.processInputProc == dev->public.realInputProc) \
+ dev->public.processInputProc = inputProc; \
+ store->processInputProc = \
+ store->realInputProc = dev->public.realInputProc; \
+ dev->public.realInputProc = inputProc;
+
+#define UNWRAP_INPUTPROC(dev,restore) \
+ dev->public.processInputProc = restore->processInputProc; \
+ dev->public.realInputProc = restore->realInputProc;
+
+#define UNWRAP_INPUTPROC(dev,restore) \
+ dev->public.processInputProc = restore->processInputProc; \
+ dev->public.realInputProc = restore->realInputProc;
+
+#define XEVIE_EVENT(xE) \
+ (xevieFlag \
+ && !xeviegrabState \
+ && clients[xevieClientIndex] \
+ && (xevieMask & xevieFilters[xE->u.u.type]))
+
+
+static void
+sendEvent(ClientPtr pClient, xEvent *xE)
+{
+ if(pClient->swapped) {
+ xEvent eventTo;
+
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[xE->u.u.type & 0177]) (xE, &eventTo);
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+ } else {
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *) xE);
+ }
+}
+
+static void
+XevieKbdProcessInputProc(xEvent *xE, DeviceIntPtr dev, int count)
+{
+ int key, bit;
+ BYTE *kptr;
+ ProcessInputProc tmp;
+ KeyClassPtr keyc = dev->key;
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(dev);
+
+ if(XEVIE_EVENT(xE)) {
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (dev->key->modifierMap[xE->u.u.detail])
+ xevieModifiersOn = TRUE;
+
+ xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+ xE->u.keyButtonPointer.root = GetCurrentRootWindow()->drawable.id;
+ xE->u.keyButtonPointer.child = (xeviewin->firstChild)
+ ? xeviewin->firstChild->drawable.id:0;
+ xE->u.keyButtonPointer.rootX = xeviehot.x;
+ xE->u.keyButtonPointer.rootY = xeviehot.y;
+ xE->u.keyButtonPointer.state = keyc->state | inputInfo.pointer->button->state;
+ /* fix bug: sequence lost in Xlib */
+ xE->u.u.sequenceNumber = clients[xevieClientIndex]->sequence;
+ /* fix for bug5092586 */
+ if(!noXkbExtension) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr |= bit; break;
+ case KeyRelease: *kptr &= ~bit; break;
+ }
+ }
+ keycq[keycqHead].time = xE->u.keyButtonPointer.time;
+ memcpy(keycq[keycqHead].keyc, keyc, sizeof(KeyClassRec) - sizeof(KeyClassPtr));
+ memcpy(keycq[keycqHead].keyc->xkbInfo, keyc->xkbInfo, sizeof(XkbSrvInfoRec));
+ if(++keycqHead >=KEYC_QUEUE_SIZE)
+ keycqHead = 0;
+ sendEvent(clients[xevieClientIndex], xE);
+ return;
+ }
+
+ tmp = dev->public.realInputProc;
+ UNWRAP_INPUTPROC(dev,xeviep);
+ dev->public.processInputProc(xE,dev,count);
+ COND_WRAP_INPUTPROC(dev,xeviep,tmp);
+}
+
+static void
+XeviePointerProcessInputProc(xEvent *xE, DeviceIntPtr dev, int count)
+{
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(dev);
+ ProcessInputProc tmp;
+
+ if (XEVIE_EVENT(xE)) {
+ /* fix bug: sequence lost in Xlib */
+ xE->u.u.sequenceNumber = clients[xevieClientIndex]->sequence;
+ sendEvent(clients[xevieClientIndex], xE);
+ return;
+ }
+
+ tmp = dev->public.realInputProc;
+ UNWRAP_INPUTPROC(dev,xeviep);
+ dev->public.processInputProc(xE,dev,count);
+ COND_WRAP_INPUTPROC(dev,xeviep,tmp);
+}
+
+static Bool
+XevieStart(void)
+{
+ ProcessInputProc prp;
+ prp = XevieKbdProcessInputProc;
+ if (!XevieAdd(inputInfo.keyboard,&prp))
+ return FALSE;
+ prp = XeviePointerProcessInputProc;
+ if (!XevieAdd(inputInfo.pointer,&prp))
+ return FALSE;
+
+ return TRUE;
+}
+
static void
XevieEnd(int clientIndex)
{
if (!clientIndex || clientIndex == xevieClientIndex) {
+
+ if(!noXkbExtension) {
+
+ XevieRemove(inputInfo.keyboard,NULL);
+
+ inputInfo.keyboard->public.processInputProc = CoreProcessKeyboardEvent;
+ inputInfo.keyboard->public.realInputProc = CoreProcessKeyboardEvent;
+ XkbSetExtension(inputInfo.keyboard,ProcessKeyboardEvent);
+
+
+ XevieRemove(inputInfo.pointer,NULL);
+
+ inputInfo.pointer->public.processInputProc = CoreProcessPointerEvent;
+ inputInfo.pointer->public.realInputProc = CoreProcessPointerEvent;
+ XkbSetExtension(inputInfo.pointer,ProcessPointerEvent);
+ }
+
xevieFlag = 0;
xevieClientIndex = 0;
DeleteCallback (&ClientStateCallback, XevieClientStateCallback, NULL);
@@ -368,4 +587,125 @@ XevieServerGrabStateCallback(CallbackListPtr *pcbl, pointer nulldata,
xeviegrabState = FALSE;
}
+#define UNWRAP_UNWRAPPROC(device,proc_store) \
+ device->unwrapProc = proc_store;
+
+#define WRAP_UNWRAPPROC(device,proc_store,proc) \
+ proc_store = device->unwrapProc; \
+ device->unwrapProc = proc;
+
+static void
+xevieUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, pointer data)
+{
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(device);
+ ProcessInputProc tmp = device->public.processInputProc;
+
+ UNWRAP_INPUTPROC(device,xeviep);
+ UNWRAP_UNWRAPPROC(device,xeviep->unwrapProc);
+ proc(device,data);
+ WRAP_INPUTPROC(device,xeviep,tmp);
+ WRAP_UNWRAPPROC(device,xeviep->unwrapProc,xevieUnwrapProc);
+}
+
+static Bool
+XevieUnwrapAdd(DeviceIntPtr device, void* data)
+{
+ if (device->unwrapProc)
+ device->unwrapProc(device,XevieUnwrapAdd,data);
+ else {
+ ProcessInputProc *ptr = data;
+ XevieWrap(device,*ptr);
+ }
+
+ return TRUE;
+}
+
+static Bool
+XevieAdd(DeviceIntPtr device, void* data)
+{
+ xevieDeviceInfoPtr xeviep;
+
+ if (!AllocateDevicePrivate(device, xevieDevicePrivateIndex))
+ return FALSE;
+
+ xeviep = xalloc (sizeof (xevieDeviceInfoRec));
+ if (!xeviep)
+ return FALSE;
+
+ device->devPrivates[xevieDevicePrivateIndex].ptr = xeviep;
+ XevieUnwrapAdd(device, data);
+
+ return TRUE;
+}
+
+static Bool
+XevieRemove(DeviceIntPtr device,pointer data)
+{
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(device);
+
+ if (!xeviep) return TRUE;
+
+ UNWRAP_INPUTPROC(device,xeviep);
+ UNWRAP_UNWRAPPROC(device,xeviep->unwrapProc);
+
+ xfree(xeviep);
+ device->devPrivates[xevieDevicePrivateIndex].ptr = NULL;
+ return TRUE;
+}
+
+static void
+XevieWrap(DeviceIntPtr device, ProcessInputProc proc)
+{
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(device);
+
+ WRAP_INPUTPROC(device,xeviep,proc);
+ WRAP_UNWRAPPROC(device,xeviep->unwrapProc,xevieUnwrapProc);
+}
+
+static void
+doSendEvent(xEvent *xE, DeviceIntPtr dev)
+{
+ xevieDeviceInfoPtr xeviep = XEVIEINFO(dev);
+ ProcessInputProc tmp = dev->public.realInputProc;
+ if (((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))
+ && !xevieModifiersOn) {
+ KeyClassPtr keyc = dev->key;
+ CARD8 realModes = dev->key->modifierMap[xE->u.u.detail];
+ int notFound = 0;
+ /* if some events are consumed by client, move the queue tail pointer to the current
+ event which just comes back from Xevie client .
+ */
+ if(keycq[keycqTail].time != xE->u.keyButtonPointer.time) {
+ while(keycq[keycqTail].time != xE->u.keyButtonPointer.time) {
+ if(++keycqTail >= KEYC_QUEUE_SIZE)
+ keycqTail = 0;
+ if(keycqTail == keycqHead) {
+ notFound = 1;
+ break;
+ }
+ }
+ }
+ if(!notFound) {
+ dev->key = keycq[keycqTail].keyc;
+ if(++keycqTail >= KEYC_QUEUE_SIZE)
+ keycqTail = 0;
+ }
+ dev->key->modifierMap[xE->u.u.detail] = 0;
+
+ UNWRAP_INPUTPROC(dev,xeviep);
+ dev->public.processInputProc(xE,dev,1);
+ COND_WRAP_INPUTPROC(dev,xeviep,tmp);
+ dev->key->modifierMap[xE->u.u.detail] = realModes;
+ dev->key = keyc;
+ if(notFound) {
+ DeleteCallback(&ClientStateCallback,XevieClientStateCallback,NULL);
+ XevieEnd(xevieClientIndex);
+ ErrorF("Error: Xevie keyc queue size is not enough, disable Xevie\n");
+ }
+ } else {
+ UNWRAP_INPUTPROC(dev,xeviep);
+ dev->public.processInputProc(xE,dev,1);
+ COND_WRAP_INPUTPROC(dev,xeviep,tmp);
+ }
+}
diff --git a/dix/devices.c b/dix/devices.c
index 3bc098158..d99fcdd36 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -48,6 +48,7 @@ SOFTWARE.
/* $Xorg: devices.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */
+/* $XdotOrg: $ */
#include <X11/X.h>
#include "misc.h"
@@ -120,6 +121,8 @@ _AddInputDevice(DeviceProc deviceProc, Bool autoStart)
#ifdef XKB
dev->xkb_interest= NULL;
#endif
+ dev->nPrivates = 0;
+ dev->devPrivates = dev->unwrapProc = NULL;
inputInfo.off_devices = dev;
return dev;
}
@@ -352,13 +355,10 @@ _RegisterPointerDevice(DeviceIntPtr device)
{
inputInfo.pointer = device;
#ifdef XKB
- if (noXkbExtension) {
- device->public.processInputProc = CoreProcessPointerEvent;
- device->public.realInputProc = CoreProcessPointerEvent;
- } else {
- device->public.processInputProc = ProcessPointerEvent;
- device->public.realInputProc = ProcessPointerEvent;
- }
+ device->public.processInputProc = CoreProcessPointerEvent;
+ device->public.realInputProc = CoreProcessPointerEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessPointerEvent);
#else
device->public.processInputProc = ProcessPointerEvent;
device->public.realInputProc = ProcessPointerEvent;
@@ -378,13 +378,10 @@ _RegisterKeyboardDevice(DeviceIntPtr device)
{
inputInfo.keyboard = device;
#ifdef XKB
- if (noXkbExtension) {
- device->public.processInputProc = CoreProcessKeyboardEvent;
- device->public.realInputProc = CoreProcessKeyboardEvent;
- } else {
- device->public.processInputProc = ProcessKeyboardEvent;
- device->public.realInputProc = ProcessKeyboardEvent;
- }
+ device->public.processInputProc = CoreProcessKeyboardEvent;
+ device->public.realInputProc = CoreProcessKeyboardEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessKeyboardEvent);
#else
device->public.processInputProc = ProcessKeyboardEvent;
device->public.realInputProc = ProcessKeyboardEvent;
diff --git a/dix/events.c b/dix/events.c
index d80b249bb..fcd6eec29 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -76,6 +76,39 @@ Equipment Corporation.
******************************************************************/
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
#include <X11/X.h>
@@ -425,7 +458,13 @@ XineramaCheckVirtualMotion(
if (qe)
{
sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
NullWindow;
@@ -462,12 +501,24 @@ XineramaCheckVirtualMotion(
lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = lims.x1;
else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = lims.x2 - 1;
if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = lims.y1;
else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = lims.y2 - 1;
if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
@@ -497,16 +548,33 @@ XineramaCheckMotion(xEvent *xE)
panoramiXdataPtr[0].x;
XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
panoramiXdataPtr[0].y;
-
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = XE_KBPTR.rootY;
if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = sprite.physLimits.x1;
else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = sprite.physLimits.x2 - 1;
if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = sprite.physLimits.y1;
else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = sprite.physLimits.y2 - 1;
if (sprite.hotShape)
@@ -523,6 +591,9 @@ XineramaCheckMotion(xEvent *xE)
XE_KBPTR.rootY = sprite.hot.y;
}
+#ifdef XEVIE
+ xeviewin =
+#endif
sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
if (sprite.win != prevSpriteWin)
@@ -744,7 +815,13 @@ CheckVirtualMotion(
if (qe)
{
sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
NullWindow;
@@ -756,16 +833,31 @@ CheckVirtualMotion(
if (sprite.hot.pScreen != pWin->drawable.pScreen)
{
sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+ xeviehot.x = xeviehot.y = 0;
+#endif
sprite.hot.x = sprite.hot.y = 0;
}
lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = lims.x1;
else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = lims.x2 - 1;
if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = lims.y1;
else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = lims.y2 - 1;
#ifdef SHAPE
if (wBoundingShape(pWin))
@@ -1951,15 +2043,33 @@ CheckMotion(xEvent *xE)
sprite.hot.pScreen = sprite.hotPhys.pScreen;
ROOT = WindowTable[sprite.hot.pScreen->myNum];
}
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = XE_KBPTR.rootY;
if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = sprite.physLimits.x1;
else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
sprite.hot.x = sprite.physLimits.x2 - 1;
if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = sprite.physLimits.y1;
else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
sprite.hot.y = sprite.physLimits.y2 - 1;
#ifdef SHAPE
if (sprite.hotShape)
@@ -1977,6 +2087,9 @@ CheckMotion(xEvent *xE)
XE_KBPTR.rootY = sprite.hot.y;
}
+#ifdef XEVIE
+ xeviewin =
+#endif
sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
#ifdef notyet
if (!(sprite.win->deliverableEvents &
@@ -2056,6 +2169,9 @@ DefineInitialRootWindow(register WindowPtr win)
sprite.hot = sprite.hotPhys;
sprite.hotLimits.x2 = pScreen->width;
sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
sprite.win = win;
sprite.current = wCursor (win);
spriteTraceGood = 1;
@@ -2641,20 +2757,13 @@ ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int coun
{} else {
#ifdef XKB
if(!noXkbExtension)
- xevieKBEventSent = 0;
+ xevieKBEventSent = 1;
#endif
if(!xevieKBEventSent)
{
xeviekb = keybd;
if(!rootWin) {
- WindowPtr pWin = xeviewin->parent;
- while(pWin) {
- if(!pWin->parent) {
- rootWin = pWin->drawable.id;
- break;
- }
- pWin = pWin->parent;
- };
+ rootWin = GetCurrentRootWindow()->drawable.id;
}
xE->u.keyButtonPointer.event = xeviewin->drawable.id;
xE->u.keyButtonPointer.root = rootWin;
@@ -2668,8 +2777,8 @@ drawable.id:0;
if(noXkbExtension)
#endif
return;
- }else {
- xevieKBEventSent = 0;
+ } else {
+ xevieKBEventSent = 0;
}
}
}
@@ -2686,13 +2795,31 @@ drawable.id:0;
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
}
}
- XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+ if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+ && !noXkbExtension
+#endif
+ )))
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
XE_KBPTR.rootX = sprite.hot.x;
XE_KBPTR.rootY = sprite.hot.y;
key = xE->u.u.detail;
kptr = &keyc->down[key >> 3];
bit = 1 << (key & 7);
modifiers = keyc->modifierMap[key];
+#ifdef XKB
+ if(!noXkbExtension && !xeviegrabState &&
+ xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr &= ~bit; break;
+ case KeyRelease: *kptr |= bit; break;
+ }
+ }
+#endif
+
#ifdef DEBUG
if ((xkbDebugFlags&0x4)&&
((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
@@ -3951,6 +4078,9 @@ InitEvents()
spriteTraceGood = 0;
lastEventMask = OwnerGrabButtonMask;
filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+ xeviewin =
+#endif
sprite.win = NullWindow;
sprite.current = NullCursor;
sprite.hotLimits.x1 = 0;
diff --git a/dix/main.c b/dix/main.c
index 41c626ca6..87ff45a36 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -362,6 +362,7 @@ main(int argc, char *argv[], char *envp[])
#endif
ResetColormapPrivates();
ResetFontPrivateIndex();
+ ResetDevicePrivateIndex();
InitCallbackManager();
InitVisualWrap();
InitOutput(&screenInfo, argc, argv);
diff --git a/dix/privates.c b/dix/privates.c
index 1353e29aa..a8f3ee9aa 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -1,4 +1,5 @@
/* $Xorg: privates.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: $ */
/*
Copyright 1993, 1998 The Open Group
@@ -39,6 +40,7 @@ from The Open Group.
#include "colormapst.h"
#include "servermd.h"
#include "site.h"
+#include "inputstr.h"
/*
* See the Wrappers and devPrivates section in "Definition of the
@@ -354,3 +356,39 @@ AllocateColormapPrivateIndex (InitCmapPrivFunc initPrivFunc)
return index;
}
+
+/*
+ * device private machinery
+ */
+
+static int devicePrivateIndex = 0;
+
+int
+AllocateDevicePrivateIndex()
+{
+ return devicePrivateIndex++;
+}
+
+Bool
+AllocateDevicePrivate(DeviceIntPtr device, int index)
+{
+ if (device->nPrivates < ++index) {
+ DevUnion *nprivs = (DevUnion *) xrealloc(device->devPrivates,
+ index * sizeof(DevUnion));
+ if (!nprivs)
+ return FALSE;
+ device->devPrivates = nprivs;
+ bzero(&nprivs[device->nPrivates], sizeof(DevUnion)
+ * (index - device->nPrivates));
+ device->nPrivates = index;
+ return TRUE;
+ } else {
+ return TRUE;
+ }
+}
+
+void
+ResetDevicePrivateIndex(void)
+{
+ devicePrivateIndex = 0;
+}
diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c
index 9829e3abf..0a90e7e77 100644
--- a/hw/xfree86/loader/dixsym.c
+++ b/hw/xfree86/loader/dixsym.c
@@ -54,6 +54,7 @@
#include "sym.h"
#include "colormap.h"
#include "cursor.h"
+#include "cursorstr.h"
#include "dix.h"
#include "dixevents.h"
#include "dixfont.h"
@@ -168,6 +169,7 @@ LOOKUP dixLookupTab[] = {
SYMFUNC(PointerConfinedToScreen)
SYMFUNC(TryClientEvents)
SYMFUNC(WriteEventsToClient)
+ SYMFUNC(GetCurrentRootWindow)
SYMFUNC(GetSpritePosition)
SYMFUNC(GetSpriteWindow)
SYMFUNC(GetSpriteCursor)
@@ -187,6 +189,10 @@ LOOKUP dixLookupTab[] = {
SYMFUNC(DeclareExtensionSecurity)
SYMFUNC(MinorOpcodeOfRequest)
SYMFUNC(StandardMinorOpcode)
+#ifdef XEVIE
+ SYMVAR(xeviehot)
+ SYMVAR(xeviewin)
+#endif
/* gc.c */
SYMFUNC(CopyGC)
SYMFUNC(CreateGC)
@@ -252,6 +258,8 @@ LOOKUP dixLookupTab[] = {
SYMFUNC(AllocateWindowPrivateIndex)
SYMFUNC(AllocateScreenPrivateIndex)
SYMFUNC(AllocateColormapPrivateIndex)
+ SYMFUNC(AllocateDevicePrivateIndex)
+ SYMFUNC(AllocateDevicePrivate)
#ifdef PIXPRIV
SYMFUNC(AllocatePixmapPrivateIndex)
SYMFUNC(AllocatePixmapPrivate)
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index f7fa0af28..f45dd818f 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1,4 +1,5 @@
/* $Xorg: xkbActions.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */
+/* $XdotOrg: $ */
/************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
@@ -38,6 +39,48 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "xkb.h"
#include <ctype.h>
+static unsigned int _xkbServerGeneration;
+int xkbDevicePrivateIndex = -1;
+
+void
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
+ pointer data)
+{
+ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+ ProcessInputProc tmp = device->public.processInputProc;
+ if(xkbPrivPtr->unwrapProc)
+ xkbPrivPtr->unwrapProc = NULL;
+
+ UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr);
+ proc(device,data);
+ WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ tmp,xkbUnwrapProc);
+}
+
+
+void
+XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
+{
+ xkbDeviceInfoPtr xkbPrivPtr;
+
+ if (serverGeneration != _xkbServerGeneration) {
+ if ((xkbDevicePrivateIndex = AllocateDevicePrivateIndex()) == -1)
+ return;
+ _xkbServerGeneration = serverGeneration;
+ }
+ if (!AllocateDevicePrivate(device, xkbDevicePrivateIndex))
+ return;
+
+ xkbPrivPtr = (xkbDeviceInfoPtr) xalloc(sizeof(xkbDeviceInfoRec));
+ if (!xkbPrivPtr)
+ return;
+ xkbPrivPtr->unwrapProc = NULL;
+
+ device->devPrivates[xkbDevicePrivateIndex].ptr = xkbPrivPtr;
+ WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ proc,xkbUnwrapProc);
+}
+
#ifdef XINPUT
extern void ProcessOtherEvent(
xEvent * /* xE */,
@@ -822,6 +865,7 @@ xEvent ev;
int x,y;
XkbStateRec old;
unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
if ((filter->keycode!=0)&&(filter->keycode!=keycode))
return 1;
@@ -870,7 +914,10 @@ unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0;
realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
- CoreProcessKeyboardEvent(&ev,xkbi->device,1);
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+ xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
if ( mask || mods ) {
@@ -908,7 +955,10 @@ unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0;
realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
- CoreProcessKeyboardEvent(&ev,xkbi->device,1);
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+ xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
if ( mask || mods ) {
@@ -1102,6 +1152,8 @@ Bool pressEvent;
#ifdef XINPUT
Bool xiEvent;
#endif
+
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
keyc= kbd->key;
xkbi= keyc->xkbInfo;
@@ -1244,7 +1296,10 @@ Bool xiEvent;
if (keyEvent) {
realMods = keyc->modifierMap[key];
keyc->modifierMap[key] = 0;
- CoreProcessKeyboardEvent(xE,dev,count);
+ UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr);
+ dev->public.processInputProc(xE,dev,count);
+ COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
keyc->modifierMap[key] = realMods;
}
else CoreProcessPointerEvent(xE,dev,count);