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 642da8aa69Stsutsui/* 652da8aa69Stsutsui * Data private to any sun pointer device. 662da8aa69Stsutsui */ 672da8aa69Stsutsuitypedef struct { 682da8aa69Stsutsui int fd; 692da8aa69Stsutsui int bmask; /* last known button state */ 702da8aa69Stsutsui int oformat; /* saved value of VUIDGFORMAT */ 71e83940e6Stsutsui Firm_event evbuf[SUN_MAXEVENTS]; /* Buffer for Firm_events */ 722da8aa69Stsutsui} sunPtrPrivRec, *sunPtrPrivPtr; 732da8aa69Stsutsui 74ee7c6486StsutsuiBool sunActiveZaphod = TRUE; 75ee7c6486StsutsuiDeviceIntPtr sunPointerDevice = NULL; 76ee7c6486Stsutsui 77177290dfStsutsuistatic void sunMouseEvents(int, int, void *); 788931864aStsutsuistatic void sunMouseCtrl(DeviceIntPtr, PtrCtrl *); 79e83940e6Stsutsuistatic int sunMouseGetEvents(DeviceIntPtr); 80177290dfStsutsuistatic void sunMouseEnqueueEvent(DeviceIntPtr, Firm_event *); 81ee7c6486Stsutsuistatic Bool sunCursorOffScreen(ScreenPtr *, int *, int *); 82ee7c6486Stsutsuistatic void sunCrossScreen(ScreenPtr, int); 83ee7c6486Stsutsuistatic void sunWarpCursor(DeviceIntPtr, ScreenPtr, int, int); 84ee7c6486Stsutsui 85ee7c6486StsutsuimiPointerScreenFuncRec sunPointerScreenFuncs = { 86ee7c6486Stsutsui sunCursorOffScreen, 87ee7c6486Stsutsui sunCrossScreen, 88ee7c6486Stsutsui sunWarpCursor, 89ee7c6486Stsutsui}; 90ee7c6486Stsutsui 91ee7c6486Stsutsuistatic void 92177290dfStsutsuisunMouseEvents(int fd, int ready, void *data) 93ee7c6486Stsutsui{ 94e83940e6Stsutsui int i, numEvents; 95177290dfStsutsui DeviceIntPtr device = (DeviceIntPtr)data; 96e83940e6Stsutsui DevicePtr pMouse = &device->public; 97e83940e6Stsutsui sunPtrPrivPtr pPriv = pMouse->devicePrivate; 98177290dfStsutsui 99177290dfStsutsui input_lock(); 100177290dfStsutsui 101177290dfStsutsui do { 102e83940e6Stsutsui numEvents = sunMouseGetEvents(device); 103177290dfStsutsui for (i = 0; i < numEvents; i++) { 104e83940e6Stsutsui sunMouseEnqueueEvent(device, &pPriv->evbuf[i]); 105177290dfStsutsui } 106e83940e6Stsutsui } while (numEvents == SUN_MAXEVENTS); 107177290dfStsutsui 108177290dfStsutsui input_unlock(); 109ee7c6486Stsutsui} 110ee7c6486Stsutsui 111ee7c6486Stsutsui/*- 112ee7c6486Stsutsui *----------------------------------------------------------------------- 113ee7c6486Stsutsui * sunMouseCtrl -- 114ee7c6486Stsutsui * Alter the control parameters for the mouse. Since acceleration 115ee7c6486Stsutsui * etc. is done from the PtrCtrl record in the mouse's device record, 116ee7c6486Stsutsui * there's nothing to do here. 117ee7c6486Stsutsui * 118ee7c6486Stsutsui * Results: 119ee7c6486Stsutsui * None. 120ee7c6486Stsutsui * 121ee7c6486Stsutsui * Side Effects: 122ee7c6486Stsutsui * None. 123ee7c6486Stsutsui * 124ee7c6486Stsutsui *----------------------------------------------------------------------- 125ee7c6486Stsutsui */ 126ee7c6486Stsutsui/*ARGSUSED*/ 127ee7c6486Stsutsuistatic void 128ee7c6486StsutsuisunMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 129ee7c6486Stsutsui{ 130ee7c6486Stsutsui} 131ee7c6486Stsutsui 132ee7c6486Stsutsui/*- 133ee7c6486Stsutsui *----------------------------------------------------------------------- 134ee7c6486Stsutsui * sunMouseProc -- 135ee7c6486Stsutsui * Handle the initialization, etc. of a mouse 136ee7c6486Stsutsui * 137ee7c6486Stsutsui * Results: 138ee7c6486Stsutsui * none. 139ee7c6486Stsutsui * 140ee7c6486Stsutsui * Side Effects: 141ee7c6486Stsutsui * 142ee7c6486Stsutsui * Note: 143ee7c6486Stsutsui * When using sunwindows, all input comes off a single fd, stored in the 144ee7c6486Stsutsui * global windowFd. Therefore, only one device should be enabled and 145ee7c6486Stsutsui * disabled, even though the application still sees both mouse and 146ee7c6486Stsutsui * keyboard. We have arbitrarily chosen to enable and disable windowFd 147ee7c6486Stsutsui * in the keyboard routine sunKbdProc rather than in sunMouseProc. 148ee7c6486Stsutsui * 149ee7c6486Stsutsui *----------------------------------------------------------------------- 150ee7c6486Stsutsui */ 151ee7c6486Stsutsuiint 152ee7c6486StsutsuisunMouseProc(DeviceIntPtr device, int what) 153ee7c6486Stsutsui{ 1549679a91bStsutsui DevicePtr pMouse = &device->public; 15548c4760eStsutsui sunPtrPrivPtr pPriv; 156ee7c6486Stsutsui int format; 157ee7c6486Stsutsui BYTE map[4]; 158ee7c6486Stsutsui Atom btn_labels[3] = {0}; 159ee7c6486Stsutsui Atom axes_labels[2] = { 0, 0 }; 160ee7c6486Stsutsui 161ee7c6486Stsutsui switch (what) { 162ee7c6486Stsutsui case DEVICE_INIT: 1632da8aa69Stsutsui pPriv = malloc(sizeof(*pPriv)); 1642da8aa69Stsutsui if (pPriv == NULL) { 1652da8aa69Stsutsui LogMessage(X_ERROR, "Cannot allocate private data for mouse\n"); 166ee7c6486Stsutsui return !Success; 167ee7c6486Stsutsui } 1682da8aa69Stsutsui pPriv->fd = open("/dev/mouse", O_RDWR | O_NONBLOCK, 0); 1692da8aa69Stsutsui if (pPriv->fd < 0) { 1702da8aa69Stsutsui LogMessage(X_ERROR, "Cannot open /dev/mouse, error %d\n", 1712da8aa69Stsutsui errno); 1722da8aa69Stsutsui free(pPriv); 173ee7c6486Stsutsui return !Success; 1742da8aa69Stsutsui } 1752da8aa69Stsutsui pPriv->bmask = 0; 1762da8aa69Stsutsui pPriv->oformat = 0; 1772da8aa69Stsutsui pMouse->devicePrivate = pPriv; 178ee7c6486Stsutsui pMouse->on = FALSE; 1792da8aa69Stsutsui 180ee7c6486Stsutsui map[1] = 1; 181ee7c6486Stsutsui map[2] = 2; 182ee7c6486Stsutsui map[3] = 3; 183ee7c6486Stsutsui btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 184ee7c6486Stsutsui btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 185ee7c6486Stsutsui btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 186ee7c6486Stsutsui axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 187ee7c6486Stsutsui axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 188ee7c6486Stsutsui 189ee7c6486Stsutsui InitPointerDeviceStruct(pMouse, map, 3, btn_labels, 190ee7c6486Stsutsui sunMouseCtrl, GetMotionHistorySize(), 191ee7c6486Stsutsui 2, axes_labels); 192d8389a6eStsutsui 193d8389a6eStsutsui /* X valuator */ 194d8389a6eStsutsui InitValuatorAxisStruct(device, 0, axes_labels[0], 195d8389a6eStsutsui NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 196d8389a6eStsutsui device->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 197d8389a6eStsutsui device->last.valuators[0] = device->valuator->axisVal[0]; 198d8389a6eStsutsui 199d8389a6eStsutsui /* Y valuator */ 200d8389a6eStsutsui InitValuatorAxisStruct(device, 1, axes_labels[1], 201d8389a6eStsutsui NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 202d8389a6eStsutsui device->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 203d8389a6eStsutsui device->last.valuators[1] = device->valuator->axisVal[1]; 204d8389a6eStsutsui 205ee7c6486Stsutsui break; 206ee7c6486Stsutsui 207ee7c6486Stsutsui case DEVICE_ON: 20848c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 2092da8aa69Stsutsui if (ioctl(pPriv->fd, VUIDGFORMAT, &pPriv->oformat) == -1) { 2102da8aa69Stsutsui LogMessage(X_ERROR, "sunMouseProc ioctl VUIDGFORMAT\n"); 211ee7c6486Stsutsui return !Success; 212ee7c6486Stsutsui } 213ee7c6486Stsutsui format = VUID_FIRM_EVENT; 2142da8aa69Stsutsui if (ioctl(pPriv->fd, VUIDSFORMAT, &format) == -1) { 2152da8aa69Stsutsui LogMessage(X_ERROR, "sunMouseProc ioctl VUIDSFORMAT\n"); 216ee7c6486Stsutsui return !Success; 217ee7c6486Stsutsui } 218177290dfStsutsui 21948c4760eStsutsui SetNotifyFd(pPriv->fd, sunMouseEvents, X_NOTIFY_READ, device); 220177290dfStsutsui 221177290dfStsutsui pPriv->bmask = 0; 222ee7c6486Stsutsui pMouse->on = TRUE; 223ee7c6486Stsutsui break; 224ee7c6486Stsutsui 2252da8aa69Stsutsui case DEVICE_OFF: 22648c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 2272da8aa69Stsutsui RemoveNotifyFd(pPriv->fd); 2282da8aa69Stsutsui if (ioctl(pPriv->fd, VUIDSFORMAT, &pPriv->oformat) == -1) 2292da8aa69Stsutsui LogMessage(X_ERROR, "sunMouseProc ioctl VUIDSFORMAT\n"); 23048c4760eStsutsui pMouse->on = FALSE; 231ee7c6486Stsutsui break; 232ee7c6486Stsutsui 2332da8aa69Stsutsui case DEVICE_CLOSE: 23448c4760eStsutsui pPriv = (sunPtrPrivPtr)pMouse->devicePrivate; 2352da8aa69Stsutsui close(pPriv->fd); 2362da8aa69Stsutsui free(pPriv); 2372da8aa69Stsutsui pMouse->devicePrivate = NULL; 238ee7c6486Stsutsui break; 2392aa2a51fStsutsui 2402aa2a51fStsutsui case DEVICE_ABORT: 2412aa2a51fStsutsui break; 242ee7c6486Stsutsui } 243ee7c6486Stsutsui return Success; 244ee7c6486Stsutsui} 245ee7c6486Stsutsui 246ee7c6486Stsutsui/*- 247ee7c6486Stsutsui *----------------------------------------------------------------------- 248ee7c6486Stsutsui * sunMouseGetEvents -- 249ee7c6486Stsutsui * Return the events waiting in the wings for the given mouse. 250ee7c6486Stsutsui * 251ee7c6486Stsutsui * Results: 252e83940e6Stsutsui * Update Firm_event buffer in DeviceIntPtr if events are received. 253e83940e6Stsutsui * Return the number of received Firm_events in the buffer. 254ee7c6486Stsutsui * 255ee7c6486Stsutsui * Side Effects: 256ee7c6486Stsutsui * None. 257ee7c6486Stsutsui *----------------------------------------------------------------------- 258ee7c6486Stsutsui */ 259ee7c6486Stsutsui 260e83940e6Stsutsuistatic int 261e83940e6StsutsuisunMouseGetEvents(DeviceIntPtr device) 262ee7c6486Stsutsui{ 263e83940e6Stsutsui DevicePtr pMouse = &device->public; 264e83940e6Stsutsui sunPtrPrivPtr pPriv = pMouse->devicePrivate; 265e83940e6Stsutsui int nBytes; /* number of bytes of events available. */ 266e83940e6Stsutsui int NumEvents = 0; 267e83940e6Stsutsui 268e83940e6Stsutsui nBytes = read(pPriv->fd, pPriv->evbuf, sizeof(pPriv->evbuf)); 269e83940e6Stsutsui if (nBytes == -1) { 270e83940e6Stsutsui if (errno != EWOULDBLOCK) { 271e83940e6Stsutsui LogMessage(X_ERROR, "Unexpected error on reading mouse\n"); 272e83940e6Stsutsui FatalError("Could not read from mouse"); 273ee7c6486Stsutsui } 274ee7c6486Stsutsui } else { 2752eda485bStsutsui NumEvents = nBytes / sizeof(pPriv->evbuf[0]); 276ee7c6486Stsutsui } 277e83940e6Stsutsui return NumEvents; 278ee7c6486Stsutsui} 279ee7c6486Stsutsui 280ee7c6486Stsutsui 281ee7c6486Stsutsui/*- 282ee7c6486Stsutsui *----------------------------------------------------------------------- 283ee7c6486Stsutsui * sunMouseEnqueueEvent -- 284ee7c6486Stsutsui * Given a Firm_event for a mouse, pass it off the the dix layer 285ee7c6486Stsutsui * properly converted... 286ee7c6486Stsutsui * 287ee7c6486Stsutsui * Results: 288ee7c6486Stsutsui * None. 289ee7c6486Stsutsui * 290ee7c6486Stsutsui * Side Effects: 291ee7c6486Stsutsui * The cursor may be redrawn...? devPrivate/x/y will be altered. 292ee7c6486Stsutsui * 293ee7c6486Stsutsui *----------------------------------------------------------------------- 294ee7c6486Stsutsui */ 295ee7c6486Stsutsui 296177290dfStsutsuistatic void 297ee7c6486StsutsuisunMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 298ee7c6486Stsutsui{ 299ee7c6486Stsutsui sunPtrPrivPtr pPriv; /* Private data for pointer */ 300ee7c6486Stsutsui int bmask; /* Temporary button mask */ 301ee7c6486Stsutsui int x, y; 302ee7c6486Stsutsui double tmpx, tmpy; 303ee7c6486Stsutsui int type, buttons, flag; 304ee7c6486Stsutsui int valuators[2]; 305ee7c6486Stsutsui ValuatorMask mask; 306ee7c6486Stsutsui 307ee7c6486Stsutsui pPriv = (sunPtrPrivPtr)device->public.devicePrivate; 308ee7c6486Stsutsui 309ee7c6486Stsutsui switch (fe->id) { 310ee7c6486Stsutsui case MS_LEFT: 311ee7c6486Stsutsui case MS_MIDDLE: 312ee7c6486Stsutsui case MS_RIGHT: 313ee7c6486Stsutsui /* 314ee7c6486Stsutsui * A button changed state. Sometimes we will get two events 315ee7c6486Stsutsui * for a single state change. Should we get a button event which 316ee7c6486Stsutsui * reflects the current state of affairs, that event is discarded. 317ee7c6486Stsutsui * 318ee7c6486Stsutsui * Mouse buttons start at 1. 319ee7c6486Stsutsui */ 320ee7c6486Stsutsui buttons = (fe->id - MS_LEFT) + 1; 321ee7c6486Stsutsui bmask = 1 << buttons; 322ee7c6486Stsutsui if (fe->value == VKEY_UP) { 323ee7c6486Stsutsui if (pPriv->bmask & bmask) { 324ee7c6486Stsutsui type = ButtonRelease; 325ee7c6486Stsutsui pPriv->bmask &= ~bmask; 326ee7c6486Stsutsui } else { 327ee7c6486Stsutsui return; 328ee7c6486Stsutsui } 329ee7c6486Stsutsui } else { 330ee7c6486Stsutsui if ((pPriv->bmask & bmask) == 0) { 331ee7c6486Stsutsui type = ButtonPress; 332ee7c6486Stsutsui pPriv->bmask |= bmask; 333ee7c6486Stsutsui } else { 334ee7c6486Stsutsui return; 335ee7c6486Stsutsui } 336ee7c6486Stsutsui } 337ee7c6486Stsutsui flag = POINTER_RELATIVE; 33819d1127dStsutsui valuator_mask_zero(&mask); 339ee7c6486Stsutsui QueuePointerEvents(device, type, buttons, flag, &mask); 340ee7c6486Stsutsui break; 341ee7c6486Stsutsui case LOC_X_DELTA: 342ee7c6486Stsutsui valuators[0] = fe->value; 343ee7c6486Stsutsui valuators[1] = 0; 344ee7c6486Stsutsui valuator_mask_set_range(&mask, 0, 2, valuators); 345ee7c6486Stsutsui flag = POINTER_RELATIVE | POINTER_ACCELERATE; 346ee7c6486Stsutsui QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 347ee7c6486Stsutsui break; 348ee7c6486Stsutsui case LOC_Y_DELTA: 349ee7c6486Stsutsui /* 350ee7c6486Stsutsui * For some reason, motion up generates a positive y delta 351ee7c6486Stsutsui * and motion down a negative delta, so we must subtract 352ee7c6486Stsutsui * here instead of add... 353ee7c6486Stsutsui */ 354ee7c6486Stsutsui valuators[0] = 0; 355ee7c6486Stsutsui valuators[1] = -fe->value; 356ee7c6486Stsutsui valuator_mask_set_range(&mask, 0, 2, valuators); 357ee7c6486Stsutsui flag = POINTER_RELATIVE | POINTER_ACCELERATE; 358ee7c6486Stsutsui QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 359ee7c6486Stsutsui break; 360ee7c6486Stsutsui case LOC_X_ABSOLUTE: 361ee7c6486Stsutsui miPointerGetPosition(device, &x, &y); 362ee7c6486Stsutsui tmpx = fe->value; 363ee7c6486Stsutsui tmpy = y; 364ee7c6486Stsutsui miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 365ee7c6486Stsutsui break; 366ee7c6486Stsutsui case LOC_Y_ABSOLUTE: 367ee7c6486Stsutsui miPointerGetPosition(device, &x, &y); 368ee7c6486Stsutsui tmpx = x; 369ee7c6486Stsutsui tmpy = fe->value; 370ee7c6486Stsutsui miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 371ee7c6486Stsutsui break; 372ee7c6486Stsutsui default: 373ee7c6486Stsutsui FatalError ("sunMouseEnqueueEvent: unrecognized id\n"); 374ee7c6486Stsutsui break; 375ee7c6486Stsutsui } 376ee7c6486Stsutsui} 377ee7c6486Stsutsui 378ee7c6486Stsutsui/*ARGSUSED*/ 379ee7c6486Stsutsuistatic Bool 380ee7c6486StsutsuisunCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) 381ee7c6486Stsutsui{ 382ee7c6486Stsutsui int index, ret = FALSE; 383ee7c6486Stsutsui DeviceIntPtr device = sunPointerDevice; /* XXX */ 384ee7c6486Stsutsui 385ee7c6486Stsutsui if (device && PointerConfinedToScreen(device)) 386ee7c6486Stsutsui return TRUE; 387ee7c6486Stsutsui /* 388ee7c6486Stsutsui * Active Zaphod implementation: 389ee7c6486Stsutsui * increment or decrement the current screen 390ee7c6486Stsutsui * if the x is to the right or the left of 391ee7c6486Stsutsui * the current screen. 392ee7c6486Stsutsui */ 393ee7c6486Stsutsui if (sunActiveZaphod && 394ee7c6486Stsutsui screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0)) { 395ee7c6486Stsutsui index = (*pScreen)->myNum; 396ee7c6486Stsutsui if (*x < 0) { 397ee7c6486Stsutsui index = (index ? index : screenInfo.numScreens) - 1; 398ee7c6486Stsutsui *pScreen = screenInfo.screens[index]; 399ee7c6486Stsutsui *x += (*pScreen)->width; 400ee7c6486Stsutsui } else { 401ee7c6486Stsutsui *x -= (*pScreen)->width; 402ee7c6486Stsutsui index = (index + 1) % screenInfo.numScreens; 403ee7c6486Stsutsui *pScreen = screenInfo.screens[index]; 404ee7c6486Stsutsui } 405ee7c6486Stsutsui ret = TRUE; 406ee7c6486Stsutsui } 407ee7c6486Stsutsui return ret; 408ee7c6486Stsutsui} 409ee7c6486Stsutsui 410ee7c6486Stsutsuistatic void 411ee7c6486StsutsuisunCrossScreen(ScreenPtr pScreen, int entering) 412ee7c6486Stsutsui{ 413ee7c6486Stsutsui if (sunFbs[pScreen->myNum].EnterLeave) 414ee7c6486Stsutsui (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, entering ? 0 : 1); 415ee7c6486Stsutsui} 416ee7c6486Stsutsui 417ee7c6486Stsutsuistatic void 418ee7c6486StsutsuisunWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 419ee7c6486Stsutsui{ 4201406604bStsutsui input_lock(); 421ee7c6486Stsutsui miPointerWarpCursor (pDev, pScreen, x, y); 4221406604bStsutsui input_unlock(); 423ee7c6486Stsutsui} 424