sunMouse.c revision 85d6961b
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 Bool sunCursorOffScreen(ScreenPtr *, int *, int *); 68static void sunCrossScreen(ScreenPtr, int); 69static void sunWarpCursor(DeviceIntPtr, ScreenPtr, int, int); 70 71miPointerScreenFuncRec sunPointerScreenFuncs = { 72 sunCursorOffScreen, 73 sunCrossScreen, 74 sunWarpCursor, 75 NULL, 76 NULL, 77}; 78 79/*- 80 *----------------------------------------------------------------------- 81 * sunMouseCtrl -- 82 * Alter the control parameters for the mouse. Since acceleration 83 * etc. is done from the PtrCtrl record in the mouse's device record, 84 * there's nothing to do here. 85 * 86 * Results: 87 * None. 88 * 89 * Side Effects: 90 * None. 91 * 92 *----------------------------------------------------------------------- 93 */ 94/*ARGSUSED*/ 95static void 96sunMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 97{ 98} 99 100/*- 101 *----------------------------------------------------------------------- 102 * sunMouseProc -- 103 * Handle the initialization, etc. of a mouse 104 * 105 * Results: 106 * none. 107 * 108 * Side Effects: 109 * 110 * Note: 111 * When using sunwindows, all input comes off a single fd, stored in the 112 * global windowFd. Therefore, only one device should be enabled and 113 * disabled, even though the application still sees both mouse and 114 * keyboard. We have arbitrarily chosen to enable and disable windowFd 115 * in the keyboard routine sunKbdProc rather than in sunMouseProc. 116 * 117 *----------------------------------------------------------------------- 118 */ 119int 120sunMouseProc(DeviceIntPtr device, int what) 121{ 122 DevicePtr pMouse = &device->public; 123 int format; 124 static int oformat; 125 BYTE map[4]; 126 Atom btn_labels[3] = {0}; 127 Atom axes_labels[2] = { 0, 0 }; 128 129 switch (what) { 130 case DEVICE_INIT: 131 if (pMouse != &sunPointerDevice->public) { 132 ErrorF ("Cannot open non-system mouse"); 133 return !Success; 134 } 135 if (sunPtrPriv.fd == -1) 136 return !Success; 137 pMouse->devicePrivate = (pointer) &sunPtrPriv; 138 pMouse->on = FALSE; 139 map[1] = 1; 140 map[2] = 2; 141 map[3] = 3; 142 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 143 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 144 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 145 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 146 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 147 148 InitPointerDeviceStruct(pMouse, map, 3, btn_labels, 149 sunMouseCtrl, GetMotionHistorySize(), 150 2, axes_labels); 151 break; 152 153 case DEVICE_ON: 154 if (ioctl (sunPtrPriv.fd, VUIDGFORMAT, &oformat) == -1) { 155 Error ("sunMouseProc ioctl VUIDGFORMAT"); 156 return !Success; 157 } 158 format = VUID_FIRM_EVENT; 159 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &format) == -1) { 160 Error ("sunMouseProc ioctl VUIDSFORMAT"); 161 return !Success; 162 } 163 sunPtrPriv.bmask = 0; 164 AddEnabledDevice (sunPtrPriv.fd); 165 pMouse->on = TRUE; 166 break; 167 168 case DEVICE_CLOSE: 169 pMouse->on = FALSE; 170 if (ioctl (sunPtrPriv.fd, VUIDSFORMAT, &oformat) == -1) 171 Error ("sunMouseProc ioctl VUIDSFORMAT"); 172 break; 173 174 case DEVICE_OFF: 175 pMouse->on = FALSE; 176 RemoveEnabledDevice (sunPtrPriv.fd); 177 break; 178 } 179 return Success; 180} 181 182/*- 183 *----------------------------------------------------------------------- 184 * sunMouseGetEvents -- 185 * Return the events waiting in the wings for the given mouse. 186 * 187 * Results: 188 * A pointer to an array of Firm_events or (Firm_event *)0 if no events 189 * The number of events contained in the array. 190 * A boolean as to whether more events might be available. 191 * 192 * Side Effects: 193 * None. 194 *----------------------------------------------------------------------- 195 */ 196 197Firm_event * 198sunMouseGetEvents(int fd, Bool on, int *pNumEvents, Bool *pAgain) 199{ 200 int nBytes; /* number of bytes of events available. */ 201 static Firm_event evBuf[MAXEVENTS]; /* Buffer for Firm_events */ 202 203 if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) { 204 if (errno == EWOULDBLOCK) { 205 *pNumEvents = 0; 206 *pAgain = FALSE; 207 } else { 208 Error ("sunMouseGetEvents read"); 209 FatalError ("Could not read from mouse"); 210 } 211 } else { 212 if (on) { 213 *pNumEvents = nBytes / sizeof (Firm_event); 214 *pAgain = (nBytes == sizeof (evBuf)); 215 } else { 216 *pNumEvents = 0; 217 *pAgain = FALSE; 218 } 219 } 220 return evBuf; 221} 222 223 224/*- 225 *----------------------------------------------------------------------- 226 * sunMouseEnqueueEvent -- 227 * Given a Firm_event for a mouse, pass it off the the dix layer 228 * properly converted... 229 * 230 * Results: 231 * None. 232 * 233 * Side Effects: 234 * The cursor may be redrawn...? devPrivate/x/y will be altered. 235 * 236 *----------------------------------------------------------------------- 237 */ 238 239void 240sunMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 241{ 242 sunPtrPrivPtr pPriv; /* Private data for pointer */ 243 int bmask; /* Temporary button mask */ 244 int x, y; 245 int type, buttons, flag; 246 int i, nevents, valuators[2]; 247 ValuatorMask mask; 248 249 GetEventList(&sunEvents); 250 251 pPriv = (sunPtrPrivPtr)device->public.devicePrivate; 252 253 switch (fe->id) { 254 case MS_LEFT: 255 case MS_MIDDLE: 256 case MS_RIGHT: 257 /* 258 * A button changed state. Sometimes we will get two events 259 * for a single state change. Should we get a button event which 260 * reflects the current state of affairs, that event is discarded. 261 * 262 * Mouse buttons start at 1. 263 */ 264 buttons = (fe->id - MS_LEFT) + 1; 265 bmask = 1 << buttons; 266 if (fe->value == VKEY_UP) { 267 if (pPriv->bmask & bmask) { 268 type = ButtonRelease; 269 pPriv->bmask &= ~bmask; 270 } else { 271 return; 272 } 273 } else { 274 if ((pPriv->bmask & bmask) == 0) { 275 type = ButtonPress; 276 pPriv->bmask |= bmask; 277 } else { 278 return; 279 } 280 } 281 flag = POINTER_RELATIVE; 282 valuator_mask_set_range(&mask, 0, 0, NULL); 283 nevents = GetPointerEvents(sunEvents, device, 284 type, buttons, flag, &mask); 285 for (i = 0; i < nevents; i++) 286 mieqEnqueue(device, (InternalEvent*)(sunEvents + i)->event); 287 break; 288 case LOC_X_DELTA: 289 valuators[0] = fe->value; 290 valuators[1] = 0; 291 valuator_mask_set_range(&mask, 0, 2, valuators); 292 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 293 nevents = GetPointerEvents(sunEvents, device, 294 MotionNotify, 0, flag, &mask); 295 for (i = 0; i < nevents; i++) 296 mieqEnqueue(device, (InternalEvent*)(sunEvents + i)->event); 297 break; 298 case LOC_Y_DELTA: 299 /* 300 * For some reason, motion up generates a positive y delta 301 * and motion down a negative delta, so we must subtract 302 * here instead of add... 303 */ 304 valuators[0] = 0; 305 valuators[1] = -fe->value; 306 valuator_mask_set_range(&mask, 0, 2, valuators); 307 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 308 nevents = GetPointerEvents(sunEvents, device, 309 MotionNotify, 0, flag, &mask); 310 for (i = 0; i < nevents; i++) 311 mieqEnqueue(device, (InternalEvent*)(sunEvents + i)->event); 312 break; 313 case LOC_X_ABSOLUTE: 314 miPointerGetPosition(device, &x, &y); 315 x = fe->value; 316 miPointerSetPosition(device, &x, &y); 317 break; 318 case LOC_Y_ABSOLUTE: 319 miPointerGetPosition(device, &x, &y); 320 y = fe->value; 321 miPointerSetPosition(device, &x, &y); 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#ifndef i386 372 sigset_t newsigmask; 373 374 (void) sigemptyset (&newsigmask); 375#ifdef SVR4 376 (void) sigaddset (&newsigmask, SIGPOLL); 377#else 378 (void) sigaddset (&newsigmask, SIGIO); 379#endif 380 (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL); 381 miPointerWarpCursor (pDev, pScreen, x, y); 382 (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL); 383#else 384 int oldmask; 385 386 oldmask = sigblock (sigmask (SIGIO)); 387 miPointerWarpCursor (pDev, pScreen, x, y); 388 sigsetmask (oldmask); 389#endif 390} 391