x68kMouse.c revision ba64b02e
1/* $NetBSD: x68kMouse.c,v 1.1 2014/03/01 19:34:47 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 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *      This product includes software developed by Yasushi Yamasaki
17 * 4. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *-----------------------------------------------------------------------*/
31
32/*-
33 * Copyright (c) 1987 by the Regents of the University of California
34 *
35 * Permission to use, copy, modify, and distribute this
36 * software and its documentation for any purpose and without
37 * fee is hereby granted, provided that the above copyright
38 * notice appear in all copies.  The University of California
39 * makes no representations about the suitability of this
40 * software for any purpose.  It is provided "as is" without
41 * express or implied warranty.
42 */
43
44/************************************************************
45Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
46
47                    All Rights Reserved
48
49Permission  to  use,  copy,  modify,  and  distribute   this
50software  and  its documentation for any purpose and without
51fee is hereby granted, provided that the above copyright no-
52tice  appear  in all copies and that both that copyright no-
53tice and this permission notice appear in  supporting  docu-
54mentation,  and  that the names of Sun or X Consortium
55not be used in advertising or publicity pertaining to
56distribution  of  the software  without specific prior
57written permission. Sun and X Consortium make no
58representations about the suitability of this software for
59any purpose. It is provided "as is" without any express or
60implied warranty.
61
62SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
63INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
64NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
65ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
66ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
67PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
68OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
69THE USE OR PERFORMANCE OF THIS SOFTWARE.
70
71********************************************************/
72/*
73 * Copyright 1991, 1992, 1993 Kaleb S. Keithley
74 *
75 * Permission to use, copy, modify, and distribute this
76 * software and its documentation for any purpose and without
77 * fee is hereby granted, provided that the above copyright
78 * notice appear in all copies.  Kaleb S. Keithley makes no
79 * representations about the suitability of this software for
80 * any purpose.  It is provided "as is" without express or
81 * implied warranty.
82 */
83
84#include "x68k.h"
85#include "mi.h"
86#include "input.h"
87#include "inpututils.h"
88
89#include "exevents.h"
90#include <X11/Xatom.h>
91#include "xserver-properties.h"
92
93static Bool x68kCursorOffScreen(ScreenPtr *, int *, int *);
94static void x68kCrossScreen(ScreenPtr, int);
95static void x68kWarpCursor(DeviceIntPtr, ScreenPtr, int, int);
96static void x68kMouseCtrl(DeviceIntPtr, PtrCtrl*);
97
98miPointerScreenFuncRec x68kPointerScreenFuncs = {
99    x68kCursorOffScreen,
100    x68kCrossScreen,
101    x68kWarpCursor,
102    NULL,
103    NULL
104};
105
106DeviceIntPtr x68kPointerDevice = NULL;
107
108static X68kMousePriv x68kMousePriv;
109
110/*-
111 *-----------------------------------------------------------------------
112 * x68kMouseProc --
113 *	Handle the initialization, etc. of a mouse
114 *
115 * Results:
116 *	none.
117 *
118 * Side Effects:
119 *-----------------------------------------------------------------------
120 */
121int
122x68kMouseProc(DeviceIntPtr device, int what)
123{
124    DevicePtr   pMouse = &device->public;
125    int	    	format;
126    static int	oformat;
127    BYTE    	map[4];
128    Atom btn_labels[3] = {0};
129    Atom axes_labels[2] = { 0, 0 };
130
131    switch (what) {
132	case DEVICE_INIT:
133            pMouse->devicePrivate = (pointer) &x68kMousePriv;
134            if( (x68kMousePriv.fd = open("/dev/mouse", O_RDONLY)) == -1 ) {
135                Error ("Can't open mouse device");
136                return !Success;
137            }
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 		x68kMouseCtrl, GetMotionHistorySize(),
150		2, axes_labels);
151	    break;
152
153	case DEVICE_ON:
154	    if (ioctl (x68kMousePriv.fd, VUIDGFORMAT, &oformat) == -1) {
155		Error ("x68kMouseProc ioctl VUIDGFORMAT");
156		return !Success;
157	    }
158	    format = VUID_FIRM_EVENT;
159	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &format) == -1) {
160		Error ("x68kMouseProc ioctl VUIDSFORMAT");
161		return !Success;
162	    }
163            if ( fcntl(x68kMousePriv.fd, F_SETOWN, getpid()) == -1 ||
164                 fcntl(x68kMousePriv.fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1
165                 ) {
166                Error ("Async mouse I/O failed");
167                return !Success;
168            }
169	    x68kMousePriv.bmask = 0;
170	    AddEnabledDevice(x68kMousePriv.fd);
171	    pMouse->on = TRUE;
172	    break;
173
174	case DEVICE_OFF:
175	    pMouse->on = FALSE;
176	    RemoveEnabledDevice(x68kMousePriv.fd);
177	    break;
178
179	case DEVICE_CLOSE:
180	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &oformat) == -1)
181		Error ("x68kMouseProc ioctl VUIDSFORMAT");
182	    break;
183
184    }
185    return Success;
186}
187
188/*-
189 *-----------------------------------------------------------------------
190 * x68kMouseCtrl --
191 *	Alter the control parameters for the mouse. Since acceleration
192 *	etc. is done from the PtrCtrl record in the mouse's device record,
193 *	there's nothing to do here.
194 *
195 * Results:
196 *	None.
197 *
198 * Side Effects:
199 *	None.
200 *
201 *-----------------------------------------------------------------------
202 */
203/*ARGSUSED*/
204static void
205x68kMouseCtrl(DeviceIntPtr device, PtrCtrl* ctrl)
206{
207}
208
209/*-
210 *-----------------------------------------------------------------------
211 * x68kMouseGetEvents --
212 *	Return the events waiting in the wings for the given mouse.
213 *
214 * Results:
215 *	A pointer to an array of Firm_events or (Firm_event *)0 if no events
216 *	The number of events contained in the array.
217 *	A boolean as to whether more events might be available.
218 *
219 * Side Effects:
220 *	None.
221 *-----------------------------------------------------------------------
222 */
223
224Firm_event *
225x68kMouseGetEvents(int fd, int *pNumEvents, Bool *pAgain)
226{
227    int nBytes;               /* number of bytes of events available. */
228    static Firm_event evBuf[MAXEVENTS];     /* Buffer for Firm_events */
229
230    if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) {
231	if (errno == EWOULDBLOCK) {
232	    *pNumEvents = 0;
233	    *pAgain = FALSE;
234	} else {
235	    Error ("x68kMouseGetEvents read");
236	    FatalError ("Could not read from mouse");
237	}
238    } else {
239	*pNumEvents = nBytes / sizeof (Firm_event);
240	*pAgain = (nBytes == sizeof (evBuf));
241    }
242    return evBuf;
243}
244
245/*-
246 *-----------------------------------------------------------------------
247 * x68kMouseEnqueueEvent --
248 *	Given a Firm_event for a mouse, pass it off the the dix layer
249 *	properly converted...
250 *
251 * Results:
252 *	None.
253 *
254 * Side Effects:
255 *	The cursor may be redrawn...? devPrivate/x/y will be altered.
256 *
257 *-----------------------------------------------------------------------
258 */
259
260void
261x68kMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe)
262{
263    X68kMousePrivPtr	pPriv;	/* Private data for pointer */
264    int			bmask;	/* Temporary button mask */
265    int			type, buttons, flag;
266    int			i, nevents, valuators[2];
267    ValuatorMask	mask;
268
269    GetEventList(&x68kEvents);
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	nevents = GetPointerEvents(x68kEvents, device,
304	    type, buttons, flag, &mask);
305	for (i = 0; i < nevents; i++)
306	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
307	break;
308    case LOC_X_DELTA:
309	valuators[0] = fe->value;
310	valuators[1] = 0;
311	valuator_mask_set_range(&mask, 0, 2, valuators);
312        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
313	nevents = GetPointerEvents(x68kEvents, device,
314	    MotionNotify, 0, flag, &mask);
315	for (i = 0; i < nevents; i++)
316	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
317	break;
318    case LOC_Y_DELTA:
319	/*
320	 * For some reason, motion up generates a positive y delta
321	 * and motion down a negative delta, so we must subtract
322	 * here instead of add...
323	 */
324	valuators[0] = 0;
325	valuators[1] = -fe->value;
326	valuator_mask_set_range(&mask, 0, 2, valuators);
327        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
328	nevents = GetPointerEvents(x68kEvents, device,
329	    MotionNotify, 0, flag, &mask);
330	for (i = 0; i < nevents; i++)
331	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
332	break;
333    case LOC_X_ABSOLUTE:
334    case LOC_Y_ABSOLUTE:
335	/* XXX not sure how to get current X and Y position */
336    default:
337	FatalError ("%s: unrecognized id\n", __func__);
338	break;
339    }
340}
341
342/*ARGSUSED*/
343static Bool
344x68kCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
345{
346    return FALSE;
347}
348
349static void
350x68kCrossScreen(ScreenPtr pScreen, int entering)
351{
352}
353
354static void
355x68kWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
356{
357    sigset_t newsigmask;
358
359    (void) sigemptyset (&newsigmask);
360    (void) sigaddset (&newsigmask, SIGIO);
361    (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
362    miPointerWarpCursor (pDev, pScreen, x, y);
363    (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
364}
365
366/* EOF x68kMouse.c */
367