123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- #include "randrstr.h"
- /*
- * When the pointer moves, check to see if the specified position is outside
- * any of theavailable CRTCs and move it to a 'sensible' place if so, where
- * sensible is the closest monitor to the departing edge.
- *
- * Returns whether the position was adjusted
- */
- static Bool
- RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
- {
- RRModePtr mode = crtc->mode;
- int scan_width, scan_height;
- if (!mode)
- return FALSE;
- RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
- if (crtc->x <= x && x < crtc->x + scan_width &&
- crtc->y <= y && y < crtc->y + scan_height)
- return TRUE;
- return FALSE;
- }
- /*
- * Find the CRTC nearest the specified position, ignoring 'skip'
- */
- static void
- RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
- {
- rrScrPriv(pScreen);
- int c;
- RRCrtcPtr nearest = NULL;
- int best = 0;
- int best_dx = 0, best_dy = 0;
- for (c = 0; c < pScrPriv->numCrtcs; c++) {
- RRCrtcPtr crtc = pScrPriv->crtcs[c];
- RRModePtr mode = crtc->mode;
- int dx, dy;
- int dist;
- int scan_width, scan_height;
- if (!mode)
- continue;
- if (crtc == skip)
- continue;
- RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
- if (x < crtc->x)
- dx = crtc->x - x;
- else if (x > crtc->x + scan_width)
- dx = x - (crtc->x + scan_width);
- else
- dx = 0;
- if (y < crtc->y)
- dy = crtc->y - x;
- else if (y > crtc->y + scan_height)
- dy = y - (crtc->y + scan_height);
- else
- dy = 0;
- dist = dx + dy;
- if (!nearest || dist < best) {
- nearest = crtc;
- best_dx = dx;
- best_dy = dy;
- }
- }
- if (best_dx || best_dy)
- (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE);
- pScrPriv->pointerCrtc = nearest;
- }
- void
- RRPointerMoved(ScreenPtr pScreen, int x, int y)
- {
- rrScrPriv(pScreen);
- RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;;
- int c;
- /* Check last known CRTC */
- if (pointerCrtc && RRCrtcContainsPosition(pointerCrtc, x, y))
- return;
- /* Check all CRTCs */
- for (c = 0; c < pScrPriv->numCrtcs; c++) {
- RRCrtcPtr crtc = pScrPriv->crtcs[c];
- if (RRCrtcContainsPosition(crtc, x, y)) {
- /* Remember containing CRTC */
- pScrPriv->pointerCrtc = crtc;
- return;
- }
- }
- /* None contain pointer, find nearest */
- RRPointerToNearestCrtc(pScreen, x, y, pointerCrtc);
- }
- /*
- * When the screen is reconfigured, move the pointer to the nearest
- * CRTC
- */
- void
- RRPointerScreenConfigured(ScreenPtr pScreen)
- {
- WindowPtr pRoot = GetCurrentRootWindow();
- ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
- int x, y;
- if (pScreen != pCurrentScreen)
- return;
- GetSpritePosition(&x, &y);
- RRPointerToNearestCrtc(pScreen, x, y, NULL);
- }
|