From add881931f2e702fb1952f4e1baba04b3dc536ee Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 18 Apr 2016 13:02:34 +0200 Subject: hw/nxagent/NXevents.c: Shrink file, drop duplicate code that can identically be found in dix/events.c. --- nx-X11/programs/Xserver/hw/nxagent/NXevents.c | 5085 ++----------------------- 1 file changed, 335 insertions(+), 4750 deletions(-) (limited to 'nx-X11/programs/Xserver/hw/nxagent/NXevents.c') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c index 3142233ac..76766f490 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c @@ -128,59 +128,9 @@ of the copyright holder. /* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */ -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include "Xlib.h" -#include "misc.h" -#include "resource.h" -#define NEED_EVENTS -#define NEED_REPLIES -#include -#include "windowstr.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "cursorstr.h" - -#include "dixstruct.h" -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif -#include "globals.h" - -#ifdef XKB -#include -extern Bool XkbFilterEvents(ClientPtr, int, xEvent *); -#endif - -#ifdef XCSECURITY -#define _SECURITY_SERVER -#include -#endif - -#ifdef XEVIE -extern int xevieFlag; -extern int xevieClientIndex; -extern DeviceIntPtr xeviemouse; -extern DeviceIntPtr xeviekb; -extern Mask xevieMask; -extern Mask xevieFilters[128]; -extern int xevieEventSent; -extern int xevieKBEventSent; -int xeviegrabState = 0; -xEvent *xeviexE; -#endif +#include -#include -#include "exevents.h" -#include "extnsionst.h" - -#include "dixevents.h" -#include "dixgrabs.h" -#include "../../dix/dispatch.h" +#include "../../dix/events.c" #include @@ -188,4324 +138,400 @@ xEvent *xeviexE; #include "Windows.h" #include "Args.h" -#ifdef NX_DEBUG_INPUT -extern int nxagentDebugInput; -extern int nxagentDebugInputDevices; -#endif - extern Display *nxagentDisplay; extern WindowPtr nxagentLastEnteredWindow; -#define EXTENSION_EVENT_BASE 64 - -#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ -#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask ) -#define AllButtonsMask ( \ - Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) -#define MotionMask ( \ - PointerMotionMask | Button1MotionMask | \ - Button2MotionMask | Button3MotionMask | Button4MotionMask | \ - Button5MotionMask | ButtonMotionMask ) -#define PropagateMask ( \ - KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ - MotionMask ) -#define PointerGrabMask ( \ - ButtonPressMask | ButtonReleaseMask | \ - EnterWindowMask | LeaveWindowMask | \ - PointerMotionHintMask | KeymapStateMask | \ - MotionMask ) -#define AllModifiersMask ( \ - ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ - Mod3Mask | Mod4Mask | Mod5Mask ) -#define AllEventMasks (lastEventMask|(lastEventMask-1)) -/* - * The following relies on the fact that the ButtonMotionMasks are equal - * to the corresponding ButtonMasks from the current modifier/button state. - */ -#define Motion_Filter(class) (PointerMotionMask | \ - (class)->state | (class)->motionMask) - - -#define WID(w) ((w) ? ((w)->drawable.id) : 0) - -#define XE_KBPTR (xE->u.keyButtonPointer) - - -#define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) - -CallbackListPtr EventCallback; -CallbackListPtr DeviceEventCallback; - -#define DNPMCOUNT 8 - -Mask DontPropagateMasks[DNPMCOUNT]; -static int DontPropagateRefCnts[DNPMCOUNT]; - -#ifdef DEBUG -static debug_events = 0; -#endif -InputInfo inputInfo; - -static struct { - QdEventPtr pending, *pendtail; - DeviceIntPtr replayDev; /* kludgy rock to put flag for */ - WindowPtr replayWin; /* ComputeFreezes */ - Bool playingEvents; - TimeStamp time; -} syncEvents; - -/* - * The window trace information is used to avoid having to compute all the - * windows between the root and the current pointer window each time a button - * or key goes down. The grabs on each of those windows must be checked. - */ -static WindowPtr *spriteTrace = (WindowPtr *)NULL; -#define ROOT spriteTrace[0] -static int spriteTraceSize = 0; -static int spriteTraceGood; - -static struct { - CursorPtr current; - BoxRec hotLimits; /* logical constraints of hot spot */ - Bool confined; /* confined to screen */ -#if defined(SHAPE) || defined(PANORAMIX) - RegionPtr hotShape; /* additional logical shape constraint */ -#endif - BoxRec physLimits; /* physical constraints of hot spot */ - WindowPtr win; /* window of logical position */ - HotSpot hot; /* logical pointer position */ - HotSpot hotPhys; /* physical pointer position */ -#ifdef PANORAMIX - ScreenPtr screen; /* all others are in Screen 0 coordinates */ - RegionRec Reg1; /* Region 1 for confining motion */ - RegionRec Reg2; /* Region 2 for confining virtual motion */ - WindowPtr windows[MAXSCREENS]; - WindowPtr confineWin; /* confine window */ -#endif -} sprite; /* info about the cursor sprite */ - -#ifdef XEVIE -WindowPtr xeviewin; -HotSpot xeviehot; -#endif - -static void DoEnterLeaveEvents( - WindowPtr fromWin, - WindowPtr toWin, - int mode -); - -static WindowPtr XYToWindow( - int x, - int y -); - -extern int lastEvent; - -static Mask lastEventMask; - -#ifdef XINPUT -extern int DeviceMotionNotify; -#endif - -#define CantBeFiltered NoEventMask -static Mask filters[128] = -{ - NoSuchEvent, /* 0 */ - NoSuchEvent, /* 1 */ - KeyPressMask, /* KeyPress */ - KeyReleaseMask, /* KeyRelease */ - ButtonPressMask, /* ButtonPress */ - ButtonReleaseMask, /* ButtonRelease */ - PointerMotionMask, /* MotionNotify (initial state) */ - EnterWindowMask, /* EnterNotify */ - LeaveWindowMask, /* LeaveNotify */ - FocusChangeMask, /* FocusIn */ - FocusChangeMask, /* FocusOut */ - KeymapStateMask, /* KeymapNotify */ - ExposureMask, /* Expose */ - CantBeFiltered, /* GraphicsExpose */ - CantBeFiltered, /* NoExpose */ - VisibilityChangeMask, /* VisibilityNotify */ - SubstructureNotifyMask, /* CreateNotify */ - StructureAndSubMask, /* DestroyNotify */ - StructureAndSubMask, /* UnmapNotify */ - StructureAndSubMask, /* MapNotify */ - SubstructureRedirectMask, /* MapRequest */ - StructureAndSubMask, /* ReparentNotify */ - StructureAndSubMask, /* ConfigureNotify */ - SubstructureRedirectMask, /* ConfigureRequest */ - StructureAndSubMask, /* GravityNotify */ - ResizeRedirectMask, /* ResizeRequest */ - StructureAndSubMask, /* CirculateNotify */ - SubstructureRedirectMask, /* CirculateRequest */ - PropertyChangeMask, /* PropertyNotify */ - CantBeFiltered, /* SelectionClear */ - CantBeFiltered, /* SelectionRequest */ - CantBeFiltered, /* SelectionNotify */ - ColormapChangeMask, /* ColormapNotify */ - CantBeFiltered, /* ClientMessage */ - CantBeFiltered /* MappingNotify */ -}; - -static CARD8 criticalEvents[32] = +void +ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, + TimeStamp time, Bool autoGrab) { - 0x7c /* key and button events */ -}; - -#ifdef PANORAMIX - -static void ConfineToShape(RegionPtr shape, int *px, int *py); -static void SyntheticMotion(int x, int y); -static void PostNewCursor(void); - -static Bool -XineramaSetCursorPosition( - int x, - int y, - Bool generateEvent -){ - ScreenPtr pScreen; - BoxRec box; - int i; - - /* x,y are in Screen 0 coordinates. We need to decide what Screen - to send the message too and what the coordinates relative to - that screen are. */ - - pScreen = sprite.screen; - x += panoramiXdataPtr[0].x; - y += panoramiXdataPtr[0].y; + WindowPtr oldWin = (mouse->grab) ? mouse->grab->window + : sprite.win; - if(!RegionContainsPoint(&XineramaScreenRegions[pScreen->myNum], - x, y, &box)) + if (grab->confineTo) { - FOR_NSCREENS(i) - { - if(i == pScreen->myNum) - continue; - if(RegionContainsPoint(&XineramaScreenRegions[i], x, y, &box)) - { - pScreen = screenInfo.screens[i]; - break; - } - } + if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) + sprite.hotPhys.x = sprite.hotPhys.y = 0; + ConfineCursorToWindow(grab->confineTo, FALSE, TRUE); } + DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab); + mouse->valuator->motionHintWindow = NullWindow; + if (syncEvents.playingEvents) + mouse->grabTime = syncEvents.time; + else + mouse->grabTime = time; + if (grab->cursor) + grab->cursor->refcnt++; + mouse->activeGrab = *grab; + mouse->grab = &mouse->activeGrab; + mouse->fromPassiveGrab = autoGrab; + PostNewCursor(); + CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); - sprite.screen = pScreen; - sprite.hotPhys.x = x - panoramiXdataPtr[0].x; - sprite.hotPhys.y = y - panoramiXdataPtr[0].y; - x -= panoramiXdataPtr[pScreen->myNum].x; - y -= panoramiXdataPtr[pScreen->myNum].y; - - return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent); -} - - -static void -XineramaConstrainCursor(void) -{ - ScreenPtr pScreen = sprite.screen; - BoxRec newBox = sprite.physLimits; - - /* Translate the constraining box to the screen - the sprite is actually on */ - newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x; - newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x; - newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; - newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; - - (* pScreen->ConstrainCursor)(pScreen, &newBox); -} - -static void -XineramaCheckPhysLimits( - CursorPtr cursor, - Bool generateEvents -){ - HotSpot new; - - if (!cursor) - return; - - new = sprite.hotPhys; + #ifdef NXAGENT_SERVER - /* I don't care what the DDX has to say about it */ - sprite.physLimits = sprite.hotLimits; + /* + * If grab is synchronous, events are delivered to clients only if they send + * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the + * delivered event is saved in a queue and replayed later, when grab is released. + * We should export sync grab to X as async in order to avoid events to be + * queued twice, in the agent and in the X server. This solution have a drawback: + * replayed events are not delivered to that application that are not clients of + * the agent. + * A different solution could be to make the grab asynchronous in the agent and + * to export it as synchronous. But this seems to be less safe. + * + * To make internal grab asynchronous, change previous line as follows. + * + * if (nxagentOption(Rootless)) + * { + * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode); + * } + * else + * { + * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); + * } + */ - /* constrain the pointer to those limits */ - if (new.x < sprite.physLimits.x1) - new.x = sprite.physLimits.x1; - else - if (new.x >= sprite.physLimits.x2) - new.x = sprite.physLimits.x2 - 1; - if (new.y < sprite.physLimits.y1) - new.y = sprite.physLimits.y1; - else - if (new.y >= sprite.physLimits.y2) - new.y = sprite.physLimits.y2 - 1; + if (nxagentOption(Rootless) == 1) + { + /* + * FIXME: We should use the correct value + * for the cursor. Temporarily we set it + * to None. + */ - if (sprite.hotShape) /* more work if the shape is a mess */ - ConfineToShape(sprite.hotShape, &new.x, &new.y); + int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource, + nxagentCollectGrabPointerPredicate); - if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y)) - { - XineramaSetCursorPosition (new.x, new.y, generateEvents); - if (!generateEvents) - SyntheticMotion(new.x, new.y); + NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window), + 1, grab -> eventMask & PointerGrabMask, + GrabModeAsync, GrabModeAsync, (grab -> confineTo) ? + nxagentWindow(grab -> confineTo) : None, + None, CurrentTime); } - /* Tell DDX what the limits are */ - XineramaConstrainCursor(); + #endif } - -static Bool -XineramaSetWindowPntrs(WindowPtr pWin) +void +DeactivatePointerGrab(register DeviceIntPtr mouse) { - if(pWin == screenInfo.screens[0]->root) { - int i; - for (i = 0; i < PanoramiXNumScreens; i++) - sprite.windows[i] = screenInfo.screens[i]->root; - } else { - PanoramiXRes *win; - int i; - - win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW); - - if(!win) - return FALSE; - - for(i = 0; i < PanoramiXNumScreens; i++) { - sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW); - if(!sprite.windows[i]) /* window is being unmapped */ - return FALSE; - } - } - return TRUE; -} - -static void -XineramaCheckVirtualMotion( - QdEventPtr qe, - WindowPtr pWin -){ + register GrabPtr grab = mouse->grab; + register DeviceIntPtr dev; - if (qe) + mouse->valuator->motionHintWindow = NullWindow; + mouse->grab = NullGrab; + mouse->sync.state = NOT_GRABBED; + mouse->fromPassiveGrab = FALSE; + for (dev = inputInfo.devices; dev; dev = dev->next) { - 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; + if (dev->sync.other == grab) + dev->sync.other = NullGrab; } - if (pWin) - { - int x, y, off_x, off_y, i; - BoxRec lims; - - if(!XineramaSetWindowPntrs(pWin)) - return; - - i = PanoramiXNumScreens - 1; - - RegionCopy(&sprite.Reg2, - &sprite.windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; - - if(x || y) - RegionTranslate(&sprite.Reg2, x, y); - - RegionUnion(&sprite.Reg2, &sprite.Reg2, - &sprite.windows[i]->borderSize); - - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } - - lims = *RegionExtents(&sprite.Reg2); + DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab); + if (grab->confineTo) + ConfineCursorToWindow(ROOT, FALSE, FALSE); + PostNewCursor(); + if (grab->cursor) + FreeCursor(grab->cursor, (Cursor)0); + ComputeFreezes(); - 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 NXAGENT_SERVER - if (RegionNumRects(&sprite.Reg2) > 1) - ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y); + if (nxagentOption(Rootless) == 1) + { + XUngrabPointer(nxagentDisplay, CurrentTime); - if (qe) - { - qe->pScreen = sprite.hot.pScreen; - qe->event->u.keyButtonPointer.rootX = sprite.hot.x; - qe->event->u.keyButtonPointer.rootY = sprite.hot.y; - } + if (sprite.win == ROOT) + { + mouse -> button -> state &= + ~(Button1Mask | Button2Mask | Button3Mask | + Button4Mask | Button5Mask); + } } + + #endif } +// int +// ProcAllowEvents(register ClientPtr client) +// { +// TimeStamp time; +// DeviceIntPtr mouse = inputInfo.pointer; +// DeviceIntPtr keybd = inputInfo.keyboard; +// REQUEST(xAllowEventsReq); +// +// REQUEST_SIZE_MATCH(xAllowEventsReq); +// time = ClientTimeToServerTime(stuff->time); +// switch (stuff->mode) +// { +// case ReplayPointer: +// AllowSome(client, time, mouse, NOT_GRABBED); +// break; +// case SyncPointer: +// AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); +// break; +// case AsyncPointer: +// AllowSome(client, time, mouse, THAWED); +// break; +// case ReplayKeyboard: +// AllowSome(client, time, keybd, NOT_GRABBED); +// break; +// case SyncKeyboard: +// AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); +// break; +// case AsyncKeyboard: +// AllowSome(client, time, keybd, THAWED); +// break; +// case SyncBoth: +// AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); +// break; +// case AsyncBoth: +// AllowSome(client, time, keybd, THAWED_BOTH); +// break; +// default: +// client->errorValue = stuff->mode; +// return BadValue; +// } +// +// /* +// * This is not necessary if we export grab to X as asynchronous. +// * +// * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard && +// * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard) +// * { +// * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime); +// * } +// */ +// +// return Success; +// } -static Bool -XineramaCheckMotion(xEvent *xE) +static WindowPtr +XYToWindow(int x, int y) { - WindowPtr prevSpriteWin = sprite.win; - - if (xE && !syncEvents.playingEvents) - { - /* Motion events entering DIX get translated to Screen 0 - coordinates. Replayed events have already been - translated since they've entered DIX before */ - XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x - - 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) - ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y); - - sprite.hotPhys = sprite.hot; - if ((sprite.hotPhys.x != XE_KBPTR.rootX) || - (sprite.hotPhys.y != XE_KBPTR.rootY)) - { - XineramaSetCursorPosition( - sprite.hotPhys.x, sprite.hotPhys.y, FALSE); - } - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; - } + register WindowPtr pWin; + BoxRec box; -#ifdef XEVIE - xeviewin = -#endif - sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y); + spriteTraceGood = 1; /* root window still there */ - if (sprite.win != prevSpriteWin) + if (nxagentOption(Rootless)) { - if (prevSpriteWin != NullWindow) { - if (!xE) - UpdateCurrentTimeIf(); - DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); - } - PostNewCursor(); - return FALSE; - } - return TRUE; -} - + if (nxagentLastEnteredWindow == NULL) + { + return ROOT; + } -static void -XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents) -{ + pWin = ROOT->lastChild; - if (syncEvents.playingEvents) - { - XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin); - SyntheticMotion(sprite.hot.x, sprite.hot.y); + while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow) + { + pWin = pWin->prevSib; + } } else { - int x, y, off_x, off_y, i; - - if(!XineramaSetWindowPntrs(pWin)) - return; - - i = PanoramiXNumScreens - 1; - - RegionCopy(&sprite.Reg1, - &sprite.windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; - - if(x || y) - RegionTranslate(&sprite.Reg1, x, y); - - RegionUnion(&sprite.Reg1, &sprite.Reg1, - &sprite.windows[i]->borderSize); - - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } - - sprite.hotLimits = *RegionExtents(&sprite.Reg1); - - if(RegionNumRects(&sprite.Reg1) > 1) - sprite.hotShape = &sprite.Reg1; - else - sprite.hotShape = NullRegion; - - sprite.confined = FALSE; - sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin; - - XineramaCheckPhysLimits(sprite.current, generateEvents); + pWin = ROOT->firstChild; } -} - -static void -XineramaChangeToCursor(CursorPtr cursor) -{ - if (cursor != sprite.current) + while (pWin) { - if ((sprite.current->bits->xhot != cursor->bits->xhot) || - (sprite.current->bits->yhot != cursor->bits->yhot)) - XineramaCheckPhysLimits(cursor, FALSE); - (*sprite.screen->DisplayCursor)(sprite.screen, cursor); - FreeCursor(sprite.current, (Cursor)0); - sprite.current = cursor; - sprite.current->refcnt++; - } -} - - -#endif /* PANORAMIX */ - -void -SetMaskForEvent(Mask mask, int event) -{ - if ((event < LASTEvent) || (event >= 128)) - FatalError("SetMaskForEvent: bogus event number"); - filters[event] = mask; -} - -void -SetCriticalEvent(int event) -{ - if (event >= 128) - FatalError("SetCriticalEvent: bogus event number"); - criticalEvents[event >> 3] |= 1 << (event & 7); -} - -static void -SyntheticMotion(int x, int y) -{ - xEvent xE; - -#ifdef PANORAMIX - /* Translate back to the sprite screen since processInputProc - will translate from sprite screen to screen 0 upon reentry - to the DIX layer */ - if(!noPanoramiXExtension) { - x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x; - y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y; - } -#endif - xE.u.keyButtonPointer.rootX = x; - xE.u.keyButtonPointer.rootY = y; - if (syncEvents.playingEvents) - xE.u.keyButtonPointer.time = syncEvents.time.milliseconds; - else - xE.u.keyButtonPointer.time = currentTime.milliseconds; - xE.u.u.type = MotionNotify; - (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1); -} - -#ifdef SHAPE -static void -ConfineToShape(RegionPtr shape, int *px, int *py) -{ - BoxRec box; - int x = *px, y = *py; - int incx = 1, incy = 1; - - if (RegionContainsPoint(shape, x, y, &box)) - return; - box = *RegionExtents(shape); - /* this is rather crude */ - do { - x += incx; - if (x >= box.x2) - { - incx = -1; - x = *px - 1; - } - else if (x < box.x1) - { - incx = 1; - x = *px; - y += incy; - if (y >= box.y2) - { - incy = -1; - y = *py - 1; - } - else if (y < box.y1) - return; /* should never get here! */ - } - } while (!RegionContainsPoint(shape, x, y, &box)); - *px = x; - *py = y; -} -#endif - -static void -CheckPhysLimits( - CursorPtr cursor, - Bool generateEvents, - Bool confineToScreen, - ScreenPtr pScreen) -{ - HotSpot new; - - if (!cursor) - return; - new = sprite.hotPhys; - if (pScreen) - new.pScreen = pScreen; - else - pScreen = new.pScreen; - (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits, - &sprite.physLimits); - sprite.confined = confineToScreen; - (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits); - if (new.x < sprite.physLimits.x1) - new.x = sprite.physLimits.x1; - else - if (new.x >= sprite.physLimits.x2) - new.x = sprite.physLimits.x2 - 1; - if (new.y < sprite.physLimits.y1) - new.y = sprite.physLimits.y1; - else - if (new.y >= sprite.physLimits.y2) - new.y = sprite.physLimits.y2 - 1; -#ifdef SHAPE - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &new.x, &new.y); -#endif - if ((pScreen != sprite.hotPhys.pScreen) || - (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y)) - { - if (pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys = new; - (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents); - if (!generateEvents) - SyntheticMotion(new.x, new.y); - } -} - -static void -CheckVirtualMotion( - register QdEventPtr qe, - register WindowPtr pWin) -{ -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaCheckVirtualMotion(qe, pWin); - return; - } -#endif - 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; - } - if (pWin) - { - BoxRec lims; - - 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 = *RegionExtents(&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)) - ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y); -#endif - if (qe) - { - qe->pScreen = sprite.hot.pScreen; - qe->event->u.keyButtonPointer.rootX = sprite.hot.x; - qe->event->u.keyButtonPointer.rootY = sprite.hot.y; - } - } - ROOT = sprite.hot.pScreen->root; -} - -static void -ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaConfineCursorToWindow(pWin, generateEvents); - return; - } -#endif - - if (syncEvents.playingEvents) - { - CheckVirtualMotion((QdEventPtr)NULL, pWin); - SyntheticMotion(sprite.hot.x, sprite.hot.y); - } - else - { - sprite.hotLimits = *RegionExtents(&pWin->borderSize); + if ((pWin->mapped) && + (x >= pWin->drawable.x - wBorderWidth (pWin)) && + (x < pWin->drawable.x + (int)pWin->drawable.width + + wBorderWidth(pWin)) && + (y >= pWin->drawable.y - wBorderWidth (pWin)) && + (y < pWin->drawable.y + (int)pWin->drawable.height + + wBorderWidth (pWin)) #ifdef SHAPE - sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize - : NullRegion; -#endif - CheckPhysLimits(sprite.current, generateEvents, confineToScreen, - pScreen); - } -} - -Bool -PointerConfinedToScreen() -{ - return sprite.confined; -} - -static void -ChangeToCursor(CursorPtr cursor) -{ -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaChangeToCursor(cursor); - return; - } -#endif - - if (cursor != sprite.current) - { - if ((sprite.current->bits->xhot != cursor->bits->xhot) || - (sprite.current->bits->yhot != cursor->bits->yhot)) - CheckPhysLimits(cursor, FALSE, sprite.confined, - (ScreenPtr)NULL); - (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen, - cursor); - FreeCursor(sprite.current, (Cursor)0); - sprite.current = cursor; - sprite.current->refcnt++; - } -} - -/* returns true if b is a descendent of a */ -Bool -IsParent(register WindowPtr a, register WindowPtr b) -{ - for (b = b->parent; b; b = b->parent) - if (b == a) return TRUE; - return FALSE; -} - -static void -PostNewCursor(void) -{ - register WindowPtr win; - register GrabPtr grab = inputInfo.pointer->grab; - - if (syncEvents.playingEvents) - return; - if (grab) - { - if (grab->cursor) - { - ChangeToCursor(grab->cursor); - return; - } - if (IsParent(grab->window, sprite.win)) - win = sprite.win; - else - win = grab->window; - } - else - win = sprite.win; - for (; win; win = win->parent) - if (win->optional && win->optional->cursor != NullCursor) - { - ChangeToCursor(win->optional->cursor); - return; - } -} - -WindowPtr -GetCurrentRootWindow() -{ - return ROOT; -} - -WindowPtr -GetSpriteWindow() -{ - return sprite.win; -} - -CursorPtr -GetSpriteCursor() -{ - return sprite.current; -} - -void -GetSpritePosition(int *px, int *py) -{ - *px = sprite.hotPhys.x; - *py = sprite.hotPhys.y; -} - -#ifdef PANORAMIX -int -XineramaGetCursorScreen() -{ - if(!noPanoramiXExtension) { - return sprite.screen->myNum; - } else { - return 0; - } -} -#endif /* PANORAMIX */ - -#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ - -static void -MonthChangedOrBadTime(register xEvent *xE) -{ - /* If the ddx/OS is careless about not processing timestamped events from - * different sources in sorted order, then it's possible for time to go - * backwards when it should not. Here we ensure a decent time. - */ - if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP) - currentTime.months++; - else - XE_KBPTR.time = currentTime.milliseconds; -} - -#define NoticeTime(xE) { \ - if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \ - MonthChangedOrBadTime(xE); \ - currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \ - lastDeviceEventTime = currentTime; } - -void -NoticeEventTime(register xEvent *xE) -{ - if (!syncEvents.playingEvents) - NoticeTime(xE); -} - -/************************************************************************** - * The following procedures deal with synchronous events * - **************************************************************************/ - -void -EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) -{ - register QdEventPtr tail = *syncEvents.pendtail; - register QdEventPtr qe; - xEvent *qxE; - - NoticeTime(xE); - -#ifdef XKB - /* Fix for key repeating bug. */ - if (device->key != NULL && device->key->xkbInfo != NULL && - xE->u.u.type == KeyRelease) - AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail); -#endif - - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - /* The RECORD spec says that the root window field of motion events - * must be valid. At this point, it hasn't been filled in yet, so - * we do it here. The long expression below is necessary to get - * the current root window; the apparently reasonable alternative - * GetCurrentRootWindow()->drawable.id doesn't give you the right - * answer on the first motion event after a screen change because - * the data that GetCurrentRootWindow relies on hasn't been - * updated yet. - */ - if (xE->u.u.type == MotionNotify) - XE_KBPTR.root = - sprite.hotPhys.pScreen->root->drawable.id; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); - } - if (xE->u.u.type == MotionNotify) - { -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x - - panoramiXdataPtr[0].x; - XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y - - panoramiXdataPtr[0].y; - } -#endif - sprite.hotPhys.x = XE_KBPTR.rootX; - sprite.hotPhys.y = XE_KBPTR.rootY; - /* do motion compression */ - if (tail && - (tail->event->u.u.type == MotionNotify) && - (tail->pScreen == sprite.hotPhys.pScreen)) - { - tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x; - tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y; - tail->event->u.keyButtonPointer.time = XE_KBPTR.time; - tail->months = currentTime.months; - return; - } - } - qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent))); - if (!qe) - return; - qe->next = (QdEventPtr)NULL; - qe->device = device; - qe->pScreen = sprite.hotPhys.pScreen; - qe->months = currentTime.months; - qe->event = (xEvent *)(qe + 1); - qe->evcount = count; - for (qxE = qe->event; --count >= 0; qxE++, xE++) - *qxE = *xE; - if (tail) - syncEvents.pendtail = &tail->next; - *syncEvents.pendtail = qe; -} - -static void -PlayReleasedEvents(void) -{ - register QdEventPtr *prev, qe; - register DeviceIntPtr dev; - - prev = &syncEvents.pending; - while ( (qe = *prev) ) - { - if (!qe->device->sync.frozen) - { - *prev = qe->next; - if (*syncEvents.pendtail == *prev) - syncEvents.pendtail = prev; - if (qe->event->u.u.type == MotionNotify) - CheckVirtualMotion(qe, NullWindow); - syncEvents.time.months = qe->months; - syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time; -#ifdef PANORAMIX - /* Translate back to the sprite screen since processInputProc - will translate from sprite screen to screen 0 upon reentry - to the DIX layer */ - if(!noPanoramiXExtension) { - qe->event->u.keyButtonPointer.rootX += - panoramiXdataPtr[0].x - - panoramiXdataPtr[sprite.screen->myNum].x; - qe->event->u.keyButtonPointer.rootY += - panoramiXdataPtr[0].y - - panoramiXdataPtr[sprite.screen->myNum].y; - } -#endif - (*qe->device->public.processInputProc)(qe->event, qe->device, - qe->evcount); - xfree(qe); - for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next) - ; - if (!dev) - break; - /* Playing the event may have unfrozen another device. */ - /* So to play it safe, restart at the head of the queue */ - prev = &syncEvents.pending; - } - else - prev = &qe->next; - } -} - -static void -FreezeThaw(register DeviceIntPtr dev, Bool frozen) -{ - dev->sync.frozen = frozen; - if (frozen) - dev->public.processInputProc = dev->public.enqueueInputProc; - else - dev->public.processInputProc = dev->public.realInputProc; -} - -void -ComputeFreezes() -{ - register DeviceIntPtr replayDev = syncEvents.replayDev; - register int i; - WindowPtr w; - register xEvent *xE; - int count; - GrabPtr grab; - register DeviceIntPtr dev; - - for (dev = inputInfo.devices; dev; dev = dev->next) - FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN)); - if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending)) - return; - syncEvents.playingEvents = TRUE; - if (replayDev) - { - xE = replayDev->sync.event; - count = replayDev->sync.evcount; - syncEvents.replayDev = (DeviceIntPtr)NULL; - - w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY); - for (i = 0; i < spriteTraceGood; i++) - { - if (syncEvents.replayWin == spriteTrace[i]) - { - if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) { - if (replayDev->focus) - DeliverFocusedEvent(replayDev, xE, w, count); - else - DeliverDeviceEvents(w, xE, NullGrab, NullWindow, - replayDev, count); - } - goto playmore; - } - } - /* must not still be in the same stack */ - if (replayDev->focus) - DeliverFocusedEvent(replayDev, xE, w, count); - else - DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count); - } -playmore: - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (!dev->sync.frozen) - { - PlayReleasedEvents(); - break; - } - } - syncEvents.playingEvents = FALSE; - /* the following may have been skipped during replay, so do it now */ - if ((grab = inputInfo.pointer->grab) && grab->confineTo) - { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); - } - else - ConfineCursorToWindow(sprite.hotPhys.pScreen->root, - TRUE, FALSE); - PostNewCursor(); -} - -#ifdef RANDR -void -ScreenRestructured (ScreenPtr pScreen) -{ - GrabPtr grab; - - if ((grab = inputInfo.pointer->grab) && grab->confineTo) - { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); - } - else - ConfineCursorToWindow(sprite.hotPhys.pScreen->root, - TRUE, FALSE); -} -#endif - -void -CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) -{ - register GrabPtr grab = thisDev->grab; - register DeviceIntPtr dev; - - if (thisMode == GrabModeSync) - thisDev->sync.state = FROZEN_NO_EVENT; - else - { /* free both if same client owns both */ - thisDev->sync.state = THAWED; - if (thisDev->sync.other && - (CLIENT_BITS(thisDev->sync.other->resource) == - CLIENT_BITS(grab->resource))) - thisDev->sync.other = NullGrab; - } - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev != thisDev) - { - if (otherMode == GrabModeSync) - dev->sync.other = grab; - else - { /* free both if same client owns both */ - if (dev->sync.other && - (CLIENT_BITS(dev->sync.other->resource) == - CLIENT_BITS(grab->resource))) - dev->sync.other = NullGrab; - } - } - } - ComputeFreezes(); -} - -void -ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, - TimeStamp time, Bool autoGrab) -{ - WindowPtr oldWin = (mouse->grab) ? mouse->grab->window - : sprite.win; - - if (grab->confineTo) - { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, FALSE, TRUE); - } - DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab); - mouse->valuator->motionHintWindow = NullWindow; - if (syncEvents.playingEvents) - mouse->grabTime = syncEvents.time; - else - mouse->grabTime = time; - if (grab->cursor) - grab->cursor->refcnt++; - mouse->activeGrab = *grab; - mouse->grab = &mouse->activeGrab; - mouse->fromPassiveGrab = autoGrab; - PostNewCursor(); - CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); - - #ifdef NXAGENT_SERVER - - /* - * If grab is synchronous, events are delivered to clients only if they send - * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the - * delivered event is saved in a queue and replayed later, when grab is released. - * We should export sync grab to X as async in order to avoid events to be - * queued twice, in the agent and in the X server. This solution have a drawback: - * replayed events are not delivered to that application that are not clients of - * the agent. - * A different solution could be to make the grab asynchronous in the agent and - * to export it as synchronous. But this seems to be less safe. - * - * To make internal grab asynchronous, change previous line as follows. - * - * if (nxagentOption(Rootless)) - * { - * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode); - * } - * else - * { - * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); - * } - */ - - if (nxagentOption(Rootless) == 1) - { - /* - * FIXME: We should use the correct value - * for the cursor. Temporarily we set it - * to None. - */ - - int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource, - nxagentCollectGrabPointerPredicate); - - NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window), - 1, grab -> eventMask & PointerGrabMask, - GrabModeAsync, GrabModeAsync, (grab -> confineTo) ? - nxagentWindow(grab -> confineTo) : None, - None, CurrentTime); - } - - #endif -} - -void -DeactivatePointerGrab(register DeviceIntPtr mouse) -{ - register GrabPtr grab = mouse->grab; - register DeviceIntPtr dev; - - mouse->valuator->motionHintWindow = NullWindow; - mouse->grab = NullGrab; - mouse->sync.state = NOT_GRABBED; - mouse->fromPassiveGrab = FALSE; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->sync.other == grab) - dev->sync.other = NullGrab; - } - DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab); - if (grab->confineTo) - ConfineCursorToWindow(ROOT, FALSE, FALSE); - PostNewCursor(); - if (grab->cursor) - FreeCursor(grab->cursor, (Cursor)0); - ComputeFreezes(); - - #ifdef NXAGENT_SERVER - - if (nxagentOption(Rootless) == 1) - { - XUngrabPointer(nxagentDisplay, CurrentTime); - - if (sprite.win == ROOT) - { - mouse -> button -> state &= - ~(Button1Mask | Button2Mask | Button3Mask | - Button4Mask | Button5Mask); - } - } - - #endif -} - -void -ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive) -{ - WindowPtr oldWin; - - if (keybd->grab) - oldWin = keybd->grab->window; - else if (keybd->focus) - oldWin = keybd->focus->win; - else - oldWin = sprite.win; - if (oldWin == FollowKeyboardWin) - oldWin = inputInfo.keyboard->focus->win; - if (keybd->valuator) - keybd->valuator->motionHintWindow = NullWindow; - DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); - if (syncEvents.playingEvents) - keybd->grabTime = syncEvents.time; - else - keybd->grabTime = time; - keybd->activeGrab = *grab; - keybd->grab = &keybd->activeGrab; - keybd->fromPassiveGrab = passive; - CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode); -} - -void -DeactivateKeyboardGrab(register DeviceIntPtr keybd) -{ - register GrabPtr grab = keybd->grab; - register DeviceIntPtr dev; - register WindowPtr focusWin = keybd->focus ? keybd->focus->win - : sprite.win; - - if (focusWin == FollowKeyboardWin) - focusWin = inputInfo.keyboard->focus->win; - if (keybd->valuator) - keybd->valuator->motionHintWindow = NullWindow; - keybd->grab = NullGrab; - keybd->sync.state = NOT_GRABBED; - keybd->fromPassiveGrab = FALSE; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->sync.other == grab) - dev->sync.other = NullGrab; - } - DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); - ComputeFreezes(); -} - -void -AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) -{ - Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced; - TimeStamp grabTime; - register DeviceIntPtr dev; - - thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client); - thisSynced = FALSE; - otherGrabbed = FALSE; - othersFrozen = TRUE; - grabTime = thisDev->grabTime; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev == thisDev) - continue; - if (dev->grab && SameClient(dev->grab, client)) - { - if (!(thisGrabbed || otherGrabbed) || - (CompareTimeStamps(dev->grabTime, grabTime) == LATER)) - grabTime = dev->grabTime; - otherGrabbed = TRUE; - if (thisDev->sync.other == dev->grab) - thisSynced = TRUE; - if (dev->sync.state < FROZEN) - othersFrozen = FALSE; - } - else if (!dev->sync.other || !SameClient(dev->sync.other, client)) - othersFrozen = FALSE; - } - if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced)) - return; - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, grabTime) == EARLIER)) - return; - switch (newState) - { - case THAWED: /* Async */ - if (thisGrabbed) - thisDev->sync.state = THAWED; - if (thisSynced) - thisDev->sync.other = NullGrab; - ComputeFreezes(); - break; - case FREEZE_NEXT_EVENT: /* Sync */ - if (thisGrabbed) - { - thisDev->sync.state = FREEZE_NEXT_EVENT; - if (thisSynced) - thisDev->sync.other = NullGrab; - ComputeFreezes(); - } - break; - case THAWED_BOTH: /* AsyncBoth */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = THAWED; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = FREEZE_BOTH_NEXT_EVENT; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - case NOT_GRABBED: /* Replay */ - if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT) - { - if (thisSynced) - thisDev->sync.other = NullGrab; - syncEvents.replayDev = thisDev; - syncEvents.replayWin = thisDev->grab->window; - (*thisDev->DeactivateGrab)(thisDev); - syncEvents.replayDev = (DeviceIntPtr)NULL; - } - break; - case THAW_OTHERS: /* AsyncOthers */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev == thisDev) - continue; - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = THAWED; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - } -} - -int -ProcAllowEvents(register ClientPtr client) -{ - TimeStamp time; - DeviceIntPtr mouse = inputInfo.pointer; - DeviceIntPtr keybd = inputInfo.keyboard; - REQUEST(xAllowEventsReq); - - REQUEST_SIZE_MATCH(xAllowEventsReq); - time = ClientTimeToServerTime(stuff->time); - switch (stuff->mode) - { - case ReplayPointer: - AllowSome(client, time, mouse, NOT_GRABBED); - break; - case SyncPointer: - AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); - break; - case AsyncPointer: - AllowSome(client, time, mouse, THAWED); - break; - case ReplayKeyboard: - AllowSome(client, time, keybd, NOT_GRABBED); - break; - case SyncKeyboard: - AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); - break; - case AsyncKeyboard: - AllowSome(client, time, keybd, THAWED); - break; - case SyncBoth: - AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); - break; - case AsyncBoth: - AllowSome(client, time, keybd, THAWED_BOTH); - break; - default: - client->errorValue = stuff->mode; - return BadValue; - } - - /* - * This is not necessary if we export grab to X as asynchronous. - * - * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard && - * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard) - * { - * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime); - * } - */ - - return Success; -} - -void -ReleaseActiveGrabs(ClientPtr client) -{ - register DeviceIntPtr dev; - Bool done; - - /* XXX CloseDownClient should remove passive grabs before - * releasing active grabs. - */ - do { - done = TRUE; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->grab && SameClient(dev->grab, client)) - { - (*dev->DeactivateGrab)(dev); - done = FALSE; - } - } - } while (!done); -} - -/************************************************************************** - * The following procedures deal with delivering events * - **************************************************************************/ - -int -TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, - Mask filter, GrabPtr grab) -{ - int i; - int type; - -#ifdef NX_DEBUG_INPUT - if (grab && nxagentDebugInput && grab->window) - { - fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n", - (unsigned int)grab->window->drawable.id); - if (!SameClient(grab, client)) - fprintf(stderr, "TryClientEvents: Events are going to be " - "discarded.\n"); - } -#endif -#if defined(DEBUG) || defined(NX_DEBUG_INPUT) -#ifdef NX_DEBUG_INPUT - if (nxagentDebugInput == 1) - fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d", - pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask, - client->index); -#else - if (debug_events) ErrorF( - "Event([%d, %d], mask=0x%x), client=%d", - pEvents->u.u.type, pEvents->u.u.detail, mask, client->index); -#endif -#endif - if ((client) && (client != serverClient) && (!client->clientGone) && - ((filter == CantBeFiltered) || (mask & filter))) - { - if (grab && !SameClient(grab, client)) - return -1; /* don't send, but notify caller */ - type = pEvents->u.u.type; - if (type == MotionNotify) - { - if (mask & PointerMotionHintMask) - { - if (WID(inputInfo.pointer->valuator->motionHintWindow) == - pEvents->u.keyButtonPointer.event) - { -#if defined(DEBUG) || defined(NX_DEBUG_INPUT) -#ifdef NX_DEBUG_INPUT - if (nxagentDebugInput == 1) - { - fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n"); - } -#else - if (debug_events) ErrorF("\n"); - fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n"); -#endif -#endif - return 1; /* don't send, but pretend we did */ - } - pEvents->u.u.detail = NotifyHint; - } - else - { - pEvents->u.u.detail = NotifyNormal; - } - } -#ifdef XINPUT - else - { - if ((type == DeviceMotionNotify) && - MaybeSendDeviceMotionNotifyHint - ((deviceKeyButtonPointer*)pEvents, mask) != 0) - return 1; - } -#endif - type &= 0177; - if (type != KeymapNotify) - { - /* all extension events must have a sequence number */ - for (i = 0; i < count; i++) - pEvents[i].u.u.sequenceNumber = client->sequence; - } - - if (BitIsOn(criticalEvents, type)) - { -#ifdef SMART_SCHEDULE - if (client->smart_priority < SMART_MAX_PRIORITY) - client->smart_priority++; -#endif - SetCriticalOutputPending(); - } - - WriteEventsToClient(client, count, pEvents); -#if defined(DEBUG) || defined(NX_DEBUG_INPUT) -#ifdef NX_DEBUG_INPUT - if (nxagentDebugInput == 1) - fprintf(stderr, " delivered\n"); -#else - if (debug_events) ErrorF( " delivered\n"); -#endif -#endif - return 1; - } - else - { -#if defined(DEBUG) || defined(NX_DEBUG_INPUT) -#ifdef NX_DEBUG_INPUT - if (nxagentDebugInput == 1) - fprintf(stderr, "\n"); -#else - if (debug_events) ErrorF("\n"); -#endif -#endif - return 0; - } -} - -int -DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count, - Mask filter, GrabPtr grab, int mskidx) -{ - int deliveries = 0, nondeliveries = 0; - int attempt; - register InputClients *other; - ClientPtr client = NullClient; - Mask deliveryMask = 0; /* If a grab occurs due to a button press, then - this mask is the mask of the grab. */ - int type = pEvents->u.u.type; - - /* CantBeFiltered means only window owner gets the event */ - if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE)) - { - /* if nobody ever wants to see this event, skip some work */ - if (filter != CantBeFiltered && - !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) - return 0; - if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count, - pWin->eventMask, filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = wClient(pWin); - deliveryMask = pWin->eventMask; - } else - nondeliveries--; - } - } - if (filter != CantBeFiltered) - { - if (type & EXTENSION_EVENT_BASE) - { - OtherInputMasks *inputMasks; - - inputMasks = wOtherInputMasks(pWin); - if (!inputMasks || - !(inputMasks->inputEvents[mskidx] & filter)) - return 0; - other = inputMasks->inputClients; - } - else - other = (InputClients *)wOtherClients(pWin); - for (; other; other = other->next) - { - if ( (attempt = TryClientEvents(rClient(other), pEvents, count, - other->mask[mskidx], filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = other->mask[mskidx]; - } else - nondeliveries--; - } - } - } - if ((type == ButtonPress) && deliveries && (!grab)) - { - GrabRec tempGrab; - - tempGrab.device = inputInfo.pointer; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n"); - } - #endif - (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab, - currentTime, TRUE); - } - else if ((type == MotionNotify) && deliveries) - inputInfo.pointer->valuator->motionHintWindow = pWin; -#ifdef XINPUT - else - { - if (((type == DeviceMotionNotify) -#ifdef XKB - || (type == DeviceButtonPress) -#endif - ) && deliveries) - CheckDeviceGrabAndHintWindow (pWin, type, - (deviceKeyButtonPointer*) pEvents, - grab, client, deliveryMask); - } -#endif - if (deliveries) - return deliveries; - return nondeliveries; -} - -/* If the event goes to dontClient, don't send it and return 0. if - send works, return 1 or if send didn't work, return 2. - Only works for core events. -*/ - -#ifdef PANORAMIX -static int -XineramaTryClientEventsResult( - ClientPtr client, - GrabPtr grab, - Mask mask, - Mask filter -){ - if ((client) && (client != serverClient) && (!client->clientGone) && - ((filter == CantBeFiltered) || (mask & filter))) - { - if (grab && !SameClient(grab, client)) return -1; - else return 1; - } - return 0; -} -#endif - -int -MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents, - int count, Mask filter, ClientPtr dontClient) -{ - register OtherClients *other; - - - if (pWin->eventMask & filter) - { - if (wClient(pWin) == dontClient) - return 0; -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return XineramaTryClientEventsResult( - wClient(pWin), NullGrab, pWin->eventMask, filter); -#endif - return TryClientEvents(wClient(pWin), pEvents, count, - pWin->eventMask, filter, NullGrab); - } - for (other = wOtherClients(pWin); other; other = other->next) - { - if (other->mask & filter) - { - if (SameClient(other, dontClient)) - return 0; -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return XineramaTryClientEventsResult( - rClient(other), NullGrab, other->mask, filter); -#endif - return TryClientEvents(rClient(other), pEvents, count, - other->mask, filter, NullGrab); - } - } - return 2; -} - -static void -FixUpEventFromWindow( - xEvent *xE, - WindowPtr pWin, - Window child, - Bool calcChild) -{ - if (calcChild) - { - WindowPtr w=spriteTrace[spriteTraceGood-1]; - /* If the search ends up past the root should the child field be - set to none or should the value in the argument be passed - through. It probably doesn't matter since everyone calls - this function with child == None anyway. */ - - while (w) - { - /* If the source window is same as event window, child should be - none. Don't bother going all all the way back to the root. */ - - if (w == pWin) - { - child = None; - break; - } - - if (w->parent == pWin) - { - child = w->drawable.id; - break; - } - w = w->parent; - } - } - XE_KBPTR.root = ROOT->drawable.id; - XE_KBPTR.event = pWin->drawable.id; - if (sprite.hot.pScreen == pWin->drawable.pScreen) - { - XE_KBPTR.sameScreen = xTrue; - XE_KBPTR.child = child; - XE_KBPTR.eventX = - XE_KBPTR.rootX - pWin->drawable.x; - XE_KBPTR.eventY = - XE_KBPTR.rootY - pWin->drawable.y; - } - else - { - XE_KBPTR.sameScreen = xFalse; - XE_KBPTR.child = None; - XE_KBPTR.eventX = 0; - XE_KBPTR.eventY = 0; - } -} - -int -DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab, - register WindowPtr stopAt, DeviceIntPtr dev, int count) -{ - Window child = None; - int type = xE->u.u.type; - Mask filter = filters[type]; - int deliveries = 0; - - if (type & EXTENSION_EVENT_BASE) - { - register OtherInputMasks *inputMasks; - int mskidx = dev->id; - - inputMasks = wOtherInputMasks(pWin); - if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx])) - return 0; - while (pWin) - { - if (inputMasks && (inputMasks->inputEvents[mskidx] & filter)) - { - FixUpEventFromWindow(xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(pWin, xE, count, filter, - grab, mskidx); - if (deliveries > 0) - return deliveries; - } - if ((deliveries < 0) || - (pWin == stopAt) || - (inputMasks && - (filter & inputMasks->dontPropagateMask[mskidx]))) - return 0; - child = pWin->drawable.id; - pWin = pWin->parent; - if (pWin) - inputMasks = wOtherInputMasks(pWin); - } - } - else - { - if (!(filter & pWin->deliverableEvents)) - return 0; - while (pWin) - { - if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter) - { - FixUpEventFromWindow(xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(pWin, xE, count, filter, - grab, 0); - if (deliveries > 0) - return deliveries; - } - if ((deliveries < 0) || - (pWin == stopAt) || - (filter & wDontPropagateMask(pWin))) - return 0; - child = pWin->drawable.id; - pWin = pWin->parent; - } - } - return 0; -} - -/* not useful for events that propagate up the tree or extension events */ -int -DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count, - register WindowPtr otherParent) -{ - Mask filter; - int deliveries; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return count; -#endif - - if (!count) - return 0; - filter = filters[xE->u.u.type]; - if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) - xE->u.destroyNotify.event = pWin->drawable.id; - if (filter != StructureAndSubMask) - return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0); - deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask, - NullGrab, 0); - if (pWin->parent) - { - xE->u.destroyNotify.event = pWin->parent->drawable.id; - deliveries += DeliverEventsToWindow(pWin->parent, xE, count, - SubstructureNotifyMask, NullGrab, - 0); - if (xE->u.u.type == ReparentNotify) - { - xE->u.destroyNotify.event = otherParent->drawable.id; - deliveries += DeliverEventsToWindow(otherParent, xE, count, - SubstructureNotifyMask, - NullGrab, 0); - } - } - return deliveries; -} - - -static Bool -PointInBorderSize(WindowPtr pWin, int x, int y) -{ - BoxRec box; - - if(RegionContainsPoint(&pWin->borderSize, x, y, &box)) - return TRUE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) { - int i; - - for(i = 1; i < PanoramiXNumScreens; i++) { - if(RegionContainsPoint( - &sprite.windows[i]->borderSize, - x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, - y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, - &box)) - return TRUE; - } - } -#endif - return FALSE; -} - -static WindowPtr -XYToWindow(int x, int y) -{ - register WindowPtr pWin; - BoxRec box; - - spriteTraceGood = 1; /* root window still there */ - - if (nxagentOption(Rootless)) - { - if (nxagentLastEnteredWindow == NULL) - { - return ROOT; - } - - pWin = ROOT->lastChild; - - while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow) - { - pWin = pWin->prevSib; - } - } - else - { - pWin = ROOT->firstChild; - } - - while (pWin) - { - if ((pWin->mapped) && - (x >= pWin->drawable.x - wBorderWidth (pWin)) && - (x < pWin->drawable.x + (int)pWin->drawable.width + - wBorderWidth(pWin)) && - (y >= pWin->drawable.y - wBorderWidth (pWin)) && - (y < pWin->drawable.y + (int)pWin->drawable.height + - wBorderWidth (pWin)) -#ifdef SHAPE - /* When a window is shaped, a further check - * is made to see if the point is inside - * borderSize - */ - && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) - && (!wInputShape(pWin) || - RegionContainsPoint( - wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box)) -#endif - ) - { - if (spriteTraceGood >= spriteTraceSize) - { - spriteTraceSize += 10; - Must_have_memory = TRUE; /* XXX */ - spriteTrace = (WindowPtr *)xrealloc( - spriteTrace, spriteTraceSize*sizeof(WindowPtr)); - Must_have_memory = FALSE; /* XXX */ - } - spriteTrace[spriteTraceGood++] = pWin; - pWin = pWin->firstChild; - } - else - pWin = pWin->nextSib; - } - return spriteTrace[spriteTraceGood-1]; -} - -static Bool -CheckMotion(xEvent *xE) -{ - WindowPtr prevSpriteWin = sprite.win; - -#ifdef PANORAMIX - if(!noPanoramiXExtension) - return XineramaCheckMotion(xE); -#endif - - if (xE && !syncEvents.playingEvents) - { - if (sprite.hot.pScreen != sprite.hotPhys.pScreen) - { - sprite.hot.pScreen = sprite.hotPhys.pScreen; - ROOT = sprite.hot.pScreen->root; - } -#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) - ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y); -#endif - sprite.hotPhys = sprite.hot; - - /* - * This code force cursor position to be inside the - * root window of the agent. We can't view a reason - * to do this and it interacts in an undesirable way - * with toggling fullscreen. - * - * if ((sprite.hotPhys.x != XE_KBPTR.rootX) || - * (sprite.hotPhys.y != XE_KBPTR.rootY)) - * { - * (*sprite.hotPhys.pScreen->SetCursorPosition)( - * sprite.hotPhys.pScreen, - * sprite.hotPhys.x, sprite.hotPhys.y, FALSE); - * } - */ - - XE_KBPTR.rootX = sprite.hot.x; - 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 & - Motion_Filter(inputInfo.pointer->button)) - !syncEvents.playingEvents) - { - /* XXX Do PointerNonInterestBox here */ - } -#endif - if (sprite.win != prevSpriteWin) - { - if (prevSpriteWin != NullWindow) { - if (!xE) - UpdateCurrentTimeIf(); - DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); - } - PostNewCursor(); - return FALSE; - } - return TRUE; -} - -void -WindowsRestructured() -{ - (void) CheckMotion((xEvent *)NULL); -} - -#ifdef PANORAMIX -/* This was added to support reconfiguration under Xdmx. The problem is - * that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to - * an origin other than 0,0, the information in the private sprite structure - * must be updated accordingly, or XYToWindow (and other routines) will not - * compute correctly. */ -void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) -{ - GrabPtr grab; - - if (noPanoramiXExtension) return; - - sprite.hot.x -= xoff; - sprite.hot.y -= yoff; - - sprite.hotPhys.x -= xoff; - sprite.hotPhys.y -= yoff; - - sprite.hotLimits.x1 -= xoff; - sprite.hotLimits.y1 -= yoff; - sprite.hotLimits.x2 -= xoff; - sprite.hotLimits.y2 -= yoff; - - if (RegionNotEmpty(&sprite.Reg1)) - RegionTranslate(&sprite.Reg1, xoff, yoff); - if (RegionNotEmpty(&sprite.Reg2)) - RegionTranslate(&sprite.Reg2, xoff, yoff); - - /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */ - if ((grab = inputInfo.pointer->grab) && grab->confineTo) { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); - } else - ConfineCursorToWindow(sprite.hotPhys.pScreen->root, - TRUE, FALSE); -} -#endif - -void -DefineInitialRootWindow(register WindowPtr win) -{ - register ScreenPtr pScreen = win->drawable.pScreen; - #ifdef VIEWPORT_FRAME - extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr); - #endif - extern int nxagentShadowInit(ScreenPtr, WindowPtr); - - sprite.hotPhys.pScreen = pScreen; - sprite.hotPhys.x = pScreen->width / 2; - sprite.hotPhys.y = pScreen->height / 2; - 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); - sprite.current->refcnt++; - spriteTraceGood = 1; - ROOT = win; - (*pScreen->CursorLimits) ( - pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits); - sprite.confined = FALSE; - (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits); - (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE); - (*pScreen->DisplayCursor) (pScreen, sprite.current); - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - sprite.hotLimits.x1 = -panoramiXdataPtr[0].x; - sprite.hotLimits.y1 = -panoramiXdataPtr[0].y; - sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; - sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; - sprite.physLimits = sprite.hotLimits; - sprite.confineWin = NullWindow; -#ifdef SHAPE - sprite.hotShape = NullRegion; -#endif - sprite.screen = pScreen; - /* gotta UNINIT these someplace */ - RegionNull(&sprite.Reg1); - RegionNull(&sprite.Reg2); - } -#endif - - #ifdef VIEWPORT_FRAME - nxagentInitViewportFrame(pScreen, win); - #endif - - if (nxagentOption(Shadow)) - { - if (nxagentShadowInit(pScreen, win) == -1) - { - FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName); - } - } -} - -/* - * This does not take any shortcuts, and even ignores its argument, since - * it does not happen very often, and one has to walk up the tree since - * this might be a newly instantiated cursor for an intermediate window - * between the one the pointer is in and the one that the last cursor was - * instantiated from. - */ -void -WindowHasNewCursor(WindowPtr pWin) -{ - PostNewCursor(); -} - -void -NewCurrentScreen(ScreenPtr newScreen, int x, int y) -{ - sprite.hotPhys.x = x; - sprite.hotPhys.y = y; -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - - panoramiXdataPtr[0].x; - sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - - panoramiXdataPtr[0].y; - if (newScreen != sprite.screen) { - sprite.screen = newScreen; - /* Make sure we tell the DDX to update its copy of the screen */ - if(sprite.confineWin) - XineramaConfineCursorToWindow(sprite.confineWin, TRUE); - else - XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE); - /* if the pointer wasn't confined, the DDX won't get - told of the pointer warp so we reposition it here */ - if(!syncEvents.playingEvents) - (*sprite.screen->SetCursorPosition)(sprite.screen, - sprite.hotPhys.x + panoramiXdataPtr[0].x - - panoramiXdataPtr[sprite.screen->myNum].x, - sprite.hotPhys.y + panoramiXdataPtr[0].y - - panoramiXdataPtr[sprite.screen->myNum].y, FALSE); - } - } else -#endif - if (newScreen != sprite.hotPhys.pScreen) - ConfineCursorToWindow(newScreen->root, TRUE, FALSE); -} - -#ifdef PANORAMIX - -static Bool -XineramaPointInWindowIsVisible( - WindowPtr pWin, - int x, - int y -) -{ - BoxRec box; - int i, xoff, yoff; - - if (!pWin->realized) return FALSE; - - if (RegionContainsPoint(&pWin->borderClip, x, y, &box)) - return TRUE; - - if(!XineramaSetWindowPntrs(pWin)) return FALSE; - - xoff = x + panoramiXdataPtr[0].x; - yoff = y + panoramiXdataPtr[0].y; - - for(i = 1; i < PanoramiXNumScreens; i++) { - pWin = sprite.windows[i]; - x = xoff - panoramiXdataPtr[i].x; - y = yoff - panoramiXdataPtr[i].y; - - if(RegionContainsPoint(&pWin->borderClip, x, y, &box) - && (!wInputShape(pWin) || - RegionContainsPoint( - wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box))) - return TRUE; - - } - - return FALSE; -} - -static int -XineramaWarpPointer(ClientPtr client) -{ - WindowPtr dest = NULL; - int x, y; - - REQUEST(xWarpPointerReq); - - - if (stuff->dstWid != None) - { - dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess); - if (!dest) - return BadWindow; - } - x = sprite.hotPhys.x; - y = sprite.hotPhys.y; - - if (stuff->srcWid != None) - { - int winX, winY; - XID winID = stuff->srcWid; - WindowPtr source; - - source = SecurityLookupWindow(winID, client, SecurityReadAccess); - if (!source) return BadWindow; - - winX = source->drawable.x; - winY = source->drawable.y; - if(source == screenInfo.screens[0]->root) { - winX -= panoramiXdataPtr[0].x; - winY -= panoramiXdataPtr[0].y; - } - if (x < winX + stuff->srcX || - y < winY + stuff->srcY || - (stuff->srcWidth != 0 && - winX + stuff->srcX + (int)stuff->srcWidth < x) || - (stuff->srcHeight != 0 && - winY + stuff->srcY + (int)stuff->srcHeight < y) || - !XineramaPointInWindowIsVisible(source, x, y)) - return Success; - } - if (dest) { - x = dest->drawable.x; - y = dest->drawable.y; - if(dest == screenInfo.screens[0]->root) { - x -= panoramiXdataPtr[0].x; - y -= panoramiXdataPtr[0].y; - } - } - - x += stuff->dstX; - y += stuff->dstY; - - if (x < sprite.physLimits.x1) - x = sprite.physLimits.x1; - else if (x >= sprite.physLimits.x2) - x = sprite.physLimits.x2 - 1; - if (y < sprite.physLimits.y1) - y = sprite.physLimits.y1; - else if (y >= sprite.physLimits.y2) - y = sprite.physLimits.y2 - 1; - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &x, &y); - - XineramaSetCursorPosition(x, y, TRUE); - - return Success; -} - -#endif - - -int -ProcWarpPointer(ClientPtr client) -{ - WindowPtr dest = NULL; - int x, y; - ScreenPtr newScreen; - - REQUEST(xWarpPointerReq); - - REQUEST_SIZE_MATCH(xWarpPointerReq); - -#ifdef PANORAMIX - if(!noPanoramiXExtension) - return XineramaWarpPointer(client); -#endif - - if (stuff->dstWid != None) - { - dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess); - if (!dest) - return BadWindow; - } - x = sprite.hotPhys.x; - y = sprite.hotPhys.y; - - if (stuff->srcWid != None) - { - int winX, winY; - XID winID = stuff->srcWid; - WindowPtr source; - - source = SecurityLookupWindow(winID, client, SecurityReadAccess); - if (!source) return BadWindow; - - winX = source->drawable.x; - winY = source->drawable.y; - if (source->drawable.pScreen != sprite.hotPhys.pScreen || - x < winX + stuff->srcX || - y < winY + stuff->srcY || - (stuff->srcWidth != 0 && - winX + stuff->srcX + (int)stuff->srcWidth < x) || - (stuff->srcHeight != 0 && - winY + stuff->srcY + (int)stuff->srcHeight < y) || - !PointInWindowIsVisible(source, x, y)) - return Success; - } - if (dest) - { - x = dest->drawable.x; - y = dest->drawable.y; - newScreen = dest->drawable.pScreen; - } else - newScreen = sprite.hotPhys.pScreen; - - x += stuff->dstX; - y += stuff->dstY; - - if (x < 0) - x = 0; - else if (x >= newScreen->width) - x = newScreen->width - 1; - if (y < 0) - y = 0; - else if (y >= newScreen->height) - y = newScreen->height - 1; - - if (newScreen == sprite.hotPhys.pScreen) - { - if (x < sprite.physLimits.x1) - x = sprite.physLimits.x1; - else if (x >= sprite.physLimits.x2) - x = sprite.physLimits.x2 - 1; - if (y < sprite.physLimits.y1) - y = sprite.physLimits.y1; - else if (y >= sprite.physLimits.y2) - y = sprite.physLimits.y2 - 1; -#if defined(SHAPE) - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &x, &y); -#endif - (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE); - } - else if (!PointerConfinedToScreen()) - { - NewCurrentScreen(newScreen, x, y); - } - return Success; -} - -static Bool -BorderSizeNotEmpty(WindowPtr pWin) -{ - if(RegionNotEmpty(&pWin->borderSize)) - return TRUE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) { - int i; - - for(i = 1; i < PanoramiXNumScreens; i++) { - if(RegionNotEmpty(&sprite.windows[i]->borderSize)) - return TRUE; - } - } -#endif - return FALSE; -} - -/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a - passive grab set on the window to be activated. */ - -static Bool -CheckPassiveGrabsOnWindow( - WindowPtr pWin, - register DeviceIntPtr device, - register xEvent *xE, - int count) -{ - register GrabPtr grab = wPassiveGrabs(pWin); - GrabRec tempGrab; - register xEvent *dxE; - - if (!grab) - return FALSE; - tempGrab.window = pWin; - tempGrab.device = device; - tempGrab.type = xE->u.u.type; - tempGrab.detail.exact = xE->u.u.detail; - tempGrab.detail.pMask = NULL; - tempGrab.modifiersDetail.pMask = NULL; - for (; grab; grab = grab->next) - { -#ifdef XKB - DeviceIntPtr gdev; - XkbSrvInfoPtr xkbi; - - gdev= grab->modifierDevice; - xkbi= gdev->key->xkbInfo; -#endif - tempGrab.modifierDevice = grab->modifierDevice; - if ((device == grab->modifierDevice) && - ((xE->u.u.type == KeyPress) -#if defined(XINPUT) && defined(XKB) - || (xE->u.u.type == DeviceKeyPress) -#endif - )) - tempGrab.modifiersDetail.exact = -#ifdef XKB - (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods); -#else - grab->modifierDevice->key->prev_state; -#endif - else - tempGrab.modifiersDetail.exact = -#ifdef XKB - (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods); -#else - grab->modifierDevice->key->state; -#endif - if (GrabMatchesSecond(&tempGrab, grab) && - (!grab->confineTo || - (grab->confineTo->realized && - BorderSizeNotEmpty(grab->confineTo)))) - { -#ifdef XCSECURITY - if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE)) - return FALSE; -#endif -#ifdef XKB - if (!noXkbExtension) { - XE_KBPTR.state &= 0x1f00; - XE_KBPTR.state |= - tempGrab.modifiersDetail.exact&(~0x1f00); - } -#endif - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n", - device == inputInfo.keyboard ? "keyboard" : "pointer"); - } - #endif - (*device->ActivateGrab)(device, grab, currentTime, TRUE); - - FixUpEventFromWindow(xE, grab->window, None, TRUE); - - (void) TryClientEvents(rClient(grab), xE, count, - filters[xE->u.u.type], - filters[xE->u.u.type], grab); - - if (device->sync.state == FROZEN_NO_EVENT) - { - if (device->sync.evcount < count) - { - Must_have_memory = TRUE; /* XXX */ - device->sync.event = (xEvent *)xrealloc(device->sync.event, - count* - sizeof(xEvent)); - Must_have_memory = FALSE; /* XXX */ - } - device->sync.evcount = count; - for (dxE = device->sync.event; --count >= 0; dxE++, xE++) - *dxE = *xE; - device->sync.state = FROZEN_WITH_EVENT; - } - return TRUE; - } - } - return FALSE; -} - -/** -"CheckDeviceGrabs" handles both keyboard and pointer events that may cause -a passive grab to be activated. If the event is a keyboard event, the -ancestors of the focus window are traced down and tried to see if they have -any passive grabs to be activated. If the focus window itself is reached and -its descendants contain the pointer, the ancestors of the window that the -pointer is in are then traced down starting at the focus window, otherwise no -grabs are activated. If the event is a pointer event, the ancestors of the -window that the pointer is in are traced down starting at the root until -CheckPassiveGrabs causes a passive grab to activate or all the windows are -tried. PRH -*/ - -Bool -CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE, - int checkFirst, int count) -{ - register int i; - register WindowPtr pWin = NULL; - register FocusClassPtr focus = device->focus; - - if (((xE->u.u.type == ButtonPress) -#if defined(XINPUT) && defined(XKB) - || (xE->u.u.type == DeviceButtonPress) -#endif - ) && (device->button->buttonsDown != 1)) - return FALSE; - - i = checkFirst; - - if (focus) - { - for (; i < focus->traceGood; i++) - { - pWin = focus->trace[i]; - if (pWin->optional && - CheckPassiveGrabsOnWindow(pWin, device, xE, count)) - return TRUE; - } - - if ((focus->win == NoneWin) || - (i >= spriteTraceGood) || - ((i > checkFirst) && (pWin != spriteTrace[i-1]))) - return FALSE; - } - - for (; i < spriteTraceGood; i++) - { - pWin = spriteTrace[i]; - if (pWin->optional && - CheckPassiveGrabsOnWindow(pWin, device, xE, count)) - return TRUE; - } - - return FALSE; -} - -void -DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count) -{ - WindowPtr focus = keybd->focus->win; - int mskidx = 0; - - if (focus == FollowKeyboardWin) - focus = inputInfo.keyboard->focus->win; - if (!focus) - return; - if (focus == PointerRootWin) - { - DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count); - return; - } - if ((focus == window) || IsParent(focus, window)) - { - if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count)) - return; - } - /* just deliver it to the focus window */ - FixUpEventFromWindow(xE, focus, None, FALSE); - if (xE->u.u.type & EXTENSION_EVENT_BASE) - mskidx = keybd->id; - (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type], - NullGrab, mskidx); -} - -void -DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev, - Bool deactivateGrab, int count) -{ - register GrabPtr grab = thisDev->grab; - int deliveries = 0; - register DeviceIntPtr dev; - register xEvent *dxE; - - if (grab->ownerEvents) - { - WindowPtr focus; - - if (thisDev->focus) - { - focus = thisDev->focus->win; - if (focus == FollowKeyboardWin) - focus = inputInfo.keyboard->focus->win; - } - else - focus = PointerRootWin; - if (focus == PointerRootWin) - deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow, - thisDev, count); - else if (focus && (focus == sprite.win || IsParent(focus, sprite.win))) - deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus, - thisDev, count); - else if (focus) - deliveries = DeliverDeviceEvents(focus, xE, grab, focus, - thisDev, count); - } - if (!deliveries) - { - FixUpEventFromWindow(xE, grab->window, None, TRUE); - deliveries = TryClientEvents(rClient(grab), xE, count, - (Mask)grab->eventMask, - filters[xE->u.u.type], grab); - if (deliveries && (xE->u.u.type == MotionNotify -#ifdef XINPUT - || xE->u.u.type == DeviceMotionNotify -#endif - )) - thisDev->valuator->motionHintWindow = grab->window; - } - if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify -#ifdef XINPUT - && xE->u.u.type != DeviceMotionNotify -#endif - )) - switch (thisDev->sync.state) - { - case FREEZE_BOTH_NEXT_EVENT: - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev == thisDev) - continue; - FreezeThaw(dev, TRUE); - if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) && - (CLIENT_BITS(dev->grab->resource) == - CLIENT_BITS(thisDev->grab->resource))) - dev->sync.state = FROZEN_NO_EVENT; - else - dev->sync.other = thisDev->grab; - } - /* fall through */ - case FREEZE_NEXT_EVENT: - thisDev->sync.state = FROZEN_WITH_EVENT; - FreezeThaw(thisDev, TRUE); - if (thisDev->sync.evcount < count) - { - Must_have_memory = TRUE; /* XXX */ - thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event, - count*sizeof(xEvent)); - Must_have_memory = FALSE; /* XXX */ - } - thisDev->sync.evcount = count; - for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++) - *dxE = *xE; - break; - } -} - -void -#ifdef XKB -CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count) -#else -ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count) -#endif -{ - int key, bit; - register BYTE *kptr; - register int i; - register CARD8 modifiers; - register CARD16 mask; - GrabPtr grab = keybd->grab; - Bool deactivateGrab = FALSE; - register KeyClassPtr keyc = keybd->key; -#ifdef XEVIE - static Window rootWin = 0; - - if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] && - (xevieMask & xevieFilters[xE->u.u.type])) { - key = xE->u.u.detail; - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - if((xE->u.u.type == KeyPress && (*kptr & bit)) || - (xE->u.u.type == KeyRelease && !(*kptr & bit))) - {} else { -#ifdef XKB - if(!noXkbExtension) - xevieKBEventSent = 1; -#endif - if(!xevieKBEventSent) - { - xeviekb = keybd; - if(!rootWin) { - rootWin = GetCurrentRootWindow()->drawable.id; - } - xE->u.keyButtonPointer.event = xeviewin->drawable.id; - xE->u.keyButtonPointer.root = rootWin; - 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; - WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE); -#ifdef XKB - if(noXkbExtension) -#endif - return; - } else { - xevieKBEventSent = 0; - } - } - } -#endif - - if (!syncEvents.playingEvents) - { - NoticeTime(xE); - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); - } - } -#ifdef XEVIE - /* 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 - ))) -#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]; -#if defined(XKB) && defined(XEVIE) - 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))) { - ErrorF("CoreProcessKbdEvent: Key %d %s\n",key, - (xE->u.u.type==KeyPress?"down":"up")); - } -#endif - switch (xE->u.u.type) - { - case KeyPress: - if (*kptr & bit) /* allow ddx to generate multiple downs */ - { - if (!modifiers) - { - xE->u.u.type = KeyRelease; - (*keybd->public.processInputProc)(xE, keybd, count); - xE->u.u.type = KeyPress; - /* release can have side effects, don't fall through */ - (*keybd->public.processInputProc)(xE, keybd, count); - } - return; - } - inputInfo.pointer->valuator->motionHintWindow = NullWindow; - *kptr |= bit; - keyc->prev_state = keyc->state; - for (i = 0, mask = 1; modifiers; i++, mask <<= 1) - { - if (mask & modifiers) - { - /* This key affects modifier "i" */ - keyc->modifierKeyCount[i]++; - keyc->state |= mask; - modifiers &= ~mask; - } - } - if (!grab && CheckDeviceGrabs(keybd, xE, 0, count)) - { - keybd->activatingKey = key; - return; - } - break; - case KeyRelease: - if (!(*kptr & bit)) /* guard against duplicates */ - return; - inputInfo.pointer->valuator->motionHintWindow = NullWindow; - *kptr &= ~bit; - keyc->prev_state = keyc->state; - for (i = 0, mask = 1; modifiers; i++, mask <<= 1) - { - if (mask & modifiers) { - /* This key affects modifier "i" */ - if (--keyc->modifierKeyCount[i] <= 0) { - keyc->state &= ~mask; - keyc->modifierKeyCount[i] = 0; - } - modifiers &= ~mask; - } - } - if (keybd->fromPassiveGrab && (key == keybd->activatingKey)) - deactivateGrab = TRUE; - break; - default: - FatalError("Impossible keyboard event"); - } - if (grab) - DeliverGrabbedEvent(xE, keybd, deactivateGrab, count); - else - DeliverFocusedEvent(keybd, xE, sprite.win, count); - if (deactivateGrab) - #ifdef NX_DEBUG_INPUT - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n"); - } - #endif - (*keybd->DeactivateGrab)(keybd); - #ifdef NX_DEBUG_INPUT - } - #endif -} - -#ifdef XKB -/* This function is used to set the key pressed or key released state - - this is only used when the pressing of keys does not cause - CoreProcessKeyEvent to be called, as in for example Mouse Keys. -*/ -void -FixKeyState (register xEvent *xE, register DeviceIntPtr keybd) -{ - int key, bit; - register BYTE *kptr; - register KeyClassPtr keyc = keybd->key; - - key = xE->u.u.detail; - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); -#ifdef DEBUG - if ((xkbDebugFlags&0x4)&& - ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) { - ErrorF("FixKeyState: Key %d %s\n",key, - (xE->u.u.type==KeyPress?"down":"up")); - } -#endif - switch (xE->u.u.type) - { - case KeyPress: - *kptr |= bit; - break; - case KeyRelease: - *kptr &= ~bit; - break; - default: - FatalError("Impossible keyboard event"); - } -} -#endif - -void -#ifdef XKB -CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count) -#else -ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count) -#endif -{ - register GrabPtr grab = mouse->grab; - Bool deactivateGrab = FALSE; - register ButtonClassPtr butc = mouse->button; -#ifdef XKB - XkbSrvInfoPtr xkbi; - - xkbi = inputInfo.keyboard->key->xkbInfo; -#endif -#ifdef XEVIE - if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState && - (xevieMask & xevieFilters[xE->u.u.type])) { - if(xevieEventSent) - xevieEventSent = 0; - else { - xeviemouse = mouse; - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n"); - } - #endif - WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE); - return; - } - } -#endif - - if (!syncEvents.playingEvents) - NoticeTime(xE) - XE_KBPTR.state = (butc->state | ( -#ifdef XKB - (noXkbExtension ? - inputInfo.keyboard->key->state : - xkbi->state.grab_mods) -#else - inputInfo.keyboard->key->state -#endif - )); - { - NoticeTime(xE); - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - /* see comment in EnqueueEvents regarding the next three lines */ - if (xE->u.u.type == MotionNotify) - XE_KBPTR.root = - sprite.hotPhys.pScreen->root->drawable.id; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); - } - } - if (xE->u.u.type != MotionNotify) - { - register int key; - register BYTE *kptr; - int bit; - - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; - - key = xE->u.u.detail; - kptr = &butc->down[key >> 3]; - bit = 1 << (key & 7); - switch (xE->u.u.type) - { - case ButtonPress: - mouse->valuator->motionHintWindow = NullWindow; - if (!(*kptr & bit)) - butc->buttonsDown++; - butc->motionMask = ButtonMotionMask; - *kptr |= bit; -#if !defined(XFree86Server) || !defined(XINPUT) - xE->u.u.detail = butc->map[key]; -#endif - #ifdef NX_DEBUG_INPUT - if (xE->u.u.detail == 0) - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0" - " for ButtonPress.\n"); - } - return; - } - #else - if (xE->u.u.detail == 0) - return; - #endif - if (xE->u.u.detail <= 5) - butc->state |= (Button1Mask >> 1) << xE->u.u.detail; - filters[MotionNotify] = Motion_Filter(butc); - if (!grab) - #ifdef NX_DEBUG_INPUT - if (CheckDeviceGrabs(mouse, xE, 0, count)) - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs" - " returned True for ButtonPress.\n"); - } - return; - } - #else - if (CheckDeviceGrabs(mouse, xE, 0, count)) - return; - #endif - break; - case ButtonRelease: - mouse->valuator->motionHintWindow = NullWindow; - if (*kptr & bit) - --butc->buttonsDown; - if (!butc->buttonsDown) - butc->motionMask = 0; - *kptr &= ~bit; -#if !defined(XFree86Server) || !defined(XINPUT) - xE->u.u.detail = butc->map[key]; -#endif - #ifdef NX_DEBUG_INPUT - if (xE->u.u.detail == 0) - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0" - " for ButtonRelease.\n"); - } - return; - } - #else - if (xE->u.u.detail == 0) - return; - #endif - if (xE->u.u.detail <= 5) - butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail); - filters[MotionNotify] = Motion_Filter(butc); - if (!butc->state && mouse->fromPassiveGrab) - deactivateGrab = TRUE; - break; - default: - FatalError("bogus pointer event from ddx"); - } - } - #ifdef NX_DEBUG_INPUT - else if (!CheckMotion(xE)) - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False" - " for MotionNotify.\n"); - } - return; - } - if (grab) - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed " - "events (count = %d).\n", count); - } - DeliverGrabbedEvent(xE, mouse, deactivateGrab, count); - } - else - { - if (nxagentDebugInput == 1) - { - fprintf(stderr, "ProcessPointerEvent: Going to deliver device " - "events (count = %d).\n", count); - } - DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow, - mouse, count); - } - #else - else if (!CheckMotion(xE)) - return; - if (grab) - DeliverGrabbedEvent(xE, mouse, deactivateGrab, count); - else - DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow, - mouse, count); - #endif - if (deactivateGrab) - #ifdef NX_DEBUG_INPUT - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n"); - } - #endif - (*mouse->DeactivateGrab)(mouse); - #ifdef NX_DEBUG_INPUT - } - #endif -} - -#define AtMostOneClient \ - (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask) - -void -RecalculateDeliverableEvents(pWin) - register WindowPtr pWin; -{ - register OtherClients *others; - register WindowPtr pChild; - - pChild = pWin; - while (1) - { - if (pChild->optional) - { - pChild->optional->otherEventMasks = 0; - for (others = wOtherClients(pChild); others; others = others->next) - { - pChild->optional->otherEventMasks |= others->mask; - } - } - pChild->deliverableEvents = pChild->eventMask| - wOtherEventMasks(pChild); - if (pChild->parent) - pChild->deliverableEvents |= - (pChild->parent->deliverableEvents & - ~wDontPropagateMask(pChild) & PropagateMask); - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - while (!pChild->nextSib && (pChild != pWin)) - pChild = pChild->parent; - if (pChild == pWin) - break; - pChild = pChild->nextSib; - } -} - -/** - * - * \param value must conform to DeleteType - */ -int -OtherClientGone(void * value, XID id) -{ - register OtherClientsPtr other, prev; - register WindowPtr pWin = (WindowPtr)value; - - prev = 0; - for (other = wOtherClients(pWin); other; other = other->next) - { - if (other->resource == id) - { - if (prev) - prev->next = other->next; - else - { - if (!(pWin->optional->otherClients = other->next)) - CheckWindowOptionalNeed (pWin); - } - xfree(other); - RecalculateDeliverableEvents(pWin); - return(Success); - } - prev = other; - } - FatalError("client not on event list"); - /*NOTREACHED*/ - return -1; /* make compiler happy */ -} - -int -EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask) -{ - Mask check; - OtherClients * others; - - if (mask & ~AllEventMasks) - { - client->errorValue = mask; - return BadValue; - } - check = (mask & AtMostOneClient); - if (check & (pWin->eventMask|wOtherEventMasks(pWin))) - { /* It is illegal for two different - clients to select on any of the - events for AtMostOneClient. However, - it is OK, for some client to - continue selecting on one of those - events. */ - if ((wClient(pWin) != client) && (check & pWin->eventMask)) - return BadAccess; - for (others = wOtherClients (pWin); others; others = others->next) - { - if (!SameClient(others, client) && (check & others->mask)) - return BadAccess; - } - } - if (wClient (pWin) == client) - { - check = pWin->eventMask; -#ifdef SGIMISC - pWin->eventMask = - (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask); -#else - pWin->eventMask = mask; -#endif - } - else - { - for (others = wOtherClients (pWin); others; others = others->next) - { - if (SameClient(others, client)) - { - check = others->mask; -#ifdef SGIMISC - mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask); -#endif - if (mask == 0) - { - FreeResource(others->resource, RT_NONE); - return Success; - } - else - others->mask = mask; - goto maskSet; - } - } - check = 0; - if (!pWin->optional && !MakeWindowOptional (pWin)) - return BadAlloc; - others = (OtherClients *) xalloc(sizeof(OtherClients)); - if (!others) - return BadAlloc; - others->mask = mask; - others->resource = FakeClientID(client->index); - others->next = pWin->optional->otherClients; - pWin->optional->otherClients = others; - if (!AddResource(others->resource, RT_OTHERCLIENT, (void *)pWin)) - return BadAlloc; - } -maskSet: - if ((inputInfo.pointer->valuator->motionHintWindow == pWin) && - (mask & PointerMotionHintMask) && - !(check & PointerMotionHintMask) && - !inputInfo.pointer->grab) - inputInfo.pointer->valuator->motionHintWindow = NullWindow; - RecalculateDeliverableEvents(pWin); - return Success; -} - -int -EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client, - Mask mask, Bool *checkOptional) -{ - register int i, free; - - if ((mask & ~PropagateMask) && !permitOldBugs) - { - client->errorValue = mask; - return BadValue; - } - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]--; - if (!mask) - i = 0; - else - { - for (i = DNPMCOUNT, free = 0; --i > 0; ) - { - if (!DontPropagateRefCnts[i]) - free = i; - else if (mask == DontPropagateMasks[i]) - break; - } - if (!i && free) - { - i = free; - DontPropagateMasks[i] = mask; - } - } - if (i || !mask) - { - pWin->dontPropagate = i; - if (i) - DontPropagateRefCnts[i]++; - if (pWin->optional) - { - pWin->optional->dontPropagateMask = mask; - *checkOptional = TRUE; - } - } - else - { - if (!pWin->optional && !MakeWindowOptional (pWin)) - { - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]++; - return BadAlloc; - } - pWin->dontPropagate = 0; - pWin->optional->dontPropagateMask = mask; - } - RecalculateDeliverableEvents(pWin); - return Success; -} - -static WindowPtr -CommonAncestor( - register WindowPtr a, - register WindowPtr b) -{ - for (b = b->parent; b; b = b->parent) - if (IsParent(b, a)) return b; - return NullWindow; -} - -static void -EnterLeaveEvent( - int type, - int mode, - int detail, - register WindowPtr pWin, - Window child) -{ - xEvent event; - register DeviceIntPtr keybd = inputInfo.keyboard; - WindowPtr focus; - register DeviceIntPtr mouse = inputInfo.pointer; - register GrabPtr grab = mouse->grab; - Mask mask; - - if ((pWin == mouse->valuator->motionHintWindow) && - (detail != NotifyInferior)) - mouse->valuator->motionHintWindow = NullWindow; - if (grab) - { - mask = (pWin == grab->window) ? grab->eventMask : 0; - if (grab->ownerEvents) - mask |= EventMaskForClient(pWin, rClient(grab)); - } - else - { - mask = pWin->eventMask | wOtherEventMasks(pWin); - } - if (mask & filters[type]) - { - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = type; - event.u.u.detail = detail; - event.u.enterLeave.time = currentTime.milliseconds; - event.u.enterLeave.rootX = sprite.hot.x; - event.u.enterLeave.rootY = sprite.hot.y; - /* Counts on the same initial structure of crossing & button events! */ - FixUpEventFromWindow(&event, pWin, None, FALSE); - /* Enter/Leave events always set child */ - event.u.enterLeave.child = child; - event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? - ELFlagSameScreen : 0; -#ifdef XKB - if (!noXkbExtension) { - event.u.enterLeave.state = mouse->button->state & 0x1f00; - event.u.enterLeave.state |= - XkbGrabStateFromRec(&keybd->key->xkbInfo->state); - } else -#endif - event.u.enterLeave.state = keybd->key->state | mouse->button->state; - event.u.enterLeave.mode = mode; - focus = keybd->focus->win; - if ((focus != NoneWin) && - ((pWin == focus) || (focus == PointerRootWin) || - IsParent(focus, pWin))) - event.u.enterLeave.flags |= ELFlagFocus; - if (grab) - (void)TryClientEvents(rClient(grab), &event, 1, mask, - filters[type], grab); - else - (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], - NullGrab, 0); - } - if ((type == EnterNotify) && (mask & KeymapStateMask)) - { - xKeymapEvent ke; - -#ifdef XCSECURITY - ClientPtr client = grab ? rClient(grab) - : clients[CLIENT_ID(pWin->drawable.id)]; - if (!SecurityCheckDeviceAccess(client, keybd, FALSE)) - { - bzero((char *)&ke.map[0], 31); - } - else -#endif - memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31); - ke.type = KeymapNotify; - if (grab) - (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask, - KeymapStateMask, grab); - else - (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab, 0); - } -} - -static void -EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail) -{ - WindowPtr parent = child->parent; - - if (ancestor == parent) - return; - EnterNotifies(ancestor, parent, mode, detail); - EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id); -} - -static void -LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail) -{ - register WindowPtr pWin; - - if (ancestor == child) - return; - for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent) - { - EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id); - child = pWin; - } -} - -static void -DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode) -{ - if (fromWin == toWin) - return; - if (IsParent(fromWin, toWin)) - { - EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None); - EnterNotifies(fromWin, toWin, mode, NotifyVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None); - } - else if (IsParent(toWin, fromWin)) - { - EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None); - LeaveNotifies(fromWin, toWin, mode, NotifyVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None); - } - else - { /* neither fromWin nor toWin is descendent of the other */ - WindowPtr common = CommonAncestor(toWin, fromWin); - /* common == NullWindow ==> different screens */ - EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None); - LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual); - EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None); - } -} - -static void -FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin) -{ - xEvent event; - -#ifdef XINPUT - if (dev != inputInfo.keyboard) - { - DeviceFocusEvent(dev, type, mode, detail, pWin); - return; - } -#endif - event.u.focus.mode = mode; - event.u.u.type = type; - event.u.u.detail = detail; - event.u.focus.window = pWin->drawable.id; - (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab, - 0); - if ((type == FocusIn) && - ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) - { - xKeymapEvent ke; -#ifdef XCSECURITY - ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)]; - if (!SecurityCheckDeviceAccess(client, dev, FALSE)) - { - bzero((char *)&ke.map[0], 31); - } - else -#endif - memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31); - ke.type = KeymapNotify; - (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab, 0); - } -} - - /* - * recursive because it is easier - * no-op if child not descended from ancestor - */ -static Bool -FocusInEvents( - DeviceIntPtr dev, - WindowPtr ancestor, WindowPtr child, WindowPtr skipChild, - int mode, int detail, - Bool doAncestor) -{ - if (child == NullWindow) - return ancestor == NullWindow; - if (ancestor == child) - { - if (doAncestor) - FocusEvent(dev, FocusIn, mode, detail, child); - return TRUE; - } - if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail, - doAncestor)) - { - if (child != skipChild) - FocusEvent(dev, FocusIn, mode, detail, child); - return TRUE; - } - return FALSE; -} - -/* dies horribly if ancestor is not an ancestor of child */ -static void -FocusOutEvents( - DeviceIntPtr dev, - WindowPtr child, WindowPtr ancestor, - int mode, int detail, - Bool doAncestor) -{ - register WindowPtr pWin; - - for (pWin = child; pWin != ancestor; pWin = pWin->parent) - FocusEvent(dev, FocusOut, mode, detail, pWin); - if (doAncestor) - FocusEvent(dev, FocusOut, mode, detail, ancestor); -} - -void -DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) -{ - int out, in; /* for holding details for to/from - PointerRoot/None */ - int i; - - if (fromWin == toWin) - return; - out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; - in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; - /* wrong values if neither, but then not referenced */ - - if ((toWin == NullWindow) || (toWin == PointerRootWin)) - { - if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) - { - if (fromWin == PointerRootWin) - FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer, - TRUE); - /* Notify all the roots */ -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); - else -#endif - for (i=0; iroot); - } - else - { - if (IsParent(fromWin, sprite.win)) - FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer, - FALSE); - FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin); - /* next call catches the root too, if the screen changed */ - FocusOutEvents(dev, fromWin->parent, NullWindow, mode, - NotifyNonlinearVirtual, FALSE); - } - /* Notify all the roots */ -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root); - else -#endif - for (i=0; iroot); - if (toWin == PointerRootWin) - (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode, - NotifyPointer, TRUE); - } - else - { - if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) - { - if (fromWin == PointerRootWin) - FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer, - TRUE); -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); - else -#endif - for (i=0; iroot); - if (toWin->parent != NullWindow) - (void)FocusInEvents(dev, ROOT, toWin, toWin, mode, - NotifyNonlinearVirtual, TRUE); - FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin); - if (IsParent(toWin, sprite.win)) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode, - NotifyPointer, FALSE); - } - else - { - if (IsParent(toWin, fromWin)) - { - FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin); - FocusOutEvents(dev, fromWin->parent, toWin, mode, - NotifyVirtual, FALSE); - FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin); - if ((IsParent(toWin, sprite.win)) && - (sprite.win != fromWin) && - (!IsParent(fromWin, sprite.win)) && - (!IsParent(sprite.win, fromWin))) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, - mode, NotifyPointer, FALSE); - } - else - if (IsParent(fromWin, toWin)) - { - if ((IsParent(fromWin, sprite.win)) && - (sprite.win != fromWin) && - (!IsParent(toWin, sprite.win)) && - (!IsParent(sprite.win, toWin))) - FocusOutEvents(dev, sprite.win, fromWin, mode, - NotifyPointer, FALSE); - FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin); - (void)FocusInEvents(dev, fromWin, toWin, toWin, mode, - NotifyVirtual, FALSE); - FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin); - } - else - { - /* neither fromWin or toWin is child of other */ - WindowPtr common = CommonAncestor(toWin, fromWin); - /* common == NullWindow ==> different screens */ - if (IsParent(fromWin, sprite.win)) - FocusOutEvents(dev, sprite.win, fromWin, mode, - NotifyPointer, FALSE); - FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin); - if (fromWin->parent != NullWindow) - FocusOutEvents(dev, fromWin->parent, common, mode, - NotifyNonlinearVirtual, FALSE); - if (toWin->parent != NullWindow) - (void)FocusInEvents(dev, common, toWin, toWin, mode, - NotifyNonlinearVirtual, FALSE); - FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin); - if (IsParent(toWin, sprite.win)) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, - mode, NotifyPointer, FALSE); - } - } - } -} - -int -SetInputFocus( - ClientPtr client, - DeviceIntPtr dev, - Window focusID, - CARD8 revertTo, - Time ctime, - Bool followOK) -{ - register FocusClassPtr focus; - register WindowPtr focusWin; - int mode; - TimeStamp time; - - UpdateCurrentTime(); - if ((revertTo != RevertToParent) && - (revertTo != RevertToPointerRoot) && - (revertTo != RevertToNone) && - ((revertTo != RevertToFollowKeyboard) || !followOK)) - { - client->errorValue = revertTo; - return BadValue; - } - time = ClientTimeToServerTime(ctime); - if ((focusID == None) || (focusID == PointerRoot)) - focusWin = (WindowPtr)(long)focusID; - else if ((focusID == FollowKeyboard) && followOK) - focusWin = inputInfo.keyboard->focus->win; - else if (!(focusWin = SecurityLookupWindow(focusID, client, - SecurityReadAccess))) - return BadWindow; - else - { - /* It is a match error to try to set the input focus to an - unviewable window. */ - - if(!focusWin->realized) - return(BadMatch); - } - focus = dev->focus; - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, focus->time) == EARLIER)) - return Success; - mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal; - if (focus->win == FollowKeyboardWin) - DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode); - else - DoFocusEvents(dev, focus->win, focusWin, mode); - focus->time = time; - focus->revert = revertTo; - if (focusID == FollowKeyboard) - focus->win = FollowKeyboardWin; - else - focus->win = focusWin; - if ((focusWin == NoneWin) || (focusWin == PointerRootWin)) - focus->traceGood = 0; - else - { - int depth = 0; - register WindowPtr pWin; - - for (pWin = focusWin; pWin; pWin = pWin->parent) depth++; - if (depth > focus->traceSize) - { - focus->traceSize = depth+1; - Must_have_memory = TRUE; /* XXX */ - focus->trace = (WindowPtr *)xrealloc(focus->trace, - focus->traceSize * - sizeof(WindowPtr)); - Must_have_memory = FALSE; /* XXX */ - } - focus->traceGood = depth; - for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) - focus->trace[depth] = pWin; - } - return Success; -} - -int -ProcSetInputFocus(client) - ClientPtr client; -{ - REQUEST(xSetInputFocusReq); - - REQUEST_SIZE_MATCH(xSetInputFocusReq); -#ifdef XCSECURITY - if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE)) - return Success; -#endif - return SetInputFocus(client, inputInfo.keyboard, stuff->focus, - stuff->revertTo, stuff->time, FALSE); -} - -int -ProcGetInputFocus(ClientPtr client) -{ - xGetInputFocusReply rep; - /* REQUEST(xReq); */ - FocusClassPtr focus = inputInfo.keyboard->focus; - - REQUEST_SIZE_MATCH(xReq); - memset(&rep, 0, sizeof(xGetInputFocusReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (focus->win == NoneWin) - rep.focus = None; - else if (focus->win == PointerRootWin) - rep.focus = PointerRoot; - else rep.focus = focus->win->drawable.id; - rep.revertTo = focus->revert; - WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep); - return Success; -} - -int -ProcGrabPointer(ClientPtr client) -{ - xGrabPointerReply rep; - DeviceIntPtr device = inputInfo.pointer; - GrabPtr grab; - WindowPtr pWin, confineTo; - CursorPtr cursor, oldCursor; - REQUEST(xGrabPointerReq); - TimeStamp time; - - REQUEST_SIZE_MATCH(xGrabPointerReq); - UpdateCurrentTime(); - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) - { - client->errorValue = stuff->ownerEvents; - return BadValue; - } - if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index); - } - #endif - if (stuff->confineTo == None) - confineTo = NullWindow; - else - { - confineTo = SecurityLookupWindow(stuff->confineTo, client, - SecurityReadAccess); - if (!confineTo) - return BadWindow; - } - if (stuff->cursor == None) - cursor = NullCursor; - else - { - cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor, - RT_CURSOR, SecurityReadAccess); - if (!cursor) - { - client->errorValue = stuff->cursor; - return BadCursor; - } - } - /* at this point, some sort of reply is guaranteed. */ - time = ClientTimeToServerTime(stuff->time); - memset(&rep, 0, sizeof(xGrabPointerReply)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - grab = device->grab; - if ((grab) && !SameClient(grab, client)) - rep.status = AlreadyGrabbed; - else if ((!pWin->realized) || - (confineTo && - !(confineTo->realized && BorderSizeNotEmpty(confineTo)))) - rep.status = GrabNotViewable; - else if (device->sync.frozen && - device->sync.other && !SameClient(device->sync.other, client)) - rep.status = GrabFrozen; - else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->grabTime) == EARLIER)) - rep.status = GrabInvalidTime; - else - { - GrabRec tempGrab; - - oldCursor = NullCursor; - if (grab) - { - if (grab->confineTo && !confineTo) - ConfineCursorToWindow(ROOT, FALSE, FALSE); - oldCursor = grab->cursor; - } - tempGrab.cursor = cursor; - tempGrab.resource = client->clientAsMask; - tempGrab.ownerEvents = stuff->ownerEvents; - tempGrab.eventMask = stuff->eventMask; - tempGrab.confineTo = confineTo; - tempGrab.window = pWin; - tempGrab.keyboardMode = stuff->keyboardMode; - tempGrab.pointerMode = stuff->pointerMode; - tempGrab.device = device; - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n"); - } - #endif - (*device->ActivateGrab)(device, &tempGrab, time, FALSE); - if (oldCursor) - FreeCursor (oldCursor, (Cursor)0); - rep.status = GrabSuccess; - } - WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); - return Success; -} - -int -ProcChangeActivePointerGrab(ClientPtr client) -{ - DeviceIntPtr device = inputInfo.pointer; - register GrabPtr grab = device->grab; - CursorPtr newCursor, oldCursor; - REQUEST(xChangeActivePointerGrabReq); - TimeStamp time; - - REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq); - if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - if (stuff->cursor == None) - newCursor = NullCursor; - else - { - newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor, - RT_CURSOR, SecurityReadAccess); - if (!newCursor) - { - client->errorValue = stuff->cursor; - return BadCursor; - } - } - if (!grab) - return Success; - if (!SameClient(grab, client)) - return Success; - time = ClientTimeToServerTime(stuff->time); - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->grabTime) == EARLIER)) - return Success; - oldCursor = grab->cursor; - grab->cursor = newCursor; - if (newCursor) - newCursor->refcnt++; - PostNewCursor(); - if (oldCursor) - FreeCursor(oldCursor, (Cursor)0); - grab->eventMask = stuff->eventMask; - return Success; -} - -int -ProcUngrabPointer(ClientPtr client) -{ - DeviceIntPtr device = inputInfo.pointer; - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index); - } - #endif - REQUEST_SIZE_MATCH(xResourceReq); - UpdateCurrentTime(); - grab = device->grab; - time = ClientTimeToServerTime(stuff->id); - if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->grabTime) != EARLIER) && - (grab) && SameClient(grab, client)) - #ifdef NX_DEBUG_INPUT - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n"); - } - #endif - (*device->DeactivateGrab)(device); - #ifdef NX_DEBUG_INPUT - } - else - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n", - currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds); - } - } - #endif - return Success; -} - -int -GrabDevice(register ClientPtr client, register DeviceIntPtr dev, - unsigned this_mode, unsigned other_mode, Window grabWindow, - unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status) -{ - register WindowPtr pWin; - register GrabPtr grab; - TimeStamp time; - - UpdateCurrentTime(); - if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync)) - { - client->errorValue = this_mode; - return BadValue; - } - if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync)) - { - client->errorValue = other_mode; - return BadValue; - } - if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) - { - client->errorValue = ownerEvents; - return BadValue; - } - pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - time = ClientTimeToServerTime(ctime); - grab = dev->grab; - if (grab && !SameClient(grab, client)) - *status = AlreadyGrabbed; - else if (!pWin->realized) - *status = GrabNotViewable; - else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, dev->grabTime) == EARLIER)) - *status = GrabInvalidTime; - else if (dev->sync.frozen && - dev->sync.other && !SameClient(dev->sync.other, client)) - *status = GrabFrozen; - else - { - GrabRec tempGrab; - - tempGrab.window = pWin; - tempGrab.resource = client->clientAsMask; - tempGrab.ownerEvents = ownerEvents; - tempGrab.keyboardMode = this_mode; - tempGrab.pointerMode = other_mode; - tempGrab.eventMask = mask; - tempGrab.device = dev; - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n"); - } - #endif - (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE); - *status = GrabSuccess; - } - return Success; -} - -int -ProcGrabKeyboard(ClientPtr client) -{ - xGrabKeyboardReply rep; - REQUEST(xGrabKeyboardReq); - int result; - - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index); - } - #endif - REQUEST_SIZE_MATCH(xGrabKeyboardReq); - memset(&rep, 0, sizeof(xGrabKeyboardReply)); - -#ifdef XCSECURITY - if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE)) - { - result = Success; - rep.status = AlreadyGrabbed; - } - else -#endif - result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode, - stuff->pointerMode, stuff->grabWindow, - stuff->ownerEvents, stuff->time, - KeyPressMask | KeyReleaseMask, &rep.status); - if (result != Success) - return result; - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep); - return Success; -} - -int -ProcUngrabKeyboard(ClientPtr client) -{ - DeviceIntPtr device = inputInfo.keyboard; - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - #ifdef NX_DEBUG_INPUT - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index); - } - #endif - REQUEST_SIZE_MATCH(xResourceReq); - UpdateCurrentTime(); - grab = device->grab; - time = ClientTimeToServerTime(stuff->id); - if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->grabTime) != EARLIER) && - (grab) && SameClient(grab, client)) - #ifdef NX_DEBUG_INPUT - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n"); - } - #endif - (*device->DeactivateGrab)(device); - #ifdef NX_DEBUG_INPUT - } - else - { - if (nxagentDebugInputDevices == 1) - { - fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n", - currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds); - } - } - #endif - return Success; -} - -int -ProcQueryPointer(ClientPtr client) -{ - xQueryPointerReply rep; - WindowPtr pWin, t; - REQUEST(xResourceReq); - DeviceIntPtr mouse = inputInfo.pointer; - - REQUEST_SIZE_MATCH(xResourceReq); - pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - if (mouse->valuator->motionHintWindow) - MaybeStopHint(mouse, client); - memset(&rep, 0, sizeof(xQueryPointerReply)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.mask = mouse->button->state | inputInfo.keyboard->key->state; - rep.length = 0; - rep.root = (ROOT)->drawable.id; - rep.rootX = sprite.hot.x; - rep.rootY = sprite.hot.y; - rep.child = None; - if (sprite.hot.pScreen == pWin->drawable.pScreen) - { - rep.sameScreen = xTrue; - rep.winX = sprite.hot.x - pWin->drawable.x; - rep.winY = sprite.hot.y - pWin->drawable.y; - for (t = sprite.win; t; t = t->parent) - if (t->parent == pWin) + /* When a window is shaped, a further check + * is made to see if the point is inside + * borderSize + */ + && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) + && (!wInputShape(pWin) || + RegionContainsPoint( + wInputShape(pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box)) +#endif + ) + { + if (spriteTraceGood >= spriteTraceSize) { - rep.child = t->drawable.id; - break; + spriteTraceSize += 10; + Must_have_memory = TRUE; /* XXX */ + spriteTrace = (WindowPtr *)xrealloc( + spriteTrace, spriteTraceSize*sizeof(WindowPtr)); + Must_have_memory = FALSE; /* XXX */ } + spriteTrace[spriteTraceGood++] = pWin; + pWin = pWin->firstChild; + } + else + pWin = pWin->nextSib; } - else - { - rep.sameScreen = xFalse; - rep.winX = 0; - rep.winY = 0; - } + return spriteTrace[spriteTraceGood-1]; +} +// static Bool +// CheckMotion(xEvent *xE) +// { +// WindowPtr prevSpriteWin = sprite.win; +// #ifdef PANORAMIX - if(!noPanoramiXExtension) { - rep.rootX += panoramiXdataPtr[0].x; - rep.rootY += panoramiXdataPtr[0].y; - if(stuff->id == rep.root) { - rep.winX += panoramiXdataPtr[0].x; - rep.winY += panoramiXdataPtr[0].y; - } - } +// if(!noPanoramiXExtension) +// return XineramaCheckMotion(xE); #endif - WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); - - return(Success); -} +// if (xE && !syncEvents.playingEvents) +// { +// if (sprite.hot.pScreen != sprite.hotPhys.pScreen) +// { +// sprite.hot.pScreen = sprite.hotPhys.pScreen; +// ROOT = sprite.hot.pScreen->root; +// } +#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) +// ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y); +#endif +// sprite.hotPhys = sprite.hot; +// +// /* +// * This code force cursor position to be inside the +// * root window of the agent. We can't view a reason +// * to do this and it interacts in an undesirable way +// * with toggling fullscreen. +// * +// * if ((sprite.hotPhys.x != XE_KBPTR.rootX) || +// * (sprite.hotPhys.y != XE_KBPTR.rootY)) +// * { +// * (*sprite.hotPhys.pScreen->SetCursorPosition)( +// * sprite.hotPhys.pScreen, +// * sprite.hotPhys.x, sprite.hotPhys.y, FALSE); +// * } +// */ +// +// XE_KBPTR.rootX = sprite.hot.x; +// 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 & +// Motion_Filter(inputInfo.pointer->button)) +// !syncEvents.playingEvents) +// { +// /* XXX Do PointerNonInterestBox here */ +// } +#endif +// if (sprite.win != prevSpriteWin) +// { +// if (prevSpriteWin != NullWindow) { +// if (!xE) +// UpdateCurrentTimeIf(); +// DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); +// } +// PostNewCursor(); +// return FALSE; +// } +// return TRUE; +// } void -InitEvents() +DefineInitialRootWindow(register WindowPtr win) { - int i; + register ScreenPtr pScreen = win->drawable.pScreen; + #ifdef VIEWPORT_FRAME + extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr); + #endif + extern int nxagentShadowInit(ScreenPtr, WindowPtr); - sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL; - inputInfo.numDevices = 0; - inputInfo.devices = (DeviceIntPtr)NULL; - inputInfo.off_devices = (DeviceIntPtr)NULL; - inputInfo.keyboard = (DeviceIntPtr)NULL; - inputInfo.pointer = (DeviceIntPtr)NULL; - if (spriteTraceSize == 0) - { - spriteTraceSize = 32; - spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr)); - if (!spriteTrace) - FatalError("failed to allocate spriteTrace"); - } - spriteTraceGood = 0; - lastEventMask = OwnerGrabButtonMask; - filters[MotionNotify] = PointerMotionMask; + sprite.hotPhys.pScreen = pScreen; + sprite.hotPhys.x = pScreen->width / 2; + sprite.hotPhys.y = pScreen->height / 2; + sprite.hot = sprite.hotPhys; + sprite.hotLimits.x2 = pScreen->width; + sprite.hotLimits.y2 = pScreen->height; #ifdef XEVIE xeviewin = #endif - sprite.win = NullWindow; - sprite.current = NullCursor; - sprite.hotLimits.x1 = 0; - sprite.hotLimits.y1 = 0; - sprite.hotLimits.x2 = 0; - sprite.hotLimits.y2 = 0; + sprite.win = win; + sprite.current = wCursor (win); + sprite.current->refcnt++; + spriteTraceGood = 1; + ROOT = win; + (*pScreen->CursorLimits) ( + pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits); sprite.confined = FALSE; - syncEvents.replayDev = (DeviceIntPtr)NULL; - syncEvents.replayWin = NullWindow; - while (syncEvents.pending) - { - QdEventPtr next = syncEvents.pending->next; - xfree(syncEvents.pending); - syncEvents.pending = next; + (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits); + (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE); + (*pScreen->DisplayCursor) (pScreen, sprite.current); + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + sprite.hotLimits.x1 = -panoramiXdataPtr[0].x; + sprite.hotLimits.y1 = -panoramiXdataPtr[0].y; + sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; + sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; + sprite.physLimits = sprite.hotLimits; + sprite.confineWin = NullWindow; +#ifdef SHAPE + sprite.hotShape = NullRegion; +#endif + sprite.screen = pScreen; + /* gotta UNINIT these someplace */ + RegionNull(&sprite.Reg1); + RegionNull(&sprite.Reg2); } - syncEvents.pendtail = &syncEvents.pending; - syncEvents.playingEvents = FALSE; - syncEvents.time.months = 0; - syncEvents.time.milliseconds = 0; /* hardly matters */ - currentTime.months = 0; - currentTime.milliseconds = GetTimeInMillis(); - lastDeviceEventTime = currentTime; - for (i = 0; i < DNPMCOUNT; i++) +#endif + + #ifdef VIEWPORT_FRAME + nxagentInitViewportFrame(pScreen, win); + #endif + + if (nxagentOption(Shadow)) { - DontPropagateMasks[i] = 0; - DontPropagateRefCnts[i] = 0; + if (nxagentShadowInit(pScreen, win) == -1) + { + FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName); + } } } -void -CloseDownEvents(void) -{ - xfree(spriteTrace); - spriteTrace = NULL; - spriteTraceSize = 0; -} - int ProcSendEvent(ClientPtr client) { @@ -4604,444 +630,3 @@ ProcSendEvent(ClientPtr client) NullGrab, 0); return Success; } - -int -ProcUngrabKey(ClientPtr client) -{ - REQUEST(xUngrabKeyReq); - WindowPtr pWin; - GrabRec tempGrab; - DeviceIntPtr keybd = inputInfo.keyboard; - - REQUEST_SIZE_MATCH(xUngrabKeyReq); - pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - - if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) || - (stuff->key < keybd->key->curKeySyms.minKeyCode)) - && (stuff->key != AnyKey)) - { - client->errorValue = stuff->key; - return BadValue; - } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - tempGrab.resource = client->clientAsMask; - tempGrab.device = keybd; - tempGrab.window = pWin; - tempGrab.modifiersDetail.exact = stuff->modifiers; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = inputInfo.keyboard; - tempGrab.type = KeyPress; - tempGrab.detail.exact = stuff->key; - tempGrab.detail.pMask = NULL; - - if (!DeletePassiveGrabFromList(&tempGrab)) - return(BadAlloc); - return(Success); -} - -int -ProcGrabKey(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xGrabKeyReq); - GrabPtr grab; - DeviceIntPtr keybd = inputInfo.keyboard; - - REQUEST_SIZE_MATCH(xGrabKeyReq); - if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse)) - { - client->errorValue = stuff->ownerEvents; - return(BadValue); - } - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) || - (stuff->key < keybd->key->curKeySyms.minKeyCode)) - && (stuff->key != AnyKey)) - { - client->errorValue = stuff->key; - return BadValue; - } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - - grab = CreateGrab(client->index, keybd, pWin, - (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents, - (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode, - keybd, stuff->modifiers, KeyPress, stuff->key, - NullWindow, NullCursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(grab); -} - - -int -ProcGrabButton(ClientPtr client) -{ - WindowPtr pWin, confineTo; - REQUEST(xGrabButtonReq); - CursorPtr cursor; - GrabPtr grab; - - REQUEST_SIZE_MATCH(xGrabButtonReq); - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) - { - client->errorValue = stuff->ownerEvents; - return BadValue; - } - if (stuff->eventMask & ~PointerGrabMask) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - if (stuff->confineTo == None) - confineTo = NullWindow; - else { - confineTo = SecurityLookupWindow(stuff->confineTo, client, - SecurityReadAccess); - if (!confineTo) - return BadWindow; - } - if (stuff->cursor == None) - cursor = NullCursor; - else - { - cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor, - RT_CURSOR, SecurityReadAccess); - if (!cursor) - { - client->errorValue = stuff->cursor; - return BadCursor; - } - } - - - grab = CreateGrab(client->index, inputInfo.pointer, pWin, - permitOldBugs ? (Mask)(stuff->eventMask | - ButtonPressMask | ButtonReleaseMask) : - (Mask)stuff->eventMask, - (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode, - (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers, - ButtonPress, stuff->button, confineTo, cursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(grab); -} - -int -ProcUngrabButton(ClientPtr client) -{ - REQUEST(xUngrabButtonReq); - WindowPtr pWin; - GrabRec tempGrab; - - REQUEST_SIZE_MATCH(xUngrabButtonReq); - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess); - if (!pWin) - return BadWindow; - tempGrab.resource = client->clientAsMask; - tempGrab.device = inputInfo.pointer; - tempGrab.window = pWin; - tempGrab.modifiersDetail.exact = stuff->modifiers; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = inputInfo.keyboard; - tempGrab.type = ButtonPress; - tempGrab.detail.exact = stuff->button; - tempGrab.detail.pMask = NULL; - - if (!DeletePassiveGrabFromList(&tempGrab)) - return(BadAlloc); - return(Success); -} - -void -DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) -{ - WindowPtr parent; - DeviceIntPtr mouse = inputInfo.pointer; - DeviceIntPtr keybd = inputInfo.keyboard; - FocusClassPtr focus = keybd->focus; - OtherClientsPtr oc; - GrabPtr passive; - - - /* Deactivate any grabs performed on this window, before making any - input focus changes. */ - - if (mouse->grab && - ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin))) - (*mouse->DeactivateGrab)(mouse); - - /* Deactivating a keyboard grab should cause focus events. */ - - if (keybd->grab && (keybd->grab->window == pWin)) - (*keybd->DeactivateGrab)(keybd); - - /* If the focus window is a root window (ie. has no parent) then don't - delete the focus from it. */ - - if ((pWin == focus->win) && (pWin->parent != NullWindow)) - { - int focusEventMode = NotifyNormal; - - /* If a grab is in progress, then alter the mode of focus events. */ - - if (keybd->grab) - focusEventMode = NotifyWhileGrabbed; - - switch (focus->revert) - { - case RevertToNone: - DoFocusEvents(keybd, pWin, NoneWin, focusEventMode); - focus->win = NoneWin; - focus->traceGood = 0; - break; - case RevertToParent: - parent = pWin; - do - { - parent = parent->parent; - focus->traceGood--; - } while (!parent->realized -/* This would be a good protocol change -- windows being reparented - during SaveSet processing would cause the focus to revert to the - nearest enclosing window which will survive the death of the exiting - client, instead of ending up reverting to a dying window and thence - to None - */ -#ifdef NOTDEF - || clients[CLIENT_ID(parent->drawable.id)]->clientGone -#endif - ); - DoFocusEvents(keybd, pWin, parent, focusEventMode); - focus->win = parent; - focus->revert = RevertToNone; - break; - case RevertToPointerRoot: - DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); - focus->win = PointerRootWin; - focus->traceGood = 0; - break; - } - } - - if (mouse->valuator->motionHintWindow == pWin) - mouse->valuator->motionHintWindow = NullWindow; - - if (freeResources) - { - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]--; - while ( (oc = wOtherClients(pWin)) ) - FreeResource(oc->resource, RT_NONE); - while ( (passive = wPassiveGrabs(pWin)) ) - FreeResource(passive->resource, RT_NONE); - } -#ifdef XINPUT - DeleteWindowFromAnyExtEvents(pWin, freeResources); -#endif -} - -/** - * Call this whenever some window at or below pWin has changed geometry - */ -void -CheckCursorConfinement(WindowPtr pWin) -{ - GrabPtr grab = inputInfo.pointer->grab; - WindowPtr confineTo; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return; -#endif - - if (grab && (confineTo = grab->confineTo)) - { - if (!BorderSizeNotEmpty(confineTo)) - (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer); - else if ((pWin == confineTo) || IsParent(pWin, confineTo)) - ConfineCursorToWindow(confineTo, TRUE, TRUE); - } -} - -Mask -EventMaskForClient(WindowPtr pWin, ClientPtr client) -{ - register OtherClientsPtr other; - - if (wClient (pWin) == client) - return pWin->eventMask; - for (other = wOtherClients(pWin); other; other = other->next) - { - if (SameClient(other, client)) - return other->mask; - } - return 0; -} - -int -ProcRecolorCursor(ClientPtr client) -{ - CursorPtr pCursor; - int nscr; - ScreenPtr pscr; - Bool displayed; - REQUEST(xRecolorCursorReq); - - REQUEST_SIZE_MATCH(xRecolorCursorReq); - pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor, - RT_CURSOR, SecurityWriteAccess); - if ( !pCursor) - { - client->errorValue = stuff->cursor; - return (BadCursor); - } - - pCursor->foreRed = stuff->foreRed; - pCursor->foreGreen = stuff->foreGreen; - pCursor->foreBlue = stuff->foreBlue; - - pCursor->backRed = stuff->backRed; - pCursor->backGreen = stuff->backGreen; - pCursor->backBlue = stuff->backBlue; - - for (nscr = 0; nscr < screenInfo.numScreens; nscr++) - { - pscr = screenInfo.screens[nscr]; -#ifdef PANORAMIX - if(!noPanoramiXExtension) - displayed = (pscr == sprite.screen); - else -#endif - displayed = (pscr == sprite.hotPhys.pScreen); - ( *pscr->RecolorCursor)(pscr, pCursor, - (pCursor == sprite.current) && displayed); - } - return (Success); -} - -void -WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) -{ -#ifdef PANORAMIX - xEvent eventCopy; -#endif - xEvent eventTo, *eventFrom; - int i; - -#ifdef XKB - if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events))) - return; -#endif - -#ifdef PANORAMIX - if(!noPanoramiXExtension && - (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) - { - switch(events->u.u.type) { - case MotionNotify: - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - case EnterNotify: - case LeaveNotify: - /* - When multiple clients want the same event DeliverEventsToWindow - passes the same event structure multiple times so we can't - modify the one passed to us - */ - count = 1; /* should always be 1 */ - memcpy(&eventCopy, events, sizeof(xEvent)); - eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x; - eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y; - if(eventCopy.u.keyButtonPointer.event == - eventCopy.u.keyButtonPointer.root) - { - eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x; - eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y; - } - events = &eventCopy; - break; - default: break; - } - } -#endif - - if (EventCallback) - { - EventInfoRec eventinfo; - eventinfo.client = pClient; - eventinfo.events = events; - eventinfo.count = count; - CallCallbacks(&EventCallback, (void *)&eventinfo); - } - if(pClient->swapped) - { - for(i = 0; i < count; i++) - { - eventFrom = &events[i]; - /* Remember to strip off the leading bit of type in case - this event was sent with "SendEvent." */ - (*EventSwapVector[eventFrom->u.u.type & 0177]) - (eventFrom, &eventTo); - (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo); - } - } - else - { - (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events); - } -} -- cgit v1.2.3