|
|
1.1 ! root 1: /*- ! 2: * sunMouse.c -- ! 3: * Functions for playing cat and mouse... sorry. ! 4: * ! 5: * Copyright (c) 1987 by the Regents of the University of California ! 6: * ! 7: * Permission to use, copy, modify, and distribute this ! 8: * software and its documentation for any purpose and without ! 9: * fee is hereby granted, provided that the above copyright ! 10: * notice appear in all copies. The University of California ! 11: * makes no representations about the suitability of this ! 12: * software for any purpose. It is provided "as is" without ! 13: * express or implied warranty. ! 14: * ! 15: * ! 16: */ ! 17: ! 18: /************************************************************ ! 19: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. ! 20: ! 21: All Rights Reserved ! 22: ! 23: Permission to use, copy, modify, and distribute this ! 24: software and its documentation for any purpose and without ! 25: fee is hereby granted, provided that the above copyright no- ! 26: tice appear in all copies and that both that copyright no- ! 27: tice and this permission notice appear in supporting docu- ! 28: mentation, and that the names of Sun or MIT not be used in ! 29: advertising or publicity pertaining to distribution of the ! 30: software without specific prior written permission. Sun and ! 31: M.I.T. make no representations about the suitability of this ! 32: software for any purpose. It is provided "as is" without any ! 33: express or implied warranty. ! 34: ! 35: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ! 36: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- ! 37: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- ! 38: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 39: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ! 40: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR ! 41: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH ! 42: THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 43: ! 44: ********************************************************/ ! 45: ! 46: #ifndef lint ! 47: static char sccsid[] = "%W %G Copyright 1987 Sun Micro"; ! 48: #endif ! 49: ! 50: #define NEED_EVENTS ! 51: #include "sun.h" ! 52: ! 53: typedef struct { ! 54: int bmask; /* Current button state */ ! 55: Bool mouseMoved; /* Mouse has moved */ ! 56: } SunMsPrivRec, *SunMsPrivPtr; ! 57: ! 58: static void sunMouseCtrl(); ! 59: static int sunMouseGetMotionEvents(); ! 60: static Firm_event *sunMouseGetEvents(); ! 61: static void sunMouseProcessEvent(); ! 62: static void sunMouseDoneEvents(); ! 63: ! 64: static SunMsPrivRec sunMousePriv; ! 65: static PtrPrivRec sysMousePriv = { ! 66: -1, /* Descriptor to device */ ! 67: sunMouseGetEvents, /* Function to read events */ ! 68: sunMouseProcessEvent, /* Function to process an event */ ! 69: sunMouseDoneEvents, /* When all the events have been */ ! 70: /* handled, this function will be */ ! 71: /* called. */ ! 72: 0, /* Current X coordinate of pointer */ ! 73: 0, /* Current Y coordinate */ ! 74: NULL, /* Screen pointer is on */ ! 75: (pointer)&sunMousePriv, /* Field private to device */ ! 76: }; ! 77: ! 78: /*- ! 79: *----------------------------------------------------------------------- ! 80: * sunMouseProc -- ! 81: * Handle the initialization, etc. of a mouse ! 82: * ! 83: * Results: ! 84: * none. ! 85: * ! 86: * Side Effects: ! 87: * ! 88: * Note: ! 89: * When using sunwindows, all input comes off a single fd, stored in the ! 90: * global windowFd. Therefore, only one device should be enabled and ! 91: * disabled, even though the application still sees both mouse and ! 92: * keyboard. We have arbitrarily chosen to enable and disable windowFd ! 93: * in the keyboard routine sunKbdProc rather than in sunMouseProc. ! 94: * ! 95: *----------------------------------------------------------------------- ! 96: */ ! 97: int ! 98: sunMouseProc (pMouse, what) ! 99: DevicePtr pMouse; /* Mouse to play with */ ! 100: int what; /* What to do with it */ ! 101: { ! 102: register int fd; ! 103: int format; ! 104: static int oformat; ! 105: BYTE map[4]; ! 106: ! 107: switch (what) { ! 108: case DEVICE_INIT: ! 109: if (pMouse != LookupPointerDevice()) { ! 110: ErrorF ("Cannot open non-system mouse"); ! 111: return (!Success); ! 112: } ! 113: ! 114: if (! sunUseSunWindows()) { ! 115: if (sysMousePriv.fd >= 0) { ! 116: fd = sysMousePriv.fd; ! 117: } else { ! 118: fd = open ("/dev/mouse", O_RDWR, 0); ! 119: if (fd < 0) { ! 120: Error ("Opening /dev/mouse"); ! 121: return (!Success); ! 122: } ! 123: if (fcntl (fd, F_SETFL, (FNDELAY|FASYNC)) < 0 ! 124: || fcntl(fd, F_SETOWN, getpid()) < 0) { ! 125: perror("sunMouseProc"); ! 126: ErrorF("Can't set up mouse on fd %d\n", fd); ! 127: } ! 128: ! 129: sysMousePriv.fd = fd; ! 130: } ! 131: } ! 132: ! 133: sysMousePriv.pScreen = &screenInfo.screen[0]; ! 134: sysMousePriv.x = sysMousePriv.pScreen->width / 2; ! 135: sysMousePriv.y = sysMousePriv.pScreen->height / 2; ! 136: ! 137: sunMousePriv.bmask = 0; ! 138: sunMousePriv.mouseMoved = FALSE; ! 139: ! 140: pMouse->devicePrivate = (pointer) &sysMousePriv; ! 141: pMouse->on = FALSE; ! 142: map[1] = 1; ! 143: map[2] = 2; ! 144: map[3] = 3; ! 145: InitPointerDeviceStruct( ! 146: pMouse, map, 3, sunMouseGetMotionEvents, sunMouseCtrl); ! 147: break; ! 148: ! 149: case DEVICE_ON: ! 150: if (! sunUseSunWindows()) { ! 151: if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd, ! 152: VUIDGFORMAT, &oformat) < 0) { ! 153: Error ("VUIDGFORMAT"); ! 154: return(!Success); ! 155: } ! 156: format = VUID_FIRM_EVENT; ! 157: if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd, ! 158: VUIDSFORMAT, &format) < 0) { ! 159: Error ("VUIDSFORMAT"); ! 160: return(!Success); ! 161: } ! 162: AddEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd); ! 163: } ! 164: ! 165: pMouse->on = TRUE; ! 166: break; ! 167: ! 168: case DEVICE_CLOSE: ! 169: if (! sunUseSunWindows()) { ! 170: if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd, ! 171: VUIDSFORMAT, &oformat) < 0) { ! 172: Error ("VUIDSFORMAT"); ! 173: } ! 174: } ! 175: break; ! 176: ! 177: case DEVICE_OFF: ! 178: pMouse->on = FALSE; ! 179: if (! sunUseSunWindows()) { ! 180: RemoveEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd); ! 181: } ! 182: break; ! 183: } ! 184: return (Success); ! 185: } ! 186: ! 187: /*- ! 188: *----------------------------------------------------------------------- ! 189: * sunMouseCtrl -- ! 190: * Alter the control parameters for the mouse. Since acceleration ! 191: * etc. is done from the PtrCtrl record in the mouse's device record, ! 192: * there's nothing to do here. ! 193: * ! 194: * Results: ! 195: * None. ! 196: * ! 197: * Side Effects: ! 198: * None. ! 199: * ! 200: *----------------------------------------------------------------------- ! 201: */ ! 202: static void ! 203: sunMouseCtrl (pMouse) ! 204: DevicePtr pMouse; ! 205: { ! 206: } ! 207: ! 208: /*- ! 209: *----------------------------------------------------------------------- ! 210: * sunMouseGetMotionEvents -- ! 211: * Return the (number of) motion events in the "motion history ! 212: * buffer" (snicker) between the given times. ! 213: * ! 214: * Results: ! 215: * The number of events stuffed. ! 216: * ! 217: * Side Effects: ! 218: * The relevant xTimecoord's are stuffed in the passed memory. ! 219: * ! 220: *----------------------------------------------------------------------- ! 221: */ ! 222: static int ! 223: sunMouseGetMotionEvents (buff, start, stop) ! 224: CARD32 start, stop; ! 225: xTimecoord *buff; ! 226: { ! 227: return 0; ! 228: } ! 229: ! 230: /*- ! 231: *----------------------------------------------------------------------- ! 232: * sunMouseGetEvents -- ! 233: * Return the events waiting in the wings for the given mouse. ! 234: * ! 235: * Results: ! 236: * A pointer to an array of Firm_events or (Firm_event *)0 if no events ! 237: * The number of events contained in the array. ! 238: * ! 239: * Side Effects: ! 240: * None. ! 241: *----------------------------------------------------------------------- ! 242: */ ! 243: static Firm_event * ! 244: sunMouseGetEvents (pMouse, pNumEvents) ! 245: DevicePtr pMouse; /* Mouse to read */ ! 246: int *pNumEvents; /* Place to return number of events */ ! 247: { ! 248: int nBytes; /* number of bytes of events available. */ ! 249: register PtrPrivPtr pPriv; ! 250: static Firm_event evBuf[MAXEVENTS]; /* Buffer for Firm_events */ ! 251: ! 252: pPriv = (PtrPrivPtr) pMouse->devicePrivate; ! 253: ! 254: nBytes = read (pPriv->fd, evBuf, sizeof(evBuf)); ! 255: ! 256: if (nBytes < 0) { ! 257: if (errno == EWOULDBLOCK) { ! 258: *pNumEvents = 0; ! 259: } else { ! 260: Error ("Reading mouse"); ! 261: FatalError ("Could not read from mouse"); ! 262: } ! 263: } else { ! 264: *pNumEvents = nBytes / sizeof (Firm_event); ! 265: } ! 266: return (evBuf); ! 267: } ! 268: ! 269: ! 270: /*- ! 271: *----------------------------------------------------------------------- ! 272: * MouseAccelerate -- ! 273: * Given a delta and a mouse, return the acceleration of the delta. ! 274: * ! 275: * Results: ! 276: * The corrected delta ! 277: * ! 278: * Side Effects: ! 279: * None. ! 280: * ! 281: *----------------------------------------------------------------------- ! 282: */ ! 283: static short ! 284: MouseAccelerate (pMouse, delta) ! 285: DevicePtr pMouse; ! 286: int delta; ! 287: { ! 288: register int sgn = sign(delta); ! 289: register PtrCtrl *pCtrl; ! 290: ! 291: delta = abs(delta); ! 292: pCtrl = &((DeviceIntPtr) pMouse)->u.ptr.ctrl; ! 293: ! 294: if (delta > pCtrl->threshold) { ! 295: return ((short) (sgn * (pCtrl->threshold + ! 296: ((delta - pCtrl->threshold) * pCtrl->num) / ! 297: pCtrl->den))); ! 298: } else { ! 299: return ((short) (sgn * delta)); ! 300: } ! 301: } ! 302: ! 303: /*- ! 304: *----------------------------------------------------------------------- ! 305: * sunMouseProcessEvent -- ! 306: * Given a Firm_event for a mouse, pass it off the the dix layer ! 307: * properly converted... ! 308: * ! 309: * Results: ! 310: * None. ! 311: * ! 312: * Side Effects: ! 313: * The cursor may be redrawn...? devPrivate/x/y will be altered. ! 314: * ! 315: *----------------------------------------------------------------------- ! 316: */ ! 317: static void ! 318: sunMouseProcessEvent (pMouse, fe) ! 319: DevicePtr pMouse; /* Mouse from which the event came */ ! 320: Firm_event *fe; /* Event to process */ ! 321: { ! 322: int index; /* screen index */ ! 323: xEvent xE; ! 324: register PtrPrivPtr pPriv; /* Private data for pointer */ ! 325: register SunMsPrivPtr pSunPriv; /* Private data for mouse */ ! 326: register int bmask; /* Temporary button mask */ ! 327: ! 328: pPriv = (PtrPrivPtr)pMouse->devicePrivate; ! 329: pSunPriv = (SunMsPrivPtr) pPriv->devPrivate; ! 330: ! 331: xE.u.keyButtonPointer.time = TVTOMILLI(fe->time); ! 332: ! 333: switch (fe->id) { ! 334: case MS_LEFT: ! 335: case MS_MIDDLE: ! 336: case MS_RIGHT: ! 337: /* ! 338: * A button changed state. Sometimes we will get two events ! 339: * for a single state change. Should we get a button event which ! 340: * reflects the current state of affairs, that event is discarded. ! 341: * ! 342: * Mouse buttons start at 1. ! 343: */ ! 344: xE.u.u.detail = (fe->id - MS_LEFT) + 1; ! 345: bmask = 1 << xE.u.u.detail; ! 346: if (fe->value == VKEY_UP) { ! 347: if (pSunPriv->bmask & bmask) { ! 348: xE.u.u.type = ButtonRelease; ! 349: pSunPriv->bmask &= ~bmask; ! 350: } else { ! 351: return; ! 352: } ! 353: } else { ! 354: if ((pSunPriv->bmask & bmask) == 0) { ! 355: xE.u.u.type = ButtonPress; ! 356: pSunPriv->bmask |= bmask; ! 357: } else { ! 358: return; ! 359: } ! 360: } ! 361: /* ! 362: * If the mouse has moved, we must update any interested client ! 363: * as well as DIX before sending a button event along. ! 364: */ ! 365: if (pSunPriv->mouseMoved) { ! 366: sunMouseDoneEvents (pMouse, FALSE); ! 367: } ! 368: ! 369: break; ! 370: case LOC_X_DELTA: ! 371: /* ! 372: * When we detect a change in the mouse coordinates, we call ! 373: * the cursor module to move the cursor. It has the option of ! 374: * simply removing the cursor or just shifting it a bit. ! 375: * If it is removed, DIX will restore it before we goes to sleep... ! 376: * ! 377: * What should be done if it goes off the screen? Move to another ! 378: * screen? For now, we just force the pointer to stay on the ! 379: * screen... ! 380: */ ! 381: pPriv->x += MouseAccelerate (pMouse, fe->value); ! 382: ! 383: /* ! 384: * Active Zaphod implementation: ! 385: * increment or decrement the current screen ! 386: * if the x is to the right or the left of ! 387: * the current screen. ! 388: */ ! 389: if (screenInfo.numScreens > 1 && ! 390: (pPriv->x > pPriv->pScreen->width || ! 391: pPriv->x < 0)) { ! 392: sunRemoveCursor(); ! 393: /* disable color plane if it's current */ ! 394: index = pPriv->pScreen->myNum; ! 395: (*sunFbs[index].EnterLeave) (pPriv->pScreen, 1); ! 396: if (pPriv->x < 0) { ! 397: if (pPriv->pScreen->myNum != 0) ! 398: (pPriv->pScreen)--; ! 399: else ! 400: pPriv->pScreen = &screenInfo.screen[screenInfo.numScreens -1]; ! 401: ! 402: pPriv->x += pPriv->pScreen->width; ! 403: } ! 404: else { ! 405: pPriv->x -= pPriv->pScreen->width; ! 406: ! 407: if (pPriv->pScreen->myNum != screenInfo.numScreens -1) ! 408: (pPriv->pScreen)++; ! 409: else ! 410: pPriv->pScreen = &screenInfo.screen[0]; ! 411: } ! 412: ! 413: index = pPriv->pScreen->myNum; ! 414: /* enable color plane if new current screen */ ! 415: (*sunFbs[index].EnterLeave) (pPriv->pScreen, 0); ! 416: } ! 417: ! 418: if (!sunConstrainXY (&pPriv->x, &pPriv->y)) { ! 419: return; ! 420: } ! 421: ! 422: NewCurrentScreen (pPriv->pScreen, pPriv->x, pPriv->y); ! 423: ! 424: #ifdef SUN_ALL_MOTION ! 425: xE.u.u.type = MotionNotify; ! 426: sunMoveCursor (pPriv->pScreen, pPriv->x, pPriv->y); ! 427: break; ! 428: #else ! 429: ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE; ! 430: return; ! 431: #endif ! 432: case LOC_Y_DELTA: ! 433: /* ! 434: * For some reason, motion up generates a positive y delta ! 435: * and motion down a negative delta, so we must subtract ! 436: * here instead of add... ! 437: */ ! 438: pPriv->y -= MouseAccelerate (pMouse, fe->value); ! 439: if (!sunConstrainXY (&pPriv->x, &pPriv->y)) { ! 440: return; ! 441: } ! 442: #ifdef SUN_ALL_MOTION ! 443: xE.u.u.type = MotionNotify; ! 444: sunMoveCursor (pPriv->pScreen, pPriv->x, pPriv->y); ! 445: break; ! 446: #else ! 447: ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE; ! 448: return; ! 449: #endif SUN_ALL_MOTION ! 450: default: ! 451: FatalError ("sunMouseProcessEvent: unrecognized id\n"); ! 452: break; ! 453: } ! 454: ! 455: xE.u.keyButtonPointer.rootX = pPriv->x; ! 456: xE.u.keyButtonPointer.rootY = pPriv->y; ! 457: ! 458: (* pMouse->processInputProc) (&xE, pMouse); ! 459: } ! 460: ! 461: /*- ! 462: *----------------------------------------------------------------------- ! 463: * sunMouseDoneEvents -- ! 464: * Finish off any mouse motions we haven't done yet. (At the moment ! 465: * this code is unused since we never save mouse motions as I'm ! 466: * unsure of the effect of getting a keystroke at a given [x,y] w/o ! 467: * having gotten a motion event to that [x,y]) ! 468: * ! 469: * Results: ! 470: * None. ! 471: * ! 472: * Side Effects: ! 473: * A MotionNotify event may be generated. ! 474: * ! 475: *----------------------------------------------------------------------- ! 476: */ ! 477: /*ARGSUSED*/ ! 478: static void ! 479: sunMouseDoneEvents (pMouse,final) ! 480: DevicePtr pMouse; ! 481: Bool final; ! 482: { ! 483: PtrPrivPtr pPriv; ! 484: SunMsPrivPtr pSunPriv; ! 485: xEvent xE; ! 486: ! 487: pPriv = (PtrPrivPtr) pMouse->devicePrivate; ! 488: pSunPriv = (SunMsPrivPtr) pPriv->devPrivate; ! 489: ! 490: if (pSunPriv->mouseMoved) { ! 491: sunMoveCursor (pPriv->pScreen, pPriv->x, pPriv->y); ! 492: xE.u.keyButtonPointer.rootX = pPriv->x; ! 493: xE.u.keyButtonPointer.rootY = pPriv->y; ! 494: xE.u.keyButtonPointer.time = lastEventTime; ! 495: xE.u.u.type = MotionNotify; ! 496: (* pMouse->processInputProc) (&xE, pMouse); ! 497: pSunPriv->mouseMoved = FALSE; ! 498: } ! 499: } ! 500: ! 501: #ifdef SUN_WINDOWS ! 502: ! 503: /* ! 504: * Process a sunwindows mouse event. The possible events are ! 505: * LOC_MOVE ! 506: * MS_LEFT ! 507: * MS_MIDDLE ! 508: * MS_RIGHT ! 509: */ ! 510: ! 511: void ! 512: sunMouseProcessEventSunWin(pMouse,se) ! 513: DeviceRec *pMouse; ! 514: register struct inputevent *se; ! 515: { ! 516: xEvent xE; ! 517: register int bmask; /* Temporary button mask */ ! 518: register PtrPrivPtr pPriv; /* Private data for pointer */ ! 519: register SunMsPrivPtr pSunPriv; /* Private data for mouse */ ! 520: ! 521: pPriv = (PtrPrivPtr)pMouse->devicePrivate; ! 522: pSunPriv = (SunMsPrivPtr) pPriv->devPrivate; ! 523: ! 524: xE.u.keyButtonPointer.time = TVTOMILLI(event_time(se)); ! 525: ! 526: switch (event_id(se)) { ! 527: case MS_LEFT: ! 528: case MS_MIDDLE: ! 529: case MS_RIGHT: ! 530: /* ! 531: * A button changed state. Sometimes we will get two events ! 532: * for a single state change. Should we get a button event which ! 533: * reflects the current state of affairs, that event is discarded. ! 534: * ! 535: * Mouse buttons start at 1. ! 536: */ ! 537: xE.u.u.detail = (event_id(se) - MS_LEFT) + 1; ! 538: bmask = 1 << xE.u.u.detail; ! 539: if (win_inputnegevent(se)) { ! 540: if (pSunPriv->bmask & bmask) { ! 541: xE.u.u.type = ButtonRelease; ! 542: pSunPriv->bmask &= ~bmask; ! 543: } else { ! 544: return; ! 545: } ! 546: } else { ! 547: if ((pSunPriv->bmask & bmask) == 0) { ! 548: xE.u.u.type = ButtonPress; ! 549: pSunPriv->bmask |= bmask; ! 550: } else { ! 551: return; ! 552: } ! 553: } ! 554: break; ! 555: case LOC_MOVE: ! 556: xE.u.u.type = MotionNotify; ! 557: xE.u.u.detail = 0; ! 558: pPriv->x = event_x(se); ! 559: pPriv->y = event_y(se); ! 560: if (!sunConstrainXY (&pPriv->x, &pPriv->y)) { ! 561: return; ! 562: } ! 563: sunMoveCursor (pPriv->pScreen, pPriv->x, pPriv->y); ! 564: if ((pPriv->x != event_x(se)) || (pPriv->y != event_y(se))) { ! 565: /* ! 566: * We constrained the pointer motion. Tell the pointer ! 567: * where it really needs to be. ! 568: */ ! 569: win_setmouseposition(windowFd, pPriv->x, pPriv->y); ! 570: } ! 571: break; ! 572: default: ! 573: FatalError ("sunMouseProcessEventSunWin: unrecognized id\n"); ! 574: break; ! 575: } ! 576: ! 577: xE.u.keyButtonPointer.rootX = event_x(se); ! 578: xE.u.keyButtonPointer.rootY = event_y(se); ! 579: ! 580: (* pMouse->processInputProc) (&xE, pMouse); ! 581: ! 582: } ! 583: #endif SUN_WINDOWS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.