diff options
author | Alan Coopersmith <Alan.Coopersmith@sun.com> | 2005-05-22 01:12:49 +0000 |
---|---|---|
committer | Alan Coopersmith <Alan.Coopersmith@sun.com> | 2005-05-22 01:12:49 +0000 |
commit | 62343f5162066f19ca6e62d1c85a4a40d45b3295 (patch) | |
tree | 801fac4154f316c82e9cb25997bbdc2fd6c81427 | |
parent | a8a61bbe22361b12d4a2dd511894987a338e3eef (diff) |
Bugzilla #2800 <https://bugs.freedesktop.org/show_bug.cgi?id=2800> Xevie
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.c | 356 | ||||
-rw-r--r-- | dix/devices.c | 25 | ||||
-rw-r--r-- | dix/events.c | 156 | ||||
-rw-r--r-- | dix/main.c | 1 | ||||
-rw-r--r-- | dix/privates.c | 38 | ||||
-rw-r--r-- | hw/xfree86/loader/dixsym.c | 8 | ||||
-rw-r--r-- | xkb/xkbActions.c | 61 |
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); |