x68kMouse.c revision d8389a6e
1/* $NetBSD: x68kMouse.c,v 1.13 2025/06/17 15:55:03 tsutsui Exp $ */ 2/*------------------------------------------------------------------------- 3 * Copyright (c) 1996 Yasushi Yamasaki 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 *-----------------------------------------------------------------------*/ 26 27/*- 28 * Copyright (c) 1987 by the Regents of the University of California 29 * 30 * Permission to use, copy, modify, and distribute this 31 * software and its documentation for any purpose and without 32 * fee is hereby granted, provided that the above copyright 33 * notice appear in all copies. The University of California 34 * makes no representations about the suitability of this 35 * software for any purpose. It is provided "as is" without 36 * express or implied warranty. 37 */ 38 39/************************************************************ 40Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. 41 42 All Rights Reserved 43 44Permission to use, copy, modify, and distribute this 45software and its documentation for any purpose and without 46fee is hereby granted, provided that the above copyright no- 47tice appear in all copies and that both that copyright no- 48tice and this permission notice appear in supporting docu- 49mentation, and that the names of Sun or X Consortium 50not be used in advertising or publicity pertaining to 51distribution of the software without specific prior 52written permission. Sun and X Consortium make no 53representations about the suitability of this software for 54any purpose. It is provided "as is" without any express or 55implied warranty. 56 57SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 58INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- 59NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- 60ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 61ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 62PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 63OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 64THE USE OR PERFORMANCE OF THIS SOFTWARE. 65 66********************************************************/ 67/* 68 * Copyright 1991, 1992, 1993 Kaleb S. Keithley 69 * 70 * Permission to use, copy, modify, and distribute this 71 * software and its documentation for any purpose and without 72 * fee is hereby granted, provided that the above copyright 73 * notice appear in all copies. Kaleb S. Keithley makes no 74 * representations about the suitability of this software for 75 * any purpose. It is provided "as is" without express or 76 * implied warranty. 77 */ 78 79#include "x68k.h" 80#include "mi.h" 81#include "input.h" 82#include "inpututils.h" 83 84#include "exevents.h" 85#include "events.h" 86#include "eventstr.h" 87#include <X11/Xatom.h> 88#include "xserver-properties.h" 89 90static void x68kMouseHandlerNotify(int, int, void *); 91static Bool x68kCursorOffScreen(ScreenPtr *, int *, int *); 92static void x68kCrossScreen(ScreenPtr, int); 93static void x68kWarpCursor(DeviceIntPtr, ScreenPtr, int, int); 94static void x68kMouseCtrl(DeviceIntPtr, PtrCtrl*); 95 96miPointerScreenFuncRec x68kPointerScreenFuncs = { 97 x68kCursorOffScreen, 98 x68kCrossScreen, 99 x68kWarpCursor, 100}; 101 102DeviceIntPtr x68kPointerDevice = NULL; 103 104static X68kMousePriv x68kMousePriv; 105 106static void 107x68kMouseHandlerNotify(int fd __unused, int ready __unused, void *data __unused) 108{ 109} 110 111/*- 112 *----------------------------------------------------------------------- 113 * x68kMouseProc -- 114 * Handle the initialization, etc. of a mouse 115 * 116 * Results: 117 * none. 118 * 119 * Side Effects: 120 *----------------------------------------------------------------------- 121 */ 122int 123x68kMouseProc(DeviceIntPtr device, int what) 124{ 125 DevicePtr pMouse = &device->public; 126 int format; 127 static int oformat; 128 BYTE map[4]; 129 Atom btn_labels[3] = {0}; 130 Atom axes_labels[2] = { 0, 0 }; 131 MouseEmu3btnPtr pEmu3btn; 132 Bool emu3enable; 133 int emu3timeout; 134 135 switch (what) { 136 case DEVICE_INIT: 137 pMouse->devicePrivate = (void *) &x68kMousePriv; 138 if( (x68kMousePriv.fd = open("/dev/mouse", O_RDONLY)) == -1 ) { 139 ErrorF("Can't open mouse device\n"); 140 return !Success; 141 } 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 x68kMouseCtrl, 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 /* Initialize emulation 3 buttons settings */ 169 emu3enable = TRUE; /* XXX should be configurable */ 170 emu3timeout = EMU3B_DEF_TIMEOUT; /* XXX should be configurable */ 171 if (emu3enable) { 172 pEmu3btn = &x68kMousePriv.emu3btn; 173 Emulate3ButtonsEnable(pEmu3btn, device, emu3timeout); 174 } 175 176 break; 177 178 case DEVICE_ON: 179 if (ioctl (x68kMousePriv.fd, VUIDGFORMAT, &oformat) == -1) { 180 ErrorF("x68kMouseProc ioctl VUIDGFORMAT\n"); 181 return !Success; 182 } 183 format = VUID_FIRM_EVENT; 184 if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &format) == -1) { 185 ErrorF("x68kMouseProc ioctl VUIDSFORMAT\n"); 186 return !Success; 187 } 188 if ( fcntl(x68kMousePriv.fd, F_SETOWN, getpid()) == -1 || 189 fcntl(x68kMousePriv.fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1 190 ) { 191 ErrorF("Async mouse I/O failed\n"); 192 return !Success; 193 } 194 x68kMousePriv.bmask = 0; 195 SetNotifyFd(x68kMousePriv.fd, x68kMouseHandlerNotify, 196 X_NOTIFY_READ, NULL); 197 pMouse->on = TRUE; 198 break; 199 200 case DEVICE_OFF: 201 pMouse->on = FALSE; 202 RemoveNotifyFd(x68kMousePriv.fd); 203 break; 204 205 case DEVICE_CLOSE: 206 if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &oformat) == -1) 207 ErrorF("x68kMouseProc ioctl VUIDSFORMAT\n"); 208 break; 209 210 case DEVICE_ABORT: 211 break; 212 } 213 return Success; 214} 215 216/*- 217 *----------------------------------------------------------------------- 218 * x68kMouseCtrl -- 219 * Alter the control parameters for the mouse. Since acceleration 220 * etc. is done from the PtrCtrl record in the mouse's device record, 221 * there's nothing to do here. 222 * 223 * Results: 224 * None. 225 * 226 * Side Effects: 227 * None. 228 * 229 *----------------------------------------------------------------------- 230 */ 231/*ARGSUSED*/ 232static void 233x68kMouseCtrl(DeviceIntPtr device, PtrCtrl* ctrl) 234{ 235} 236 237/*- 238 *----------------------------------------------------------------------- 239 * x68kMouseGetEvents -- 240 * Return the events waiting in the wings for the given mouse. 241 * 242 * Results: 243 * A pointer to an array of Firm_events or (Firm_event *)0 if no events 244 * The number of events contained in the array. 245 * A boolean as to whether more events might be available. 246 * 247 * Side Effects: 248 * None. 249 *----------------------------------------------------------------------- 250 */ 251 252Firm_event * 253x68kMouseGetEvents(int fd, int *pNumEvents, Bool *pAgain) 254{ 255 int nBytes; /* number of bytes of events available. */ 256 static Firm_event evBuf[X68K_MAXEVENTS]; /* Buffer for Firm_events */ 257 258 if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) { 259 if (errno == EWOULDBLOCK) { 260 *pNumEvents = 0; 261 *pAgain = FALSE; 262 } else { 263 ErrorF("x68kMouseGetEvents read\n"); 264 FatalError ("Could not read from mouse"); 265 } 266 } else { 267 *pNumEvents = nBytes / sizeof (Firm_event); 268 *pAgain = (nBytes == sizeof (evBuf)); 269 } 270 return evBuf; 271} 272 273/*- 274 *----------------------------------------------------------------------- 275 * x68kMouseEnqueueEvent -- 276 * Given a Firm_event for a mouse, pass it off the the dix layer 277 * properly converted... 278 * 279 * Results: 280 * None. 281 * 282 * Side Effects: 283 * The cursor may be redrawn...? devPrivate/x/y will be altered. 284 * 285 *----------------------------------------------------------------------- 286 */ 287 288void 289x68kMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 290{ 291 X68kMousePrivPtr pPriv; /* Private data for pointer */ 292 int bmask; /* Temporary button mask */ 293 int type, buttons, flag; 294 int valuators[2]; 295 ValuatorMask mask; 296 297 pPriv = (X68kMousePrivPtr)device->public.devicePrivate; 298 299 switch (fe->id) { 300 case MS_LEFT: 301 case MS_MIDDLE: 302 case MS_RIGHT: 303 /* 304 * A button changed state. Sometimes we will get two events 305 * for a single state change. Should we get a button event which 306 * reflects the current state of affairs, that event is discarded. 307 * 308 * Mouse buttons start at 1 as defined in <X11/X.h>. 309 * 310 * The bmask stores which buttons are currently pressed. 311 * This bmask is also used for Emulate3Buttons functions that 312 * assume the left button is LSB as defined in mouseEmu3btn.c. 313 */ 314 buttons = (fe->id - MS_LEFT) + 1; 315 bmask = 1 << (buttons - 1); 316 if (fe->value == VKEY_UP) { 317 if (pPriv->bmask & bmask) { 318 type = ButtonRelease; 319 pPriv->bmask &= ~bmask; 320 } else { 321 return; 322 } 323 } else { 324 if ((pPriv->bmask & bmask) == 0) { 325 type = ButtonPress; 326 pPriv->bmask |= bmask; 327 } else { 328 return; 329 } 330 } 331 if (buttons == Button1 || buttons == Button3) { 332 /* Handle middle button emulation */ 333 Emulate3ButtonsQueueEvent(&pPriv->emu3btn, type, buttons, pPriv->bmask); 334 } else { 335 flag = POINTER_RELATIVE; 336 valuator_mask_zero(&mask); 337 QueuePointerEvents(device, type, buttons, flag, &mask); 338 } 339 break; 340 case LOC_X_DELTA: 341 valuators[0] = fe->value; 342 valuators[1] = 0; 343 valuator_mask_set_range(&mask, 0, 2, valuators); 344 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 345 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 346 break; 347 case LOC_Y_DELTA: 348 /* 349 * For some reason, motion up generates a positive y delta 350 * and motion down a negative delta, so we must subtract 351 * here instead of add... 352 */ 353 valuators[0] = 0; 354 valuators[1] = -fe->value; 355 valuator_mask_set_range(&mask, 0, 2, valuators); 356 flag = POINTER_RELATIVE | POINTER_ACCELERATE; 357 QueuePointerEvents(device, MotionNotify, 0, flag, &mask); 358 break; 359 case LOC_X_ABSOLUTE: 360 case LOC_Y_ABSOLUTE: 361 /* XXX not sure how to get current X and Y position */ 362 default: 363 FatalError ("%s: unrecognized id\n", __func__); 364 break; 365 } 366} 367 368/*ARGSUSED*/ 369static Bool 370x68kCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) 371{ 372 return FALSE; 373} 374 375static void 376x68kCrossScreen(ScreenPtr pScreen, int entering) 377{ 378} 379 380static void 381x68kWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 382{ 383 input_lock(); 384 miPointerWarpCursor (pDev, pScreen, x, y); 385 input_unlock(); 386} 387 388/* EOF x68kMouse.c */ 389