X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fdix%2Fevents.c;fp=Xserver%2Fprograms%2FXserver%2Fdix%2Fevents.c;h=0000000000000000000000000000000000000000;hp=b6251ac5cdca7cdce56a50bacc22bb9f86d5db26;hb=ce66b81460e5353db09d45c02339d4583fbda255;hpb=7772d71ffd742cfc9b7ff214659d16c5bb56a391 diff --git a/Xserver/programs/Xserver/dix/events.c b/Xserver/programs/Xserver/dix/events.c deleted file mode 100644 index b6251ac..0000000 --- a/Xserver/programs/Xserver/dix/events.c +++ /dev/null @@ -1,3837 +0,0 @@ -/************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -********************************************************/ - - -/* $XConsortium: events.c /main/187 1996/09/25 00:47:41 dpw $ */ -/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.11 1996/12/24 02:23:45 dawes Exp $ */ - -#include "X.h" -#include "misc.h" -#include "resource.h" -#define NEED_EVENTS -#define NEED_REPLIES -#include "Xproto.h" -#include "windowstr.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "cursorstr.h" - -#include "dixstruct.h" - -#ifdef XKB -#include "XKBsrv.h" -#endif - -#ifdef XCSECURITY -#define _SECURITY_SERVER -#include "extensions/security.h" -#endif - -#include "XIproto.h" -#include "exevents.h" -#include "extnsionst.h" - -#include "dixevents.h" -#include "dixgrabs.h" -#include "dispatch.h" - -extern WindowPtr *WindowTable; - -#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 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; - -typedef struct { - int x, y; - ScreenPtr pScreen; -} HotSpot; - -static struct { - CursorPtr current; - BoxRec hotLimits; /* logical constraints of hot spot */ - Bool confined; /* confined to screen */ -#ifdef SHAPE - 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 */ -} sprite; /* info about the cursor sprite */ - -static void DoEnterLeaveEvents( -#if NeedFunctionPrototypes - WindowPtr /*fromWin*/, - WindowPtr /*toWin*/, - int /*mode*/ -#endif -); - -static WindowPtr XYToWindow( -#if NeedFunctionPrototypes - int /*x*/, - int /*y*/ -#endif -); - -extern Bool permitOldBugs; -extern Bool Must_have_memory; -extern int lastEvent; -#ifdef XINPUT -extern int DeviceMotionNotify, DeviceButtonPress, DeviceKeyPress; -#endif - -static Mask lastEventMask; - -#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] = -{ - 0x3c /* key and button events */ -}; - -Mask -GetNextEventMask() -{ - lastEventMask <<= 1; - return lastEventMask; -} - -void -SetMaskForEvent(mask, event) - Mask mask; - int event; -{ - if ((event < LASTEvent) || (event >= 128)) - FatalError("SetMaskForEvent: bogus event number"); - filters[event] = mask; -} - -void -SetCriticalEvent(event) - int event; -{ - if (event >= 128) - FatalError("SetCriticalEvent: bogus event number"); - criticalEvents[event >> 3] |= 1 << (event & 7); -} - -static void -#if NeedFunctionPrototypes -SyntheticMotion(int x, int y) -#else -SyntheticMotion(x, y) - int x, y; -#endif -{ - xEvent xE; - - 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 -#if NeedFunctionPrototypes -ConfineToShape(RegionPtr shape, int *px, int *py) -#else -ConfineToShape(shape, px, py) - RegionPtr shape; - int *px, *py; -#endif -{ - BoxRec box; - int x = *px, y = *py; - int incx = 1, incy = 1; - - if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box)) - return; - box = *REGION_EXTENTS(sprite.hot.pScreen, 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 (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box)); - *px = x; - *py = y; -} -#endif - -static void -#if NeedFunctionPrototypes -CheckPhysLimits( - CursorPtr cursor, - Bool generateEvents, - Bool confineToScreen, - ScreenPtr pScreen) -#else -CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen) - CursorPtr cursor; - Bool generateEvents; - Bool confineToScreen; - ScreenPtr pScreen; -#endif -{ - 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 -#if NeedFunctionPrototypes -CheckVirtualMotion( - register QdEventPtr qe, - register WindowPtr pWin) -#else -CheckVirtualMotion(qe, pWin) - register QdEventPtr qe; - register WindowPtr pWin; -#endif -{ - - if (qe) - { - sprite.hot.pScreen = qe->pScreen; - sprite.hot.x = qe->event->u.keyButtonPointer.rootX; - 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; - sprite.hot.x = sprite.hot.y = 0; - } - lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize); - if (sprite.hot.x < lims.x1) - sprite.hot.x = lims.x1; - else if (sprite.hot.x >= lims.x2) - sprite.hot.x = lims.x2 - 1; - if (sprite.hot.y < lims.y1) - sprite.hot.y = lims.y1; - else if (sprite.hot.y >= lims.y2) - 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 = WindowTable[sprite.hot.pScreen->myNum]; -} - -void -ConfineCursorToWindow(pWin, generateEvents, confineToScreen) - WindowPtr pWin; - Bool generateEvents; - Bool confineToScreen; -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - if (syncEvents.playingEvents) - { - CheckVirtualMotion((QdEventPtr)NULL, pWin); - SyntheticMotion(sprite.hot.x, sprite.hot.y); - } - else - { - sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize); -#ifdef SHAPE - sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize - : NullRegion; -#endif - CheckPhysLimits(sprite.current, generateEvents, confineToScreen, - pScreen); - } -} - -Bool -PointerConfinedToScreen() -{ - return sprite.confined; -} - -static void -#if NeedFunctionPrototypes -ChangeToCursor(CursorPtr cursor) -#else -ChangeToCursor(cursor) - CursorPtr cursor; -#endif -{ - if (cursor != sprite.current) - { - if ((sprite.current->bits->xhot != cursor->bits->xhot) || - (sprite.current->bits->yhot != cursor->bits->yhot)) - CheckPhysLimits(cursor, FALSE, PointerConfinedToScreen(), - (ScreenPtr)NULL); - (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen, - cursor); - sprite.current = cursor; - } -} - -/* returns true if b is a descendent of a */ -Bool -IsParent(a, b) - register WindowPtr a, b; -{ - for (b = b->parent; b; b = b->parent) - if (b == a) return TRUE; - return FALSE; -} - -static void -#if NeedFunctionPrototypes -PostNewCursor(void) -#else -PostNewCursor() -#endif -{ - 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(px, py) - int *px, *py; -{ - *px = sprite.hotPhys.x; - *py = sprite.hotPhys.y; -} - -#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ - -static void -#if NeedFunctionPrototypes -MonthChangedOrBadTime(register xEvent *xE) -#else -MonthChangedOrBadTime(xE) - register xEvent *xE; -#endif -{ - /* 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->u.keyButtonPointer.time) > TIMESLOP) - currentTime.months++; - else - xE->u.keyButtonPointer.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(xE) - register xEvent *xE; -{ - if (!syncEvents.playingEvents) - NoticeTime(xE); -} - -/************************************************************************** - * The following procedures deal with synchronous events * - **************************************************************************/ - -void -EnqueueEvent(xE, device, count) - xEvent *xE; - DeviceIntPtr device; - int count; -{ - register QdEventPtr tail = *syncEvents.pendtail; - register QdEventPtr qe; - xEvent *qxE; - - NoticeTime(xE); - 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->u.keyButtonPointer.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); - } - if (xE->u.u.type == MotionNotify) - { - sprite.hotPhys.x = xE->u.keyButtonPointer.rootX; - sprite.hotPhys.y = xE->u.keyButtonPointer.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->u.keyButtonPointer.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 -#if NeedFunctionPrototypes -PlayReleasedEvents(void) -#else -PlayReleasedEvents() -#endif -{ - 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; - (*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 -#if NeedFunctionPrototypes -FreezeThaw(register DeviceIntPtr dev, Bool frozen) -#else -FreezeThaw(dev, frozen) - register DeviceIntPtr dev; - Bool frozen; -#endif -{ - 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->u.keyButtonPointer.rootX, xE->u.keyButtonPointer.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(WindowTable[sprite.hotPhys.pScreen->myNum], - TRUE, FALSE); - PostNewCursor(); -} - -void -CheckGrabForSyncs(thisDev, thisMode, otherMode) - register DeviceIntPtr thisDev; - Bool thisMode, 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(mouse, grab, time, autoGrab) - register GrabPtr grab; - register DeviceIntPtr mouse; - 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); -} - -void -DeactivatePointerGrab(mouse) - 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(); -} - -void -ActivateKeyboardGrab(keybd, grab, time, passive) - 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(keybd) - 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(client, time, thisDev, newState) - ClientPtr client; - TimeStamp time; - register 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(client) - 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; - } - return Success; -} - -void -ReleaseActiveGrabs(client) - 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 (client, pEvents, count, mask, filter, grab) - ClientPtr client; - GrabPtr grab; - xEvent *pEvents; - int count; - Mask mask, filter; -{ - int i; - int type; - -#ifdef DEBUG - if (debug_events) ErrorF( - "Event([%d, %d], mask=0x%x), client=%d", - pEvents->u.u.type, pEvents->u.u.detail, mask, client->index); -#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) - { -#ifdef DEBUG - if (debug_events) ErrorF("\n"); -#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)) - SetCriticalOutputPending(); - - WriteEventsToClient(client, count, pEvents); -#ifdef DEBUG - if (debug_events) ErrorF( " delivered\n"); -#endif - return 1; - } - else - { -#ifdef DEBUG - if (debug_events) ErrorF("\n"); -#endif - return 0; - } -} - -int -DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx) - register WindowPtr pWin; - GrabPtr grab; - xEvent *pEvents; - int count; - Mask filter; - int mskidx; -{ - int deliveries = 0, nondeliveries = 0; - int attempt; - register InputClients *other; - ClientPtr client = NullClient; - Mask deliveryMask; /* 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; - (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab, - currentTime, TRUE); - } - else if ((type == MotionNotify) && deliveries) - inputInfo.pointer->valuator->motionHintWindow = pWin; -#ifdef XINPUT - else - { - if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) && - 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. -*/ - -int -MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient) - register WindowPtr pWin; - xEvent *pEvents; - int count; - Mask filter; - ClientPtr dontClient; -{ - register OtherClients *other; - - if (pWin->eventMask & filter) - { - if (wClient(pWin) == dontClient) - return 0; - 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; - return TryClientEvents(rClient(other), pEvents, count, - other->mask, filter, NullGrab); - } - } - return 2; -} - -static void -#if NeedFunctionPrototypes -FixUpEventFromWindow( - xEvent *xE, - WindowPtr pWin, - Window child, - Bool calcChild) -#else -FixUpEventFromWindow(xE, pWin, child, calcChild) - xEvent *xE; - WindowPtr pWin; - Window child; - Bool calcChild; -#endif -{ - 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->u.keyButtonPointer.root = ROOT->drawable.id; - xE->u.keyButtonPointer.event = pWin->drawable.id; - if (sprite.hot.pScreen == pWin->drawable.pScreen) - { - xE->u.keyButtonPointer.sameScreen = xTrue; - xE->u.keyButtonPointer.child = child; - xE->u.keyButtonPointer.eventX = - xE->u.keyButtonPointer.rootX - pWin->drawable.x; - xE->u.keyButtonPointer.eventY = - xE->u.keyButtonPointer.rootY - pWin->drawable.y; - } - else - { - xE->u.keyButtonPointer.sameScreen = xFalse; - xE->u.keyButtonPointer.child = None; - xE->u.keyButtonPointer.eventX = 0; - xE->u.keyButtonPointer.eventY = 0; - } -} - -int -DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count) - register WindowPtr pWin, stopAt; - register xEvent *xE; - GrabPtr grab; - 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(pWin, xE, count, otherParent) - register WindowPtr pWin, otherParent; - register xEvent *xE; - int count; -{ - Mask filter; - int deliveries; - - 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 WindowPtr -#if NeedFunctionPrototypes -XYToWindow(int x, int y) -#else -XYToWindow(x, y) - int x, y; -#endif -{ - register WindowPtr pWin; -#ifdef SHAPE - BoxRec box; -#endif - - spriteTraceGood = 1; /* root window still there */ - 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) || - POINT_IN_REGION(pWin->drawable.pScreen, - &pWin->borderSize, x, 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 -#if NeedFunctionPrototypes -CheckMotion(xEvent *xE) -#else -CheckMotion(xE) - xEvent *xE; -#endif -{ - WindowPtr prevSpriteWin = sprite.win; - - if (xE && !syncEvents.playingEvents) - { - if (sprite.hot.pScreen != sprite.hotPhys.pScreen) - { - sprite.hot.pScreen = sprite.hotPhys.pScreen; - ROOT = WindowTable[sprite.hot.pScreen->myNum]; - } - sprite.hot.x = xE->u.keyButtonPointer.rootX; - sprite.hot.y = xE->u.keyButtonPointer.rootY; - if (sprite.hot.x < sprite.physLimits.x1) - sprite.hot.x = sprite.physLimits.x1; - else if (sprite.hot.x >= sprite.physLimits.x2) - sprite.hot.x = sprite.physLimits.x2 - 1; - if (sprite.hot.y < sprite.physLimits.y1) - sprite.hot.y = sprite.physLimits.y1; - else if (sprite.hot.y >= sprite.physLimits.y2) - 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; - if ((sprite.hotPhys.x != xE->u.keyButtonPointer.rootX) || - (sprite.hotPhys.y != xE->u.keyButtonPointer.rootY)) - (*sprite.hotPhys.pScreen->SetCursorPosition)( - sprite.hotPhys.pScreen, - sprite.hotPhys.x, sprite.hotPhys.y, FALSE); - xE->u.keyButtonPointer.rootX = sprite.hot.x; - xE->u.keyButtonPointer.rootY = sprite.hot.y; - } - - 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); -} - -void -DefineInitialRootWindow(win) - register WindowPtr win; -{ - register ScreenPtr pScreen = win->drawable.pScreen; - - 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; - sprite.win = win; - sprite.current = wCursor (win); - 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); -} - -/* - * 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. - */ -/*ARGSUSED*/ -void -WindowHasNewCursor(pWin) - WindowPtr pWin; -{ - PostNewCursor(); -} - -void -NewCurrentScreen(newScreen, x, y) - ScreenPtr newScreen; - int x,y; -{ - sprite.hotPhys.x = x; - sprite.hotPhys.y = y; - if (newScreen != sprite.hotPhys.pScreen) - ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE); -} - -int -ProcWarpPointer(client) - ClientPtr client; -{ - WindowPtr dest = NULL; - int x, y; - ScreenPtr newScreen; - - REQUEST(xWarpPointerReq); - - REQUEST_SIZE_MATCH(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; - WindowPtr source = SecurityLookupWindow(stuff->srcWid, 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; -#ifdef 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; -} - -/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a - passive grab set on the window to be activated. */ - -static Bool -#if NeedFunctionPrototypes -CheckPassiveGrabsOnWindow( - WindowPtr pWin, - register DeviceIntPtr device, - register xEvent *xE, - int count) -#else -CheckPassiveGrabsOnWindow(pWin, device, xE, count) - WindowPtr pWin; - register DeviceIntPtr device; - register xEvent *xE; - int count; -#endif -{ - 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 -#ifdef XINPUT - || 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 && - REGION_NOTEMPTY( grab->confineTo->drawable.pScreen, - &grab->confineTo->borderSize)))) - { -#ifdef XCSECURITY - if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE)) - return FALSE; -#endif -#ifdef XKB - if (!noXkbExtension) { - xE->u.keyButtonPointer.state &= 0x1f00; - xE->u.keyButtonPointer.state |= - tempGrab.modifiersDetail.exact&(~0x1f00); - } -#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 -it's descendants contain they 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(device, xE, checkFirst, count) - register DeviceIntPtr device; - register xEvent *xE; - int checkFirst; - int count; -{ - register int i; - register WindowPtr pWin; - register FocusClassPtr focus = device->focus; - - if ((xE->u.u.type == ButtonPress -#ifdef XINPUT - || 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(keybd, xE, window, count) - xEvent *xE; - DeviceIntPtr keybd; - 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(xE, thisDev, deactivateGrab, count) - 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 (xE, keybd, count) -#else -ProcessKeyboardEvent (xE, keybd, count) -#endif - register xEvent *xE; - register DeviceIntPtr keybd; - int count; -{ - 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; - - if (!syncEvents.playingEvents) - { - NoticeTime(xE); - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); - } - } - xE->u.keyButtonPointer.state = (keyc->state | - inputInfo.pointer->button->state); - xE->u.keyButtonPointer.rootX = sprite.hot.x; - xE->u.keyButtonPointer.rootY = sprite.hot.y; - key = xE->u.u.detail; - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - modifiers = keyc->modifierMap[key]; -#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) - (*keybd->DeactivateGrab)(keybd); -} - -void -#ifdef XKB -CoreProcessPointerEvent (xE, mouse, count) -#else -ProcessPointerEvent (xE, mouse, count) -#endif - register xEvent *xE; - register DeviceIntPtr mouse; - int count; -{ - register GrabPtr grab = mouse->grab; - Bool deactivateGrab = FALSE; - register ButtonClassPtr butc = mouse->button; -#ifdef XKB - XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo; -#endif - - if (!syncEvents.playingEvents) - NoticeTime(xE) - xE->u.keyButtonPointer.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->u.keyButtonPointer.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; - eventinfo.events = xE; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); - } - } - if (xE->u.u.type != MotionNotify) - { - register int key; - register BYTE *kptr; - int bit; - - xE->u.keyButtonPointer.rootX = sprite.hot.x; - xE->u.keyButtonPointer.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; - butc->buttonsDown++; - butc->motionMask = ButtonMotionMask; - *kptr |= bit; - xE->u.u.detail = butc->map[key]; - if (xE->u.u.detail == 0) - return; - if (xE->u.u.detail <= 5) - butc->state |= (Button1Mask >> 1) << xE->u.u.detail; - filters[MotionNotify] = Motion_Filter(butc); - if (!grab) - if (CheckDeviceGrabs(mouse, xE, 0, count)) - return; - break; - case ButtonRelease: - mouse->valuator->motionHintWindow = NullWindow; - if (!--butc->buttonsDown) - butc->motionMask = 0; - *kptr &= ~bit; - xE->u.u.detail = butc->map[key]; - if (xE->u.u.detail == 0) - return; - 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"); - } - } - else if (!CheckMotion(xE)) - return; - if (grab) - DeliverGrabbedEvent(xE, mouse, deactivateGrab, count); - else - DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow, - mouse, count); - if (deactivateGrab) - (*mouse->DeactivateGrab)(mouse); -} - -#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; - } -} - -int -OtherClientGone(value, id) - pointer value; /* must conform to DeleteType */ - 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(pWin, client, mask) - 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; -#if 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; -#if 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, (pointer)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; -} - -/*ARGSUSED*/ -int -EventSuppressForWindow(pWin, client, mask, checkOptional) - 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 -#if NeedFunctionPrototypes -CommonAncestor( - register WindowPtr a, - register WindowPtr b) -#else -CommonAncestor(a, b) - register WindowPtr a, b; -#endif -{ - for (b = b->parent; b; b = b->parent) - if (IsParent(b, a)) return b; - return NullWindow; -} - -static void -#if NeedFunctionPrototypes -EnterLeaveEvent( - int type, - int mode, - int detail, - register WindowPtr pWin, - Window child) -#else -EnterLeaveEvent(type, mode, detail, pWin, child) - int type, mode, detail; - register WindowPtr pWin; - Window child; -#endif -{ - 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]) - { - 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 -#if NeedFunctionPrototypes -EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail) -#else -EnterNotifies(ancestor, child, mode, detail) - WindowPtr ancestor, child; - int mode, detail; -#endif -{ - WindowPtr parent = child->parent; - - if (ancestor == parent) - return; - EnterNotifies(ancestor, parent, mode, detail); - EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id); -} - -static void -#if NeedFunctionPrototypes -LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail) -#else -LeaveNotifies(child, ancestor, mode, detail) - WindowPtr child, ancestor; - int detail, mode; -#endif -{ - 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 -#if NeedFunctionPrototypes -DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode) -#else -DoEnterLeaveEvents(fromWin, toWin, mode) - WindowPtr fromWin, toWin; - int mode; -#endif -{ - 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 -#if NeedFunctionPrototypes -FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin) -#else -FocusEvent(dev, type, mode, detail, pWin) - DeviceIntPtr dev; - int type, mode, detail; - register WindowPtr pWin; -#endif -{ - 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 -#if NeedFunctionPrototypes -FocusInEvents( - DeviceIntPtr dev, - WindowPtr ancestor, WindowPtr child, WindowPtr skipChild, - int mode, int detail, - Bool doAncestor) -#else -FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor) - DeviceIntPtr dev; - WindowPtr ancestor, child, skipChild; - int mode, detail; - Bool doAncestor; -#endif -{ - 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 -#if NeedFunctionPrototypes -FocusOutEvents( - DeviceIntPtr dev, - WindowPtr child, WindowPtr ancestor, - int mode, int detail, - Bool doAncestor) -#else -FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor) - DeviceIntPtr dev; - WindowPtr child, ancestor; - int mode; - int detail; - Bool doAncestor; -#endif -{ - 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(dev, fromWin, toWin, mode) - DeviceIntPtr dev; - WindowPtr fromWin, 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 */ - for (i=0; iparent, NullWindow, mode, - NotifyNonlinearVirtual, FALSE); - } - /* Notify all the roots */ - for (i=0; iparent != 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 -#if NeedFunctionPrototypes -SetInputFocus( - ClientPtr client, - DeviceIntPtr dev, - Window focusID, - CARD8 revertTo, - Time ctime, - Bool followOK) -#else -SetInputFocus(client, dev, focusID, revertTo, ctime, followOK) - ClientPtr client; - DeviceIntPtr dev; - Window focusID; - CARD8 revertTo; - Time ctime; - Bool followOK; -#endif -{ - 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)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(client) - ClientPtr client; -{ - xGetInputFocusReply rep; - FocusClassPtr focus = inputInfo.keyboard->focus; - - REQUEST_SIZE_MATCH(xReq); - 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(client) - 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; - 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); - 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 && - REGION_NOTEMPTY( confineTo->drawable.pScreen, - &confineTo->borderSize)))) - 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; - (*device->ActivateGrab)(device, &tempGrab, time, FALSE); - if (oldCursor) - FreeCursor (oldCursor, (Cursor)0); - rep.status = GrabSuccess; - } - WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); - return Success; -} - -int -ProcChangeActivePointerGrab(client) - 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(client) - ClientPtr client; -{ - DeviceIntPtr device = inputInfo.pointer; - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - 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)) - (*device->DeactivateGrab)(device); - return Success; -} - -int -GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime, - mask, status) - 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; - (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE); - *status = GrabSuccess; - } - return Success; -} - -int -ProcGrabKeyboard(client) - ClientPtr client; -{ - xGrabKeyboardReply rep; - REQUEST(xGrabKeyboardReq); - int result; - - REQUEST_SIZE_MATCH(xGrabKeyboardReq); -#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(client) - ClientPtr client; -{ - DeviceIntPtr device = inputInfo.keyboard; - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - 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)) - (*device->DeactivateGrab)(device); - return Success; -} - -int -ProcQueryPointer(client) - 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); - 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) - { - rep.child = t->drawable.id; - break; - } - } - else - { - rep.sameScreen = xFalse; - rep.winX = 0; - rep.winY = 0; - } - WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); - - return(Success); -} - -void -InitEvents() -{ - int i; - - 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.win = NullWindow; - sprite.current = NullCursor; - sprite.hotLimits.x1 = 0; - sprite.hotLimits.y1 = 0; - sprite.hotLimits.x2 = 0; - sprite.hotLimits.y2 = 0; - sprite.confined = FALSE; - syncEvents.replayDev = (DeviceIntPtr)NULL; - syncEvents.replayWin = NullWindow; - while (syncEvents.pending) - { - QdEventPtr next = syncEvents.pending->next; - xfree(syncEvents.pending); - syncEvents.pending = next; - } - 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++) - { - DontPropagateMasks[i] = 0; - DontPropagateRefCnts[i] = 0; - } -} - -int -ProcSendEvent(client) - ClientPtr client; -{ - WindowPtr pWin; - WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - REQUEST(xSendEventReq); - - REQUEST_SIZE_MATCH(xSendEventReq); - - /* The client's event type must be a core event type or one defined by an - extension. */ - - if ( ! ((stuff->event.u.u.type > X_Reply && - stuff->event.u.u.type < LASTEvent) || - (stuff->event.u.u.type >= EXTENSION_EVENT_BASE && - stuff->event.u.u.type < (unsigned)lastEvent))) - { - client->errorValue = stuff->event.u.u.type; - return BadValue; - } - if (stuff->event.u.u.type == ClientMessage && - stuff->event.u.u.detail != 8 && - stuff->event.u.u.detail != 16 && - stuff->event.u.u.detail != 32 && - !permitOldBugs) - { - client->errorValue = stuff->event.u.u.detail; - return BadValue; - } - if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - - if (stuff->destination == PointerWindow) - pWin = sprite.win; - else if (stuff->destination == InputFocus) - { - WindowPtr inputFocus = inputInfo.keyboard->focus->win; - - if (inputFocus == NoneWin) - return Success; - - /* If the input focus is PointerRootWin, send the event to where - the pointer is if possible, then perhaps propogate up to root. */ - if (inputFocus == PointerRootWin) - inputFocus = ROOT; - - if (IsParent(inputFocus, sprite.win)) - { - effectiveFocus = inputFocus; - pWin = sprite.win; - } - else - effectiveFocus = pWin = inputFocus; - } - else - pWin = SecurityLookupWindow(stuff->destination, client, - SecurityReadAccess); - if (!pWin) - return BadWindow; - if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) - { - client->errorValue = stuff->propagate; - return BadValue; - } - stuff->event.u.u.type |= 0x80; - if (stuff->propagate) - { - for (;pWin; pWin = pWin->parent) - { - if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask, - NullGrab, 0)) - return Success; - if (pWin == effectiveFocus) - return Success; - stuff->eventMask &= ~wDontPropagateMask(pWin); - if (!stuff->eventMask) - break; - } - } - else - (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask, - NullGrab, 0); - return Success; -} - -int -ProcUngrabKey(client) - 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(client) - 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(client) - 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(client) - 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(pWin, freeResources) - 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 */ - -/*ARGSUSED*/ -void -CheckCursorConfinement(pWin) - WindowPtr pWin; -{ - GrabPtr grab = inputInfo.pointer->grab; - WindowPtr confineTo; - - if (grab && (confineTo = grab->confineTo)) - { - if (!REGION_NOTEMPTY( confineTo->drawable.pScreen, - &confineTo->borderSize)) - (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer); - else if ((pWin == confineTo) || IsParent(pWin, confineTo)) - ConfineCursorToWindow(confineTo, TRUE, TRUE); - } -} - -Mask -EventMaskForClient(pWin, client) - 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(client) - ClientPtr client; -{ - CursorPtr pCursor; - int nscr; - ScreenPtr pscr; - 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]; - ( *pscr->RecolorCursor)(pscr, pCursor, - (pCursor == sprite.current) && - (pscr == sprite.hotPhys.pScreen)); - } - return (Success); -} - -void -WriteEventsToClient(pClient, count, events) - ClientPtr pClient; - int count; - xEvent *events; -{ - xEvent eventTo, *eventFrom; - int i; - -#ifdef XKB - if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events))) - return; -#endif - - if (EventCallback) - { - EventInfoRec eventinfo; - eventinfo.client = pClient; - eventinfo.events = events; - eventinfo.count = count; - CallCallbacks(&EventCallback, (pointer)&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); - } -}