sunMouse.c revision 48c4760e
1ee7c6486Stsutsui/* $Xorg: sunMouse.c,v 1.3 2000/08/17 19:48:32 cpqbld Exp $ */ 2ee7c6486Stsutsui/*- 3ee7c6486Stsutsui * Copyright 1987 by the Regents of the University of California 4ee7c6486Stsutsui * 5ee7c6486Stsutsui * Permission to use, copy, modify, and distribute this 6ee7c6486Stsutsui * software and its documentation for any purpose and without 7ee7c6486Stsutsui * fee is hereby granted, provided that the above copyright 8ee7c6486Stsutsui * notice appear in all copies. The University of California 9ee7c6486Stsutsui * makes no representations about the suitability of this 10ee7c6486Stsutsui * software for any purpose. It is provided "as is" without 11ee7c6486Stsutsui * express or implied warranty. 12ee7c6486Stsutsui */ 13ee7c6486Stsutsui 14ee7c6486Stsutsui/************************************************************ 15ee7c6486StsutsuiCopyright 1987 by Sun Microsystems, Inc. Mountain View, CA. 16ee7c6486Stsutsui 17ee7c6486Stsutsui All Rights Reserved 18ee7c6486Stsutsui 19ee7c6486StsutsuiPermission to use, copy, modify, and distribute this 20ee7c6486Stsutsuisoftware and its documentation for any purpose and without 21ee7c6486Stsutsuifee is hereby granted, provided that the above copyright no- 22ee7c6486Stsutsuitice appear in all copies and that both that copyright no- 23ee7c6486Stsutsuitice and this permission notice appear in supporting docu- 24ee7c6486Stsutsuimentation, and that the names of Sun or The Open Group 25ee7c6486Stsutsuinot be used in advertising or publicity pertaining to 26ee7c6486Stsutsuidistribution of the software without specific prior 27ee7c6486Stsutsuiwritten permission. Sun and The Open Group make no 28ee7c6486Stsutsuirepresentations about the suitability of this software for 29ee7c6486Stsutsuiany purpose. It is provided "as is" without any express or 30ee7c6486Stsutsuiimplied warranty. 31ee7c6486Stsutsui 32ee7c6486StsutsuiSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 33ee7c6486StsutsuiINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- 34ee7c6486StsutsuiNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- 35ee7c6486StsutsuiABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 36ee7c6486StsutsuiANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 37ee7c6486StsutsuiPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 38ee7c6486StsutsuiOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 39ee7c6486StsutsuiTHE USE OR PERFORMANCE OF THIS SOFTWARE. 40ee7c6486Stsutsui 41ee7c6486Stsutsui********************************************************/ 42ee7c6486Stsutsui/* 43ee7c6486Stsutsui * Copyright 1991, 1992, 1993 Kaleb S. Keithley 44ee7c6486Stsutsui * 45ee7c6486Stsutsui * Permission to use, copy, modify, and distribute this 46ee7c6486Stsutsui * software and its documentation for any purpose and without 47ee7c6486Stsutsui * fee is hereby granted, provided that the above copyright 48ee7c6486Stsutsui * notice appear in all copies. Kaleb S. Keithley makes no 49ee7c6486Stsutsui * representations about the suitability of this software for 50ee7c6486Stsutsui * any purpose. It is provided "as is" without express or 51ee7c6486Stsutsui * implied warranty. 52ee7c6486Stsutsui */ 53ee7c6486Stsutsui/* $XFree86: xc/programs/Xserver/hw/sun/sunMouse.c,v 1.4 2003/11/17 22:20:36 dawes Exp $ */ 54ee7c6486Stsutsui 55ee7c6486Stsutsui#define NEED_EVENTS 56ee7c6486Stsutsui#include "sun.h" 57ee7c6486Stsutsui#include "mi.h" 58ee7c6486Stsutsui#include "cursor.h" 59ee7c6486Stsutsui#include "input.h" 60ee7c6486Stsutsui#include "inpututils.h" 61ee7c6486Stsutsui#include "exevents.h" 62ee7c6486Stsutsui#include "xserver-properties.h" 63ee7c6486Stsutsui 64ee7c6486StsutsuiBool sunActiveZaphod = TRUE; 65ee7c6486StsutsuiDeviceIntPtr sunPointerDevice = NULL; 66ee7c6486Stsutsui 67177290dfStsutsuistatic void sunMouseEvents(int, int, void *); 68177290dfStsutsuistatic Firm_event *sunMouseGetEvents(int, Bool, int *, Bool *); 69177290dfStsutsuistatic void sunMouseEnqueueEvent(DeviceIntPtr, Firm_event *); 70ee7c6486Stsutsuistatic Bool sunCursorOffScreen(ScreenPtr *, int *, int *); 71ee7c6486Stsutsuistatic void sunCrossScreen(ScreenPtr, int); 72ee7c6486Stsutsuistatic void sunWarpCursor(DeviceIntPtr, ScreenPtr, int, int); 73ee7c6486Stsutsui 74ee7c6486StsutsuimiPointerScreenFuncRec sunPointerScreenFuncs = { 75ee7c6486Stsutsui sunCursorOffScreen, 76ee7c6486Stsutsui sunCrossScreen, 77ee7c6486Stsutsui sunWarpCursor, 78ee7c6486Stsutsui}; 79ee7c6486Stsutsui 80ee7c6486Stsutsuistatic void 81177290dfStsutsuisunMouseEvents(int fd, int ready, void *data) 82ee7c6486Stsutsui{ 83177290dfStsutsui int i, numEvents = 0; 84177290dfStsutsui Bool again = FALSE; 85177290dfStsutsui Firm_event *events; 86177290dfStsutsui DeviceIntPtr device = (DeviceIntPtr)data; 87177290dfStsutsui 88177290dfStsutsui input_lock(); 89177290dfStsutsui 90177290dfStsutsui do { 91177290dfStsutsui events = sunMouseGetEvents(fd, device->public.on, &numEvents, &again); 92177290dfStsutsui for (i = 0; i < numEvents; i++) { 93177290dfStsutsui sunMouseEnqueueEvent(device, &events[i]); 94177290dfStsutsui } 95177290dfStsutsui } while (again); 96177290dfStsutsui 97177290dfStsutsui input_unlock(); 98ee7c6486Stsutsui} 99ee7c6486Stsutsui 100ee7c6486Stsutsui/*- 101ee7c6486Stsutsui *----------------------------------------------------------------------- 102ee7c6486Stsutsui * sunMouseCtrl -- 103ee7c6486Stsutsui * Alter the control parameters for the mouse. Since acceleration 104ee7c6486Stsutsui * etc. is done from the PtrCtrl record in the mouse's device record, 105ee7c6486Stsutsui * there's nothing to do here. 106ee7c6486Stsutsui * 107ee7c6486Stsutsui * Results: 108ee7c6486Stsutsui * None. 109ee7c6486Stsutsui * 110ee7c6486Stsutsui * Side Effects: 111ee7c6486Stsutsui * None. 112ee7c6486Stsutsui * 113ee7c6486Stsutsui *----------------------------------------------------------------------- 114ee7c6486Stsutsui */ 115ee7c6486Stsutsui/*ARGSUSED*/ 116ee7c6486Stsutsuistatic void 117ee7c6486StsutsuisunMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 118ee7c6486Stsutsui{ 119ee7c6486Stsutsui} 120ee7c6486Stsutsui 121ee7c6486Stsutsui/*- 122ee7c6486Stsutsui *----------------------------------------------------------------------- 123ee7c6486Stsutsui * sunMouseProc -- 124ee7c6486Stsutsui * Handle the initialization, etc. of a mouse 125ee7c6486Stsutsui * 126ee7c6486Stsutsui * Results: 127ee7c6486Stsutsui * none. 128ee7c6486Stsutsui * 129ee7c6486Stsutsui * Side Effects: 130ee7c6486Stsutsui * 131ee7c6486Stsutsui * Note: 132ee7c6486Stsutsui * When using sunwindows, all input comes off a single fd, stored in the 133ee7c6486Stsutsui * global windowFd. Therefore, only one device should be enabled and 134ee7c6486Stsutsui * disabled, even though the application still sees both mouse and 135ee7c6486Stsutsui * keyboard. We have arbitrarily chosen to enable and disable windowFd 136ee7c6486Stsutsui * in the keyboard routine sunKbdProc rather than in sunMouseProc. 137ee7c6486Stsutsui * 138ee7c6486Stsutsui *----------------------------------------------------------------------- 139ee7c6486Stsutsui */ 140ee7c6486Stsutsuiint 141ee7c6486StsutsuisunMouseProc(DeviceIntPtr device, int what) 142ee7c6486Stsutsui{ 1439679a91bStsutsui DevicePtr pMouse = &device->public; 14448c4760eStsutsui sunPtrPrivPtr pPriv; 145ee7c6486Stsutsui int format; 146ee7c6486Stsutsui static int oformat; 147ee7c6486Stsutsui BYTE map[4]; 148ee7c6486Stsutsui Atom btn_labels[3] = {0}; 149ee7c6486Stsutsui Atom axes_labels[2] = { 0, 0 }; 150ee7c6486Stsutsui 151ee7c6486Stsutsui switch (what) { 152ee7c6486Stsutsui case DEVICE_INIT: 1539679a91bStsutsui if (pMouse != &sunPointerDevice->public) { 1549c576acfStsutsui ErrorF ("Cannot open non-system mouse\n"); 155ee7c6486Stsutsui return !Success; 156ee7c6486Stsutsui } 157ee7c6486Stsutsui if (sunPtrPriv.fd == -1) 158ee7c6486Stsutsui return !Success; 159ee7c6486Stsutsui pMouse->devicePrivate = (void *) &sunPtrPriv; 160ee7c6486Stsutsui pMouse->on = FALSE; 161ee7c6486Stsutsui map[1] = 1; 162ee7c6486Stsutsui map[2] = 2; 163ee7c6486Stsutsui map[3] = 3; 164ee7c6486Stsutsui btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 165ee7c6486Stsutsui btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 166ee7c6486Stsutsui btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 167ee7c6486Stsutsui axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 168ee7c6486Stsutsui axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 169ee7c6486Stsutsui 170ee7c6486Stsutsui InitPointerDeviceStruct(pMouse, map, 3, btn_labels, 171ee7c6486Stsutsui sunMouseCtrl, GetMotionHistorySize(), 172ee7c6486Stsutsui 2, axes_labels); 173d8389a6eStsutsui 174d8389a6eStsutsui /* X valuator */ 175d8389a6eStsutsui InitValuatorAxisStruct(device, 0, axes_labels[0], 176d8389a6eStsutsui NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 177d8389a6eStsutsui device->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 178d8389a6eStsutsui device->last.valuators[0] = device->valuator->axisVal[0]; 179d8389a6eStsutsui 180d8389a6eStsutsui /* Y valuator */ 181d8389a6eStsutsui InitValuatorAxisStruct(device, 1, axes_labels[1], 182d8389a6eStsutsui NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 183d8389a6eStsutsui device->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 184d8389a6eStsutsui device->last.valuators[1] = device->valuator->axisVal[1]; 185d8389a6eStsutsui 186ee7c6486Stsutsui break; 187ee7c6486Stsutsui 188ee7c6486Stsutsui case DEVICE_ON: 18948c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 19048c4760eStsutsui if (ioctl (pPriv->fd, VUIDGFORMAT, &oformat) == -1) { 1919c576acfStsutsui ErrorF("sunMouseProc ioctl VUIDGFORMAT\n"); 192ee7c6486Stsutsui return !Success; 193ee7c6486Stsutsui } 194ee7c6486Stsutsui format = VUID_FIRM_EVENT; 19548c4760eStsutsui if (ioctl (pPriv->fd, VUIDSFORMAT, &format) == -1) { 1969c576acfStsutsui ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 197ee7c6486Stsutsui return !Success; 198ee7c6486Stsutsui } 199177290dfStsutsui 20048c4760eStsutsui if (fcntl(pPriv->fd, F_SETFL, O_NONBLOCK) == -1) { 201177290dfStsutsui ErrorF("Non-blocking mouse I/O failed"); 202177290dfStsutsui return !Success; 203177290dfStsutsui } 20448c4760eStsutsui SetNotifyFd(pPriv->fd, sunMouseEvents, X_NOTIFY_READ, device); 205177290dfStsutsui 206177290dfStsutsui pPriv->bmask = 0; 207ee7c6486Stsutsui pMouse->on = TRUE; 208ee7c6486Stsutsui break; 209ee7c6486Stsutsui 210ee7c6486Stsutsui case DEVICE_CLOSE: 21148c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 21248c4760eStsutsui if (ioctl (pPriv->fd, VUIDSFORMAT, &oformat) == -1) 2139c576acfStsutsui ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 21448c4760eStsutsui pMouse->on = FALSE; 215ee7c6486Stsutsui break; 216ee7c6486Stsutsui 217ee7c6486Stsutsui case DEVICE_OFF: 21848c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 21948c4760eStsutsui RemoveNotifyFd(pPriv->fd); 220ee7c6486Stsutsui pMouse->on = FALSE; 221ee7c6486Stsutsui break; 2222aa2a51fStsutsui 2232aa2a51fStsutsui case DEVICE_ABORT: 2242aa2a51fStsutsui break; 225ee7c6486Stsutsui } 226ee7c6486Stsutsui return Success; 227ee7c6486Stsutsui} 228ee7c6486Stsutsui 229ee7c6486Stsutsui/*- 230ee7c6486Stsutsui *----------------------------------------------------------------------- 231ee7c6486Stsutsui * sunMouseGetEvents -- 232ee7c6486Stsutsui * Return the events waiting in the wings for the given mouse. 233ee7c6486Stsutsui * 234ee7c6486Stsutsui * Results: 235ee7c6486Stsutsui * A pointer to an array of Firm_events or (Firm_event *)0 if no events 236ee7c6486Stsutsui * The number of events contained in the array. 237ee7c6486Stsutsui * A boolean as to whether more events might be available. 238ee7c6486Stsutsui * 239ee7c6486Stsutsui * Side Effects: 240ee7c6486Stsutsui * None. 241ee7c6486Stsutsui *----------------------------------------------------------------------- 242ee7c6486Stsutsui */ 243ee7c6486Stsutsui 244177290dfStsutsuistatic Firm_event * 245ee7c6486StsutsuisunMouseGetEvents(int fd, Bool on, int *pNumEvents, Bool *pAgain) 246ee7c6486Stsutsui{ 247ee7c6486Stsutsui int nBytes; /* number of bytes of events available. */ 248ee7c6486Stsutsui static Firm_event evBuf[SUN_MAXEVENTS]; /* Buffer for Firm_events */ 249ee7c6486Stsutsui 250ee7c6486Stsutsui if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) { 251ee7c6486Stsutsui if (errno == EWOULDBLOCK) { 252ee7c6486Stsutsui *pNumEvents = 0; 253ee7c6486Stsutsui *pAgain = FALSE; 254ee7c6486Stsutsui } else { 2559c576acfStsutsui ErrorF("sunMouseGetEvents read\n"); 256ee7c6486Stsutsui FatalError ("Could not read from mouse"); 257ee7c6486Stsutsui } 258ee7c6486Stsutsui } else { 259ee7c6486Stsutsui if (on) { 260ee7c6486Stsutsui *pNumEvents = nBytes / sizeof (Firm_event); 261ee7c6486Stsutsui *pAgain = (nBytes == sizeof (evBuf)); 262ee7c6486Stsutsui } else { 263ee7c6486Stsutsui *pNumEvents = 0; 264ee7c6486Stsutsui *pAgain = FALSE; 265ee7c6486Stsutsui } 266ee7c6486Stsutsui } 267ee7c6486Stsutsui return evBuf; 268ee7c6486Stsutsui} 269ee7c6486Stsutsui 270ee7c6486Stsutsui 271ee7c6486Stsutsui/*- 272ee7c6486Stsutsui *----------------------------------------------------------------------- 273ee7c6486Stsutsui * sunMouseEnqueueEvent -- 274ee7c6486Stsutsui * Given a Firm_event for a mouse, pass it off the the dix layer 275ee7c6486Stsutsui * properly converted... 276ee7c6486Stsutsui * 277ee7c6486Stsutsui * Results: 278ee7c6486Stsutsui * None. 279ee7c6486Stsutsui * 280ee7c6486Stsutsui * Side Effects: 281ee7c6486Stsutsui * The cursor may be redrawn...? devPrivate/x/y will be altered. 282ee7c6486Stsutsui * 283ee7c6486Stsutsui *----------------------------------------------------------------------- 284ee7c6486Stsutsui */ 285ee7c6486Stsutsui 286177290dfStsutsuistatic void 287ee7c6486StsutsuisunMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 288ee7c6486Stsutsui{ 289ee7c6486Stsutsui sunPtrPrivPtr pPriv; /* Private data for pointer */ 290ee7c6486Stsutsui int bmask; /* Temporary button mask */ 291ee7c6486Stsutsui int x, y; 292ee7c6486Stsutsui double tmpx, tmpy; 293ee7c6486Stsutsui int type, buttons, flag; 294ee7c6486Stsutsui int valuators[2]; 295ee7c6486Stsutsui ValuatorMask mask; 296ee7c6486Stsutsui 297ee7c6486Stsutsui pPriv = (sunPtrPrivPtr)device->public.devicePrivate; 298ee7c6486Stsutsui 299ee7c6486Stsutsui switch (fe->id) { 300ee7c6486Stsutsui case MS_LEFT: 301ee7c6486Stsutsui case MS_MIDDLE: 302ee7c6486Stsutsui case MS_RIGHT: 303ee7c6486Stsutsui /* 304ee7c6486Stsutsui * A button changed state. Sometimes we will get two events 305ee7c6486Stsutsui * for a single state change. Should we get a button event which 306ee7c6486Stsutsui * reflects the current state of affairs, that event is discarded. 307ee7c6486Stsutsui * 308ee7c6486Stsutsui * Mouse buttons start at 1. 309ee7c6486Stsutsui */ 310ee7c6486Stsutsui buttons = (fe->id - MS_LEFT) + 1; 311ee7c6486Stsutsui bmask = 1 << buttons; 312ee7c6486Stsutsui if (fe->value == VKEY_UP) { 313ee7c6486Stsutsui if (pPriv->bmask & bmask) { 314ee7c6486Stsutsui type = ButtonRelease; 315ee7c6486Stsutsui pPriv->bmask &= ~bmask; 316ee7c6486Stsutsui } else { 317ee7c6486Stsutsui return; 318ee7c6486Stsutsui } 319ee7c6486Stsutsui } else { 320ee7c6486Stsutsui if ((pPriv->bmask & bmask) == 0) { 321ee7c6486Stsutsui type = ButtonPress; 322ee7c6486Stsutsui pPriv->bmask |= bmask; 323ee7c6486Stsutsui } else { 324ee7c6486Stsutsui return; 325ee7c6486Stsutsui } 326ee7c6486Stsutsui } 327ee7c6486Stsutsui flag = POINTER_RELATIVE; 32819d1127dStsutsui valuator_mask_zero(&mask); 329ee7c6486Stsutsui QueuePointerEvents(device, type, buttons, flag, &mask); 330ee7c6486Stsutsui break; 331ee7c6486Stsutsui case LOC_X_DELTA: 332ee7c6486Stsutsui valuators[0] = fe->value; 333ee7c6486Stsutsui valuators[1] = 0; 334ee7c6486Stsutsui valuator_mask_set_range(&mask, 0, 2, valuators); 335ee7c6486Stsutsui flag = POINTER_RELATIVE | POINTER_ACCELERATE; 336ee7c6486Stsutsui QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 337ee7c6486Stsutsui break; 338ee7c6486Stsutsui case LOC_Y_DELTA: 339ee7c6486Stsutsui /* 340ee7c6486Stsutsui * For some reason, motion up generates a positive y delta 341ee7c6486Stsutsui * and motion down a negative delta, so we must subtract 342ee7c6486Stsutsui * here instead of add... 343ee7c6486Stsutsui */ 344ee7c6486Stsutsui valuators[0] = 0; 345ee7c6486Stsutsui valuators[1] = -fe->value; 346ee7c6486Stsutsui valuator_mask_set_range(&mask, 0, 2, valuators); 347ee7c6486Stsutsui flag = POINTER_RELATIVE | POINTER_ACCELERATE; 348ee7c6486Stsutsui QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 349ee7c6486Stsutsui break; 350ee7c6486Stsutsui case LOC_X_ABSOLUTE: 351ee7c6486Stsutsui miPointerGetPosition(device, &x, &y); 352ee7c6486Stsutsui tmpx = fe->value; 353ee7c6486Stsutsui tmpy = y; 354ee7c6486Stsutsui miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 355ee7c6486Stsutsui break; 356ee7c6486Stsutsui case LOC_Y_ABSOLUTE: 357ee7c6486Stsutsui miPointerGetPosition(device, &x, &y); 358ee7c6486Stsutsui tmpx = x; 359ee7c6486Stsutsui tmpy = fe->value; 360ee7c6486Stsutsui miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 361ee7c6486Stsutsui break; 362ee7c6486Stsutsui default: 363ee7c6486Stsutsui FatalError ("sunMouseEnqueueEvent: unrecognized id\n"); 364ee7c6486Stsutsui break; 365ee7c6486Stsutsui } 366ee7c6486Stsutsui} 367ee7c6486Stsutsui 368ee7c6486Stsutsui/*ARGSUSED*/ 369ee7c6486Stsutsuistatic Bool 370ee7c6486StsutsuisunCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) 371ee7c6486Stsutsui{ 372ee7c6486Stsutsui int index, ret = FALSE; 373ee7c6486Stsutsui DeviceIntPtr device = sunPointerDevice; /* XXX */ 374ee7c6486Stsutsui 375ee7c6486Stsutsui if (device && PointerConfinedToScreen(device)) 376ee7c6486Stsutsui return TRUE; 377ee7c6486Stsutsui /* 378ee7c6486Stsutsui * Active Zaphod implementation: 379ee7c6486Stsutsui * increment or decrement the current screen 380ee7c6486Stsutsui * if the x is to the right or the left of 381ee7c6486Stsutsui * the current screen. 382ee7c6486Stsutsui */ 383ee7c6486Stsutsui if (sunActiveZaphod && 384ee7c6486Stsutsui screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0)) { 385ee7c6486Stsutsui index = (*pScreen)->myNum; 386ee7c6486Stsutsui if (*x < 0) { 387ee7c6486Stsutsui index = (index ? index : screenInfo.numScreens) - 1; 388ee7c6486Stsutsui *pScreen = screenInfo.screens[index]; 389ee7c6486Stsutsui *x += (*pScreen)->width; 390ee7c6486Stsutsui } else { 391ee7c6486Stsutsui *x -= (*pScreen)->width; 392ee7c6486Stsutsui index = (index + 1) % screenInfo.numScreens; 393ee7c6486Stsutsui *pScreen = screenInfo.screens[index]; 394ee7c6486Stsutsui } 395ee7c6486Stsutsui ret = TRUE; 396ee7c6486Stsutsui } 397ee7c6486Stsutsui return ret; 398ee7c6486Stsutsui} 399ee7c6486Stsutsui 400ee7c6486Stsutsuistatic void 401ee7c6486StsutsuisunCrossScreen(ScreenPtr pScreen, int entering) 402ee7c6486Stsutsui{ 403ee7c6486Stsutsui if (sunFbs[pScreen->myNum].EnterLeave) 404ee7c6486Stsutsui (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, entering ? 0 : 1); 405ee7c6486Stsutsui} 406ee7c6486Stsutsui 407ee7c6486Stsutsuistatic void 408ee7c6486StsutsuisunWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 409ee7c6486Stsutsui{ 4101406604bStsutsui input_lock(); 411ee7c6486Stsutsui miPointerWarpCursor (pDev, pScreen, x, y); 4121406604bStsutsui input_unlock(); 413ee7c6486Stsutsui} 414