mipointer.c revision 6747b715
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# include <X11/X.h> 3105b261ecSmrg# include <X11/Xmd.h> 3205b261ecSmrg# include <X11/Xproto.h> 3305b261ecSmrg# include "misc.h" 3405b261ecSmrg# include "windowstr.h" 3505b261ecSmrg# include "pixmapstr.h" 3605b261ecSmrg# include "mi.h" 3705b261ecSmrg# include "scrnintstr.h" 3805b261ecSmrg# include "mipointrst.h" 3905b261ecSmrg# include "cursorstr.h" 4005b261ecSmrg# include "dixstruct.h" 4105b261ecSmrg# include "inputstr.h" 4205b261ecSmrg 436747b715SmrgDevPrivateKeyRec miPointerScreenKeyRec; 4405b261ecSmrg 454642e01fSmrg#define GetScreenPrivate(s) ((miPointerScreenPtr) \ 464642e01fSmrg dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey)) 4705b261ecSmrg#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s) 4805b261ecSmrg 496747b715SmrgDevPrivateKeyRec miPointerPrivKeyRec; 504642e01fSmrg 514642e01fSmrg#define MIPOINTER(dev) \ 526747b715Smrg ((!IsMaster(dev) && !dev->u.master) ? \ 534642e01fSmrg (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \ 546747b715Smrg (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey)) 554642e01fSmrg 564642e01fSmrgstatic Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 574642e01fSmrg CursorPtr pCursor); 584642e01fSmrgstatic Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 594642e01fSmrg CursorPtr pCursor); 604642e01fSmrgstatic Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 614642e01fSmrg CursorPtr pCursor); 624642e01fSmrgstatic void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 634642e01fSmrg BoxPtr pBox); 644642e01fSmrgstatic void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, 654642e01fSmrg CursorPtr pCursor, BoxPtr pHotBox, 664642e01fSmrg BoxPtr pTopLeftBox); 674642e01fSmrgstatic Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 684642e01fSmrg int x, int y, 6905b261ecSmrg Bool generateEvent); 7005b261ecSmrgstatic Bool miPointerCloseScreen(int index, ScreenPtr pScreen); 714642e01fSmrgstatic void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, 724642e01fSmrg int x, int y); 734642e01fSmrgstatic Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); 744642e01fSmrgstatic void miPointerDeviceCleanup(DeviceIntPtr pDev, 754642e01fSmrg ScreenPtr pScreen); 766747b715Smrgstatic void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); 7705b261ecSmrg 784642e01fSmrgstatic EventList* events; /* for WarpPointer MotionNotifies */ 7905b261ecSmrg 806747b715SmrgBool 814642e01fSmrgmiPointerInitialize (ScreenPtr pScreen, 824642e01fSmrg miPointerSpriteFuncPtr spriteFuncs, 834642e01fSmrg miPointerScreenFuncPtr screenFuncs, 844642e01fSmrg Bool waitForUpdate) 8505b261ecSmrg{ 8605b261ecSmrg miPointerScreenPtr pScreenPriv; 8705b261ecSmrg 886747b715Smrg if (!dixRegisterPrivateKey(&miPointerScreenKeyRec, PRIVATE_SCREEN, 0)) 896747b715Smrg return FALSE; 906747b715Smrg 916747b715Smrg if (!dixRegisterPrivateKey(&miPointerPrivKeyRec, PRIVATE_DEVICE, 0)) 926747b715Smrg return FALSE; 936747b715Smrg 946747b715Smrg pScreenPriv = malloc(sizeof (miPointerScreenRec)); 9505b261ecSmrg if (!pScreenPriv) 9605b261ecSmrg return FALSE; 9705b261ecSmrg pScreenPriv->spriteFuncs = spriteFuncs; 9805b261ecSmrg pScreenPriv->screenFuncs = screenFuncs; 9905b261ecSmrg /* 10005b261ecSmrg * check for uninitialized methods 10105b261ecSmrg */ 10205b261ecSmrg if (!screenFuncs->EnqueueEvent) 10305b261ecSmrg screenFuncs->EnqueueEvent = mieqEnqueue; 10405b261ecSmrg if (!screenFuncs->NewEventScreen) 10505b261ecSmrg screenFuncs->NewEventScreen = mieqSwitchScreen; 10605b261ecSmrg pScreenPriv->waitForUpdate = waitForUpdate; 10705b261ecSmrg pScreenPriv->showTransparent = FALSE; 10805b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 10905b261ecSmrg pScreen->CloseScreen = miPointerCloseScreen; 1104642e01fSmrg dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv); 11105b261ecSmrg /* 11205b261ecSmrg * set up screen cursor method table 11305b261ecSmrg */ 11405b261ecSmrg pScreen->ConstrainCursor = miPointerConstrainCursor; 11505b261ecSmrg pScreen->CursorLimits = miPointerCursorLimits; 11605b261ecSmrg pScreen->DisplayCursor = miPointerDisplayCursor; 11705b261ecSmrg pScreen->RealizeCursor = miPointerRealizeCursor; 11805b261ecSmrg pScreen->UnrealizeCursor = miPointerUnrealizeCursor; 11905b261ecSmrg pScreen->SetCursorPosition = miPointerSetCursorPosition; 12005b261ecSmrg pScreen->RecolorCursor = miRecolorCursor; 1214642e01fSmrg pScreen->DeviceCursorInitialize = miPointerDeviceInitialize; 1224642e01fSmrg pScreen->DeviceCursorCleanup = miPointerDeviceCleanup; 12305b261ecSmrg 12405b261ecSmrg events = NULL; 12505b261ecSmrg return TRUE; 12605b261ecSmrg} 12705b261ecSmrg 12805b261ecSmrgstatic Bool 1294642e01fSmrgmiPointerCloseScreen (int index, ScreenPtr pScreen) 13005b261ecSmrg{ 1314642e01fSmrg#if 0 1324642e01fSmrg miPointerPtr pPointer; 1334642e01fSmrg DeviceIntPtr pDev; 1344642e01fSmrg#endif 1354642e01fSmrg 13605b261ecSmrg SetupScreen(pScreen); 13705b261ecSmrg 1384642e01fSmrg#if 0 1394642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 1404642e01fSmrg { 1414642e01fSmrg if (DevHasCursor(pDev)) 1424642e01fSmrg { 1434642e01fSmrg pPointer = MIPOINTER(pDev); 1444642e01fSmrg 1454642e01fSmrg if (pScreen == pPointer->pScreen) 1464642e01fSmrg pPointer->pScreen = 0; 1474642e01fSmrg if (pScreen == pPointer->pSpriteScreen) 1484642e01fSmrg pPointer->pSpriteScreen = 0; 1494642e01fSmrg } 1504642e01fSmrg } 1514642e01fSmrg 1524642e01fSmrg if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen) 1534642e01fSmrg MIPOINTER(inputInfo.pointer)->pScreen = 0; 1544642e01fSmrg if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen) 1554642e01fSmrg MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0; 1564642e01fSmrg#endif 1574642e01fSmrg 15805b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 1596747b715Smrg free((pointer) pScreenPriv); 1604642e01fSmrg FreeEventList(events, GetMaximumEventsNum()); 16105b261ecSmrg events = NULL; 16205b261ecSmrg return (*pScreen->CloseScreen) (index, pScreen); 16305b261ecSmrg} 16405b261ecSmrg 16505b261ecSmrg/* 16605b261ecSmrg * DIX/DDX interface routines 16705b261ecSmrg */ 16805b261ecSmrg 16905b261ecSmrgstatic Bool 1704642e01fSmrgmiPointerRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 17105b261ecSmrg{ 17205b261ecSmrg SetupScreen(pScreen); 1734642e01fSmrg return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor); 17405b261ecSmrg} 17505b261ecSmrg 17605b261ecSmrgstatic Bool 1774642e01fSmrgmiPointerUnrealizeCursor (DeviceIntPtr pDev, 1784642e01fSmrg ScreenPtr pScreen, 1794642e01fSmrg CursorPtr pCursor) 18005b261ecSmrg{ 18105b261ecSmrg SetupScreen(pScreen); 1824642e01fSmrg return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor); 18305b261ecSmrg} 18405b261ecSmrg 18505b261ecSmrgstatic Bool 1864642e01fSmrgmiPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 18705b261ecSmrg{ 1884642e01fSmrg miPointerPtr pPointer; 1894642e01fSmrg 1904642e01fSmrg /* return for keyboards */ 1916747b715Smrg if ((IsMaster(pDev) && !DevHasCursor(pDev)) || 1926747b715Smrg (!IsMaster(pDev) && pDev->u.master && !DevHasCursor(pDev->u.master))) 1934642e01fSmrg return FALSE; 1944642e01fSmrg 1954642e01fSmrg pPointer = MIPOINTER(pDev); 1964642e01fSmrg 1974642e01fSmrg pPointer->pCursor = pCursor; 1984642e01fSmrg pPointer->pScreen = pScreen; 1994642e01fSmrg miPointerUpdateSprite(pDev); 20005b261ecSmrg return TRUE; 20105b261ecSmrg} 20205b261ecSmrg 20305b261ecSmrgstatic void 2044642e01fSmrgmiPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) 20505b261ecSmrg{ 2064642e01fSmrg miPointerPtr pPointer; 2074642e01fSmrg 2084642e01fSmrg pPointer = MIPOINTER(pDev); 2094642e01fSmrg 2104642e01fSmrg pPointer->limits = *pBox; 2114642e01fSmrg pPointer->confined = PointerConfinedToScreen(pDev); 21205b261ecSmrg} 21305b261ecSmrg 21405b261ecSmrg/*ARGSUSED*/ 21505b261ecSmrgstatic void 2164642e01fSmrgmiPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, 2174642e01fSmrg BoxPtr pHotBox, BoxPtr pTopLeftBox) 21805b261ecSmrg{ 21905b261ecSmrg *pTopLeftBox = *pHotBox; 22005b261ecSmrg} 22105b261ecSmrg 22205b261ecSmrgstatic Bool GenerateEvent; 22305b261ecSmrg 22405b261ecSmrgstatic Bool 2254642e01fSmrgmiPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 2264642e01fSmrg int x, int y, Bool generateEvent) 22705b261ecSmrg{ 22805b261ecSmrg SetupScreen (pScreen); 22905b261ecSmrg 23005b261ecSmrg GenerateEvent = generateEvent; 23105b261ecSmrg /* device dependent - must pend signal and call miPointerWarpCursor */ 2324642e01fSmrg (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); 23305b261ecSmrg if (!generateEvent) 2344642e01fSmrg miPointerUpdateSprite(pDev); 23505b261ecSmrg return TRUE; 23605b261ecSmrg} 23705b261ecSmrg 2384642e01fSmrg/* Set up sprite information for the device. 2394642e01fSmrg This function will be called once for each device after it is initialized 2404642e01fSmrg in the DIX. 2414642e01fSmrg */ 2424642e01fSmrgstatic Bool 2434642e01fSmrgmiPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 2444642e01fSmrg{ 2454642e01fSmrg miPointerPtr pPointer; 2464642e01fSmrg SetupScreen (pScreen); 2474642e01fSmrg 2486747b715Smrg pPointer = malloc(sizeof(miPointerRec)); 2494642e01fSmrg if (!pPointer) 2504642e01fSmrg return FALSE; 2514642e01fSmrg 2524642e01fSmrg pPointer->pScreen = NULL; 2534642e01fSmrg pPointer->pSpriteScreen = NULL; 2544642e01fSmrg pPointer->pCursor = NULL; 2554642e01fSmrg pPointer->pSpriteCursor = NULL; 2564642e01fSmrg pPointer->limits.x1 = 0; 2574642e01fSmrg pPointer->limits.x2 = 32767; 2584642e01fSmrg pPointer->limits.y1 = 0; 2594642e01fSmrg pPointer->limits.y2 = 32767; 2604642e01fSmrg pPointer->confined = FALSE; 2614642e01fSmrg pPointer->x = 0; 2624642e01fSmrg pPointer->y = 0; 2634642e01fSmrg 2644642e01fSmrg if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen))) 2654642e01fSmrg { 2666747b715Smrg free(pPointer); 2674642e01fSmrg return FALSE; 2684642e01fSmrg } 2694642e01fSmrg 2704642e01fSmrg dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, pPointer); 2714642e01fSmrg return TRUE; 2724642e01fSmrg} 2734642e01fSmrg 2744642e01fSmrg/* Clean up after device. 2754642e01fSmrg This function will be called once before the device is freed in the DIX 2764642e01fSmrg */ 2774642e01fSmrgstatic void 2784642e01fSmrgmiPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 2794642e01fSmrg{ 2806747b715Smrg SetupScreen(pScreen); 2816747b715Smrg 2826747b715Smrg if (!IsMaster(pDev) && pDev->u.master) 2834642e01fSmrg return; 2844642e01fSmrg 2854642e01fSmrg (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen); 2866747b715Smrg free(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey)); 2874642e01fSmrg dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL); 2884642e01fSmrg} 2894642e01fSmrg 2904642e01fSmrg 29105b261ecSmrg/* Once signals are ignored, the WarpCursor function can call this */ 29205b261ecSmrg 2936747b715Smrgvoid 2944642e01fSmrgmiPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 29505b261ecSmrg{ 2964642e01fSmrg miPointerPtr pPointer; 2974642e01fSmrg BOOL changedScreen = FALSE; 2984642e01fSmrg 29905b261ecSmrg SetupScreen (pScreen); 3006747b715Smrg pPointer = MIPOINTER(pDev); 30105b261ecSmrg 3024642e01fSmrg if (pPointer->pScreen != pScreen) 3034642e01fSmrg { 3044642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); 3054642e01fSmrg changedScreen = TRUE; 3064642e01fSmrg } 30705b261ecSmrg 30805b261ecSmrg if (GenerateEvent) 3094642e01fSmrg miPointerMove (pDev, pScreen, x, y); 31005b261ecSmrg else 3116747b715Smrg miPointerMoveNoEvent(pDev, pScreen, x, y); 3124642e01fSmrg 3134642e01fSmrg /* Don't call USFS if we use Xinerama, otherwise the root window is 3144642e01fSmrg * updated to the second screen, and we never receive any events. 3154642e01fSmrg * (FDO bug #18668) */ 3164642e01fSmrg if (changedScreen 3174642e01fSmrg#ifdef PANORAMIX 3184642e01fSmrg && noPanoramiXExtension 3194642e01fSmrg#endif 3204642e01fSmrg ) 3214642e01fSmrg UpdateSpriteForScreen (pDev, pScreen) ; 32205b261ecSmrg} 32305b261ecSmrg 32405b261ecSmrg/* 32505b261ecSmrg * Pointer/CursorDisplay interface routines 32605b261ecSmrg */ 32705b261ecSmrg 32805b261ecSmrg/* 3294642e01fSmrg * miPointerUpdateSprite 33005b261ecSmrg * 33105b261ecSmrg * Syncronize the sprite with the cursor - called from ProcessInputEvents 33205b261ecSmrg */ 33305b261ecSmrg 33405b261ecSmrgvoid 33505b261ecSmrgmiPointerUpdateSprite (DeviceIntPtr pDev) 33605b261ecSmrg{ 33705b261ecSmrg ScreenPtr pScreen; 33805b261ecSmrg miPointerScreenPtr pScreenPriv; 33905b261ecSmrg CursorPtr pCursor; 34005b261ecSmrg int x, y, devx, devy; 3414642e01fSmrg miPointerPtr pPointer; 34205b261ecSmrg 3434642e01fSmrg if (!pDev || !pDev->coreEvents) 34405b261ecSmrg return; 34505b261ecSmrg 3464642e01fSmrg pPointer = MIPOINTER(pDev); 3474642e01fSmrg 3486747b715Smrg if (!pPointer) 3496747b715Smrg return; 3506747b715Smrg 3514642e01fSmrg pScreen = pPointer->pScreen; 35205b261ecSmrg if (!pScreen) 35305b261ecSmrg return; 35405b261ecSmrg 3554642e01fSmrg x = pPointer->x; 3564642e01fSmrg y = pPointer->y; 3574642e01fSmrg devx = pPointer->devx; 3584642e01fSmrg devy = pPointer->devy; 35905b261ecSmrg 36005b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 36105b261ecSmrg /* 36205b261ecSmrg * if the cursor has switched screens, disable the sprite 36305b261ecSmrg * on the old screen 36405b261ecSmrg */ 3654642e01fSmrg if (pScreen != pPointer->pSpriteScreen) 36605b261ecSmrg { 3674642e01fSmrg if (pPointer->pSpriteScreen) 36805b261ecSmrg { 36905b261ecSmrg miPointerScreenPtr pOldPriv; 37005b261ecSmrg 3714642e01fSmrg pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen); 3724642e01fSmrg if (pPointer->pCursor) 37305b261ecSmrg { 37405b261ecSmrg (*pOldPriv->spriteFuncs->SetCursor) 3754642e01fSmrg (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); 37605b261ecSmrg } 3774642e01fSmrg (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE); 37805b261ecSmrg } 37905b261ecSmrg (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); 38005b261ecSmrg (*pScreenPriv->spriteFuncs->SetCursor) 3814642e01fSmrg (pDev, pScreen, pPointer->pCursor, x, y); 3824642e01fSmrg pPointer->devx = x; 3834642e01fSmrg pPointer->devy = y; 3844642e01fSmrg pPointer->pSpriteCursor = pPointer->pCursor; 3854642e01fSmrg pPointer->pSpriteScreen = pScreen; 38605b261ecSmrg } 38705b261ecSmrg /* 38805b261ecSmrg * if the cursor has changed, display the new one 38905b261ecSmrg */ 3904642e01fSmrg else if (pPointer->pCursor != pPointer->pSpriteCursor) 39105b261ecSmrg { 3924642e01fSmrg pCursor = pPointer->pCursor; 3934642e01fSmrg if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)) 39405b261ecSmrg pCursor = NullCursor; 3954642e01fSmrg (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); 39605b261ecSmrg 3974642e01fSmrg pPointer->devx = x; 3984642e01fSmrg pPointer->devy = y; 3994642e01fSmrg pPointer->pSpriteCursor = pPointer->pCursor; 40005b261ecSmrg } 40105b261ecSmrg else if (x != devx || y != devy) 40205b261ecSmrg { 4034642e01fSmrg pPointer->devx = x; 4044642e01fSmrg pPointer->devy = y; 4054642e01fSmrg if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) 4064642e01fSmrg (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); 40705b261ecSmrg } 40805b261ecSmrg} 40905b261ecSmrg 41005b261ecSmrgvoid 41105b261ecSmrgmiPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) 41205b261ecSmrg{ 41305b261ecSmrg miPointerScreenPtr pScreenPriv; 41405b261ecSmrg ScreenPtr pScreen; 4154642e01fSmrg miPointerPtr pPointer; 4164642e01fSmrg 4174642e01fSmrg pPointer = MIPOINTER(pDev); 41805b261ecSmrg 41905b261ecSmrg pScreen = screenInfo.screens[screen_no]; 42005b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 4214642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); 4224642e01fSmrg NewCurrentScreen (pDev, pScreen, x, y); 4234642e01fSmrg 4244642e01fSmrg pPointer->limits.x2 = pScreen->width; 4254642e01fSmrg pPointer->limits.y2 = pScreen->height; 42605b261ecSmrg} 42705b261ecSmrg 4286747b715SmrgScreenPtr 4296747b715SmrgmiPointerCurrentScreen (void) 43005b261ecSmrg{ 43105b261ecSmrg return miPointerGetScreen(inputInfo.pointer); 43205b261ecSmrg} 43305b261ecSmrg 4346747b715SmrgScreenPtr 43505b261ecSmrgmiPointerGetScreen(DeviceIntPtr pDev) 43605b261ecSmrg{ 4374642e01fSmrg miPointerPtr pPointer = MIPOINTER(pDev); 4384642e01fSmrg return (pPointer) ? pPointer->pScreen : NULL; 43905b261ecSmrg} 44005b261ecSmrg 4416747b715Smrg/* Controls whether the cursor image should be updated immediately when 4426747b715Smrg moved (FALSE) or if something else will be responsible for updating 4436747b715Smrg it later (TRUE). Returns current setting. 4446747b715Smrg Caller is responsible for calling OsBlockSignal first. 4456747b715Smrg*/ 4466747b715SmrgBool 4476747b715SmrgmiPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait) 44805b261ecSmrg{ 4496747b715Smrg SetupScreen(pScreen); 4506747b715Smrg Bool prevWait = pScreenPriv->waitForUpdate; 4516747b715Smrg 4526747b715Smrg pScreenPriv->waitForUpdate = wait; 4536747b715Smrg return prevWait; 45405b261ecSmrg} 45505b261ecSmrg 4566747b715Smrg 45705b261ecSmrg/* Move the pointer on the current screen, and update the sprite. */ 45805b261ecSmrgstatic void 4596747b715SmrgmiPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, 4604642e01fSmrg int x, int y) 46105b261ecSmrg{ 4624642e01fSmrg miPointerPtr pPointer; 46305b261ecSmrg SetupScreen(pScreen); 46405b261ecSmrg 4654642e01fSmrg pPointer = MIPOINTER(pDev); 4664642e01fSmrg 4674642e01fSmrg /* Hack: We mustn't call into ->MoveCursor for anything but the 4684642e01fSmrg * VCP, as this may cause a non-HW rendered cursor to be rendered during 4694642e01fSmrg * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT. 4704642e01fSmrg */ 4716747b715Smrg if ((pDev == inputInfo.pointer || (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer)) 4724642e01fSmrg && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) 47305b261ecSmrg { 4744642e01fSmrg pPointer->devx = x; 4754642e01fSmrg pPointer->devy = y; 4764642e01fSmrg if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) 4774642e01fSmrg (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); 47805b261ecSmrg } 47905b261ecSmrg 4804642e01fSmrg pPointer->x = x; 4814642e01fSmrg pPointer->y = y; 4824642e01fSmrg pPointer->pScreen = pScreen; 48305b261ecSmrg} 48405b261ecSmrg 4856747b715Smrgvoid 4864642e01fSmrgmiPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) 48705b261ecSmrg{ 48805b261ecSmrg miPointerScreenPtr pScreenPriv; 48905b261ecSmrg ScreenPtr pScreen; 49005b261ecSmrg ScreenPtr newScreen; 49105b261ecSmrg 4924642e01fSmrg miPointerPtr pPointer; 4934642e01fSmrg 4946747b715Smrg if (!pDev || !pDev->coreEvents) 4956747b715Smrg return; 4966747b715Smrg 4974642e01fSmrg pPointer = MIPOINTER(pDev); 4984642e01fSmrg pScreen = pPointer->pScreen; 49905b261ecSmrg if (!pScreen) 50005b261ecSmrg return; /* called before ready */ 50105b261ecSmrg 50205b261ecSmrg if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height) 50305b261ecSmrg { 50405b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 5054642e01fSmrg if (!pPointer->confined) 50605b261ecSmrg { 50705b261ecSmrg newScreen = pScreen; 50805b261ecSmrg (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y); 50905b261ecSmrg if (newScreen != pScreen) 51005b261ecSmrg { 51105b261ecSmrg pScreen = newScreen; 5124642e01fSmrg (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, 5134642e01fSmrg FALSE); 51405b261ecSmrg pScreenPriv = GetScreenPrivate (pScreen); 51505b261ecSmrg /* Smash the confine to the new screen */ 5164642e01fSmrg pPointer->limits.x2 = pScreen->width; 5174642e01fSmrg pPointer->limits.y2 = pScreen->height; 51805b261ecSmrg } 51905b261ecSmrg } 52005b261ecSmrg } 52105b261ecSmrg /* Constrain the sprite to the current limits. */ 5224642e01fSmrg if (*x < pPointer->limits.x1) 5234642e01fSmrg *x = pPointer->limits.x1; 5244642e01fSmrg if (*x >= pPointer->limits.x2) 5254642e01fSmrg *x = pPointer->limits.x2 - 1; 5264642e01fSmrg if (*y < pPointer->limits.y1) 5274642e01fSmrg *y = pPointer->limits.y1; 5284642e01fSmrg if (*y >= pPointer->limits.y2) 5294642e01fSmrg *y = pPointer->limits.y2 - 1; 5304642e01fSmrg 5314642e01fSmrg if (pPointer->x == *x && pPointer->y == *y && 5324642e01fSmrg pPointer->pScreen == pScreen) 5334642e01fSmrg return; 53405b261ecSmrg 5356747b715Smrg miPointerMoveNoEvent(pDev, pScreen, *x, *y); 53605b261ecSmrg} 53705b261ecSmrg 5386747b715Smrgvoid 53905b261ecSmrgmiPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) 54005b261ecSmrg{ 5414642e01fSmrg *x = MIPOINTER(pDev)->x; 5424642e01fSmrg *y = MIPOINTER(pDev)->y; 54305b261ecSmrg} 54405b261ecSmrg 5454642e01fSmrg#ifdef XQUARTZ 5464642e01fSmrg#include <pthread.h> 5474642e01fSmrgvoid darwinEvents_lock(void); 5484642e01fSmrgvoid darwinEvents_unlock(void); 5494642e01fSmrg#endif 5504642e01fSmrg 55105b261ecSmrgvoid 5524642e01fSmrgmiPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 55305b261ecSmrg{ 55405b261ecSmrg int i, nevents; 55505b261ecSmrg int valuators[2]; 55605b261ecSmrg 5576747b715Smrg miPointerMoveNoEvent(pDev, pScreen, x, y); 55805b261ecSmrg 55905b261ecSmrg /* generate motion notify */ 56005b261ecSmrg valuators[0] = x; 56105b261ecSmrg valuators[1] = y; 56205b261ecSmrg 56305b261ecSmrg if (!events) 56405b261ecSmrg { 5654642e01fSmrg events = InitEventList(GetMaximumEventsNum()); 56605b261ecSmrg 56705b261ecSmrg if (!events) 56805b261ecSmrg { 56905b261ecSmrg FatalError("Could not allocate event store.\n"); 57005b261ecSmrg return; 57105b261ecSmrg } 57205b261ecSmrg } 57305b261ecSmrg 5744642e01fSmrg nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, 0, 2, valuators); 57505b261ecSmrg 5764642e01fSmrg OsBlockSignals(); 5774642e01fSmrg#ifdef XQUARTZ 5784642e01fSmrg darwinEvents_lock(); 5794642e01fSmrg#endif 58005b261ecSmrg for (i = 0; i < nevents; i++) 5816747b715Smrg mieqEnqueue(pDev, (InternalEvent*)events[i].event); 5824642e01fSmrg#ifdef XQUARTZ 5834642e01fSmrg darwinEvents_unlock(); 5844642e01fSmrg#endif 5854642e01fSmrg OsReleaseSignals(); 58605b261ecSmrg} 587