mipointer.c revision 4642e01f
105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg*/ 2505b261ecSmrg 2605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2705b261ecSmrg#include <dix-config.h> 2805b261ecSmrg#endif 2905b261ecSmrg 3005b261ecSmrg# define NEED_EVENTS 3105b261ecSmrg# include <X11/X.h> 3205b261ecSmrg# include <X11/Xmd.h> 3305b261ecSmrg# include <X11/Xproto.h> 3405b261ecSmrg# include "misc.h" 3505b261ecSmrg# include "windowstr.h" 3605b261ecSmrg# include "pixmapstr.h" 3705b261ecSmrg# include "mi.h" 3805b261ecSmrg# include "scrnintstr.h" 3905b261ecSmrg# include "mipointrst.h" 4005b261ecSmrg# include "cursorstr.h" 4105b261ecSmrg# include "dixstruct.h" 4205b261ecSmrg# include "inputstr.h" 4305b261ecSmrg 444642e01fSmrgstatic int miPointerScreenKeyIndex; 454642e01fSmrg_X_EXPORT DevPrivateKey miPointerScreenKey = &miPointerScreenKeyIndex; 4605b261ecSmrg 474642e01fSmrg#define GetScreenPrivate(s) ((miPointerScreenPtr) \ 484642e01fSmrg dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey)) 4905b261ecSmrg#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s) 5005b261ecSmrg 514642e01fSmrgstatic int miPointerPrivKeyIndex; 524642e01fSmrgstatic DevPrivateKey miPointerPrivKey = &miPointerPrivKeyIndex; 534642e01fSmrg 544642e01fSmrg#define MIPOINTER(dev) \ 554642e01fSmrg ((DevHasCursor((dev)) || (!dev->isMaster && !dev->u.master)) ? \ 564642e01fSmrg (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \ 574642e01fSmrg (miPointerPtr)dixLookupPrivate(&(dev)->u.master->devPrivates, miPointerPrivKey)) 584642e01fSmrg 594642e01fSmrgstatic Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 604642e01fSmrg CursorPtr pCursor); 614642e01fSmrgstatic Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 624642e01fSmrg CursorPtr pCursor); 634642e01fSmrgstatic Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 644642e01fSmrg CursorPtr pCursor); 654642e01fSmrgstatic void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 664642e01fSmrg BoxPtr pBox); 674642e01fSmrgstatic void miPointerPointerNonInterestBox(DeviceIntPtr pDev, 684642e01fSmrg ScreenPtr pScreen, BoxPtr pBox); 694642e01fSmrgstatic void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, 704642e01fSmrg CursorPtr pCursor, BoxPtr pHotBox, 714642e01fSmrg BoxPtr pTopLeftBox); 724642e01fSmrgstatic Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 734642e01fSmrg int x, int y, 7405b261ecSmrg Bool generateEvent); 7505b261ecSmrgstatic Bool miPointerCloseScreen(int index, ScreenPtr pScreen); 764642e01fSmrgstatic void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, 774642e01fSmrg int x, int y); 784642e01fSmrgstatic Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); 794642e01fSmrgstatic void miPointerDeviceCleanup(DeviceIntPtr pDev, 804642e01fSmrg ScreenPtr pScreen); 8105b261ecSmrg 824642e01fSmrgstatic EventList* events; /* for WarpPointer MotionNotifies */ 8305b261ecSmrg 8405b261ecSmrg_X_EXPORT Bool 854642e01fSmrgmiPointerInitialize (ScreenPtr pScreen, 864642e01fSmrg miPointerSpriteFuncPtr spriteFuncs, 874642e01fSmrg miPointerScreenFuncPtr screenFuncs, 884642e01fSmrg Bool waitForUpdate) 8905b261ecSmrg{ 9005b261ecSmrg miPointerScreenPtr pScreenPriv; 9105b261ecSmrg 9205b261ecSmrg pScreenPriv = (miPointerScreenPtr) xalloc (sizeof (miPointerScreenRec)); 9305b261ecSmrg if (!pScreenPriv) 9405b261ecSmrg return FALSE; 9505b261ecSmrg pScreenPriv->spriteFuncs = spriteFuncs; 9605b261ecSmrg pScreenPriv->screenFuncs = screenFuncs; 9705b261ecSmrg /* 9805b261ecSmrg * check for uninitialized methods 9905b261ecSmrg */ 10005b261ecSmrg if (!screenFuncs->EnqueueEvent) 10105b261ecSmrg screenFuncs->EnqueueEvent = mieqEnqueue; 10205b261ecSmrg if (!screenFuncs->NewEventScreen) 10305b261ecSmrg screenFuncs->NewEventScreen = mieqSwitchScreen; 10405b261ecSmrg pScreenPriv->waitForUpdate = waitForUpdate; 10505b261ecSmrg pScreenPriv->showTransparent = FALSE; 10605b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 10705b261ecSmrg pScreen->CloseScreen = miPointerCloseScreen; 1084642e01fSmrg dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv); 10905b261ecSmrg /* 11005b261ecSmrg * set up screen cursor method table 11105b261ecSmrg */ 11205b261ecSmrg pScreen->ConstrainCursor = miPointerConstrainCursor; 11305b261ecSmrg pScreen->CursorLimits = miPointerCursorLimits; 11405b261ecSmrg pScreen->DisplayCursor = miPointerDisplayCursor; 11505b261ecSmrg pScreen->RealizeCursor = miPointerRealizeCursor; 11605b261ecSmrg pScreen->UnrealizeCursor = miPointerUnrealizeCursor; 11705b261ecSmrg pScreen->SetCursorPosition = miPointerSetCursorPosition; 11805b261ecSmrg pScreen->RecolorCursor = miRecolorCursor; 11905b261ecSmrg pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox; 1204642e01fSmrg pScreen->DeviceCursorInitialize = miPointerDeviceInitialize; 1214642e01fSmrg pScreen->DeviceCursorCleanup = miPointerDeviceCleanup; 12205b261ecSmrg 12305b261ecSmrg events = NULL; 12405b261ecSmrg return TRUE; 12505b261ecSmrg} 12605b261ecSmrg 12705b261ecSmrgstatic Bool 1284642e01fSmrgmiPointerCloseScreen (int index, ScreenPtr pScreen) 12905b261ecSmrg{ 1304642e01fSmrg#if 0 1314642e01fSmrg miPointerPtr pPointer; 1324642e01fSmrg DeviceIntPtr pDev; 1334642e01fSmrg#endif 1344642e01fSmrg 13505b261ecSmrg SetupScreen(pScreen); 13605b261ecSmrg 1374642e01fSmrg#if 0 1384642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 1394642e01fSmrg { 1404642e01fSmrg if (DevHasCursor(pDev)) 1414642e01fSmrg { 1424642e01fSmrg pPointer = MIPOINTER(pDev); 1434642e01fSmrg 1444642e01fSmrg if (pScreen == pPointer->pScreen) 1454642e01fSmrg pPointer->pScreen = 0; 1464642e01fSmrg if (pScreen == pPointer->pSpriteScreen) 1474642e01fSmrg pPointer->pSpriteScreen = 0; 1484642e01fSmrg } 1494642e01fSmrg } 1504642e01fSmrg 1514642e01fSmrg if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen) 1524642e01fSmrg MIPOINTER(inputInfo.pointer)->pScreen = 0; 1534642e01fSmrg if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen) 1544642e01fSmrg MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0; 1554642e01fSmrg#endif 1564642e01fSmrg 15705b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 15805b261ecSmrg xfree ((pointer) pScreenPriv); 1594642e01fSmrg FreeEventList(events, GetMaximumEventsNum()); 16005b261ecSmrg events = NULL; 16105b261ecSmrg return (*pScreen->CloseScreen) (index, pScreen); 16205b261ecSmrg} 16305b261ecSmrg 16405b261ecSmrg/* 16505b261ecSmrg * DIX/DDX interface routines 16605b261ecSmrg */ 16705b261ecSmrg 16805b261ecSmrgstatic Bool 1694642e01fSmrgmiPointerRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 17005b261ecSmrg{ 17105b261ecSmrg SetupScreen(pScreen); 1724642e01fSmrg return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor); 17305b261ecSmrg} 17405b261ecSmrg 17505b261ecSmrgstatic Bool 1764642e01fSmrgmiPointerUnrealizeCursor (DeviceIntPtr pDev, 1774642e01fSmrg ScreenPtr pScreen, 1784642e01fSmrg CursorPtr pCursor) 17905b261ecSmrg{ 18005b261ecSmrg SetupScreen(pScreen); 1814642e01fSmrg return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor); 18205b261ecSmrg} 18305b261ecSmrg 18405b261ecSmrgstatic Bool 1854642e01fSmrgmiPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 18605b261ecSmrg{ 1874642e01fSmrg miPointerPtr pPointer; 1884642e01fSmrg 1894642e01fSmrg /* return for keyboards */ 1904642e01fSmrg if ((pDev->isMaster && !DevHasCursor(pDev)) || 1914642e01fSmrg (!pDev->isMaster && pDev->u.master && !DevHasCursor(pDev->u.master))) 1924642e01fSmrg return FALSE; 1934642e01fSmrg 1944642e01fSmrg pPointer = MIPOINTER(pDev); 1954642e01fSmrg 1964642e01fSmrg pPointer->pCursor = pCursor; 1974642e01fSmrg pPointer->pScreen = pScreen; 1984642e01fSmrg miPointerUpdateSprite(pDev); 19905b261ecSmrg return TRUE; 20005b261ecSmrg} 20105b261ecSmrg 20205b261ecSmrgstatic void 2034642e01fSmrgmiPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) 20405b261ecSmrg{ 2054642e01fSmrg miPointerPtr pPointer; 2064642e01fSmrg 2074642e01fSmrg pPointer = MIPOINTER(pDev); 2084642e01fSmrg 2094642e01fSmrg pPointer->limits = *pBox; 2104642e01fSmrg pPointer->confined = PointerConfinedToScreen(pDev); 21105b261ecSmrg} 21205b261ecSmrg 21305b261ecSmrg/*ARGSUSED*/ 21405b261ecSmrgstatic void 2154642e01fSmrgmiPointerPointerNonInterestBox (DeviceIntPtr pDev, 2164642e01fSmrg ScreenPtr pScreen, 2174642e01fSmrg BoxPtr pBox) 21805b261ecSmrg{ 21905b261ecSmrg /* until DIX uses this, this will remain a stub */ 22005b261ecSmrg} 22105b261ecSmrg 22205b261ecSmrg/*ARGSUSED*/ 22305b261ecSmrgstatic void 2244642e01fSmrgmiPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, 2254642e01fSmrg BoxPtr pHotBox, BoxPtr pTopLeftBox) 22605b261ecSmrg{ 22705b261ecSmrg *pTopLeftBox = *pHotBox; 22805b261ecSmrg} 22905b261ecSmrg 23005b261ecSmrgstatic Bool GenerateEvent; 23105b261ecSmrg 23205b261ecSmrgstatic Bool 2334642e01fSmrgmiPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 2344642e01fSmrg int x, int y, Bool generateEvent) 23505b261ecSmrg{ 23605b261ecSmrg SetupScreen (pScreen); 23705b261ecSmrg 23805b261ecSmrg GenerateEvent = generateEvent; 23905b261ecSmrg /* device dependent - must pend signal and call miPointerWarpCursor */ 2404642e01fSmrg (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); 24105b261ecSmrg if (!generateEvent) 2424642e01fSmrg miPointerUpdateSprite(pDev); 24305b261ecSmrg return TRUE; 24405b261ecSmrg} 24505b261ecSmrg 2464642e01fSmrg/* Set up sprite information for the device. 2474642e01fSmrg This function will be called once for each device after it is initialized 2484642e01fSmrg in the DIX. 2494642e01fSmrg */ 2504642e01fSmrgstatic Bool 2514642e01fSmrgmiPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 2524642e01fSmrg{ 2534642e01fSmrg miPointerPtr pPointer; 2544642e01fSmrg SetupScreen (pScreen); 2554642e01fSmrg 2564642e01fSmrg pPointer = xalloc(sizeof(miPointerRec)); 2574642e01fSmrg if (!pPointer) 2584642e01fSmrg return FALSE; 2594642e01fSmrg 2604642e01fSmrg pPointer->pScreen = NULL; 2614642e01fSmrg pPointer->pSpriteScreen = NULL; 2624642e01fSmrg pPointer->pCursor = NULL; 2634642e01fSmrg pPointer->pSpriteCursor = NULL; 2644642e01fSmrg pPointer->limits.x1 = 0; 2654642e01fSmrg pPointer->limits.x2 = 32767; 2664642e01fSmrg pPointer->limits.y1 = 0; 2674642e01fSmrg pPointer->limits.y2 = 32767; 2684642e01fSmrg pPointer->confined = FALSE; 2694642e01fSmrg pPointer->x = 0; 2704642e01fSmrg pPointer->y = 0; 2714642e01fSmrg 2724642e01fSmrg if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen))) 2734642e01fSmrg { 2744642e01fSmrg xfree(pPointer); 2754642e01fSmrg return FALSE; 2764642e01fSmrg } 2774642e01fSmrg 2784642e01fSmrg dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, pPointer); 2794642e01fSmrg return TRUE; 2804642e01fSmrg} 2814642e01fSmrg 2824642e01fSmrg/* Clean up after device. 2834642e01fSmrg This function will be called once before the device is freed in the DIX 2844642e01fSmrg */ 2854642e01fSmrgstatic void 2864642e01fSmrgmiPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 2874642e01fSmrg{ 2884642e01fSmrg if (!pDev->isMaster && pDev->u.master) 2894642e01fSmrg return; 2904642e01fSmrg 2914642e01fSmrg SetupScreen(pScreen); 2924642e01fSmrg (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen); 2934642e01fSmrg xfree(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey)); 2944642e01fSmrg dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL); 2954642e01fSmrg} 2964642e01fSmrg 2974642e01fSmrg 29805b261ecSmrg/* Once signals are ignored, the WarpCursor function can call this */ 29905b261ecSmrg 30005b261ecSmrg_X_EXPORT void 3014642e01fSmrgmiPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 30205b261ecSmrg{ 3034642e01fSmrg miPointerPtr pPointer; 3044642e01fSmrg BOOL changedScreen = FALSE; 3054642e01fSmrg 3064642e01fSmrg pPointer = MIPOINTER(pDev); 30705b261ecSmrg SetupScreen (pScreen); 30805b261ecSmrg 3094642e01fSmrg if (pPointer->pScreen != pScreen) 3104642e01fSmrg { 3114642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); 3124642e01fSmrg changedScreen = TRUE; 3134642e01fSmrg } 31405b261ecSmrg 31505b261ecSmrg if (GenerateEvent) 31605b261ecSmrg { 3174642e01fSmrg miPointerMove (pDev, pScreen, x, y); 31805b261ecSmrg } 31905b261ecSmrg else 32005b261ecSmrg { 32105b261ecSmrg /* everything from miPointerMove except the event and history */ 32205b261ecSmrg 3234642e01fSmrg if (!pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) 32405b261ecSmrg { 3254642e01fSmrg pPointer->devx = x; 3264642e01fSmrg pPointer->devy = y; 3274642e01fSmrg if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) 3284642e01fSmrg (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); 32905b261ecSmrg } 3304642e01fSmrg pPointer->x = x; 3314642e01fSmrg pPointer->y = y; 3324642e01fSmrg pPointer->pScreen = pScreen; 33305b261ecSmrg } 3344642e01fSmrg 3354642e01fSmrg /* Don't call USFS if we use Xinerama, otherwise the root window is 3364642e01fSmrg * updated to the second screen, and we never receive any events. 3374642e01fSmrg * (FDO bug #18668) */ 3384642e01fSmrg if (changedScreen 3394642e01fSmrg#ifdef PANORAMIX 3404642e01fSmrg && noPanoramiXExtension 3414642e01fSmrg#endif 3424642e01fSmrg ) 3434642e01fSmrg UpdateSpriteForScreen (pDev, pScreen) ; 34405b261ecSmrg} 34505b261ecSmrg 34605b261ecSmrg/* 34705b261ecSmrg * Pointer/CursorDisplay interface routines 34805b261ecSmrg */ 34905b261ecSmrg 35005b261ecSmrg/* 3514642e01fSmrg * miPointerUpdateSprite 35205b261ecSmrg * 35305b261ecSmrg * Syncronize the sprite with the cursor - called from ProcessInputEvents 35405b261ecSmrg */ 35505b261ecSmrg 35605b261ecSmrgvoid 35705b261ecSmrgmiPointerUpdateSprite (DeviceIntPtr pDev) 35805b261ecSmrg{ 35905b261ecSmrg ScreenPtr pScreen; 36005b261ecSmrg miPointerScreenPtr pScreenPriv; 36105b261ecSmrg CursorPtr pCursor; 36205b261ecSmrg int x, y, devx, devy; 3634642e01fSmrg miPointerPtr pPointer; 36405b261ecSmrg 3654642e01fSmrg if (!pDev || !pDev->coreEvents) 36605b261ecSmrg return; 36705b261ecSmrg 3684642e01fSmrg pPointer = MIPOINTER(pDev); 3694642e01fSmrg 3704642e01fSmrg pScreen = pPointer->pScreen; 37105b261ecSmrg if (!pScreen) 37205b261ecSmrg return; 37305b261ecSmrg 3744642e01fSmrg x = pPointer->x; 3754642e01fSmrg y = pPointer->y; 3764642e01fSmrg devx = pPointer->devx; 3774642e01fSmrg devy = pPointer->devy; 37805b261ecSmrg 37905b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 38005b261ecSmrg /* 38105b261ecSmrg * if the cursor has switched screens, disable the sprite 38205b261ecSmrg * on the old screen 38305b261ecSmrg */ 3844642e01fSmrg if (pScreen != pPointer->pSpriteScreen) 38505b261ecSmrg { 3864642e01fSmrg if (pPointer->pSpriteScreen) 38705b261ecSmrg { 38805b261ecSmrg miPointerScreenPtr pOldPriv; 38905b261ecSmrg 3904642e01fSmrg pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen); 3914642e01fSmrg if (pPointer->pCursor) 39205b261ecSmrg { 39305b261ecSmrg (*pOldPriv->spriteFuncs->SetCursor) 3944642e01fSmrg (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); 39505b261ecSmrg } 3964642e01fSmrg (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE); 39705b261ecSmrg } 39805b261ecSmrg (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); 39905b261ecSmrg (*pScreenPriv->spriteFuncs->SetCursor) 4004642e01fSmrg (pDev, pScreen, pPointer->pCursor, x, y); 4014642e01fSmrg pPointer->devx = x; 4024642e01fSmrg pPointer->devy = y; 4034642e01fSmrg pPointer->pSpriteCursor = pPointer->pCursor; 4044642e01fSmrg pPointer->pSpriteScreen = pScreen; 40505b261ecSmrg } 40605b261ecSmrg /* 40705b261ecSmrg * if the cursor has changed, display the new one 40805b261ecSmrg */ 4094642e01fSmrg else if (pPointer->pCursor != pPointer->pSpriteCursor) 41005b261ecSmrg { 4114642e01fSmrg pCursor = pPointer->pCursor; 4124642e01fSmrg if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)) 41305b261ecSmrg pCursor = NullCursor; 4144642e01fSmrg (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); 41505b261ecSmrg 4164642e01fSmrg pPointer->devx = x; 4174642e01fSmrg pPointer->devy = y; 4184642e01fSmrg pPointer->pSpriteCursor = pPointer->pCursor; 41905b261ecSmrg } 42005b261ecSmrg else if (x != devx || y != devy) 42105b261ecSmrg { 4224642e01fSmrg pPointer->devx = x; 4234642e01fSmrg pPointer->devy = y; 4244642e01fSmrg if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) 4254642e01fSmrg (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); 42605b261ecSmrg } 42705b261ecSmrg} 42805b261ecSmrg 42905b261ecSmrgvoid 43005b261ecSmrgmiPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) 43105b261ecSmrg{ 43205b261ecSmrg miPointerScreenPtr pScreenPriv; 43305b261ecSmrg ScreenPtr pScreen; 4344642e01fSmrg miPointerPtr pPointer; 4354642e01fSmrg 4364642e01fSmrg pPointer = MIPOINTER(pDev); 43705b261ecSmrg 43805b261ecSmrg pScreen = screenInfo.screens[screen_no]; 43905b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 4404642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); 4414642e01fSmrg NewCurrentScreen (pDev, pScreen, x, y); 4424642e01fSmrg 4434642e01fSmrg pPointer->limits.x2 = pScreen->width; 4444642e01fSmrg pPointer->limits.y2 = pScreen->height; 44505b261ecSmrg} 44605b261ecSmrg 44705b261ecSmrg_X_EXPORT ScreenPtr 44805b261ecSmrgmiPointerCurrentScreen () 44905b261ecSmrg{ 45005b261ecSmrg return miPointerGetScreen(inputInfo.pointer); 45105b261ecSmrg} 45205b261ecSmrg 45305b261ecSmrg_X_EXPORT ScreenPtr 45405b261ecSmrgmiPointerGetScreen(DeviceIntPtr pDev) 45505b261ecSmrg{ 4564642e01fSmrg miPointerPtr pPointer = MIPOINTER(pDev); 4574642e01fSmrg return (pPointer) ? pPointer->pScreen : NULL; 45805b261ecSmrg} 45905b261ecSmrg 46005b261ecSmrg/* Move the pointer to x, y on the current screen, update the sprite, and 46105b261ecSmrg * the motion history. Generates no events. Does not return changed x 46205b261ecSmrg * and y if they are clipped; use miPointerSetPosition instead. */ 46305b261ecSmrg_X_EXPORT void 46405b261ecSmrgmiPointerAbsoluteCursor (int x, int y, unsigned long time) 46505b261ecSmrg{ 4664642e01fSmrg miPointerSetPosition(inputInfo.pointer, &x, &y); 46705b261ecSmrg} 46805b261ecSmrg 46905b261ecSmrg/* Move the pointer on the current screen, and update the sprite. */ 47005b261ecSmrgstatic void 4714642e01fSmrgmiPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen, 4724642e01fSmrg int x, int y) 47305b261ecSmrg{ 4744642e01fSmrg miPointerPtr pPointer; 47505b261ecSmrg SetupScreen(pScreen); 47605b261ecSmrg 4774642e01fSmrg pPointer = MIPOINTER(pDev); 4784642e01fSmrg 4794642e01fSmrg /* Hack: We mustn't call into ->MoveCursor for anything but the 4804642e01fSmrg * VCP, as this may cause a non-HW rendered cursor to be rendered during 4814642e01fSmrg * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT. 4824642e01fSmrg */ 4834642e01fSmrg if ((pDev == inputInfo.pointer || (!pDev->isMaster && pDev->u.master == inputInfo.pointer)) 4844642e01fSmrg && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) 48505b261ecSmrg { 4864642e01fSmrg pPointer->devx = x; 4874642e01fSmrg pPointer->devy = y; 4884642e01fSmrg if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) 4894642e01fSmrg (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); 49005b261ecSmrg } 49105b261ecSmrg 4924642e01fSmrg pPointer->x = x; 4934642e01fSmrg pPointer->y = y; 4944642e01fSmrg pPointer->pScreen = pScreen; 49505b261ecSmrg} 49605b261ecSmrg 49705b261ecSmrg_X_EXPORT void 4984642e01fSmrgmiPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) 49905b261ecSmrg{ 50005b261ecSmrg miPointerScreenPtr pScreenPriv; 50105b261ecSmrg ScreenPtr pScreen; 50205b261ecSmrg ScreenPtr newScreen; 50305b261ecSmrg 5044642e01fSmrg miPointerPtr pPointer; 5054642e01fSmrg 5064642e01fSmrg pPointer = MIPOINTER(pDev); 5074642e01fSmrg pScreen = pPointer->pScreen; 50805b261ecSmrg if (!pScreen) 50905b261ecSmrg return; /* called before ready */ 51005b261ecSmrg 5114642e01fSmrg if (!pDev || !pDev->coreEvents) 51205b261ecSmrg return; 51305b261ecSmrg 51405b261ecSmrg if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height) 51505b261ecSmrg { 51605b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 5174642e01fSmrg if (!pPointer->confined) 51805b261ecSmrg { 51905b261ecSmrg newScreen = pScreen; 52005b261ecSmrg (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y); 52105b261ecSmrg if (newScreen != pScreen) 52205b261ecSmrg { 52305b261ecSmrg pScreen = newScreen; 5244642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, 5254642e01fSmrg FALSE); 52605b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 52705b261ecSmrg /* Smash the confine to the new screen */ 5284642e01fSmrg pPointer->limits.x2 = pScreen->width; 5294642e01fSmrg pPointer->limits.y2 = pScreen->height; 53005b261ecSmrg } 53105b261ecSmrg } 53205b261ecSmrg } 53305b261ecSmrg /* Constrain the sprite to the current limits. */ 5344642e01fSmrg if (*x < pPointer->limits.x1) 5354642e01fSmrg *x = pPointer->limits.x1; 5364642e01fSmrg if (*x >= pPointer->limits.x2) 5374642e01fSmrg *x = pPointer->limits.x2 - 1; 5384642e01fSmrg if (*y < pPointer->limits.y1) 5394642e01fSmrg *y = pPointer->limits.y1; 5404642e01fSmrg if (*y >= pPointer->limits.y2) 5414642e01fSmrg *y = pPointer->limits.y2 - 1; 5424642e01fSmrg 5434642e01fSmrg if (pPointer->x == *x && pPointer->y == *y && 5444642e01fSmrg pPointer->pScreen == pScreen) 5454642e01fSmrg return; 54605b261ecSmrg 5474642e01fSmrg miPointerMoved(pDev, pScreen, *x, *y); 54805b261ecSmrg} 54905b261ecSmrg 55005b261ecSmrg_X_EXPORT void 55105b261ecSmrgmiPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) 55205b261ecSmrg{ 5534642e01fSmrg *x = MIPOINTER(pDev)->x; 5544642e01fSmrg *y = MIPOINTER(pDev)->y; 55505b261ecSmrg} 55605b261ecSmrg 5574642e01fSmrg#ifdef XQUARTZ 5584642e01fSmrg#include <pthread.h> 5594642e01fSmrgvoid darwinEvents_lock(void); 5604642e01fSmrgvoid darwinEvents_unlock(void); 5614642e01fSmrg#endif 5624642e01fSmrg 56305b261ecSmrgvoid 5644642e01fSmrgmiPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 56505b261ecSmrg{ 56605b261ecSmrg int i, nevents; 56705b261ecSmrg int valuators[2]; 56805b261ecSmrg 5694642e01fSmrg miPointerMoved(pDev, pScreen, x, y); 57005b261ecSmrg 57105b261ecSmrg /* generate motion notify */ 57205b261ecSmrg valuators[0] = x; 57305b261ecSmrg valuators[1] = y; 57405b261ecSmrg 57505b261ecSmrg if (!events) 57605b261ecSmrg { 5774642e01fSmrg events = InitEventList(GetMaximumEventsNum()); 57805b261ecSmrg 57905b261ecSmrg if (!events) 58005b261ecSmrg { 58105b261ecSmrg FatalError("Could not allocate event store.\n"); 58205b261ecSmrg return; 58305b261ecSmrg } 58405b261ecSmrg } 58505b261ecSmrg 5864642e01fSmrg nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, 0, 2, valuators); 58705b261ecSmrg 5884642e01fSmrg OsBlockSignals(); 5894642e01fSmrg#ifdef XQUARTZ 5904642e01fSmrg darwinEvents_lock(); 5914642e01fSmrg#endif 59205b261ecSmrg for (i = 0; i < nevents; i++) 5934642e01fSmrg mieqEnqueue(pDev, events[i].event); 5944642e01fSmrg#ifdef XQUARTZ 5954642e01fSmrg darwinEvents_unlock(); 5964642e01fSmrg#endif 5974642e01fSmrg OsReleaseSignals(); 59805b261ecSmrg} 599