sunMouse.c revision d8389a6e
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 156 /* X valuator */ 157 InitValuatorAxisStruct(device, 0, axes_labels[0], 158 NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 159 device->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 160 device->last.valuators[0] = device->valuator->axisVal[0]; 161 162 /* Y valuator */ 163 InitValuatorAxisStruct(device, 1, axes_labels[1], 164 NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative); 165 device->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 166 device->last.valuators[1] = device->valuator->axisVal[1]; 167 168 break; 169 170 case DEVICE_ON: 171 if (ioctl (sunPtrPriv.fd, VUIDGFORMAT, &oformat) == -1) { 172 ErrorF("sunMouseProc ioctl VUIDGFORMAT\n"); 173 return !Success; 174 } 175 format = VUID_FIRM_EVENT; 176 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &format) == -1) { 177 ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 178 return !Success; 179 } 180 sunPtrPriv.bmask = 0; 181 SetNotifyFd(sunPtrPriv.fd, sunMouseHandlerNotify, 182 X_NOTIFY_READ, NULL); 183 pMouse->on = TRUE; 184 break; 185 186 case DEVICE_CLOSE: 187 pMouse->on = FALSE; 188 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &oformat) == -1) 189 ErrorF("sunMouseProc ioctl VUIDSFORMAT\n"); 190 break; 191 192 case DEVICE_OFF: 193 pMouse->on = FALSE; 194 RemoveNotifyFd(sunPtrPriv.fd); 195 break; 196 197 case DEVICE_ABORT: 198 break; 199 } 200 return Success; 201} 202 203/*- 204 *----------------------------------------------------------------------- 205 * sunMouseGetEvents -- 206 * Return the events waiting in the wings for the given mouse. 207 * 208 * Results: 209 * A pointer to an array of Firm_events or (Firm_event *)0 if no events 210 * The number of events contained in the array. 211 * A boolean as to whether more events might be available. 212 * 213 * Side Effects: 214 * None. 215 *----------------------------------------------------------------------- 216 */ 217 218Firm_event * 219sunMouseGetEvents(int fd, Bool on, int *pNumEvents, Bool *pAgain) 220{ 221 int nBytes; /* number of bytes of events available. */ 222 static Firm_event evBuf[SUN_MAXEVENTS]; /* Buffer for Firm_events */ 223 224 if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) { 225 if (errno == EWOULDBLOCK) { 226 *pNumEvents = 0; 227 *pAgain = FALSE; 228 } else { 229 ErrorF("sunMouseGetEvents read\n"); 230 FatalError ("Could not read from mouse"); 231 } 232 } else { 233 if (on) { 234 *pNumEvents = nBytes / sizeof (Firm_event); 235 *pAgain = (nBytes == sizeof (evBuf)); 236 } else { 237 *pNumEvents = 0; 238 *pAgain = FALSE; 239 } 240 } 241 return evBuf; 242} 243 244 245/*- 246 *----------------------------------------------------------------------- 247 * sunMouseEnqueueEvent -- 248 * Given a Firm_event for a mouse, pass it off the the dix layer 249 * properly converted... 250 * 251 * Results: 252 * None. 253 * 254 * Side Effects: 255 * The cursor may be redrawn...? devPrivate/x/y will be altered. 256 * 257 *----------------------------------------------------------------------- 258 */ 259 260void 261sunMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 262{ 263 sunPtrPrivPtr pPriv; /* Private data for pointer */ 264 int bmask; /* Temporary button mask */ 265 int x, y; 266 double tmpx, tmpy; 267 int type, buttons, flag; 268 int valuators[2]; 269 ValuatorMask mask; 270 271 pPriv = (sunPtrPrivPtr)device->public.devicePrivate; 272 273 switch (fe->id) { 274 case MS_LEFT: 275 case MS_MIDDLE: 276 case MS_RIGHT: 277 /* 278 * A button changed state. Sometimes we will get two events 279 * for a single state change. Should we get a button event which 280 * reflects the current state of affairs, that event is discarded. 281 * 282 * Mouse buttons start at 1. 283 */ 284 buttons = (fe->id - MS_LEFT) + 1; 285 bmask = 1 << buttons; 286 if (fe->value == VKEY_UP) { 287 if (pPriv->bmask & bmask) { 288 type = ButtonRelease; 289 pPriv->bmask &= ~bmask; 290 } else { 291 return; 292 } 293 } else { 294 if ((pPriv->bmask & bmask) == 0) { 295 type = ButtonPress; 296 pPriv->bmask |= bmask; 297 } else { 298 return; 299 } 300 } 301 flag = POINTER_RELATIVE; 302 valuator_mask_zero(&mask); 303 QueuePointerEvents(device, type, buttons, flag, &mask); 304 break; 305 case LOC_X_DELTA: 306 valuators[0] = fe->value; 307 valuators[1] = 0; 308 valuator_mask_set_range(&mask, 0, 2, valuators); 309 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 310 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 311 break; 312 case LOC_Y_DELTA: 313 /* 314 * For some reason, motion up generates a positive y delta 315 * and motion down a negative delta, so we must subtract 316 * here instead of add... 317 */ 318 valuators[0] = 0; 319 valuators[1] = -fe->value; 320 valuator_mask_set_range(&mask, 0, 2, valuators); 321 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 322 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 323 break; 324 case LOC_X_ABSOLUTE: 325 miPointerGetPosition(device, &x, &y); 326 tmpx = fe->value; 327 tmpy = y; 328 miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 329 break; 330 case LOC_Y_ABSOLUTE: 331 miPointerGetPosition(device, &x, &y); 332 tmpx = x; 333 tmpy = fe->value; 334 miPointerSetPosition(device, Absolute, &tmpx, &tmpy, NULL, NULL); 335 break; 336 default: 337 FatalError ("sunMouseEnqueueEvent: unrecognized id\n"); 338 break; 339 } 340} 341 342/*ARGSUSED*/ 343static Bool 344sunCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) 345{ 346 int index, ret = FALSE; 347 DeviceIntPtr device = sunPointerDevice; /* XXX */ 348 349 if (device && PointerConfinedToScreen(device)) 350 return TRUE; 351 /* 352 * Active Zaphod implementation: 353 * increment or decrement the current screen 354 * if the x is to the right or the left of 355 * the current screen. 356 */ 357 if (sunActiveZaphod && 358 screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0)) { 359 index = (*pScreen)->myNum; 360 if (*x < 0) { 361 index = (index ? index : screenInfo.numScreens) - 1; 362 *pScreen = screenInfo.screens[index]; 363 *x += (*pScreen)->width; 364 } else { 365 *x -= (*pScreen)->width; 366 index = (index + 1) % screenInfo.numScreens; 367 *pScreen = screenInfo.screens[index]; 368 } 369 ret = TRUE; 370 } 371 return ret; 372} 373 374static void 375sunCrossScreen(ScreenPtr pScreen, int entering) 376{ 377 if (sunFbs[pScreen->myNum].EnterLeave) 378 (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, entering ? 0 : 1); 379} 380 381static void 382sunWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 383{ 384 input_lock(); 385 miPointerWarpCursor (pDev, pScreen, x, y); 386 input_unlock(); 387} 388