x68kMouse.c revision 80c54d45
1/* $NetBSD: x68kMouse.c,v 1.2 2020/04/10 16:49:36 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 <X11/Xatom.h>
86#include "xserver-properties.h"
87
88static Bool x68kCursorOffScreen(ScreenPtr *, int *, int *);
89static void x68kCrossScreen(ScreenPtr, int);
90static void x68kWarpCursor(DeviceIntPtr, ScreenPtr, int, int);
91static void x68kMouseCtrl(DeviceIntPtr, PtrCtrl*);
92
93miPointerScreenFuncRec x68kPointerScreenFuncs = {
94    x68kCursorOffScreen,
95    x68kCrossScreen,
96    x68kWarpCursor,
97    NULL,
98    NULL
99};
100
101DeviceIntPtr x68kPointerDevice = NULL;
102
103static X68kMousePriv x68kMousePriv;
104
105/*-
106 *-----------------------------------------------------------------------
107 * x68kMouseProc --
108 *	Handle the initialization, etc. of a mouse
109 *
110 * Results:
111 *	none.
112 *
113 * Side Effects:
114 *-----------------------------------------------------------------------
115 */
116int
117x68kMouseProc(DeviceIntPtr device, int what)
118{
119    DevicePtr   pMouse = &device->public;
120    int	    	format;
121    static int	oformat;
122    BYTE    	map[4];
123    Atom btn_labels[3] = {0};
124    Atom axes_labels[2] = { 0, 0 };
125
126    switch (what) {
127	case DEVICE_INIT:
128            pMouse->devicePrivate = (pointer) &x68kMousePriv;
129            if( (x68kMousePriv.fd = open("/dev/mouse", O_RDONLY)) == -1 ) {
130                Error ("Can't open mouse device");
131                return !Success;
132            }
133	    pMouse->on = FALSE;
134	    map[1] = 1;
135	    map[2] = 2;
136	    map[3] = 3;
137	    btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
138	    btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
139	    btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
140	    axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
141	    axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
142
143	    InitPointerDeviceStruct(pMouse, map, 3, btn_labels,
144 		x68kMouseCtrl, GetMotionHistorySize(),
145		2, axes_labels);
146	    break;
147
148	case DEVICE_ON:
149	    if (ioctl (x68kMousePriv.fd, VUIDGFORMAT, &oformat) == -1) {
150		Error ("x68kMouseProc ioctl VUIDGFORMAT");
151		return !Success;
152	    }
153	    format = VUID_FIRM_EVENT;
154	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &format) == -1) {
155		Error ("x68kMouseProc ioctl VUIDSFORMAT");
156		return !Success;
157	    }
158            if ( fcntl(x68kMousePriv.fd, F_SETOWN, getpid()) == -1 ||
159                 fcntl(x68kMousePriv.fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1
160                 ) {
161                Error ("Async mouse I/O failed");
162                return !Success;
163            }
164	    x68kMousePriv.bmask = 0;
165	    AddEnabledDevice(x68kMousePriv.fd);
166	    pMouse->on = TRUE;
167	    break;
168
169	case DEVICE_OFF:
170	    pMouse->on = FALSE;
171	    RemoveEnabledDevice(x68kMousePriv.fd);
172	    break;
173
174	case DEVICE_CLOSE:
175	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &oformat) == -1)
176		Error ("x68kMouseProc ioctl VUIDSFORMAT");
177	    break;
178
179    }
180    return Success;
181}
182
183/*-
184 *-----------------------------------------------------------------------
185 * x68kMouseCtrl --
186 *	Alter the control parameters for the mouse. Since acceleration
187 *	etc. is done from the PtrCtrl record in the mouse's device record,
188 *	there's nothing to do here.
189 *
190 * Results:
191 *	None.
192 *
193 * Side Effects:
194 *	None.
195 *
196 *-----------------------------------------------------------------------
197 */
198/*ARGSUSED*/
199static void
200x68kMouseCtrl(DeviceIntPtr device, PtrCtrl* ctrl)
201{
202}
203
204/*-
205 *-----------------------------------------------------------------------
206 * x68kMouseGetEvents --
207 *	Return the events waiting in the wings for the given mouse.
208 *
209 * Results:
210 *	A pointer to an array of Firm_events or (Firm_event *)0 if no events
211 *	The number of events contained in the array.
212 *	A boolean as to whether more events might be available.
213 *
214 * Side Effects:
215 *	None.
216 *-----------------------------------------------------------------------
217 */
218
219Firm_event *
220x68kMouseGetEvents(int fd, int *pNumEvents, Bool *pAgain)
221{
222    int nBytes;               /* number of bytes of events available. */
223    static Firm_event evBuf[MAXEVENTS];     /* Buffer for Firm_events */
224
225    if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) {
226	if (errno == EWOULDBLOCK) {
227	    *pNumEvents = 0;
228	    *pAgain = FALSE;
229	} else {
230	    Error ("x68kMouseGetEvents read");
231	    FatalError ("Could not read from mouse");
232	}
233    } else {
234	*pNumEvents = nBytes / sizeof (Firm_event);
235	*pAgain = (nBytes == sizeof (evBuf));
236    }
237    return evBuf;
238}
239
240/*-
241 *-----------------------------------------------------------------------
242 * x68kMouseEnqueueEvent --
243 *	Given a Firm_event for a mouse, pass it off the the dix layer
244 *	properly converted...
245 *
246 * Results:
247 *	None.
248 *
249 * Side Effects:
250 *	The cursor may be redrawn...? devPrivate/x/y will be altered.
251 *
252 *-----------------------------------------------------------------------
253 */
254
255void
256x68kMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe)
257{
258    X68kMousePrivPtr	pPriv;	/* Private data for pointer */
259    int			bmask;	/* Temporary button mask */
260    int			type, buttons, flag;
261    int			i, nevents, valuators[2];
262    ValuatorMask	mask;
263
264    GetEventList(&x68kEvents);
265
266    pPriv = (X68kMousePrivPtr)device->public.devicePrivate;
267
268    switch (fe->id) {
269    case MS_LEFT:
270    case MS_MIDDLE:
271    case MS_RIGHT:
272	/*
273	 * A button changed state. Sometimes we will get two events
274	 * for a single state change. Should we get a button event which
275	 * reflects the current state of affairs, that event is discarded.
276	 *
277	 * Mouse buttons start at 1.
278	 */
279	buttons = (fe->id - MS_LEFT) + 1;
280	bmask = 1 << buttons;
281	if (fe->value == VKEY_UP) {
282	    if (pPriv->bmask & bmask) {
283		type = ButtonRelease;
284		pPriv->bmask &= ~bmask;
285	    } else {
286		return;
287	    }
288	} else {
289	    if ((pPriv->bmask & bmask) == 0) {
290		type = ButtonPress;
291		pPriv->bmask |= bmask;
292	    } else {
293		return;
294	    }
295	}
296	flag = POINTER_RELATIVE;
297	valuator_mask_set_range(&mask, 0, 0, NULL);
298	nevents = GetPointerEvents(x68kEvents, device,
299	    type, buttons, flag, &mask);
300	for (i = 0; i < nevents; i++)
301	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
302	break;
303    case LOC_X_DELTA:
304	valuators[0] = fe->value;
305	valuators[1] = 0;
306	valuator_mask_set_range(&mask, 0, 2, valuators);
307        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
308	nevents = GetPointerEvents(x68kEvents, device,
309	    MotionNotify, 0, flag, &mask);
310	for (i = 0; i < nevents; i++)
311	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
312	break;
313    case LOC_Y_DELTA:
314	/*
315	 * For some reason, motion up generates a positive y delta
316	 * and motion down a negative delta, so we must subtract
317	 * here instead of add...
318	 */
319	valuators[0] = 0;
320	valuators[1] = -fe->value;
321	valuator_mask_set_range(&mask, 0, 2, valuators);
322        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
323	nevents = GetPointerEvents(x68kEvents, device,
324	    MotionNotify, 0, flag, &mask);
325	for (i = 0; i < nevents; i++)
326	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
327	break;
328    case LOC_X_ABSOLUTE:
329    case LOC_Y_ABSOLUTE:
330	/* XXX not sure how to get current X and Y position */
331    default:
332	FatalError ("%s: unrecognized id\n", __func__);
333	break;
334    }
335}
336
337/*ARGSUSED*/
338static Bool
339x68kCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
340{
341    return FALSE;
342}
343
344static void
345x68kCrossScreen(ScreenPtr pScreen, int entering)
346{
347}
348
349static void
350x68kWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
351{
352    sigset_t newsigmask;
353
354    (void) sigemptyset (&newsigmask);
355    (void) sigaddset (&newsigmask, SIGIO);
356    (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
357    miPointerWarpCursor (pDev, pScreen, x, y);
358    (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
359}
360
361/* EOF x68kMouse.c */
362