aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/mi/mipointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/mi/mipointer.c')
-rw-r--r--xorg-server/mi/mipointer.c196
1 files changed, 147 insertions, 49 deletions
diff --git a/xorg-server/mi/mipointer.c b/xorg-server/mi/mipointer.c
index f9ca9a70b..bbb32f745 100644
--- a/xorg-server/mi/mipointer.c
+++ b/xorg-server/mi/mipointer.c
@@ -23,6 +23,29 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
+/**
+ * @file
+ * This file contains functions to move the pointer on the screen and/or
+ * restrict its movement. These functions are divided into two sets:
+ * Screen-specific functions that are used as function pointers from other
+ * parts of the server (and end up heavily wrapped by e.g. animcur and
+ * xfixes):
+ * miPointerConstrainCursor
+ * miPointerCursorLimits
+ * miPointerDisplayCursor
+ * miPointerRealizeCursor
+ * miPointerUnrealizeCursor
+ * miPointerSetCursorPosition
+ * miRecolorCursor
+ * miPointerDeviceInitialize
+ * miPointerDeviceCleanup
+ * If wrapped, these are the last element in the wrapping chain. They may
+ * call into sprite-specific code through further function pointers though.
+ *
+ * The second type of functions are those that are directly called by the
+ * DIX, DDX and some drivers.
+ */
+
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@@ -50,7 +73,7 @@ DevPrivateKeyRec miPointerScreenKeyRec;
DevPrivateKeyRec miPointerPrivKeyRec;
#define MIPOINTER(dev) \
- ((!IsMaster(dev) && !dev->u.master) ? \
+ (IsFloating(dev) ? \
(miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
(miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
@@ -126,36 +149,17 @@ miPointerInitialize (ScreenPtr pScreen,
return TRUE;
}
+/**
+ * Destroy screen-specific information.
+ *
+ * @param index Screen index of the screen in screenInfo.screens[]
+ * @param pScreen The actual screen pointer
+ */
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());
@@ -189,8 +193,7 @@ 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)))
+ if (!IsPointerDevice(pDev))
return FALSE;
pPointer = MIPOINTER(pDev);
@@ -201,6 +204,15 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
return TRUE;
}
+/**
+ * Set up the constraints for the given device. This function does not
+ * actually constrain the cursor but merely copies the given box to the
+ * internal constraint storage.
+ *
+ * @param pDev The device to constrain to the box
+ * @param pBox The rectangle to constrain the cursor to
+ * @param pScreen Used for copying screen confinement
+ */
static void
miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
{
@@ -212,7 +224,17 @@ miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
pPointer->confined = PointerConfinedToScreen(pDev);
}
-/*ARGSUSED*/
+/**
+ * Should calculate the box for the given cursor, based on screen and the
+ * confinement given. But we assume that whatever box is passed in is valid
+ * anyway.
+ *
+ * @param pDev The device to calculate the cursor limits for
+ * @param pScreen The screen the confinement happens on
+ * @param pCursor The screen the confinement happens on
+ * @param pHotBox The confinement box for the cursor
+ * @param[out] pTopLeftBox The new confinement box, always *pHotBox.
+ */
static void
miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
BoxPtr pHotBox, BoxPtr pTopLeftBox)
@@ -220,15 +242,36 @@ miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
*pTopLeftBox = *pHotBox;
}
-static Bool GenerateEvent;
-
+/**
+ * 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;
- GenerateEvent = generateEvent;
/* device dependent - must pend signal and call miPointerWarpCursor */
(*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
if (!generateEvent)
@@ -236,9 +279,13 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
return TRUE;
}
-/* Set up sprite information for the device.
- This function will be called once for each device after it is initialized
- in the DIX.
+/**
+ * Set up sprite information for the device.
+ * This function will be called once for each device after it is initialized
+ * in the DIX.
+ *
+ * @param pDev The newly created device
+ * @param pScreen The initial sprite scree.
*/
static Bool
miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
@@ -261,6 +308,7 @@ miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
pPointer->confined = FALSE;
pPointer->x = 0;
pPointer->y = 0;
+ pPointer->generateEvent = FALSE;
if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen)))
{
@@ -272,15 +320,19 @@ miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
return TRUE;
}
-/* Clean up after device.
- This function will be called once before the device is freed in the DIX
+/**
+ * Clean up after device.
+ * This function will be called once before the device is freed in the DIX
+ *
+ * @param pDev The device to be removed from the server
+ * @param pScreen Current screen of the device
*/
static void
miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
{
SetupScreen(pScreen);
- if (!IsMaster(pDev) && pDev->u.master)
+ if (!IsMaster(pDev) && !IsFloating(pDev))
return;
(*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
@@ -289,7 +341,17 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
}
-/* Once signals are ignored, the WarpCursor function can call this */
+/**
+ * Warp the pointer to the given position on the given screen. May generate
+ * an event, depending on whether we're coming from miPointerSetPosition.
+ *
+ * Once signals are ignored, the WarpCursor function can call this
+ *
+ * @param pDev The device to warp
+ * @param pScreen Screen to warp on
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ */
void
miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
@@ -306,7 +368,7 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
changedScreen = TRUE;
}
- if (GenerateEvent)
+ if (pPointer->generateEvent)
miPointerMove (pDev, pScreen, x, y);
else
miPointerMoveNoEvent(pDev, pScreen, x, y);
@@ -322,16 +384,11 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
UpdateSpriteForScreen (pDev, pScreen) ;
}
-/*
- * Pointer/CursorDisplay interface routines
- */
-
-/*
- * miPointerUpdateSprite
+/**
+ * Syncronize the sprite with the cursor.
*
- * Syncronize the sprite with the cursor - called from ProcessInputEvents
+ * @param pDev The device to sync
*/
-
void
miPointerUpdateSprite (DeviceIntPtr pDev)
{
@@ -408,6 +465,14 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
}
}
+/**
+ * Set the device to the coordinates on the given screen.
+ *
+ * @param pDev The device to move
+ * @param screen_no Index of the screen to move to
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ */
void
miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
{
@@ -426,12 +491,18 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
pPointer->limits.y2 = pScreen->height;
}
+/**
+ * @return The current screen of the VCP
+ */
ScreenPtr
miPointerCurrentScreen (void)
{
return miPointerGetScreen(inputInfo.pointer);
}
+/**
+ * @return The current screen of the given device or NULL.
+ */
ScreenPtr
miPointerGetScreen(DeviceIntPtr pDev)
{
@@ -469,7 +540,7 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
* 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))
+ if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer
&& !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen)
{
pPointer->devx = x;
@@ -483,6 +554,18 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
pPointer->pScreen = 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).
+ *
+ * @param pDev The device to move
+ * @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 *x, int *y)
{
@@ -536,6 +619,12 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
miPointerMoveNoEvent(pDev, pScreen, *x, *y);
}
+/**
+ * Get the current position of the device in desktop coordinates.
+ *
+ * @param x Return value for the current x coordinate in desktop coordiates.
+ * @param y Return value for the current y coordinate in desktop coordiates.
+ */
void
miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
{
@@ -549,6 +638,15 @@ void darwinEvents_lock(void);
void darwinEvents_unlock(void);
#endif
+/**
+ * Move the device's pointer to the x/y coordinates on the given screen.
+ * This function generates and enqueues pointer events.
+ *
+ * @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
+ */
void
miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{