x68kMouse.c revision 72502d70
1/* $NetBSD: x68kMouse.c,v 1.5 2020/07/18 15:37:02 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
132    switch (what) {
133	case DEVICE_INIT:
134            pMouse->devicePrivate = (pointer) &x68kMousePriv;
135            if( (x68kMousePriv.fd = open("/dev/mouse", O_RDONLY)) == -1 ) {
136                ErrorF("Can't open mouse device");
137                return !Success;
138            }
139	    pMouse->on = FALSE;
140	    map[1] = 1;
141	    map[2] = 2;
142	    map[3] = 3;
143	    btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
144	    btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
145	    btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
146	    axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
147	    axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
148
149	    InitPointerDeviceStruct(pMouse, map, 3, btn_labels,
150 		x68kMouseCtrl, GetMotionHistorySize(),
151		2, axes_labels);
152	    break;
153
154	case DEVICE_ON:
155	    if (ioctl (x68kMousePriv.fd, VUIDGFORMAT, &oformat) == -1) {
156		ErrorF("x68kMouseProc ioctl VUIDGFORMAT");
157		return !Success;
158	    }
159	    format = VUID_FIRM_EVENT;
160	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &format) == -1) {
161		ErrorF("x68kMouseProc ioctl VUIDSFORMAT");
162		return !Success;
163	    }
164            if ( fcntl(x68kMousePriv.fd, F_SETOWN, getpid()) == -1 ||
165                 fcntl(x68kMousePriv.fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1
166                 ) {
167                ErrorF("Async mouse I/O failed");
168                return !Success;
169            }
170	    x68kMousePriv.bmask = 0;
171	    SetNotifyFd(x68kMousePriv.fd, x68kMouseHandlerNotify,
172		X_NOTIFY_READ, NULL);
173	    pMouse->on = TRUE;
174	    break;
175
176	case DEVICE_OFF:
177	    pMouse->on = FALSE;
178	    RemoveNotifyFd(x68kMousePriv.fd);
179	    break;
180
181	case DEVICE_CLOSE:
182	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &oformat) == -1)
183		ErrorF("x68kMouseProc ioctl VUIDSFORMAT");
184	    break;
185
186    }
187    return Success;
188}
189
190/*-
191 *-----------------------------------------------------------------------
192 * x68kMouseCtrl --
193 *	Alter the control parameters for the mouse. Since acceleration
194 *	etc. is done from the PtrCtrl record in the mouse's device record,
195 *	there's nothing to do here.
196 *
197 * Results:
198 *	None.
199 *
200 * Side Effects:
201 *	None.
202 *
203 *-----------------------------------------------------------------------
204 */
205/*ARGSUSED*/
206static void
207x68kMouseCtrl(DeviceIntPtr device, PtrCtrl* ctrl)
208{
209}
210
211/*-
212 *-----------------------------------------------------------------------
213 * x68kMouseGetEvents --
214 *	Return the events waiting in the wings for the given mouse.
215 *
216 * Results:
217 *	A pointer to an array of Firm_events or (Firm_event *)0 if no events
218 *	The number of events contained in the array.
219 *	A boolean as to whether more events might be available.
220 *
221 * Side Effects:
222 *	None.
223 *-----------------------------------------------------------------------
224 */
225
226Firm_event *
227x68kMouseGetEvents(int fd, int *pNumEvents, Bool *pAgain)
228{
229    int nBytes;               /* number of bytes of events available. */
230    static Firm_event evBuf[X68K_MAXEVENTS];     /* Buffer for Firm_events */
231
232    if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) {
233	if (errno == EWOULDBLOCK) {
234	    *pNumEvents = 0;
235	    *pAgain = FALSE;
236	} else {
237	    ErrorF("x68kMouseGetEvents read");
238	    FatalError ("Could not read from mouse");
239	}
240    } else {
241	*pNumEvents = nBytes / sizeof (Firm_event);
242	*pAgain = (nBytes == sizeof (evBuf));
243    }
244    return evBuf;
245}
246
247/*-
248 *-----------------------------------------------------------------------
249 * x68kMouseEnqueueEvent --
250 *	Given a Firm_event for a mouse, pass it off the the dix layer
251 *	properly converted...
252 *
253 * Results:
254 *	None.
255 *
256 * Side Effects:
257 *	The cursor may be redrawn...? devPrivate/x/y will be altered.
258 *
259 *-----------------------------------------------------------------------
260 */
261
262void
263x68kMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe)
264{
265    X68kMousePrivPtr	pPriv;	/* Private data for pointer */
266    int			bmask;	/* Temporary button mask */
267    int			type, buttons, flag;
268    int			valuators[2];
269    ValuatorMask	mask;
270
271    pPriv = (X68kMousePrivPtr)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_set_range(&mask, 0, 0, NULL);
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    case LOC_Y_ABSOLUTE:
326	/* XXX not sure how to get current X and Y position */
327    default:
328	FatalError ("%s: unrecognized id\n", __func__);
329	break;
330    }
331}
332
333/*ARGSUSED*/
334static Bool
335x68kCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
336{
337    return FALSE;
338}
339
340static void
341x68kCrossScreen(ScreenPtr pScreen, int entering)
342{
343}
344
345static void
346x68kWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
347{
348    sigset_t newsigmask;
349
350    (void) sigemptyset (&newsigmask);
351    (void) sigaddset (&newsigmask, SIGIO);
352    (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
353    miPointerWarpCursor (pDev, pScreen, x, y);
354    (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
355}
356
357/* EOF x68kMouse.c */
358