2 * Copyright © 2006 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 * When the pointer moves, check to see if the specified position is outside
27 * any of theavailable CRTCs and move it to a 'sensible' place if so, where
28 * sensible is the closest monitor to the departing edge.
30 * Returns whether the position was adjusted
34 RRCrtcContainsPosition (RRCrtcPtr crtc
, int x
, int y
)
36 RRModePtr mode
= crtc
->mode
;
37 int scan_width
, scan_height
;
42 RRCrtcGetScanoutSize (crtc
, &scan_width
, &scan_height
);
44 if (crtc
->x
<= x
&& x
< crtc
->x
+ scan_width
&&
45 crtc
->y
<= y
&& y
< crtc
->y
+ scan_height
)
51 * Find the CRTC nearest the specified position, ignoring 'skip'
54 RRPointerToNearestCrtc (ScreenPtr pScreen
, int x
, int y
, RRCrtcPtr skip
)
58 RRCrtcPtr nearest
= NULL
;
60 int best_dx
= 0, best_dy
= 0;
62 for (c
= 0; c
< pScrPriv
->numCrtcs
; c
++)
64 RRCrtcPtr crtc
= pScrPriv
->crtcs
[c
];
65 RRModePtr mode
= crtc
->mode
;
68 int scan_width
, scan_height
;
75 RRCrtcGetScanoutSize (crtc
, &scan_width
, &scan_height
);
79 else if (x
> crtc
->x
+ scan_width
)
80 dx
= x
- (crtc
->x
+ scan_width
);
85 else if (y
> crtc
->y
+ scan_height
)
86 dy
= y
- (crtc
->y
+ scan_height
);
90 if (!nearest
|| dist
< best
)
97 if (best_dx
|| best_dy
)
98 (*pScreen
->SetCursorPosition
) (pScreen
, x
+ best_dx
, y
+ best_dy
, TRUE
);
99 pScrPriv
->pointerCrtc
= nearest
;
103 RRPointerMoved (ScreenPtr pScreen
, int x
, int y
)
106 RRCrtcPtr pointerCrtc
= pScrPriv
->pointerCrtc
;
109 /* Check last known CRTC */
110 if (pointerCrtc
&& RRCrtcContainsPosition (pointerCrtc
, x
, y
))
113 /* Check all CRTCs */
114 for (c
= 0; c
< pScrPriv
->numCrtcs
; c
++)
116 RRCrtcPtr crtc
= pScrPriv
->crtcs
[c
];
118 if (RRCrtcContainsPosition (crtc
, x
, y
))
120 /* Remember containing CRTC */
121 pScrPriv
->pointerCrtc
= crtc
;
126 /* None contain pointer, find nearest */
127 RRPointerToNearestCrtc (pScreen
, x
, y
, pointerCrtc
);
131 * When the screen is reconfigured, move the pointer to the nearest
135 RRPointerScreenConfigured (ScreenPtr pScreen
)
137 WindowPtr pRoot
= GetCurrentRootWindow ();
138 ScreenPtr pCurrentScreen
= pRoot
? pRoot
->drawable
.pScreen
: NULL
;
141 if (pScreen
!= pCurrentScreen
)
143 GetSpritePosition (&x
, &y
);
144 RRPointerToNearestCrtc (pScreen
, x
, y
, NULL
);