/* Move the pointer on the current screen, and update the sprite. */ static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { miPointerPtr pPointer; SetupScreen(pScreen); pPointer = MIPOINTER(pDev); /* Hack: We mustn't call into ->MoveCursor for anything but the * VCP, as this may cause a non-HW rendered cursor to be rendered during * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT. */ if ((pDev == inputInfo.pointer || (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer)) && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { pPointer->devx = x; pPointer->devy = y; if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } pPointer->x = x; pPointer->y = y; pPointer->pScreen = pScreen; }
/** * @return The current screen of the given device or NULL. */ ScreenPtr miPointerGetScreen(DeviceIntPtr pDev) { miPointerPtr pPointer = MIPOINTER(pDev); return (pPointer) ? pPointer->pScreen : NULL; }
void miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { miPointerPtr pPointer; BOOL changedScreen = FALSE; SetupScreen (pScreen); pPointer = MIPOINTER(pDev); if (pPointer->pScreen != pScreen) { (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); changedScreen = TRUE; } if (GenerateEvent) miPointerMove (pDev, pScreen, x, y); else miPointerMoveNoEvent(pDev, pScreen, x, y); /* Don't call USFS if we use Xinerama, otherwise the root window is * updated to the second screen, and we never receive any events. * (FDO bug #18668) */ if (changedScreen #ifdef PANORAMIX && noPanoramiXExtension #endif ) UpdateSpriteForScreen (pDev, pScreen) ; }
static void miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) { miPointerPtr pPointer; pPointer = MIPOINTER(pDev); pPointer->limits = *pBox; pPointer->confined = PointerConfinedToScreen(pDev); }
/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) * @param[in,out] x The x coordiante in screen coordinates (in regards to total * desktop size) * @param[in,out] y The y coordiante in screen coordinates (in regards to total * desktop size) */ void miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; if (!pScreen) return; /* called before ready */ if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height) { pScreenPriv = GetScreenPrivate (pScreen); if (!pPointer->confined) { newScreen = pScreen; (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); pScreenPriv = GetScreenPrivate (pScreen); /* Smash the confine to the new screen */ pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; } } } /* Constrain the sprite to the current limits. */ if (*x < pPointer->limits.x1) *x = pPointer->limits.x1; if (*x >= pPointer->limits.x2) *x = pPointer->limits.x2 - 1; if (*y < pPointer->limits.y1) *y = pPointer->limits.y1; if (*y >= pPointer->limits.y2) *y = pPointer->limits.y2 - 1; if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y); if (pPointer->x == *x && pPointer->y == *y && pPointer->pScreen == pScreen) return; miPointerMoveNoEvent(pDev, pScreen, *x, *y); }
static Bool miPointerCloseScreen (int index, ScreenPtr pScreen) { #if 0 miPointerPtr pPointer; DeviceIntPtr pDev; #endif SetupScreen(pScreen); #if 0 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (DevHasCursor(pDev)) { pPointer = MIPOINTER(pDev); if (pScreen == pPointer->pScreen) pPointer->pScreen = 0; if (pScreen == pPointer->pSpriteScreen) pPointer->pSpriteScreen = 0; } } if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen) MIPOINTER(inputInfo.pointer)->pScreen = 0; if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen) MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0; #endif pScreen->CloseScreen = pScreenPriv->CloseScreen; free((pointer) pScreenPriv); FreeEventList(events, GetMaximumEventsNum()); events = NULL; return (*pScreen->CloseScreen) (index, pScreen); }
static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { miPointerPtr pPointer; /* return for keyboards */ if (!IsPointerDevice(pDev)) return FALSE; pPointer = MIPOINTER(pDev); pPointer->pCursor = pCursor; pPointer->pScreen = pScreen; miPointerUpdateSprite(pDev); return TRUE; }
void miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; miPointerPtr pPointer; pPointer = MIPOINTER(pDev); pScreen = screenInfo.screens[screen_no]; pScreenPriv = GetScreenPrivate (pScreen); (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); NewCurrentScreen (pDev, pScreen, x, y); pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; }
static Bool miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { miPointerPtr pPointer; /* return for keyboards */ if ((IsMaster(pDev) && !DevHasCursor(pDev)) || (!IsMaster(pDev) && pDev->u.master && !DevHasCursor(pDev->u.master))) return FALSE; pPointer = MIPOINTER(pDev); pPointer->pCursor = pCursor; pPointer->pScreen = pScreen; miPointerUpdateSprite(pDev); return TRUE; }
void miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { miPointerPtr pPointer; BOOL changedScreen = FALSE; SetupScreen (pScreen); pPointer = MIPOINTER(pDev); if (pPointer->pScreen != pScreen) { (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE); changedScreen = TRUE; } if (GenerateEvent) { miPointerMove (pDev, pScreen, x, y); } else { /* everything from miPointerMove except the event and history */ if (!pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { pPointer->devx = x; pPointer->devy = y; if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } pPointer->x = x; pPointer->y = y; pPointer->pScreen = pScreen; } /* Don't call USFS if we use Xinerama, otherwise the root window is * updated to the second screen, and we never receive any events. * (FDO bug #18668) */ if (changedScreen #ifdef PANORAMIX && noPanoramiXExtension #endif ) UpdateSpriteForScreen (pDev, pScreen) ; }
/** * Set the device's cursor position to the x/y position on the given screen. * Generates and event if required. * * This function is called from: * - sprite init code to place onto initial position * - the various WarpPointer implementations (core, XI, Xinerama, dmx,…) * - during the cursor update path in CheckMotion * - in the Xinerama part of NewCurrentScreen * - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so * it's set back to the original pos) * * @param pDev The device to move * @param pScreen The screen the device is on * @param x The x coordinate in per-screen coordinates * @param y The y coordinate in per-screen coordinates * @param generateEvent True if the pointer movement should generate an * event. * * @return TRUE in all cases */ static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) { SetupScreen(pScreen); miPointerPtr pPointer = MIPOINTER(pDev); pPointer->generateEvent = generateEvent; if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y); /* device dependent - must pend signal and call miPointerWarpCursor */ (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) miPointerUpdateSprite(pDev); return TRUE; }
void miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) { *x = MIPOINTER(pDev)->x; *y = MIPOINTER(pDev)->y; }
void miPointerUpdateSprite (DeviceIntPtr pDev) { ScreenPtr pScreen; miPointerScreenPtr pScreenPriv; CursorPtr pCursor; int x, y, devx, devy; miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return; pPointer = MIPOINTER(pDev); if (!pPointer) return; pScreen = pPointer->pScreen; if (!pScreen) return; x = pPointer->x; y = pPointer->y; devx = pPointer->devx; devy = pPointer->devy; pScreenPriv = GetScreenPrivate (pScreen); /* * if the cursor has switched screens, disable the sprite * on the old screen */ if (pScreen != pPointer->pSpriteScreen) { if (pPointer->pSpriteScreen) { miPointerScreenPtr pOldPriv; pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen); if (pPointer->pCursor) { (*pOldPriv->spriteFuncs->SetCursor) (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); } (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE); } (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pPointer->pCursor, x, y); pPointer->devx = x; pPointer->devy = y; pPointer->pSpriteCursor = pPointer->pCursor; pPointer->pSpriteScreen = pScreen; } /* * if the cursor has changed, display the new one */ else if (pPointer->pCursor != pPointer->pSpriteCursor) { pCursor = pPointer->pCursor; if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)) pCursor = NullCursor; (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); pPointer->devx = x; pPointer->devy = y; pPointer->pSpriteCursor = pPointer->pCursor; } else if (x != devx || y != devy) { pPointer->devx = x; pPointer->devy = y; if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask) (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } }
/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) * @param[in,out] screenx The x coordinate in desktop coordinates * @param[in,out] screeny The y coordinate in desktop coordinates */ ScreenPtr miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny, int *nevents, InternalEvent* events) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; int x, y; Bool switch_screen = FALSE; Bool should_constrain_barriers = FALSE; int i; miPointerPtr pPointer; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; x = trunc(*screenx); y = trunc(*screeny); switch_screen = !point_on_screen(pScreen, x, y); /* Switch to per-screen coordinates for CursorOffScreen and * Pointer->limits */ x -= pScreen->x; y -= pScreen->y; should_constrain_barriers = (mode == Relative); if (should_constrain_barriers) { /* coordinates after clamped to a barrier */ int constrained_x, constrained_y; int current_x, current_y; /* current position in per-screen coord */ current_x = MIPOINTER(pDev)->x - pScreen->y; current_y = MIPOINTER(pDev)->y - pScreen->x; input_constrain_cursor(pDev, pScreen, current_x, current_y, x, y, &constrained_x, &constrained_y, nevents, events); x = constrained_x; y = constrained_y; } if (switch_screen) { pScreenPriv = GetScreenPrivate(pScreen); if (!pPointer->confined) { newScreen = pScreen; (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); /* Smash the confine to the new screen */ pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; } } } /* Constrain the sprite to the current limits. */ if (x < pPointer->limits.x1) x = pPointer->limits.x1; if (x >= pPointer->limits.x2) x = pPointer->limits.x2 - 1; if (y < pPointer->limits.y1) y = pPointer->limits.y1; if (y >= pPointer->limits.y2) y = pPointer->limits.y2 - 1; if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen) miPointerMoveNoEvent(pDev, pScreen, x, y); /* check if we generated any barrier events and if so, update root x/y * to the fully constrained coords */ if (should_constrain_barriers) { for (i = 0; i < *nevents; i++) { if (events[i].any.type == ET_BarrierHit || events[i].any.type == ET_BarrierLeave) { events[i].barrier_event.root_x = x; events[i].barrier_event.root_y = y; } } } /* Convert to desktop coordinates again */ x += pScreen->x; y += pScreen->y; /* In the event we actually change screen or we get confined, we just * drop the float component on the floor * FIXME: only drop remainder for ConstrainCursorHarder, not for screen * crossings */ if (x != trunc(*screenx)) *screenx = x; if (y != trunc(*screeny)) *screeny = y; return pScreen; }
/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) * @param[in,out] screenx The x coordinate in desktop coordinates * @param[in,out] screeny The y coordinate in desktop coordinates */ ScreenPtr miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; int x, y; Bool switch_screen = FALSE; miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return NULL; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; if (!pScreen) return NULL; /* called before ready */ x = trunc(*screenx); y = trunc(*screeny); switch_screen = !point_on_screen(pScreen, x, y); /* Switch to per-screen coordinates for CursorOffScreen and * Pointer->limits */ x -= pScreen->x; y -= pScreen->y; if (switch_screen) { pScreenPriv = GetScreenPrivate (pScreen); if (!pPointer->confined) { newScreen = pScreen; (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); /* Smash the confine to the new screen */ pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; } } } /* Constrain the sprite to the current limits. */ if (x < pPointer->limits.x1) x = pPointer->limits.x1; if (x >= pPointer->limits.x2) x = pPointer->limits.x2 - 1; if (y < pPointer->limits.y1) y = pPointer->limits.y1; if (y >= pPointer->limits.y2) y = pPointer->limits.y2 - 1; if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen) miPointerMoveNoEvent(pDev, pScreen, x, y); /* Convert to desktop coordinates again */ x += pScreen->x; y += pScreen->y; /* In the event we actually change screen or we get confined, we just * drop the float component on the floor * FIXME: only drop remainder for ConstrainCursorHarder, not for screen * crossings */ if (x != trunc(*screenx)) *screenx = x; if (y != trunc(*screeny)) *screeny = y; return pScreen; }