sunMouse.c revision 1406604b
1/* $Xorg: sunMouse.c,v 1.3 2000/08/17 19:48:32 cpqbld Exp $ */ 2/*- 3 * Copyright 1987 by the Regents of the University of California 4 * 5 * Permission to use, copy, modify, and distribute this 6 * software and its documentation for any purpose and without 7 * fee is hereby granted, provided that the above copyright 8 * notice appear in all copies. The University of California 9 * makes no representations about the suitability of this 10 * software for any purpose. It is provided "as is" without 11 * express or implied warranty. 12 */ 13 14/************************************************************ 15Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. 16 17 All Rights Reserved 18 19Permission to use, copy, modify, and distribute this 20software and its documentation for any purpose and without 21fee is hereby granted, provided that the above copyright no- 22tice appear in all copies and that both that copyright no- 23tice and this permission notice appear in supporting docu- 24mentation, and that the names of Sun or The Open Group 25not be used in advertising or publicity pertaining to 26distribution of the software without specific prior 27written permission. Sun and The Open Group make no 28representations about the suitability of this software for 29any purpose. It is provided "as is" without any express or 30implied warranty. 31 32SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 33INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- 34NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- 35ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 36ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 37PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 38OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 39THE USE OR PERFORMANCE OF THIS SOFTWARE. 40 41********************************************************/ 42/* 43 * Copyright 1991, 1992, 1993 Kaleb S. Keithley 44 * 45 * Permission to use, copy, modify, and distribute this 46 * software and its documentation for any purpose and without 47 * fee is hereby granted, provided that the above copyright 48 * notice appear in all copies. Kaleb S. Keithley makes no 49 * representations about the suitability of this software for 50 * any purpose. It is provided "as is" without express or 51 * implied warranty. 52 */ 53/* $XFree86: xc/programs/Xserver/hw/sun/sunMouse.c,v 1.4 2003/11/17 22:20:36 dawes Exp $ */ 54 55#define NEED_EVENTS 56#include "sun.h" 57#include "mi.h" 58#include "cursor.h" 59#include "input.h" 60#include "inpututils.h" 61#include "exevents.h" 62#include "xserver-properties.h" 63 64Bool sunActiveZaphod = TRUE; 65DeviceIntPtr sunPointerDevice = NULL; 66 67static void sunMouseHandlerNotify(int, int, void *); 68static Bool sunCursorOffScreen(ScreenPtr *, int *, int *); 69static void sunCrossScreen(ScreenPtr, int); 70static void sunWarpCursor(DeviceIntPtr, ScreenPtr, int, int); 71 72miPointerScreenFuncRec sunPointerScreenFuncs = { 73 sunCursorOffScreen, 74 sunCrossScreen, 75 sunWarpCursor, 76}; 77 78static void 79sunMouseHandlerNotify(int fd __unused, int ready __unused, void *data __unused) 80{ 81} 82 83/*- 84 *----------------------------------------------------------------------- 85 * sunMouseCtrl -- 86 * Alter the control parameters for the mouse. Since acceleration 87 * etc. is done from the PtrCtrl record in the mouse's device record, 88 * there's nothing to do here. 89 * 90 * Results: 91 * None. 92 * 93 * Side Effects: 94 * None. 95 * 96 *----------------------------------------------------------------------- 97 */ 98/*ARGSUSED*/ 99static void 100sunMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 101{ 102} 103 104/*- 105 *----------------------------------------------------------------------- 106 * sunMouseProc -- 107 * Handle the initialization, etc. of a mouse 108 * 109 * Results: 110 * none. 111 * 112 * Side Effects: 113 * 114 * Note: 115 * When using sunwindows, all input comes off a single fd, stored in the 116 * global windowFd. Therefore, only one device should be enabled and 117 * disabled, even though the application still sees both mouse and 118 * keyboard. We have arbitrarily chosen to enable and disable windowFd 119 * in the keyboard routine sunKbdProc rather than in sunMouseProc. 120 * 121 *----------------------------------------------------------------------- 122 */ 123int 124sunMouseProc(DeviceIntPtr device, int what) 125{ 126 DevicePtr pMouse = &device->public; 127 int format; 128 static int oformat; 129 BYTE map[4]; 130 Atom btn_labels[3] = {0}; 131 Atom axes_labels[2] = { 0, 0 }; 132 133 switch (what) { 134 case DEVICE_INIT: 135 if (pMouse != &sunPointerDevice->public) { 136 ErrorF ("Cannot open non-system mouse\n"); 137 return !Success; 138 } 139 if (sunPtrPriv.fd == -1) 140 return !Success; 141 pMouse->devicePrivate = (void *) &sunPtrPriv; 142 pMouse->on = FALSE; 143 map[1] = 1; 144 map[2] = 2; 145 map[3] = 3; 146 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 147 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 148 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 149 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 150 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 151 152 InitPointerDeviceStruct(pMouse, map, 3, btn_labels, 153 sunMouseCtrl, GetMotionHistorySize(), 154 2, axes_labels); 155 break; 156 157 case DEVICE_ON: 158 if (ioctl (sunPtrPriv.fd, VUIDGFORMAT, &oformat) == -1) { 159 ErrorF("sunMouseProc ioctl VUIDGFORMAT\n"); 160 return !Success; 161 } 162 format = VUID_FIRM_EVENT; 163 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &format) == -1) { 164 ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 165 return !Success; 166 } 167 sunPtrPriv.bmask = 0; 168 SetNotifyFd(sunPtrPriv.fd, sunMouseHandlerNotify, 169 X_NOTIFY_READ, NULL); 170 pMouse->on = TRUE; 171 break; 172 173 case DEVICE_CLOSE: 174 pMouse->on = FALSE; 175 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &oformat) == -1) 176 ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 177 break; 178 179 case DEVICE_OFF: 180 pMouse->on = FALSE; 181 RemoveNotifyFd(sunPtrPriv.fd); 182 break; 183 184 case DEVICE_ABORT: 185 break; 186 } 187 return Success; 188} 189 190/*- 191 *----------------------------------------------------------------------- 192 * sunMouseGetEvents -- 193 * Return the events waiting in the wings for the given mouse. 194 * 195 * Results: 196 * A pointer to an array of Firm_events or (Firm_event *)0 if no events 197 * The number of events contained in the array. 198 * A boolean as to whether more events might be available. 199 * 200 * Side Effects: 201 * None. 202 *----------------------------------------------------------------------- 203 */ 204 205Firm_event * 206sunMouseGetEvents(int fd, Bool on, int *pNumEvents, Bool *pAgain) 207{ 208 int nBytes; /* number of bytes of events available. */ 209 static Firm_event evBuf[SUN_MAXEVENTS]; /* Buffer for Firm_events */ 210 211 if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) { 212 if (errno == EWOULDBLOCK) { 213 *pNumEvents = 0; 214 *pAgain = FALSE; 215 } else { 216 ErrorF("sunMouseGetEvents read\n"); 217 FatalError ("Could not read from mouse"); 218 } 219 } else { 220 if (on) { 221 *pNumEvents = nBytes / sizeof (Firm_event); 222 *pAgain = (nBytes == sizeof (evBuf)); 223 } else { 224 *pNumEvents = 0; 225 *pAgain = FALSE; 226 } 227 } 228 return evBuf; 229} 230 231 232/*- 233 *----------------------------------------------------------------------- 234 * sunMouseEnqueueEvent -- 235 * Given a Firm_event for a mouse, pass it off the the dix layer 236 * properly converted... 237 * 238 * Results: 239 * None. 240 * 241 * Side Effects: 242 * The cursor may be redrawn...? devPrivate/x/y will be altered. 243 * 244 *----------------------------------------------------------------------- 245 */ 246 247void 248sunMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 249{ 250 sunPtrPrivPtr pPriv; /* Private data for pointer */ 251 int bmask; /* Temporary button mask */ 252 int x, y; 253 double tmpx, tmpy; 254 int type, buttons, flag; 255 int valuators[2]; 256 ValuatorMask mask; 257 258 pPriv = (sunPtrPrivPtr)device->public.devicePrivate; 259 260 switch (fe->id) { 261 case MS_LEFT: 262 case MS_MIDDLE: 263 case MS_RIGHT: 264 /* 265 * A button changed state. Sometimes we will get two events 266 * for a single state change. Should we get a button event which 267 * reflects the current state of affairs, that event is discarded. 268 * 269 * Mouse buttons start at 1. 270 */ 271 buttons = (fe->id - MS_LEFT) + 1; 272 bmask = 1 << buttons; 273 if (fe->value == VKEY_UP) { 274 if (pPriv->bmask & bmask) { 275 type = ButtonRelease; 276 pPriv->bmask &= ~bmask; 277 } else { 278 return; 279 } 280 } else { 281 if ((pPriv->bmask & bmask) == 0) { 282 type = ButtonPress; 283 pPriv->bmask |= bmask; 284 } else { 285 return; 286 } 287 } 288 flag = POINTER_RELATIVE; 289 valuator_mask_zero(&mask); 290 QueuePointerEvents(device, type, buttons, flag, &mask); 291 break; 292 case LOC_X_DELTA: 293 valuators[0] = fe->value; 294 valuators[1] = 0; 295 valuator_mask_set_range(&mask, 0, 2, valuators); 296 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 297 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 298 break; 299 case LOC_Y_DELTA: 300 /* 301 * For some reason, motion up generates a positive y delta 302 * and motion down a negative delta, so we must subtract 303 * here instead of add... 304 */ 305 valuators[0] = 0; 306 valuators[1] = -fe->value; 307 valuator_mask_set_range(&mask, 0, 2, valuators); 308 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 309 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 310 break; 311 case LOC_X_ABSOLUTE: 312 miPointerGetPosition(device, &x, &y); 313 tmpx = fe->value; 314 tmpy = y; 315 miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 316 break; 317 case LOC_Y_ABSOLUTE: 318 miPointerGetPosition(device, &x, &y); 319 tmpx = x; 320 tmpy = fe->value; 321 miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 322 break; 323 default: 324 FatalError ("sunMouseEnqueueEvent: unrecognized id\n"); 325 break; 326 } 327} 328 329/*ARGSUSED*/ 330static Bool 331sunCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) 332{ 333 int index, ret = FALSE; 334 DeviceIntPtr device = sunPointerDevice; /* XXX */ 335 336 if (device && PointerConfinedToScreen(device)) 337 return TRUE; 338 /* 339 * Active Zaphod implementation: 340 * increment or decrement the current screen 341 * if the x is to the right or the left of 342 * the current screen. 343 */ 344 if (sunActiveZaphod && 345 screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0)) { 346 index = (*pScreen)->myNum; 347 if (*x < 0) { 348 index = (index ? index : screenInfo.numScreens) - 1; 349 *pScreen = screenInfo.screens[index]; 350 *x += (*pScreen)->width; 351 } else { 352 *x -= (*pScreen)->width; 353 index = (index + 1) % screenInfo.numScreens; 354 *pScreen = screenInfo.screens[index]; 355 } 356 ret = TRUE; 357 } 358 return ret; 359} 360 361static void 362sunCrossScreen(ScreenPtr pScreen, int entering) 363{ 364 if (sunFbs[pScreen->myNum].EnterLeave) 365 (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, entering ? 0 : 1); 366} 367 368static void 369sunWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 370{ 371 input_lock(); 372 miPointerWarpCursor (pDev, pScreen, x, y); 373 input_unlock(); 374} 375