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
27 * When the pointer moves, check to see if the specified position is outside
28 * any of theavailable CRTCs and move it to a 'sensible' place if so, where
29 * sensible is the closest monitor to the departing edge.
31 * Returns whether the position was adjusted
35 RRCrtcContainsPosition(RRCrtcPtr crtc
, int x
, int y
)
37 RRModePtr mode
= crtc
->mode
;
38 int scan_width
, scan_height
;
43 RRCrtcGetScanoutSize(crtc
, &scan_width
, &scan_height
);
45 if (crtc
->x
<= x
&& x
< crtc
->x
+ scan_width
&&
46 crtc
->y
<= y
&& y
< crtc
->y
+ scan_height
)
52 * Find the CRTC nearest the specified position, ignoring 'skip'
55 RRPointerToNearestCrtc(DeviceIntPtr pDev
, ScreenPtr pScreen
, int x
, int y
,
60 RRCrtcPtr nearest
= NULL
;
62 int best_dx
= 0, best_dy
= 0;
64 for (c
= 0; c
< pScrPriv
->numCrtcs
; c
++) {
65 RRCrtcPtr crtc
= pScrPriv
->crtcs
[c
];
66 RRModePtr mode
= crtc
->mode
;
69 int scan_width
, scan_height
;
76 RRCrtcGetScanoutSize(crtc
, &scan_width
, &scan_height
);
80 else if (x
> crtc
->x
+ scan_width
)
81 dx
= x
- (crtc
->x
+ scan_width
);
86 else if (y
> crtc
->y
+ scan_height
)
87 dy
= y
- (crtc
->y
+ scan_height
);
91 if (!nearest
|| dist
< best
) {
97 if (best_dx
|| best_dy
)
98 (*pScreen
->SetCursorPosition
) (pDev
, pScreen
, x
+ best_dx
, y
+ best_dy
,
100 pScrPriv
->pointerCrtc
= nearest
;
104 RRPointerMoved(ScreenPtr pScreen
, int x
, int y
)
107 RRCrtcPtr pointerCrtc
= pScrPriv
->pointerCrtc
;
110 /* Check last known CRTC */
111 if (pointerCrtc
&& RRCrtcContainsPosition(pointerCrtc
, x
, y
))
114 /* Check all CRTCs */
115 for (c
= 0; c
< pScrPriv
->numCrtcs
; c
++) {
116 RRCrtcPtr crtc
= pScrPriv
->crtcs
[c
];
118 if (RRCrtcContainsPosition(crtc
, x
, y
)) {
119 /* Remember containing CRTC */
120 pScrPriv
->pointerCrtc
= crtc
;
125 /* None contain pointer, find nearest */
126 ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
127 RRPointerToNearestCrtc(inputInfo
.pointer
, pScreen
, x
, y
, pointerCrtc
);
131 * When the screen is reconfigured, move all pointers to the nearest
135 RRPointerScreenConfigured(ScreenPtr pScreen
)
138 ScreenPtr pCurrentScreen
;
142 for (pDev
= inputInfo
.devices
; pDev
; pDev
= pDev
->next
) {
143 if (IsPointerDevice(pDev
)) {
144 pRoot
= GetCurrentRootWindow(pDev
);
145 pCurrentScreen
= pRoot
? pRoot
->drawable
.pScreen
: NULL
;
147 if (pScreen
== pCurrentScreen
) {
148 GetSpritePosition(pDev
, &x
, &y
);
149 RRPointerToNearestCrtc(pDev
, pScreen
, x
, y
, NULL
);