23
23
in this Software without prior written authorization from The Open Group.
28
* This file contains functions to move the pointer on the screen and/or
29
* restrict its movement. These functions are divided into two sets:
30
* Screen-specific functions that are used as function pointers from other
31
* parts of the server (and end up heavily wrapped by e.g. animcur and
33
* miPointerConstrainCursor
34
* miPointerCursorLimits
35
* miPointerDisplayCursor
36
* miPointerRealizeCursor
37
* miPointerUnrealizeCursor
38
* miPointerSetCursorPosition
40
* miPointerDeviceInitialize
41
* miPointerDeviceCleanup
42
* If wrapped, these are the last element in the wrapping chain. They may
43
* call into sprite-specific code through further function pointers though.
45
* The second type of functions are those that are directly called by the
46
* DIX, DDX and some drivers.
26
49
#ifdef HAVE_DIX_CONFIG_H
27
50
#include <dix-config.h>
154
* Destroy screen-specific information.
156
* @param index Screen index of the screen in screenInfo.screens[]
157
* @param pScreen The actual screen pointer
130
160
miPointerCloseScreen (int index, ScreenPtr pScreen)
133
miPointerPtr pPointer;
137
162
SetupScreen(pScreen);
140
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
142
if (DevHasCursor(pDev))
144
pPointer = MIPOINTER(pDev);
146
if (pScreen == pPointer->pScreen)
147
pPointer->pScreen = 0;
148
if (pScreen == pPointer->pSpriteScreen)
149
pPointer->pSpriteScreen = 0;
153
if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen)
154
MIPOINTER(inputInfo.pointer)->pScreen = 0;
155
if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen)
156
MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0;
159
164
pScreen->CloseScreen = pScreenPriv->CloseScreen;
160
165
free((pointer) pScreenPriv);
161
166
FreeEventList(events, GetMaximumEventsNum());
212
225
pPointer->confined = PointerConfinedToScreen(pDev);
229
* Should calculate the box for the given cursor, based on screen and the
230
* confinement given. But we assume that whatever box is passed in is valid
233
* @param pDev The device to calculate the cursor limits for
234
* @param pScreen The screen the confinement happens on
235
* @param pCursor The screen the confinement happens on
236
* @param pHotBox The confinement box for the cursor
237
* @param[out] pTopLeftBox The new confinement box, always *pHotBox.
217
240
miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
218
241
BoxPtr pHotBox, BoxPtr pTopLeftBox)
220
243
*pTopLeftBox = *pHotBox;
223
static Bool GenerateEvent;
247
* Set the device's cursor position to the x/y position on the given screen.
248
* Generates and event if required.
250
* This function is called from:
251
* - sprite init code to place onto initial position
252
* - the various WarpPointer implementations (core, XI, Xinerama, dmx,…)
253
* - during the cursor update path in CheckMotion
254
* - in the Xinerama part of NewCurrentScreen
255
* - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so
256
* it's set back to the original pos)
258
* @param pDev The device to move
259
* @param pScreen The screen the device is on
260
* @param x The x coordinate in per-screen coordinates
261
* @param y The y coordinate in per-screen coordinates
262
* @param generateEvent True if the pointer movement should generate an
265
* @return TRUE in all cases
226
268
miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
227
269
int x, int y, Bool generateEvent)
229
271
SetupScreen (pScreen);
231
GenerateEvent = generateEvent;
272
miPointerPtr pPointer = MIPOINTER(pDev);
274
pPointer->generateEvent = generateEvent;
276
if (pScreen->ConstrainCursorHarder)
277
pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
232
279
/* device dependent - must pend signal and call miPointerWarpCursor */
233
280
(*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
234
281
if (!generateEvent)
292
/* Once signals are ignored, the WarpCursor function can call this */
349
* Warp the pointer to the given position on the given screen. May generate
350
* an event, depending on whether we're coming from miPointerSetPosition.
352
* Once signals are ignored, the WarpCursor function can call this
354
* @param pDev The device to warp
355
* @param pScreen Screen to warp on
356
* @param x The x coordinate in per-screen coordinates
357
* @param y The y coordinate in per-screen coordinates
295
361
miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
483
558
pPointer->pScreen = pScreen;
487
miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
562
* Set the devices' cursor position to the given x/y position.
564
* This function is called during the pointer update path in
565
* GetPointerEvents and friends (and the same in the xwin DDX).
567
* The coordinates provided are always absolute. The parameter mode whether
568
* it was relative or absolute movement that landed us at those coordinates.
570
* @param pDev The device to move
571
* @param mode Movement mode (Absolute or Relative)
572
* @param[in,out] screenx The x coordinate in desktop coordinates
573
* @param[in,out] screeny The y coordinate in desktop coordinates
576
miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny)
489
578
miPointerScreenPtr pScreenPriv;
490
579
ScreenPtr pScreen;
491
580
ScreenPtr newScreen;
582
Bool switch_screen = FALSE;
493
584
miPointerPtr pPointer;
495
586
if (!pDev || !pDev->coreEvents)
498
589
pPointer = MIPOINTER(pDev);
499
590
pScreen = pPointer->pScreen;
501
return; /* called before ready */
503
if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
592
return NULL; /* called before ready */
597
switch_screen = !point_on_screen(pScreen, x, y);
599
/* Switch to per-screen coordinates for CursorOffScreen and
505
606
pScreenPriv = GetScreenPrivate (pScreen);
506
607
if (!pPointer->confined)
508
609
newScreen = pScreen;
509
(*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y);
610
(*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y);
510
611
if (newScreen != pScreen)
512
613
pScreen = newScreen;
513
614
(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen,
515
/* Smash the confine to the new screen */
616
/* Smash the confine to the new screen */
516
617
pPointer->limits.x2 = pScreen->width;
517
618
pPointer->limits.y2 = pScreen->height;
521
622
/* Constrain the sprite to the current limits. */
522
if (*x < pPointer->limits.x1)
523
*x = pPointer->limits.x1;
524
if (*x >= pPointer->limits.x2)
525
*x = pPointer->limits.x2 - 1;
526
if (*y < pPointer->limits.y1)
527
*y = pPointer->limits.y1;
528
if (*y >= pPointer->limits.y2)
529
*y = pPointer->limits.y2 - 1;
531
if (pPointer->x == *x && pPointer->y == *y &&
532
pPointer->pScreen == pScreen)
535
miPointerMoveNoEvent(pDev, pScreen, *x, *y);
623
if (x < pPointer->limits.x1)
624
x = pPointer->limits.x1;
625
if (x >= pPointer->limits.x2)
626
x = pPointer->limits.x2 - 1;
627
if (y < pPointer->limits.y1)
628
y = pPointer->limits.y1;
629
if (y >= pPointer->limits.y2)
630
y = pPointer->limits.y2 - 1;
632
if (pScreen->ConstrainCursorHarder)
633
pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y);
635
if (pPointer->x != x || pPointer->y != y ||
636
pPointer->pScreen != pScreen)
637
miPointerMoveNoEvent(pDev, pScreen, x, y);
639
/* Convert to desktop coordinates again */
643
/* In the event we actually change screen or we get confined, we just
644
* drop the float component on the floor
645
* FIXME: only drop remainder for ConstrainCursorHarder, not for screen
647
if (x != trunc(*screenx))
649
if (y != trunc(*screeny))
656
* Get the current position of the device in desktop coordinates.
658
* @param x Return value for the current x coordinate in desktop coordiates.
659
* @param y Return value for the current y coordinate in desktop coordiates.
539
662
miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)