rrpointer.c revision 05b261ec
1/* 2 * Copyright © 2006 Keith Packard 3 * 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. 13 * 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 20 * OF THIS SOFTWARE. 21 */ 22 23#include "randrstr.h" 24 25/* 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. 29 * 30 * Returns whether the position was adjusted 31 */ 32 33static Bool 34RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y) 35{ 36 RRModePtr mode = crtc->mode; 37 int scan_width, scan_height; 38 39 if (!mode) 40 return FALSE; 41 42 RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height); 43 44 if (crtc->x <= x && x < crtc->x + scan_width && 45 crtc->y <= y && y < crtc->y + scan_height) 46 return TRUE; 47 return FALSE; 48} 49 50/* 51 * Find the CRTC nearest the specified position, ignoring 'skip' 52 */ 53static void 54RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) 55{ 56 rrScrPriv (pScreen); 57 int c; 58 RRCrtcPtr nearest = NULL; 59 int best = 0; 60 int best_dx = 0, best_dy = 0; 61 62 for (c = 0; c < pScrPriv->numCrtcs; c++) 63 { 64 RRCrtcPtr crtc = pScrPriv->crtcs[c]; 65 RRModePtr mode = crtc->mode; 66 int dx, dy; 67 int dist; 68 int scan_width, scan_height; 69 70 if (!mode) 71 continue; 72 if (crtc == skip) 73 continue; 74 75 RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height); 76 77 if (x < crtc->x) 78 dx = crtc->x - x; 79 else if (x > crtc->x + scan_width) 80 dx = x - (crtc->x + scan_width); 81 else 82 dx = 0; 83 if (y < crtc->y) 84 dy = crtc->y - x; 85 else if (y > crtc->y + scan_height) 86 dy = y - (crtc->y + scan_height); 87 else 88 dy = 0; 89 dist = dx + dy; 90 if (!nearest || dist < best) 91 { 92 nearest = crtc; 93 best_dx = dx; 94 best_dy = dy; 95 } 96 } 97 if (best_dx || best_dy) 98 (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); 99 pScrPriv->pointerCrtc = nearest; 100} 101 102void 103RRPointerMoved (ScreenPtr pScreen, int x, int y) 104{ 105 rrScrPriv (pScreen); 106 RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc; 107 int c; 108 109 /* Check last known CRTC */ 110 if (pointerCrtc && RRCrtcContainsPosition (pointerCrtc, x, y)) 111 return; 112 113 /* Check all CRTCs */ 114 for (c = 0; c < pScrPriv->numCrtcs; c++) 115 { 116 RRCrtcPtr crtc = pScrPriv->crtcs[c]; 117 118 if (RRCrtcContainsPosition (crtc, x, y)) 119 { 120 /* Remember containing CRTC */ 121 pScrPriv->pointerCrtc = crtc; 122 return; 123 } 124 } 125 126 /* None contain pointer, find nearest */ 127 RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc); 128} 129 130/* 131 * When the screen is reconfigured, move the pointer to the nearest 132 * CRTC 133 */ 134void 135RRPointerScreenConfigured (ScreenPtr pScreen) 136{ 137 WindowPtr pRoot = GetCurrentRootWindow (); 138 ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; 139 int x, y; 140 141 if (pScreen != pCurrentScreen) 142 return; 143 GetSpritePosition (&x, &y); 144 RRPointerToNearestCrtc (pScreen, x, y, NULL); 145} 146