1ab290810Stsutsui/* $NetBSD: x68kMouse.c,v 1.3 2020/08/01 20:09:03 tsutsui Exp $ */
2706f2543Smrg/*-------------------------------------------------------------------------
3706f2543Smrg * Copyright (c) 1996 Yasushi Yamasaki
4706f2543Smrg * All rights reserved.
5706f2543Smrg *
6706f2543Smrg * Redistribution and use in source and binary forms, with or without
7706f2543Smrg * modification, are permitted provided that the following conditions
8706f2543Smrg * are met:
9706f2543Smrg * 1. Redistributions of source code must retain the above copyright
10706f2543Smrg *    notice, this list of conditions and the following disclaimer.
11706f2543Smrg * 2. Redistributions in binary form must reproduce the above copyright
12706f2543Smrg *    notice, this list of conditions and the following disclaimer in the
13706f2543Smrg *    documentation and/or other materials provided with the distribution.
14706f2543Smrg *
15706f2543Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16706f2543Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17706f2543Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18706f2543Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19706f2543Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20706f2543Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21706f2543Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22706f2543Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23706f2543Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24706f2543Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25706f2543Smrg *-----------------------------------------------------------------------*/
26706f2543Smrg
27706f2543Smrg/*-
28706f2543Smrg * Copyright (c) 1987 by the Regents of the University of California
29706f2543Smrg *
30706f2543Smrg * Permission to use, copy, modify, and distribute this
31706f2543Smrg * software and its documentation for any purpose and without
32706f2543Smrg * fee is hereby granted, provided that the above copyright
33706f2543Smrg * notice appear in all copies.  The University of California
34706f2543Smrg * makes no representations about the suitability of this
35706f2543Smrg * software for any purpose.  It is provided "as is" without
36706f2543Smrg * express or implied warranty.
37706f2543Smrg */
38706f2543Smrg
39706f2543Smrg/************************************************************
40706f2543SmrgCopyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
41706f2543Smrg
42706f2543Smrg                    All Rights Reserved
43706f2543Smrg
44706f2543SmrgPermission  to  use,  copy,  modify,  and  distribute   this
45706f2543Smrgsoftware  and  its documentation for any purpose and without
46706f2543Smrgfee is hereby granted, provided that the above copyright no-
47706f2543Smrgtice  appear  in all copies and that both that copyright no-
48706f2543Smrgtice and this permission notice appear in  supporting  docu-
49706f2543Smrgmentation,  and  that the names of Sun or X Consortium
50ab290810Stsutsuinot be used in advertising or publicity pertaining to
51ab290810Stsutsuidistribution  of  the software  without specific prior
52ab290810Stsutsuiwritten permission. Sun and X Consortium make no
53ab290810Stsutsuirepresentations about the suitability of this software for
54ab290810Stsutsuiany purpose. It is provided "as is" without any express or
55706f2543Smrgimplied warranty.
56706f2543Smrg
57706f2543SmrgSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
58706f2543SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
59706f2543SmrgNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
60706f2543SmrgABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
61706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
62706f2543SmrgPROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
63706f2543SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
64706f2543SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
65706f2543Smrg
66706f2543Smrg********************************************************/
67706f2543Smrg/*
68706f2543Smrg * Copyright 1991, 1992, 1993 Kaleb S. Keithley
69706f2543Smrg *
70706f2543Smrg * Permission to use, copy, modify, and distribute this
71706f2543Smrg * software and its documentation for any purpose and without
72706f2543Smrg * fee is hereby granted, provided that the above copyright
73ab290810Stsutsui * notice appear in all copies.  Kaleb S. Keithley makes no
74ab290810Stsutsui * representations about the suitability of this software for
75ab290810Stsutsui * any purpose.  It is provided "as is" without express or
76706f2543Smrg * implied warranty.
77706f2543Smrg */
78706f2543Smrg
79706f2543Smrg#include "x68k.h"
80706f2543Smrg#include "mi.h"
81706f2543Smrg#include "input.h"
82706f2543Smrg#include "inpututils.h"
83706f2543Smrg
84706f2543Smrg#include "exevents.h"
85706f2543Smrg#include <X11/Xatom.h>
86706f2543Smrg#include "xserver-properties.h"
87706f2543Smrg
88706f2543Smrgstatic Bool x68kCursorOffScreen(ScreenPtr *, int *, int *);
89706f2543Smrgstatic void x68kCrossScreen(ScreenPtr, int);
90706f2543Smrgstatic void x68kWarpCursor(DeviceIntPtr, ScreenPtr, int, int);
91706f2543Smrgstatic void x68kMouseCtrl(DeviceIntPtr, PtrCtrl*);
92706f2543Smrg
93706f2543SmrgmiPointerScreenFuncRec x68kPointerScreenFuncs = {
94706f2543Smrg    x68kCursorOffScreen,
95706f2543Smrg    x68kCrossScreen,
96706f2543Smrg    x68kWarpCursor,
97706f2543Smrg    NULL,
98706f2543Smrg    NULL
99706f2543Smrg};
100706f2543Smrg
101706f2543SmrgDeviceIntPtr x68kPointerDevice = NULL;
102706f2543Smrg
103706f2543Smrgstatic X68kMousePriv x68kMousePriv;
104706f2543Smrg
105706f2543Smrg/*-
106706f2543Smrg *-----------------------------------------------------------------------
107706f2543Smrg * x68kMouseProc --
108706f2543Smrg *	Handle the initialization, etc. of a mouse
109706f2543Smrg *
110706f2543Smrg * Results:
111706f2543Smrg *	none.
112706f2543Smrg *
113706f2543Smrg * Side Effects:
114706f2543Smrg *-----------------------------------------------------------------------
115706f2543Smrg */
116706f2543Smrgint
117706f2543Smrgx68kMouseProc(DeviceIntPtr device, int what)
118706f2543Smrg{
119706f2543Smrg    DevicePtr   pMouse = &device->public;
120ab290810Stsutsui    int		format;
121706f2543Smrg    static int	oformat;
122ab290810Stsutsui    BYTE	map[4];
123706f2543Smrg    Atom btn_labels[3] = {0};
124706f2543Smrg    Atom axes_labels[2] = { 0, 0 };
125706f2543Smrg
126706f2543Smrg    switch (what) {
127706f2543Smrg	case DEVICE_INIT:
128706f2543Smrg            pMouse->devicePrivate = (pointer) &x68kMousePriv;
129706f2543Smrg            if( (x68kMousePriv.fd = open("/dev/mouse", O_RDONLY)) == -1 ) {
130706f2543Smrg                Error ("Can't open mouse device");
131706f2543Smrg                return !Success;
132706f2543Smrg            }
133706f2543Smrg	    pMouse->on = FALSE;
134706f2543Smrg	    map[1] = 1;
135706f2543Smrg	    map[2] = 2;
136706f2543Smrg	    map[3] = 3;
137706f2543Smrg	    btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
138706f2543Smrg	    btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
139706f2543Smrg	    btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
140706f2543Smrg	    axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
141706f2543Smrg	    axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
142706f2543Smrg
143706f2543Smrg	    InitPointerDeviceStruct(pMouse, map, 3, btn_labels,
144ab290810Stsutsui		x68kMouseCtrl, GetMotionHistorySize(),
145706f2543Smrg		2, axes_labels);
146706f2543Smrg	    break;
147706f2543Smrg
148706f2543Smrg	case DEVICE_ON:
149706f2543Smrg	    if (ioctl (x68kMousePriv.fd, VUIDGFORMAT, &oformat) == -1) {
150706f2543Smrg		Error ("x68kMouseProc ioctl VUIDGFORMAT");
151706f2543Smrg		return !Success;
152706f2543Smrg	    }
153706f2543Smrg	    format = VUID_FIRM_EVENT;
154706f2543Smrg	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &format) == -1) {
155706f2543Smrg		Error ("x68kMouseProc ioctl VUIDSFORMAT");
156706f2543Smrg		return !Success;
157706f2543Smrg	    }
158706f2543Smrg            if ( fcntl(x68kMousePriv.fd, F_SETOWN, getpid()) == -1 ||
159706f2543Smrg                 fcntl(x68kMousePriv.fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1
160706f2543Smrg                 ) {
161706f2543Smrg                Error ("Async mouse I/O failed");
162706f2543Smrg                return !Success;
163706f2543Smrg            }
164706f2543Smrg	    x68kMousePriv.bmask = 0;
165706f2543Smrg	    AddEnabledDevice(x68kMousePriv.fd);
166706f2543Smrg	    pMouse->on = TRUE;
167706f2543Smrg	    break;
168706f2543Smrg
169706f2543Smrg	case DEVICE_OFF:
170706f2543Smrg	    pMouse->on = FALSE;
171706f2543Smrg	    RemoveEnabledDevice(x68kMousePriv.fd);
172706f2543Smrg	    break;
173706f2543Smrg
174706f2543Smrg	case DEVICE_CLOSE:
175706f2543Smrg	    if (ioctl (x68kMousePriv.fd, VUIDSFORMAT, &oformat) == -1)
176706f2543Smrg		Error ("x68kMouseProc ioctl VUIDSFORMAT");
177706f2543Smrg	    break;
178706f2543Smrg
179706f2543Smrg    }
180706f2543Smrg    return Success;
181706f2543Smrg}
182ab290810Stsutsui
183706f2543Smrg/*-
184706f2543Smrg *-----------------------------------------------------------------------
185706f2543Smrg * x68kMouseCtrl --
186706f2543Smrg *	Alter the control parameters for the mouse. Since acceleration
187706f2543Smrg *	etc. is done from the PtrCtrl record in the mouse's device record,
188706f2543Smrg *	there's nothing to do here.
189706f2543Smrg *
190706f2543Smrg * Results:
191706f2543Smrg *	None.
192706f2543Smrg *
193706f2543Smrg * Side Effects:
194706f2543Smrg *	None.
195706f2543Smrg *
196706f2543Smrg *-----------------------------------------------------------------------
197706f2543Smrg */
198706f2543Smrg/*ARGSUSED*/
199706f2543Smrgstatic void
200706f2543Smrgx68kMouseCtrl(DeviceIntPtr device, PtrCtrl* ctrl)
201706f2543Smrg{
202706f2543Smrg}
203706f2543Smrg
204706f2543Smrg/*-
205706f2543Smrg *-----------------------------------------------------------------------
206706f2543Smrg * x68kMouseGetEvents --
207706f2543Smrg *	Return the events waiting in the wings for the given mouse.
208706f2543Smrg *
209706f2543Smrg * Results:
210706f2543Smrg *	A pointer to an array of Firm_events or (Firm_event *)0 if no events
211706f2543Smrg *	The number of events contained in the array.
212706f2543Smrg *	A boolean as to whether more events might be available.
213706f2543Smrg *
214706f2543Smrg * Side Effects:
215706f2543Smrg *	None.
216706f2543Smrg *-----------------------------------------------------------------------
217706f2543Smrg */
218706f2543Smrg
219706f2543SmrgFirm_event *
220706f2543Smrgx68kMouseGetEvents(int fd, int *pNumEvents, Bool *pAgain)
221706f2543Smrg{
222706f2543Smrg    int nBytes;               /* number of bytes of events available. */
223706f2543Smrg    static Firm_event evBuf[MAXEVENTS];     /* Buffer for Firm_events */
224706f2543Smrg
225706f2543Smrg    if ((nBytes = read (fd, (char *)evBuf, sizeof(evBuf))) == -1) {
226706f2543Smrg	if (errno == EWOULDBLOCK) {
227706f2543Smrg	    *pNumEvents = 0;
228706f2543Smrg	    *pAgain = FALSE;
229706f2543Smrg	} else {
230706f2543Smrg	    Error ("x68kMouseGetEvents read");
231706f2543Smrg	    FatalError ("Could not read from mouse");
232706f2543Smrg	}
233706f2543Smrg    } else {
234706f2543Smrg	*pNumEvents = nBytes / sizeof (Firm_event);
235706f2543Smrg	*pAgain = (nBytes == sizeof (evBuf));
236706f2543Smrg    }
237706f2543Smrg    return evBuf;
238706f2543Smrg}
239706f2543Smrg
240706f2543Smrg/*-
241706f2543Smrg *-----------------------------------------------------------------------
242706f2543Smrg * x68kMouseEnqueueEvent --
243706f2543Smrg *	Given a Firm_event for a mouse, pass it off the the dix layer
244706f2543Smrg *	properly converted...
245706f2543Smrg *
246706f2543Smrg * Results:
247706f2543Smrg *	None.
248706f2543Smrg *
249706f2543Smrg * Side Effects:
250706f2543Smrg *	The cursor may be redrawn...? devPrivate/x/y will be altered.
251706f2543Smrg *
252706f2543Smrg *-----------------------------------------------------------------------
253706f2543Smrg */
254706f2543Smrg
255706f2543Smrgvoid
256706f2543Smrgx68kMouseEnqueueEvent(DeviceIntPtr device, Firm_event *fe)
257706f2543Smrg{
258706f2543Smrg    X68kMousePrivPtr	pPriv;	/* Private data for pointer */
259706f2543Smrg    int			bmask;	/* Temporary button mask */
260706f2543Smrg    int			type, buttons, flag;
261706f2543Smrg    int			i, nevents, valuators[2];
262706f2543Smrg    ValuatorMask	mask;
263706f2543Smrg
264706f2543Smrg    GetEventList(&x68kEvents);
265706f2543Smrg
266706f2543Smrg    pPriv = (X68kMousePrivPtr)device->public.devicePrivate;
267706f2543Smrg
268706f2543Smrg    switch (fe->id) {
269706f2543Smrg    case MS_LEFT:
270706f2543Smrg    case MS_MIDDLE:
271706f2543Smrg    case MS_RIGHT:
272706f2543Smrg	/*
273706f2543Smrg	 * A button changed state. Sometimes we will get two events
274706f2543Smrg	 * for a single state change. Should we get a button event which
275706f2543Smrg	 * reflects the current state of affairs, that event is discarded.
276706f2543Smrg	 *
277706f2543Smrg	 * Mouse buttons start at 1.
278706f2543Smrg	 */
279706f2543Smrg	buttons = (fe->id - MS_LEFT) + 1;
280706f2543Smrg	bmask = 1 << buttons;
281706f2543Smrg	if (fe->value == VKEY_UP) {
282706f2543Smrg	    if (pPriv->bmask & bmask) {
283706f2543Smrg		type = ButtonRelease;
284706f2543Smrg		pPriv->bmask &= ~bmask;
285706f2543Smrg	    } else {
286706f2543Smrg		return;
287706f2543Smrg	    }
288706f2543Smrg	} else {
289706f2543Smrg	    if ((pPriv->bmask & bmask) == 0) {
290706f2543Smrg		type = ButtonPress;
291706f2543Smrg		pPriv->bmask |= bmask;
292706f2543Smrg	    } else {
293706f2543Smrg		return;
294706f2543Smrg	    }
295706f2543Smrg	}
296706f2543Smrg	flag = POINTER_RELATIVE;
297706f2543Smrg	valuator_mask_set_range(&mask, 0, 0, NULL);
298706f2543Smrg	nevents = GetPointerEvents(x68kEvents, device,
299706f2543Smrg	    type, buttons, flag, &mask);
300706f2543Smrg	for (i = 0; i < nevents; i++)
301706f2543Smrg	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
302706f2543Smrg	break;
303706f2543Smrg    case LOC_X_DELTA:
304706f2543Smrg	valuators[0] = fe->value;
305706f2543Smrg	valuators[1] = 0;
306706f2543Smrg	valuator_mask_set_range(&mask, 0, 2, valuators);
307706f2543Smrg        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
308706f2543Smrg	nevents = GetPointerEvents(x68kEvents, device,
309706f2543Smrg	    MotionNotify, 0, flag, &mask);
310706f2543Smrg	for (i = 0; i < nevents; i++)
311706f2543Smrg	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
312706f2543Smrg	break;
313706f2543Smrg    case LOC_Y_DELTA:
314706f2543Smrg	/*
315706f2543Smrg	 * For some reason, motion up generates a positive y delta
316706f2543Smrg	 * and motion down a negative delta, so we must subtract
317706f2543Smrg	 * here instead of add...
318706f2543Smrg	 */
319706f2543Smrg	valuators[0] = 0;
320706f2543Smrg	valuators[1] = -fe->value;
321706f2543Smrg	valuator_mask_set_range(&mask, 0, 2, valuators);
322706f2543Smrg        flag = POINTER_RELATIVE | POINTER_ACCELERATE;
323706f2543Smrg	nevents = GetPointerEvents(x68kEvents, device,
324706f2543Smrg	    MotionNotify, 0, flag, &mask);
325706f2543Smrg	for (i = 0; i < nevents; i++)
326706f2543Smrg	    mieqEnqueue(device, (InternalEvent*)(x68kEvents + i)->event);
327706f2543Smrg	break;
328706f2543Smrg    case LOC_X_ABSOLUTE:
329706f2543Smrg    case LOC_Y_ABSOLUTE:
330706f2543Smrg	/* XXX not sure how to get current X and Y position */
331706f2543Smrg    default:
332706f2543Smrg	FatalError ("%s: unrecognized id\n", __func__);
333706f2543Smrg	break;
334706f2543Smrg    }
335706f2543Smrg}
336706f2543Smrg
337706f2543Smrg/*ARGSUSED*/
338706f2543Smrgstatic Bool
339706f2543Smrgx68kCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
340706f2543Smrg{
341706f2543Smrg    return FALSE;
342706f2543Smrg}
343706f2543Smrg
344706f2543Smrgstatic void
345706f2543Smrgx68kCrossScreen(ScreenPtr pScreen, int entering)
346706f2543Smrg{
347706f2543Smrg}
348706f2543Smrg
349706f2543Smrgstatic void
350706f2543Smrgx68kWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
351706f2543Smrg{
352706f2543Smrg    sigset_t newsigmask;
353706f2543Smrg
354706f2543Smrg    (void) sigemptyset (&newsigmask);
355706f2543Smrg    (void) sigaddset (&newsigmask, SIGIO);
356706f2543Smrg    (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
357706f2543Smrg    miPointerWarpCursor (pDev, pScreen, x, y);
358706f2543Smrg    (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
359706f2543Smrg}
360706f2543Smrg
361706f2543Smrg/* EOF x68kMouse.c */
362