Major rototilling of the wsmux code. No user visible changes (except that
many bugs have been fixed). Changes: The wskbd, wsmouse, and wsmux are now "sub-classes" of wsevsrc, which is a source of ws events. This make the structure of those drivers a little more uniform. Many bug fixes involving adding and removing devices from muxes. When a kernel is configured without wsmux there will now be none (unlike before where you got a console mux anyway). The kernel now compiles with all combinations of ws devices present.
This commit is contained in:
parent
ad870d54a0
commit
2f1f0a1702
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.wscons,v 1.22 2001/10/05 22:08:29 eeh Exp $
|
||||
# $NetBSD: files.wscons,v 1.23 2001/10/24 14:07:31 augustss Exp $
|
||||
|
||||
#
|
||||
# "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
|
||||
@ -40,7 +40,7 @@ file dev/wscons/wsemul_vt100.c wsdisplay & wsemul_vt100
|
||||
file dev/wscons/wsemul_vt100_subr.c wsdisplay & wsemul_vt100
|
||||
file dev/wscons/wsemul_vt100_chars.c wsdisplay & wsemul_vt100
|
||||
file dev/wscons/wsemul_vt100_keys.c wsdisplay & wsemul_vt100
|
||||
file dev/wscons/wsevent.c wskbd | wsmouse
|
||||
file dev/wscons/wsevent.c wskbd | wsmouse | wsmux
|
||||
file dev/wscons/wskbd.c wskbd needs-flag
|
||||
file dev/wscons/wskbdutil.c wskbd needs-flag
|
||||
file dev/wscons/wsmouse.c wsmouse needs-flag
|
||||
@ -52,4 +52,4 @@ file dev/wscons/wscons_rinit.c wsrasteremulops
|
||||
file dev/wscons/wscons_rops.c wsrasteremulops
|
||||
|
||||
defpseudo wsmux
|
||||
file dev/wscons/wsmux.c wsmux | wsdisplay needs-flag
|
||||
file dev/wscons/wsmux.c wsmux needs-flag
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wscons_callbacks.h,v 1.14 2001/10/13 15:56:15 augustss Exp $ */
|
||||
/* $NetBSD: wscons_callbacks.h,v 1.15 2001/10/24 14:07:32 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -30,10 +30,12 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct wsevsrc;
|
||||
|
||||
/*
|
||||
* Calls to the display interface from the glue code.
|
||||
*/
|
||||
struct device *wsdisplay_set_console_kbd(struct device *);
|
||||
struct device *wsdisplay_set_console_kbd(struct wsevsrc *);
|
||||
|
||||
/*
|
||||
* Calls to the display interface from the keyboard interface.
|
||||
@ -57,6 +59,5 @@ int wsdisplay_param(struct device*, u_long, struct wsdisplay_param*);
|
||||
/*
|
||||
* Calls to the keyboard interface from the glue code.
|
||||
*/
|
||||
struct wsmux_softc;
|
||||
struct device *wskbd_set_console_display(struct device *, struct wsmux_softc *);
|
||||
struct wsevsrc *wskbd_set_console_display(struct device *, struct wsevsrc *);
|
||||
int wskbd_pickfree(void);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsconsio.h,v 1.43 2001/10/02 21:03:05 mycroft Exp $ */
|
||||
/* $NetBSD: wsconsio.h,v 1.44 2001/10/24 14:07:32 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -40,7 +40,8 @@
|
||||
* 0-31 keyboard ioctls (WSKBDIO)
|
||||
* 32-63 mouse ioctls (WSMOUSEIO)
|
||||
* 64-95 display ioctls (WSDISPLAYIO)
|
||||
* 96-255 reserved for future use
|
||||
* 96-f127 mux ioctls (WSMUXIO)
|
||||
* 128-255 reserved for future use
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -340,7 +341,7 @@ struct wsdisplay_usefontdata {
|
||||
};
|
||||
#define WSDISPLAYIO_USEFONT _IOW('W', 80, struct wsdisplay_usefontdata)
|
||||
|
||||
/* Replaced by WSMUX_{ADD,REMOVE}_DEVICE */
|
||||
/* Obsolete, replaced by WSMUXIO_{ADD,REMOVE}_DEVICE */
|
||||
struct wsdisplay_kbddata {
|
||||
int op;
|
||||
#define _O_WSDISPLAY_KBD_ADD 0
|
||||
@ -365,7 +366,8 @@ struct wsdisplay_param {
|
||||
/* Mapping information retrieval. */
|
||||
|
||||
/* Mux ioctls (96 - 127) */
|
||||
#define WSMUX_INJECTEVENT _IOW('W', 96, struct wscons_event)
|
||||
#define WSMUXIO_INJECTEVENT _IOW('W', 96, struct wscons_event)
|
||||
#define WSMUX_INJECTEVENT WSMUXIO_INJECTEVENT /* XXX compat */
|
||||
|
||||
struct wsmux_device {
|
||||
int type;
|
||||
@ -374,14 +376,17 @@ struct wsmux_device {
|
||||
#define WSMUX_MUX 3
|
||||
int idx;
|
||||
};
|
||||
#define WSMUX_ADD_DEVICE _IOW('W', 97, struct wsmux_device)
|
||||
#define WSMUX_REMOVE_DEVICE _IOW('W', 98, struct wsmux_device)
|
||||
#define WSMUXIO_ADD_DEVICE _IOW('W', 97, struct wsmux_device)
|
||||
#define WSMUX_ADD_DEVICE WSMUXIO_ADD_DEVICE /* XXX compat */
|
||||
#define WSMUXIO_REMOVE_DEVICE _IOW('W', 98, struct wsmux_device)
|
||||
#define WSMUX_REMOVE_DEVICE WSMUXIO_REMOVE_DEVICE /* XXX compat */
|
||||
|
||||
#define WSMUX_MAXDEV 32
|
||||
struct wsmux_device_list {
|
||||
int ndevices;
|
||||
struct wsmux_device devices[WSMUX_MAXDEV];
|
||||
};
|
||||
#define WSMUX_LIST_DEVICES _IOWR('W', 99, struct wsmux_device_list)
|
||||
#define WSMUXIO_LIST_DEVICES _IOWR('W', 99, struct wsmux_device_list)
|
||||
#define WSMUX_LIST_DEVICES WSMUXIO_LIST_DEVICES /* XXX compat */
|
||||
|
||||
#endif /* _DEV_WSCONS_WSCONSIO_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsdisplay.c,v 1.55 2001/10/15 21:51:33 augustss Exp $ */
|
||||
/* $NetBSD: wsdisplay.c,v 1.56 2001/10/24 14:07:32 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -30,8 +30,14 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opt_wsdisplay_compat.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "wskbd.h"
|
||||
#include "wsmux.h"
|
||||
#include "wsdisplay.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.55 2001/10/15 21:51:33 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.56 2001/10/24 14:07:32 augustss Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -48,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.55 2001/10/15 21:51:33 augustss Exp
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <dev/wscons/wseventvar.h>
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsdisplayvar.h>
|
||||
#include <dev/wscons/wsksymvar.h>
|
||||
@ -56,16 +64,6 @@ __KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.55 2001/10/15 21:51:33 augustss Exp
|
||||
#include <dev/wscons/wscons_callbacks.h>
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include "opt_wsdisplay_compat.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "wskbd.h"
|
||||
#include "wsmux.h"
|
||||
|
||||
#if NWSKBD > 0
|
||||
#include <dev/wscons/wseventvar.h>
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
#endif
|
||||
|
||||
struct wsscreen_internal {
|
||||
const struct wsdisplay_emulops *emulops;
|
||||
void *emulcookie;
|
||||
@ -128,7 +126,7 @@ struct wsdisplay_softc {
|
||||
int sc_screenwanted, sc_oldscreen; /* valid with SC_SWITCHPENDING */
|
||||
|
||||
#if NWSKBD > 0
|
||||
struct wsmux_softc *sc_muxdv;
|
||||
struct wsevsrc *sc_input;
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
int sc_rawkbd;
|
||||
#endif
|
||||
@ -562,23 +560,28 @@ wsdisplay_common_attach(struct wsdisplay_softc *sc, int console, int kbdmux,
|
||||
static int hookset;
|
||||
int i, start=0;
|
||||
#if NWSKBD > 0
|
||||
struct device *dv;
|
||||
|
||||
struct wsevsrc *kme;
|
||||
#if NWSMUX > 0
|
||||
struct wsevsrc *inp;
|
||||
|
||||
if (kbdmux >= 0)
|
||||
sc->sc_muxdv = wsmux_getmux(kbdmux);
|
||||
inp = &wsmux_getmux(kbdmux)->sc_base;
|
||||
else
|
||||
#endif
|
||||
sc->sc_muxdv = wsmux_create("dmux", sc->sc_dv.dv_unit);
|
||||
inp = &wsmux_create("dmux", sc->sc_dv.dv_unit)->sc_base;
|
||||
/* XXX panic()ing isn't nice, but attach cannot fail */
|
||||
if (!sc->sc_muxdv)
|
||||
if (inp == NULL)
|
||||
panic("wsdisplay_common_attach: no memory\n");
|
||||
sc->sc_muxdv->sc_displaydv = &sc->sc_dv;
|
||||
sc->sc_input = inp;
|
||||
inp->me_dispdv = &sc->sc_dv;
|
||||
printf(" kbdmux %d", kbdmux);
|
||||
#else
|
||||
if (kbdmux >= 0)
|
||||
printf(" (kbdmux ignored)");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
sc->sc_isconsole = console;
|
||||
|
||||
printf(" kbdmux %d", kbdmux);
|
||||
if (console) {
|
||||
KASSERT(wsdisplay_console_initted);
|
||||
KASSERT(wsdisplay_console_device == NULL);
|
||||
@ -591,8 +594,12 @@ wsdisplay_common_attach(struct wsdisplay_softc *sc, int console, int kbdmux,
|
||||
wsdisplay_console_conf.wsemul->name);
|
||||
|
||||
#if NWSKBD > 0
|
||||
if ((dv = wskbd_set_console_display(&sc->sc_dv, sc->sc_muxdv)))
|
||||
printf(", using %s", dv->dv_xname);
|
||||
kme = wskbd_set_console_display(&sc->sc_dv, sc->sc_input);
|
||||
if (kme != NULL)
|
||||
printf(", using %s", kme->me_dv.dv_xname);
|
||||
#if NWSMUX == 0
|
||||
sc->sc_input = kme;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
sc->sc_focusidx = 0;
|
||||
@ -755,8 +762,8 @@ wsdisplayclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
if (scr->scr_rawkbd) {
|
||||
int kbmode = WSKBD_TRANSLATED;
|
||||
(void) wsdisplay_internal_ioctl(sc, scr, WSKBDIO_SETMODE,
|
||||
(caddr_t)&kbmode, 0, p);
|
||||
(void)wsdisplay_internal_ioctl(sc, scr, WSKBDIO_SETMODE,
|
||||
(caddr_t)&kbmode, 0, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -908,6 +915,8 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr,
|
||||
struct wsdisplay_font fd;
|
||||
|
||||
#if NWSKBD > 0
|
||||
struct wsevsrc *inp;
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
switch (cmd) {
|
||||
case WSKBDIO_SETMODE:
|
||||
@ -919,7 +928,8 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr,
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
error = wsmux_displayioctl(&sc->sc_muxdv->sc_dv, cmd, data, flag, p);
|
||||
inp = sc->sc_input;
|
||||
error = wsevsrc_display_ioctl(inp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
#endif /* NWSKBD > 0 */
|
||||
@ -987,6 +997,9 @@ wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data,
|
||||
#if defined(COMPAT_14) && NWSKBD > 0
|
||||
struct wsmux_device wsmuxdata;
|
||||
#endif
|
||||
#if NWSKBD > 0
|
||||
struct wsevsrc *inp;
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case WSDISPLAYIO_ADDSCREEN:
|
||||
@ -1056,31 +1069,30 @@ wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data,
|
||||
}
|
||||
wsmuxdata.type = WSMUX_KBD;
|
||||
wsmuxdata.idx = d->idx;
|
||||
return (wsmuxdoioctl(&sc->sc_muxdv->sc_dv,
|
||||
WSMUX_ADD_DEVICE,
|
||||
(caddr_t)&wsmuxdata, flag, p));
|
||||
return (wsevsrc_ioctl(sc->sc_input, WSMUX_ADD_DEVICE,
|
||||
&wsmuxdata, flag, p));
|
||||
case _O_WSDISPLAY_KBD_DEL:
|
||||
wsmuxdata.type = WSMUX_KBD;
|
||||
wsmuxdata.idx = d->idx;
|
||||
return (wsmuxdoioctl(&sc->sc_muxdv->sc_dv,
|
||||
WSMUX_REMOVE_DEVICE,
|
||||
(caddr_t)&wsmuxdata, flag, p));
|
||||
return (wsevsrc_ioctl(sc->sc_input,WSMUX_REMOVE_DEVICE,
|
||||
&wsmuxdata, flag, p));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
#undef d
|
||||
#endif
|
||||
|
||||
case WSMUX_ADD_DEVICE:
|
||||
case WSMUXIO_ADD_DEVICE:
|
||||
#define d ((struct wsmux_device *)data)
|
||||
if (d->idx == -1 && d->type == WSMUX_KBD)
|
||||
d->idx = wskbd_pickfree();
|
||||
#undef d
|
||||
/* fall into */
|
||||
case WSMUX_INJECTEVENT:
|
||||
case WSMUX_REMOVE_DEVICE:
|
||||
case WSMUX_LIST_DEVICES:
|
||||
return (wsmuxdoioctl(&sc->sc_muxdv->sc_dv, cmd, data, flag,p));
|
||||
case WSMUXIO_INJECTEVENT:
|
||||
case WSMUXIO_REMOVE_DEVICE:
|
||||
case WSMUXIO_LIST_DEVICES:
|
||||
inp = sc->sc_input;
|
||||
return (wsevsrc_ioctl(inp, cmd, data, flag, p));
|
||||
#endif /* NWSKBD > 0 */
|
||||
|
||||
}
|
||||
@ -1170,7 +1182,7 @@ wsdisplaystart(struct tty *tp)
|
||||
if (tp->t_outq.c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state&TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)&tp->t_outq);
|
||||
wakeup(&tp->t_outq);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
@ -1268,11 +1280,14 @@ wsdisplay_kbdinput(struct device *dev, keysym_t ks)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
#if defined(WSDISPLAY_COMPAT_RAWKBD)
|
||||
int
|
||||
wsdisplay_update_rawkbd(struct wsdisplay_softc *sc, struct wsscreen *scr)
|
||||
{
|
||||
#if NWSKBD > 0
|
||||
int s, raw, data, error;
|
||||
struct wsevsrc *inp;
|
||||
|
||||
s = spltty();
|
||||
|
||||
raw = (scr ? scr->scr_rawkbd : 0);
|
||||
@ -1284,12 +1299,15 @@ wsdisplay_update_rawkbd(struct wsdisplay_softc *sc, struct wsscreen *scr)
|
||||
}
|
||||
|
||||
data = raw ? WSKBD_RAW : WSKBD_TRANSLATED;
|
||||
error = wsmux_displayioctl(&sc->sc_muxdv->sc_dv, WSKBDIO_SETMODE,
|
||||
(caddr_t)&data, 0, 0);
|
||||
inp = sc->sc_input;
|
||||
error = wsevsrc_display_ioctl(inp, WSKBDIO_SETMODE, &data, 0, 0);
|
||||
if (!error)
|
||||
sc->sc_rawkbd = raw;
|
||||
splx(s);
|
||||
return (error);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1638,12 +1656,17 @@ wsdisplay_kbdholdscreen(struct device *dev, int hold)
|
||||
|
||||
#if NWSKBD > 0
|
||||
struct device *
|
||||
wsdisplay_set_console_kbd(struct device *kbddv)
|
||||
wsdisplay_set_console_kbd(struct wsevsrc *kbd)
|
||||
{
|
||||
if (!wsdisplay_console_device)
|
||||
return (0);
|
||||
if (wskbd_add_mux(kbddv->dv_unit, wsdisplay_console_device->sc_muxdv))
|
||||
return (0);
|
||||
if (wsdisplay_console_device == NULL)
|
||||
return (NULL);
|
||||
#if NWSMUX > 0
|
||||
if (wskbd_add_mux(kbd->me_dv.dv_unit,
|
||||
(struct wsmux_softc *)wsdisplay_console_device->sc_input))
|
||||
return (NULL);
|
||||
#else
|
||||
wsdisplay_console_device->sc_input = kbd;
|
||||
#endif
|
||||
return (&wsdisplay_console_device->sc_dv);
|
||||
}
|
||||
#endif /* NWSKBD > 0 */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsevent.c,v 1.6 2001/10/13 15:56:16 augustss Exp $ */
|
||||
/* $NetBSD: wsevent.c,v 1.7 2001/10/24 14:07:32 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsevent.c,v 1.6 2001/10/13 15:56:16 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsevent.c,v 1.7 2001/10/24 14:07:32 augustss Exp $");
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -100,10 +100,16 @@ void
|
||||
wsevent_init(struct wseventvar *ev)
|
||||
{
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ev->q != NULL) {
|
||||
printf("wsevent_init: already init\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ev->get = ev->put = 0;
|
||||
ev->q = malloc((u_long)WSEVENT_QSIZE * sizeof(struct wscons_event),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
memset((caddr_t)ev->q, 0, WSEVENT_QSIZE * sizeof(struct wscons_event));
|
||||
M_DEVBUF, M_WAITOK);
|
||||
memset(ev->q, 0, WSEVENT_QSIZE * sizeof(struct wscons_event));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -114,6 +120,31 @@ wsevent_fini(struct wseventvar *ev)
|
||||
{
|
||||
|
||||
free(ev->q, M_DEVBUF);
|
||||
ev->q = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a wseventvar.
|
||||
*/
|
||||
struct wseventvar *
|
||||
wsevent_alloc(void)
|
||||
{
|
||||
struct wseventvar *ev;
|
||||
|
||||
ev = malloc(sizeof(*ev), M_DEVBUF, M_WAITOK);
|
||||
memset(ev, 0, sizeof *ev);
|
||||
wsevent_init(ev);
|
||||
return (ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a wseventvar.
|
||||
*/
|
||||
void
|
||||
wsevent_free(struct wseventvar *ev)
|
||||
{
|
||||
wsevent_fini(ev);
|
||||
free(ev, M_DEVBUF);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -137,7 +168,7 @@ wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
|
||||
return (EWOULDBLOCK);
|
||||
}
|
||||
ev->wanted = 1;
|
||||
error = tsleep((caddr_t)ev, PWSEVENT | PCATCH,
|
||||
error = tsleep(ev, PWSEVENT | PCATCH,
|
||||
"wsevent_read", 0);
|
||||
if (error) {
|
||||
splx(s);
|
||||
@ -156,7 +187,7 @@ wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
|
||||
n = howmany(uio->uio_resid, sizeof(struct wscons_event));
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->q[ev->get],
|
||||
error = uiomove(&ev->q[ev->get],
|
||||
cnt * sizeof(struct wscons_event), uio);
|
||||
n -= cnt;
|
||||
/*
|
||||
@ -169,7 +200,7 @@ wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
|
||||
return (error);
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->q[0],
|
||||
error = uiomove(&ev->q[0],
|
||||
cnt * sizeof(struct wscons_event), uio);
|
||||
ev->get = cnt;
|
||||
return (error);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wseventvar.h,v 1.2 2001/10/13 15:56:16 augustss Exp $ */
|
||||
/* $NetBSD: wseventvar.h,v 1.3 2001/10/24 14:07:33 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -99,14 +99,16 @@ struct wseventvar {
|
||||
selwakeup(&(ev)->sel); \
|
||||
if ((ev)->wanted) { \
|
||||
(ev)->wanted = 0; \
|
||||
wakeup((caddr_t)(ev)); \
|
||||
wakeup((ev)); \
|
||||
} \
|
||||
if ((ev)->async) \
|
||||
psignal((ev)->io, SIGIO); \
|
||||
}
|
||||
|
||||
void wsevent_init(struct wseventvar *);
|
||||
struct wseventvar *wsevent_alloc(void);
|
||||
void wsevent_fini(struct wseventvar *);
|
||||
void wsevent_free(struct wseventvar *);
|
||||
int wsevent_read(struct wseventvar *, struct uio *, int);
|
||||
int wsevent_poll(struct wseventvar *, int, struct proc *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wskbd.c,v 1.47 2001/10/13 19:58:35 augustss Exp $ */
|
||||
/* $NetBSD: wskbd.c,v 1.48 2001/10/24 14:07:33 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.47 2001/10/13 19:58:35 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.48 2001/10/24 14:07:33 augustss Exp $");
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -87,6 +87,11 @@ __KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.47 2001/10/13 19:58:35 augustss Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kgdb.h"
|
||||
#include "opt_wsdisplay_compat.h"
|
||||
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
#include "wsmux.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -111,11 +116,6 @@ __KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.47 2001/10/13 19:58:35 augustss Exp $");
|
||||
#include <dev/wscons/wseventvar.h>
|
||||
#include <dev/wscons/wscons_callbacks.h>
|
||||
|
||||
#include "opt_wsdisplay_compat.h"
|
||||
|
||||
#include "wsdisplay.h"
|
||||
#include "wsmux.h"
|
||||
|
||||
#ifdef KGDB
|
||||
#include <sys/kgdb.h>
|
||||
#endif
|
||||
@ -127,9 +127,7 @@ int wskbddebug = 0;
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
#endif
|
||||
|
||||
struct wskbd_internal {
|
||||
const struct wskbd_mapdata *t_keymap;
|
||||
@ -151,7 +149,7 @@ struct wskbd_internal {
|
||||
};
|
||||
|
||||
struct wskbd_softc {
|
||||
struct device sc_dv;
|
||||
struct wsevsrc sc_base;
|
||||
|
||||
struct wskbd_internal *id;
|
||||
|
||||
@ -160,13 +158,7 @@ struct wskbd_softc {
|
||||
|
||||
int sc_ledstate;
|
||||
|
||||
int sc_ready; /* accepting events */
|
||||
struct wseventvar sc_events; /* event queue state */
|
||||
|
||||
int sc_isconsole;
|
||||
#if NWSDISPLAY > 0
|
||||
struct device *sc_displaydv;
|
||||
#endif
|
||||
|
||||
struct wskbd_bell_data sc_bell_data;
|
||||
struct wskbd_keyrepeat_data sc_keyrepeat_data;
|
||||
@ -182,10 +174,6 @@ struct wskbd_softc {
|
||||
|
||||
int sc_refcnt;
|
||||
u_char sc_dying; /* device is being detached */
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
struct wsmux_softc *sc_mux;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MOD_SHIFT_L (1 << 0)
|
||||
@ -211,14 +199,18 @@ struct wskbd_softc {
|
||||
#define MOD_ONESET(id, mask) (((id)->t_modifiers & (mask)) != 0)
|
||||
#define MOD_ALLSET(id, mask) (((id)->t_modifiers & (mask)) == (mask))
|
||||
|
||||
int wskbd_match(struct device *, struct cfdata *, void *);
|
||||
void wskbd_attach(struct device *, struct device *, void *);
|
||||
int wskbd_detach(struct device *, int);
|
||||
int wskbd_activate(struct device *, enum devact);
|
||||
static int wskbd_match(struct device *, struct cfdata *, void *);
|
||||
static void wskbd_attach(struct device *, struct device *, void *);
|
||||
static int wskbd_detach(struct device *, int);
|
||||
static int wskbd_activate(struct device *, enum devact);
|
||||
|
||||
static int wskbd_displayioctl
|
||||
(struct device *, u_long, caddr_t, int, struct proc *p);
|
||||
int wskbd_set_display(struct device *, struct wsmux_softc *);
|
||||
static int wskbd_displayioctl(struct device *, u_long, caddr_t, int,
|
||||
struct proc *);
|
||||
#if NWSDISPLAY > 0
|
||||
static int wskbd_set_display(struct device *, struct wsevsrc *);
|
||||
#else
|
||||
#define wskbd_set_display NULL
|
||||
#endif
|
||||
|
||||
static inline void update_leds(struct wskbd_internal *);
|
||||
static inline void update_modifier(struct wskbd_internal *, u_int, int, int);
|
||||
@ -230,10 +222,19 @@ static void change_displayparam(struct wskbd_softc *, int, int, int);
|
||||
static void wskbd_holdscreen(struct wskbd_softc *, int);
|
||||
#endif
|
||||
|
||||
int wskbd_do_ioctl(struct wskbd_softc *, u_long, caddr_t, int,struct proc*);
|
||||
static int wskbd_do_ioctl_sc(struct wskbd_softc *, u_long, caddr_t, int,
|
||||
struct proc *);
|
||||
|
||||
int wskbddoclose(struct device *, int, int, struct proc *);
|
||||
int wskbddoioctl(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
#if NWSMUX > 0
|
||||
static int wskbd_mux_open(struct wsevsrc *, struct wseventvar *);
|
||||
static int wskbd_mux_close(struct wsevsrc *);
|
||||
#else
|
||||
#define wskbd_mux_open NULL
|
||||
#define wskbd_mux_close NULL
|
||||
#endif
|
||||
|
||||
static int wskbd_do_open(struct wskbd_softc *, struct wseventvar *);
|
||||
static int wskbd_do_ioctl(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
|
||||
struct cfattach wskbd_ca = {
|
||||
sizeof (struct wskbd_softc), wskbd_match, wskbd_attach,
|
||||
@ -274,10 +275,11 @@ struct wskbd_keyrepeat_data wskbd_default_keyrepeat_data = {
|
||||
|
||||
cdev_decl(wskbd);
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
struct wsmuxops wskbd_muxops = {
|
||||
wskbdopen, wskbddoclose, wskbddoioctl, wskbd_displayioctl,
|
||||
wskbd_set_display
|
||||
#if NWSDISPLAY > 0 || NWSMUX > 0
|
||||
struct wssrcops wskbd_srcops = {
|
||||
WSMUX_KBD,
|
||||
wskbd_mux_open, wskbd_mux_close, wskbd_do_ioctl,
|
||||
wskbd_displayioctl, wskbd_set_display
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -345,23 +347,26 @@ wskbd_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)self;
|
||||
struct wskbddev_attach_args *ap = aux;
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
int mux;
|
||||
#if NWSMUX > 0
|
||||
int mux, error;
|
||||
#endif
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
sc->sc_displaydv = NULL;
|
||||
#endif
|
||||
sc->sc_isconsole = ap->console;
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
mux = sc->sc_dv.dv_cfdata->wskbddevcf_mux;
|
||||
if (sc->sc_isconsole && mux != WSKBDDEVCF_MUX_DEFAULT) {
|
||||
printf(" (mux %d ignored for console)", mux);
|
||||
mux = WSKBDDEVCF_MUX_DEFAULT;
|
||||
sc->sc_base.me_ops = &wskbd_srcops;
|
||||
#endif
|
||||
#if NWSMUX > 0
|
||||
mux = sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux;
|
||||
if (sc->sc_isconsole && mux >= 0) {
|
||||
/* printf(" (mux %d ignored for console)", mux); */
|
||||
mux = -1;
|
||||
}
|
||||
if (mux != WSKBDDEVCF_MUX_DEFAULT)
|
||||
if (mux >= 0)
|
||||
printf(" mux %d", mux);
|
||||
#else
|
||||
if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
|
||||
printf(" (mux ignored)");
|
||||
#endif
|
||||
|
||||
if (ap->console) {
|
||||
@ -380,7 +385,6 @@ wskbd_attach(struct device *parent, struct device *self, void *aux)
|
||||
|
||||
sc->sc_accessops = ap->accessops;
|
||||
sc->sc_accesscookie = ap->accesscookie;
|
||||
sc->sc_ready = 0; /* sanity */
|
||||
sc->sc_repeating = 0;
|
||||
sc->sc_translating = 1;
|
||||
sc->sc_ledstate = -1; /* force update */
|
||||
@ -404,18 +408,21 @@ wskbd_attach(struct device *parent, struct device *self, void *aux)
|
||||
printf(": console keyboard");
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
if ((sc->sc_displaydv = wsdisplay_set_console_kbd(self)))
|
||||
printf(", using %s", sc->sc_displaydv->dv_xname);
|
||||
sc->sc_base.me_dispdv = wsdisplay_set_console_kbd(&sc->sc_base);
|
||||
if (sc->sc_base.me_dispdv != NULL)
|
||||
printf(", using %s", sc->sc_base.me_dispdv->dv_xname);
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#if NWSMUX > 0
|
||||
if (mux != WSKBDDEVCF_MUX_DEFAULT)
|
||||
wsmux_attach(mux, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wskbd_muxops);
|
||||
if (mux != WSKBDDEVCF_MUX_DEFAULT) {
|
||||
error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
|
||||
if (error)
|
||||
printf("%s: attach error=%d\n",
|
||||
sc->sc_base.me_dv.dv_xname, error);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -469,10 +476,10 @@ wskbd_repeat(void *v)
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
if (sc->sc_displaydv != NULL) {
|
||||
if (sc->sc_base.me_dispdv != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < sc->sc_repeating; i++)
|
||||
wsdisplay_kbdinput(sc->sc_displaydv,
|
||||
wsdisplay_kbdinput(sc->sc_base.me_dispdv,
|
||||
sc->id->t_symbols[i]);
|
||||
}
|
||||
callout_reset(&sc->sc_repeat_ch,
|
||||
@ -484,7 +491,10 @@ wskbd_repeat(void *v)
|
||||
int
|
||||
wskbd_activate(struct device *self, enum devact act)
|
||||
{
|
||||
/* XXX should we do something more? */
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)self;
|
||||
|
||||
if (act == DVACT_DEACTIVATE)
|
||||
sc->sc_dying = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -503,16 +513,15 @@ wskbd_detach(struct device *self, int flags)
|
||||
struct wseventvar *evar;
|
||||
int maj, mn;
|
||||
int s;
|
||||
#if NWSMUX > 0
|
||||
int mux;
|
||||
|
||||
mux = sc->sc_dv.dv_cfdata->wskbddevcf_mux;
|
||||
if (mux != WSMOUSEDEVCF_MUX_DEFAULT)
|
||||
wsmux_detach(mux, &sc->sc_dv);
|
||||
#if NWSMUX > 0
|
||||
/* Tell parent mux we're leaving. */
|
||||
if (sc->sc_base.me_parent != NULL)
|
||||
wsmux_detach_sc(&sc->sc_base);
|
||||
#endif
|
||||
|
||||
evar = &sc->sc_events;
|
||||
if (evar->io) {
|
||||
evar = sc->sc_base.me_evp;
|
||||
if (evar != NULL && evar->io != NULL) {
|
||||
s = spltty();
|
||||
if (--sc->sc_refcnt >= 0) {
|
||||
/* Wake everyone by generating a dummy event. */
|
||||
@ -522,7 +531,7 @@ wskbd_detach(struct device *self, int flags)
|
||||
/* Wait for processes to go away. */
|
||||
if (tsleep(sc, PZERO, "wskdet", hz * 60))
|
||||
printf("wskbd_detach: %s didn't detach\n",
|
||||
sc->sc_dv.dv_xname);
|
||||
sc->sc_base.me_dv.dv_xname);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
@ -545,7 +554,7 @@ wskbd_input(struct device *dev, u_int type, int value)
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
|
||||
struct wscons_event *ev;
|
||||
struct wseventvar *evar;
|
||||
struct timeval xxxtime;
|
||||
struct timeval thistime;
|
||||
#if NWSDISPLAY > 0
|
||||
int num, i;
|
||||
#endif
|
||||
@ -564,9 +573,10 @@ wskbd_input(struct device *dev, u_int type, int value)
|
||||
if (sc->sc_translating) {
|
||||
num = wskbd_translate(sc->id, type, value);
|
||||
if (num > 0) {
|
||||
if (sc->sc_displaydv != NULL) {
|
||||
if (sc->sc_base.me_dispdv != NULL) {
|
||||
for (i = 0; i < num; i++)
|
||||
wsdisplay_kbdinput(sc->sc_displaydv,
|
||||
wsdisplay_kbdinput(
|
||||
sc->sc_base.me_dispdv,
|
||||
sc->id->t_symbols[i]);
|
||||
}
|
||||
|
||||
@ -585,29 +595,24 @@ wskbd_input(struct device *dev, u_int type, int value)
|
||||
* keystroke is lost (sorry!).
|
||||
*/
|
||||
|
||||
/* no one to receive; punt!*/
|
||||
if (!sc->sc_ready)
|
||||
evar = sc->sc_base.me_evp;
|
||||
if (evar == NULL) {
|
||||
DPRINTF(("wskbd_input: not open\n"));
|
||||
return;
|
||||
|
||||
#if NWSMUX > 0
|
||||
if (sc->sc_mux)
|
||||
evar = &sc->sc_mux->sc_events;
|
||||
else
|
||||
#endif
|
||||
evar = &sc->sc_events;
|
||||
}
|
||||
|
||||
put = evar->put;
|
||||
ev = &evar->q[put];
|
||||
put = (put + 1) % WSEVENT_QSIZE;
|
||||
if (put == evar->get) {
|
||||
log(LOG_WARNING, "%s: event queue overflow\n",
|
||||
sc->sc_dv.dv_xname);
|
||||
sc->sc_base.me_dv.dv_xname);
|
||||
return;
|
||||
}
|
||||
ev->type = type;
|
||||
ev->value = value;
|
||||
microtime(&xxxtime);
|
||||
TIMEVAL_TO_TIMESPEC(&xxxtime, &ev->time);
|
||||
microtime(&thistime);
|
||||
TIMEVAL_TO_TIMESPEC(&thistime, &ev->time);
|
||||
evar->put = put;
|
||||
WSEVENT_WAKEUP(evar);
|
||||
}
|
||||
@ -620,9 +625,9 @@ wskbd_rawinput(struct device *dev, u_char *buf, int len)
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
|
||||
int i;
|
||||
|
||||
if (sc->sc_displaydv != NULL)
|
||||
if (sc->sc_base.me_dispdv != NULL)
|
||||
for (i = 0; i < len; i++)
|
||||
wsdisplay_kbdinput(sc->sc_displaydv, buf[i]);
|
||||
wsdisplay_kbdinput(sc->sc_base.me_dispdv, buf[i]);
|
||||
/* this is KS_GROUP_Ascii */
|
||||
#endif
|
||||
}
|
||||
@ -634,8 +639,8 @@ wskbd_holdscreen(struct wskbd_softc *sc, int hold)
|
||||
{
|
||||
int new_state;
|
||||
|
||||
if (sc->sc_displaydv != NULL) {
|
||||
wsdisplay_kbdholdscreen(sc->sc_displaydv, hold);
|
||||
if (sc->sc_base.me_dispdv != NULL) {
|
||||
wsdisplay_kbdholdscreen(sc->sc_base.me_dispdv, hold);
|
||||
new_state = sc->sc_ledstate;
|
||||
if (hold)
|
||||
new_state |= WSKBD_LED_SCROLL;
|
||||
@ -653,56 +658,90 @@ wskbd_holdscreen(struct wskbd_softc *sc, int hold)
|
||||
static int
|
||||
wskbd_enable(struct wskbd_softc *sc, int on)
|
||||
{
|
||||
int res;
|
||||
int error;
|
||||
|
||||
/* XXX reference count? */
|
||||
#if 0
|
||||
/* I don't understand the purpose of this code. And it seems to
|
||||
* break things, so it's out. -- Lennart
|
||||
*/
|
||||
if (!on && (!sc->sc_translating
|
||||
#if NWSDISPLAY > 0
|
||||
|| sc->sc_displaydv
|
||||
|| sc->sc_base.me_dispdv
|
||||
#endif
|
||||
))
|
||||
return (EBUSY);
|
||||
#endif
|
||||
|
||||
res = (*sc->sc_accessops->enable)(sc->sc_accesscookie, on);
|
||||
return (res);
|
||||
error = (*sc->sc_accessops->enable)(sc->sc_accesscookie, on);
|
||||
DPRINTF(("wskbd_enable: sc=%p on=%d res=%d\n", sc, on, error));
|
||||
return (error);
|
||||
}
|
||||
|
||||
#if NWSMUX > 0
|
||||
int
|
||||
wskbd_mux_open(struct wsevsrc *me, struct wseventvar *evp)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)me;
|
||||
|
||||
if (sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
return wskbd_do_open(sc, evp);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
wskbdopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
struct wskbd_softc *sc;
|
||||
int unit;
|
||||
struct wseventvar *evar;
|
||||
int unit, error;
|
||||
|
||||
unit = minor(dev);
|
||||
if (unit >= wskbd_cd.cd_ndevs || /* make sure it was attached */
|
||||
(sc = wskbd_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
#if NWSMUX > 0
|
||||
DPRINTF(("wskbdopen: %s mux=%p p=%p\n", sc->sc_base.me_dv.dv_xname,
|
||||
sc->sc_base.me_parent, p));
|
||||
#endif
|
||||
|
||||
if (sc->sc_dying)
|
||||
return (EIO);
|
||||
|
||||
if (!(flags & FREAD)) {
|
||||
if ((flags & (FREAD | FWRITE)) == FWRITE)
|
||||
/* Not opening for read, only ioctl is available. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if NWSMUX > 0
|
||||
if (sc->sc_mux) {
|
||||
if (sc->sc_base.me_parent != NULL)
|
||||
/* Grab the keyboard out of the greedy hands of the mux. */
|
||||
int error = wskbd_rem_mux(unit, sc->sc_mux);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
wsmux_detach_sc(&sc->sc_base);
|
||||
#endif
|
||||
|
||||
if (sc->sc_events.io) /* and that it's not in use */
|
||||
if (sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
sc->sc_events.io = p;
|
||||
wsevent_init(&sc->sc_events); /* may cause sleep */
|
||||
evar = wsevent_alloc();
|
||||
sc->sc_base.me_evp = evar;
|
||||
evar->io = p;
|
||||
|
||||
error = wskbd_do_open(sc, evar);
|
||||
if (error) {
|
||||
DPRINTF(("wskbdopen: %s open failed\n",
|
||||
sc->sc_base.me_dv.dv_xname));
|
||||
sc->sc_base.me_evp = NULL;
|
||||
wsevent_free(evar);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_do_open(struct wskbd_softc *sc, struct wseventvar *evp)
|
||||
{
|
||||
sc->sc_base.me_evp = evp;
|
||||
sc->sc_translating = 0;
|
||||
sc->sc_ready = 1; /* start accepting events */
|
||||
|
||||
wskbd_enable(sc, 1);
|
||||
return (0);
|
||||
@ -711,29 +750,36 @@ wskbdopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
int
|
||||
wskbdclose(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
return (wskbddoclose(wskbd_cd.cd_devs[minor(dev)], flags, mode, p));
|
||||
}
|
||||
struct wskbd_softc *sc =
|
||||
(struct wskbd_softc *)wskbd_cd.cd_devs[minor(dev)];
|
||||
struct wseventvar *evar = sc->sc_base.me_evp;
|
||||
|
||||
int
|
||||
wskbddoclose(struct device *dv, int flags, int mode, struct proc *p)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
|
||||
|
||||
if (!(flags & FREAD)) {
|
||||
/* Nothing to do, because open didn't do anything. */
|
||||
if (evar == NULL)
|
||||
/* not open for read */
|
||||
return (0);
|
||||
}
|
||||
|
||||
sc->sc_ready = 0; /* stop accepting events */
|
||||
sc->sc_base.me_evp = NULL;
|
||||
sc->sc_translating = 1;
|
||||
|
||||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
|
||||
wskbd_enable(sc, 0);
|
||||
wsevent_free(evar);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if NWSMUX > 0
|
||||
int
|
||||
wskbd_mux_close(struct wsevsrc *me)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)me;
|
||||
|
||||
sc->sc_base.me_evp = NULL;
|
||||
sc->sc_translating = 1;
|
||||
wskbd_enable(sc, 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
wskbdread(dev_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
@ -743,8 +789,15 @@ wskbdread(dev_t dev, struct uio *uio, int flags)
|
||||
if (sc->sc_dying)
|
||||
return (EIO);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_base.me_evp == NULL) {
|
||||
printf("wskbdread: evp == NULL\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
sc->sc_refcnt++;
|
||||
error = wsevent_read(&sc->sc_events, uio, flags);
|
||||
error = wsevent_read(sc->sc_base.me_evp, uio, flags);
|
||||
if (--sc->sc_refcnt < 0) {
|
||||
wakeup(sc);
|
||||
error = EIO;
|
||||
@ -755,27 +808,27 @@ wskbdread(dev_t dev, struct uio *uio, int flags)
|
||||
int
|
||||
wskbdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
return (wskbddoioctl(wskbd_cd.cd_devs[minor(dev)], cmd, data, flag,p));
|
||||
return (wskbd_do_ioctl(wskbd_cd.cd_devs[minor(dev)], cmd, data, flag,p));
|
||||
}
|
||||
|
||||
/* A wrapper around the ioctl() workhorse to make reference counting easy. */
|
||||
int
|
||||
wskbddoioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
|
||||
wskbd_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
|
||||
struct proc *p)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
|
||||
int error;
|
||||
|
||||
sc->sc_refcnt++;
|
||||
error = wskbd_do_ioctl(sc, cmd, data, flag, p);
|
||||
error = wskbd_do_ioctl_sc(sc, cmd, data, flag, p);
|
||||
if (--sc->sc_refcnt < 0)
|
||||
wakeup(sc);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_do_ioctl(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
|
||||
struct proc *p)
|
||||
wskbd_do_ioctl_sc(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
|
||||
struct proc *p)
|
||||
{
|
||||
int error;
|
||||
|
||||
@ -787,11 +840,15 @@ wskbd_do_ioctl(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
sc->sc_events.async = *(int *)data != 0;
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
sc->sc_base.me_evp->async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != sc->sc_events.io->p_pgid)
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
if (*(int *)data != sc->sc_base.me_evp->io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
}
|
||||
@ -800,7 +857,7 @@ wskbd_do_ioctl(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
|
||||
* Try the keyboard driver for WSKBDIO ioctls. It returns -1
|
||||
* if it didn't recognize the request.
|
||||
*/
|
||||
error = wskbd_displayioctl((struct device *)sc, cmd, data, flag, p);
|
||||
error = wskbd_displayioctl(&sc->sc_base.me_dv, cmd, data, flag, p);
|
||||
return (error != -1 ? error : ENOTTY);
|
||||
}
|
||||
|
||||
@ -1005,7 +1062,9 @@ wskbdpoll(dev_t dev, int events, struct proc *p)
|
||||
{
|
||||
struct wskbd_softc *sc = wskbd_cd.cd_devs[minor(dev)];
|
||||
|
||||
return (wsevent_poll(&sc->sc_events, events, p));
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
return (wsevent_poll(sc->sc_base.me_evp, events, p));
|
||||
}
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
@ -1019,99 +1078,86 @@ wskbd_pickfree(void)
|
||||
for (i = 0; i < wskbd_cd.cd_ndevs; i++) {
|
||||
if ((sc = wskbd_cd.cd_devs[i]) == NULL)
|
||||
continue;
|
||||
if (sc->sc_displaydv == NULL)
|
||||
if (sc->sc_base.me_dispdv == NULL)
|
||||
return (i);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
struct device *
|
||||
wskbd_set_console_display(struct device *displaydv, struct wsmux_softc *muxsc)
|
||||
struct wsevsrc *
|
||||
wskbd_set_console_display(struct device *displaydv, struct wsevsrc *me)
|
||||
{
|
||||
struct wskbd_softc *sc = wskbd_console_device;
|
||||
|
||||
if (!sc)
|
||||
return (0);
|
||||
sc->sc_displaydv = displaydv;
|
||||
(void)wsmux_attach_sc(muxsc, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wskbd_muxops);
|
||||
return (&sc->sc_dv);
|
||||
if (sc == NULL)
|
||||
return (NULL);
|
||||
sc->sc_base.me_dispdv = displaydv;
|
||||
#if NWSMUX > 0
|
||||
(void)wsmux_attach_sc((struct wsmux_softc *)me, &sc->sc_base);
|
||||
#endif
|
||||
return (&sc->sc_base);
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_set_display(struct device *dv, struct wsmux_softc *muxsc)
|
||||
wskbd_set_display(struct device *dv, struct wsevsrc *me)
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
|
||||
struct device *displaydv = muxsc ? muxsc->sc_displaydv : 0;
|
||||
struct device *displaydv = me != NULL ? me->me_dispdv : NULL;
|
||||
struct device *odisplaydv;
|
||||
int error;
|
||||
|
||||
DPRINTF(("wskbd_set_display: %s mux=%p disp=%p odisp=%p cons=%d\n",
|
||||
dv->dv_xname, muxsc, sc->sc_displaydv, displaydv,
|
||||
DPRINTF(("wskbd_set_display: %s me=%p disp=%p odisp=%p cons=%d\n",
|
||||
dv->dv_xname, me, sc->sc_base.me_dispdv, displaydv,
|
||||
sc->sc_isconsole));
|
||||
|
||||
if (sc->sc_isconsole)
|
||||
return (EBUSY);
|
||||
|
||||
if (displaydv) {
|
||||
if (sc->sc_displaydv)
|
||||
if (displaydv != NULL) {
|
||||
if (sc->sc_base.me_dispdv != NULL)
|
||||
return (EBUSY);
|
||||
} else {
|
||||
if (sc->sc_displaydv == NULL)
|
||||
if (sc->sc_base.me_dispdv == NULL)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
odisplaydv = sc->sc_displaydv;
|
||||
sc->sc_displaydv = displaydv;
|
||||
odisplaydv = sc->sc_base.me_dispdv;
|
||||
sc->sc_base.me_dispdv = displaydv;
|
||||
|
||||
error = wskbd_enable(sc, displaydv != NULL);
|
||||
if (error) {
|
||||
sc->sc_displaydv = odisplaydv;
|
||||
sc->sc_base.me_dispdv = odisplaydv;
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (displaydv)
|
||||
printf("%s: connecting to %s\n",
|
||||
sc->sc_dv.dv_xname, displaydv->dv_xname);
|
||||
sc->sc_base.me_dv.dv_xname, displaydv->dv_xname);
|
||||
else
|
||||
printf("%s: disconnecting from %s\n",
|
||||
sc->sc_dv.dv_xname, odisplaydv->dv_xname);
|
||||
sc->sc_base.me_dv.dv_xname, odisplaydv->dv_xname);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* NWSDISPLAY > 0 */
|
||||
|
||||
#if NWSMUX > 0
|
||||
int
|
||||
wskbd_add_mux(int unit, struct wsmux_softc *muxsc)
|
||||
{
|
||||
struct wskbd_softc *sc;
|
||||
|
||||
DPRINTF(("wskbd_add_mux: %d %s %p\n", unit, muxsc->sc_dv.dv_xname,
|
||||
muxsc->sc_displaydv));
|
||||
if (unit < 0 || unit >= wskbd_cd.cd_ndevs ||
|
||||
(sc = wskbd_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
if (sc->sc_mux || sc->sc_events.io)
|
||||
if (sc->sc_base.me_parent != NULL || sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
return (wsmux_attach_sc(muxsc, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wskbd_muxops));
|
||||
return (wsmux_attach_sc(muxsc, &sc->sc_base));
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_rem_mux(int unit, struct wsmux_softc *muxsc)
|
||||
{
|
||||
struct wskbd_softc *sc;
|
||||
|
||||
DPRINTF(("wskbd_rem_mux: %d %s\n", unit, muxsc->sc_dv.dv_xname));
|
||||
if (unit < 0 || unit >= wskbd_cd.cd_ndevs ||
|
||||
(sc = wskbd_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
return (wsmux_detach_sc(muxsc, &sc->sc_dv));
|
||||
}
|
||||
|
||||
#endif /* NWSDISPLAY > 0 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Console interface.
|
||||
@ -1219,11 +1265,11 @@ change_displayparam(struct wskbd_softc *sc, int param, int updown,
|
||||
int res;
|
||||
struct wsdisplay_param dp;
|
||||
|
||||
if (sc->sc_displaydv == NULL)
|
||||
if (sc->sc_base.me_dispdv == NULL)
|
||||
return;
|
||||
|
||||
dp.param = param;
|
||||
res = wsdisplay_param(sc->sc_displaydv, WSDISPLAYIO_GETPARAM, &dp);
|
||||
res = wsdisplay_param(sc->sc_base.me_dispdv, WSDISPLAYIO_GETPARAM, &dp);
|
||||
|
||||
if (res == EINVAL)
|
||||
return; /* no such parameter */
|
||||
@ -1234,7 +1280,7 @@ change_displayparam(struct wskbd_softc *sc, int param, int updown,
|
||||
else
|
||||
if (dp.curval < dp.min)
|
||||
dp.curval = wraparound ? dp.max : dp.min;
|
||||
wsdisplay_param(sc->sc_displaydv, WSDISPLAYIO_SETPARAM, &dp);
|
||||
wsdisplay_param(sc->sc_base.me_dispdv, WSDISPLAYIO_SETPARAM, &dp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1289,13 +1335,13 @@ internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym,
|
||||
case KS_Cmd_Screen7:
|
||||
case KS_Cmd_Screen8:
|
||||
case KS_Cmd_Screen9:
|
||||
wsdisplay_switch(sc->sc_displaydv, ksym - KS_Cmd_Screen0, 0);
|
||||
wsdisplay_switch(sc->sc_base.me_dispdv, ksym - KS_Cmd_Screen0, 0);
|
||||
return (1);
|
||||
case KS_Cmd_ResetEmul:
|
||||
wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETEMUL);
|
||||
wsdisplay_reset(sc->sc_base.me_dispdv, WSDISPLAY_RESETEMUL);
|
||||
return (1);
|
||||
case KS_Cmd_ResetClose:
|
||||
wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETCLOSE);
|
||||
wsdisplay_reset(sc->sc_base.me_dispdv, WSDISPLAY_RESETCLOSE);
|
||||
return (1);
|
||||
case KS_Cmd_BacklightOn:
|
||||
case KS_Cmd_BacklightOff:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsmouse.c,v 1.16 2001/10/13 19:56:09 augustss Exp $ */
|
||||
/* $NetBSD: wsmouse.c,v 1.17 2001/10/24 14:07:33 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.16 2001/10/13 19:56:09 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.17 2001/10/24 14:07:33 augustss Exp $");
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -81,6 +81,10 @@ __KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.16 2001/10/13 19:56:09 augustss Exp $"
|
||||
* Mouse driver.
|
||||
*/
|
||||
|
||||
#include "wsmouse.h"
|
||||
#include "wsdisplay.h"
|
||||
#include "wsmux.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -97,14 +101,15 @@ __KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.16 2001/10/13 19:56:09 augustss Exp $"
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsmousevar.h>
|
||||
#include <dev/wscons/wseventvar.h>
|
||||
|
||||
#include "wsmouse.h"
|
||||
#include "wsmux.h"
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
|
||||
#if NWSMUX > 0
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
|
||||
#if defined(WSMUX_DEBUG) && NWSMUX > 0
|
||||
#define DPRINTF(x) if (wsmuxdebug) printf x
|
||||
#define DPRINTFN(n,x) if (wsmuxdebug > (n)) printf x
|
||||
extern int wsmuxdebug;
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#define DPRINTFN(n,x)
|
||||
#endif
|
||||
|
||||
#define INVALID_X INT_MAX
|
||||
@ -112,14 +117,11 @@ __KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.16 2001/10/13 19:56:09 augustss Exp $"
|
||||
#define INVALID_Z INT_MAX
|
||||
|
||||
struct wsmouse_softc {
|
||||
struct device sc_dv;
|
||||
struct wsevsrc sc_base;
|
||||
|
||||
const struct wsmouse_accessops *sc_accessops;
|
||||
void *sc_accesscookie;
|
||||
|
||||
int sc_ready; /* accepting events */
|
||||
struct wseventvar sc_events; /* event queue state */
|
||||
|
||||
u_int sc_mb; /* mouse button state */
|
||||
u_int sc_ub; /* user button state */
|
||||
int sc_dx; /* delta-x */
|
||||
@ -131,22 +133,24 @@ struct wsmouse_softc {
|
||||
|
||||
int sc_refcnt;
|
||||
u_char sc_dying; /* device is being detached */
|
||||
|
||||
#if NWSMUX > 0
|
||||
struct wsmux_softc *sc_mux;
|
||||
#endif
|
||||
};
|
||||
|
||||
int wsmouse_match(struct device *, struct cfdata *, void *);
|
||||
void wsmouse_attach(struct device *, struct device *, void *);
|
||||
int wsmouse_detach(struct device *, int);
|
||||
int wsmouse_activate(struct device *, enum devact);
|
||||
static int wsmouse_match(struct device *, struct cfdata *, void *);
|
||||
static void wsmouse_attach(struct device *, struct device *, void *);
|
||||
static int wsmouse_detach(struct device *, int);
|
||||
static int wsmouse_activate(struct device *, enum devact);
|
||||
|
||||
int wsmouse_do_ioctl(struct wsmouse_softc *, u_long, caddr_t,
|
||||
int, struct proc *);
|
||||
static int wsmouse_do_ioctl(struct wsmouse_softc *, u_long, caddr_t,
|
||||
int, struct proc *);
|
||||
|
||||
int wsmousedoclose(struct device *, int, int, struct proc *);
|
||||
int wsmousedoioctl(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
#if NWSMUX > 0
|
||||
static int wsmouse_mux_open(struct wsevsrc *, struct wseventvar *);
|
||||
static int wsmouse_mux_close(struct wsevsrc *);
|
||||
#endif
|
||||
|
||||
static int wsmousedoioctl(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
|
||||
static int wsmousedoopen(struct wsmouse_softc *, struct wseventvar *);
|
||||
|
||||
struct cfattach wsmouse_ca = {
|
||||
sizeof (struct wsmouse_softc), wsmouse_match, wsmouse_attach,
|
||||
@ -160,8 +164,9 @@ extern struct cfdriver wsmouse_cd;
|
||||
cdev_decl(wsmouse);
|
||||
|
||||
#if NWSMUX > 0
|
||||
struct wsmuxops wsmouse_muxops = {
|
||||
wsmouseopen, wsmousedoclose, wsmousedoioctl, 0, 0
|
||||
struct wssrcops wsmouse_srcops = {
|
||||
WSMUX_MOUSE,
|
||||
wsmouse_mux_open, wsmouse_mux_close, wsmousedoioctl, NULL, NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -189,20 +194,25 @@ wsmouse_attach(struct device *parent, struct device *self, void *aux)
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)self;
|
||||
struct wsmousedev_attach_args *ap = aux;
|
||||
#if NWSMUX > 0
|
||||
int mux;
|
||||
int mux, error;
|
||||
#endif
|
||||
|
||||
sc->sc_accessops = ap->accessops;
|
||||
sc->sc_accesscookie = ap->accesscookie;
|
||||
sc->sc_ready = 0; /* sanity */
|
||||
|
||||
#if NWSMUX > 0
|
||||
mux = sc->sc_dv.dv_cfdata->wsmousedevcf_mux;
|
||||
if (mux != WSMOUSEDEVCF_MUX_DEFAULT) {
|
||||
wsmux_attach(mux, WSMUX_MOUSE, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wsmouse_muxops);
|
||||
printf(" mux %d", mux);
|
||||
sc->sc_base.me_ops = &wsmouse_srcops;
|
||||
mux = sc->sc_base.me_dv.dv_cfdata->wsmousedevcf_mux;
|
||||
if (mux >= 0) {
|
||||
error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
|
||||
if (error)
|
||||
printf(" attach error=%d", error);
|
||||
else
|
||||
printf(" mux %d", mux);
|
||||
}
|
||||
#else
|
||||
if (sc->sc_base.me_dv.dv_cfdata->wsmousedevcf_mux >= 0)
|
||||
printf(" (mux ignored)");
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
@ -211,7 +221,10 @@ wsmouse_attach(struct device *parent, struct device *self, void *aux)
|
||||
int
|
||||
wsmouse_activate(struct device *self, enum devact act)
|
||||
{
|
||||
/* XXX should we do something more? */
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)self;
|
||||
|
||||
if (act == DVACT_DEACTIVATE)
|
||||
sc->sc_dying = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -230,20 +243,16 @@ wsmouse_detach(struct device *self, int flags)
|
||||
struct wseventvar *evar;
|
||||
int maj, mn;
|
||||
int s;
|
||||
#if NWSMUX > 0
|
||||
int mux;
|
||||
#endif
|
||||
|
||||
sc->sc_dying = 1;
|
||||
|
||||
#if NWSMUX > 0
|
||||
mux = sc->sc_dv.dv_cfdata->wsmousedevcf_mux;
|
||||
if (mux != WSMOUSEDEVCF_MUX_DEFAULT)
|
||||
wsmux_detach(mux, &sc->sc_dv);
|
||||
/* Tell parent mux we're leaving. */
|
||||
if (sc->sc_base.me_parent != NULL)
|
||||
wsmux_detach_sc(&sc->sc_base);
|
||||
#endif
|
||||
|
||||
evar = &sc->sc_events;
|
||||
if (evar->io) {
|
||||
/* If we're open ... */
|
||||
evar = sc->sc_base.me_evp;
|
||||
if (evar != NULL && evar->io != NULL) {
|
||||
s = spltty();
|
||||
if (--sc->sc_refcnt >= 0) {
|
||||
/* Wake everyone by generating a dummy event. */
|
||||
@ -253,7 +262,7 @@ wsmouse_detach(struct device *self, int flags)
|
||||
/* Wait for processes to go away. */
|
||||
if (tsleep(sc, PZERO, "wsmdet", hz * 60))
|
||||
printf("wsmouse_detach: %s didn't detach\n",
|
||||
sc->sc_dv.dv_xname);
|
||||
sc->sc_base.me_dv.dv_xname);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
@ -280,17 +289,16 @@ wsmouse_input(struct device *wsmousedev, u_int btns /* 0 is up */,
|
||||
int mb, ub, d, get, put, any;
|
||||
|
||||
/*
|
||||
* Discard input if not ready.
|
||||
* Discard input if not open.
|
||||
*/
|
||||
if (sc->sc_ready == 0)
|
||||
evar = sc->sc_base.me_evp;
|
||||
if (evar == NULL)
|
||||
return;
|
||||
|
||||
#if NWSMUX > 0
|
||||
if (sc->sc_mux)
|
||||
evar = &sc->sc_mux->sc_events;
|
||||
else
|
||||
DPRINTFN(5,("wsmouse_input: %s mux=%p, evar=%p\n",
|
||||
sc->sc_base.me_dv.dv_xname, sc->sc_base.me_parent, evar));
|
||||
#endif
|
||||
evar = &sc->sc_events;
|
||||
|
||||
sc->sc_mb = btns;
|
||||
if (!(flags & WSMOUSE_INPUT_ABSOLUTE_X))
|
||||
@ -423,8 +431,8 @@ out:
|
||||
int
|
||||
wsmouseopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
struct wsmouse_softc *sc;
|
||||
struct wseventvar *evar;
|
||||
int error, unit;
|
||||
|
||||
unit = minor(dev);
|
||||
@ -432,6 +440,11 @@ wsmouseopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
(sc = wsmouse_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
#if NWSMUX > 0
|
||||
DPRINTF(("wsmouseopen: %s mux=%p p=%p\n", sc->sc_base.me_dv.dv_xname,
|
||||
sc->sc_base.me_parent, p));
|
||||
#endif
|
||||
|
||||
if (sc->sc_dying)
|
||||
return (EIO);
|
||||
|
||||
@ -440,103 +453,89 @@ wsmouseopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
so ioctl() is possible. */
|
||||
|
||||
#if NWSMUX > 0
|
||||
if (sc->sc_mux != NULL) {
|
||||
if (sc->sc_base.me_parent != NULL)
|
||||
/* Grab the mouse out of the greedy hands of the mux. */
|
||||
error = wsmouse_rem_mux(unit, sc->sc_mux);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
wsmux_detach_sc(&sc->sc_base);
|
||||
#endif
|
||||
|
||||
if (sc->sc_events.io) /* and that it's not in use */
|
||||
if (sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
sc->sc_events.io = p;
|
||||
wsevent_init(&sc->sc_events); /* may cause sleep */
|
||||
evar = wsevent_alloc();
|
||||
sc->sc_base.me_evp = evar;
|
||||
evar->io = p;
|
||||
|
||||
sc->sc_ready = 1; /* start accepting events */
|
||||
sc->sc_x = INVALID_X;
|
||||
sc->sc_y = INVALID_Y;
|
||||
sc->sc_z = INVALID_Z;
|
||||
|
||||
/* enable the device, and punt if that's not possible */
|
||||
error = (*sc->sc_accessops->enable)(sc->sc_accesscookie);
|
||||
error = wsmousedoopen(sc, evar);
|
||||
if (error) {
|
||||
sc->sc_ready = 0; /* stop accepting events */
|
||||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
return (error);
|
||||
DPRINTF(("wsmouseopen: %s open failed\n",
|
||||
sc->sc_base.me_dv.dv_xname));
|
||||
sc->sc_base.me_evp = NULL;
|
||||
wsevent_free(evar);
|
||||
}
|
||||
|
||||
return (0);
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wsmouseclose(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
return (wsmousedoclose(wsmouse_cd.cd_devs[minor(dev)],
|
||||
flags, mode, p));
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
#if NWSMOUSE > 0
|
||||
int
|
||||
wsmousedoclose(struct device *dv, int flags, int mode, struct proc *p)
|
||||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)dv;
|
||||
|
||||
if ((flags & (FREAD | FWRITE)) == FWRITE)
|
||||
return (0); /* see wsmouseopen() */
|
||||
struct wsmouse_softc *sc =
|
||||
(struct wsmouse_softc *)wsmouse_cd.cd_devs[minor(dev)];
|
||||
struct wseventvar *evar = sc->sc_base.me_evp;
|
||||
|
||||
if (evar == NULL)
|
||||
/* not open for read */
|
||||
return (0);
|
||||
sc->sc_base.me_evp = NULL;
|
||||
(*sc->sc_accessops->disable)(sc->sc_accesscookie);
|
||||
wsevent_free(evar);
|
||||
|
||||
sc->sc_ready = 0; /* stop accepting events */
|
||||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
return (0);
|
||||
}
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
|
||||
int
|
||||
wsmousedoopen(struct wsmouse_softc *sc, struct wseventvar *evp)
|
||||
{
|
||||
sc->sc_base.me_evp = evp;
|
||||
sc->sc_x = INVALID_X;
|
||||
sc->sc_y = INVALID_Y;
|
||||
sc->sc_z = INVALID_Z;
|
||||
|
||||
/* enable the device, and punt if that's not possible */
|
||||
return (*sc->sc_accessops->enable)(sc->sc_accesscookie);
|
||||
}
|
||||
|
||||
int
|
||||
wsmouseread(dev_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
struct wsmouse_softc *sc = wsmouse_cd.cd_devs[minor(dev)];
|
||||
int error;
|
||||
|
||||
if (sc->sc_dying)
|
||||
return (EIO);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_base.me_evp == NULL) {
|
||||
printf("wsmouseread: evp == NULL\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
sc->sc_refcnt++;
|
||||
error = wsevent_read(&sc->sc_events, uio, flags);
|
||||
error = wsevent_read(sc->sc_base.me_evp, uio, flags);
|
||||
if (--sc->sc_refcnt < 0) {
|
||||
wakeup(sc);
|
||||
error = EIO;
|
||||
}
|
||||
return (error);
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
int
|
||||
wsmouseioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
return (wsmousedoioctl(wsmouse_cd.cd_devs[minor(dev)],
|
||||
cmd, data, flag, p));
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
#if NWSMOUSE > 0
|
||||
/* A wrapper around the ioctl() workhorse to make reference counting easy. */
|
||||
int
|
||||
wsmousedoioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
|
||||
@ -569,11 +568,15 @@ wsmouse_do_ioctl(struct wsmouse_softc *sc, u_long cmd, caddr_t data,
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
sc->sc_events.async = *(int *)data != 0;
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
sc->sc_base.me_evp->async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != sc->sc_events.io->p_pgid)
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
if (*(int *)data != sc->sc_base.me_evp->io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
}
|
||||
@ -586,21 +589,40 @@ wsmouse_do_ioctl(struct wsmouse_softc *sc, u_long cmd, caddr_t data,
|
||||
data, flag, p);
|
||||
return (error != -1 ? error : ENOTTY);
|
||||
}
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
|
||||
int
|
||||
wsmousepoll(dev_t dev, int events, struct proc *p)
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
struct wsmouse_softc *sc = wsmouse_cd.cd_devs[minor(dev)];
|
||||
|
||||
return (wsevent_poll(&sc->sc_events, events, p));
|
||||
#else
|
||||
return (0);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
if (sc->sc_base.me_evp == NULL)
|
||||
return (EINVAL);
|
||||
return (wsevent_poll(sc->sc_base.me_evp, events, p));
|
||||
}
|
||||
|
||||
#if NWSMUX > 0
|
||||
int
|
||||
wsmouse_mux_open(struct wsevsrc *me, struct wseventvar *evp)
|
||||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)me;
|
||||
|
||||
if (sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
return wsmousedoopen(sc, evp);
|
||||
}
|
||||
|
||||
int
|
||||
wsmouse_mux_close(struct wsevsrc *me)
|
||||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)me;
|
||||
|
||||
sc->sc_base.me_evp = NULL;
|
||||
(*sc->sc_accessops->disable)(sc->sc_accesscookie);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
wsmouse_add_mux(int unit, struct wsmux_softc *muxsc)
|
||||
{
|
||||
@ -610,23 +632,9 @@ wsmouse_add_mux(int unit, struct wsmux_softc *muxsc)
|
||||
(sc = wsmouse_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
if (sc->sc_mux || sc->sc_events.io)
|
||||
if (sc->sc_base.me_parent != NULL || sc->sc_base.me_evp != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
return (wsmux_attach_sc(muxsc, WSMUX_MOUSE, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wsmouse_muxops));
|
||||
return (wsmux_attach_sc(muxsc, &sc->sc_base));
|
||||
}
|
||||
|
||||
int
|
||||
wsmouse_rem_mux(int unit, struct wsmux_softc *muxsc)
|
||||
{
|
||||
struct wsmouse_softc *sc;
|
||||
|
||||
if (unit < 0 || unit >= wsmouse_cd.cd_ndevs ||
|
||||
(sc = wsmouse_cd.cd_devs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
return (wsmux_detach_sc(muxsc, &sc->sc_dv));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* NWSMUX > 0 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsmuxvar.h,v 1.3 2001/10/13 15:56:16 augustss Exp $ */
|
||||
/* $NetBSD: wsmuxvar.h,v 1.4 2001/10/24 14:07:33 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -36,52 +36,58 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct wsdisplay_softc;
|
||||
struct wsplink;
|
||||
/*
|
||||
* A ws event source, i.e., wskbd, wsmouse, or wsmux.
|
||||
*/
|
||||
struct wsevsrc {
|
||||
struct device me_dv;
|
||||
const struct wssrcops *me_ops; /* method pointers */
|
||||
struct wseventvar *me_evp; /* our wseventvar when open */
|
||||
#if NWSDISPLAY > 0
|
||||
struct device *me_dispdv; /* our display if part of one */
|
||||
#endif
|
||||
#if NWSMUX > 0
|
||||
struct wsmux_softc *me_parent; /* parent mux device */
|
||||
CIRCLEQ_ENTRY(wsevsrc) me_next; /* sibling pointers */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Methods that can be performed on an events source. Usually called
|
||||
* from a wsmux.
|
||||
*/
|
||||
struct wssrcops {
|
||||
int type; /* device type: WSMUX_{MOUSE,KBD,MUX} */
|
||||
int (*dopen)(struct wsevsrc *, struct wseventvar *);
|
||||
int (*dclose)(struct wsevsrc *);
|
||||
int (*dioctl)(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
int (*ddispioctl)(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
int (*dsetdisplay)(struct device *, struct wsevsrc *);
|
||||
};
|
||||
|
||||
#define wsevsrc_ioctl(me, cmd, data, flag, p) \
|
||||
((me)->me_ops->dioctl(&(me)->me_dv, cmd, (caddr_t)data, flag, p))
|
||||
#define wsevsrc_display_ioctl(me, cmd, data, flag, p) \
|
||||
((me)->me_ops->ddispioctl(&(me)->me_dv, cmd, (caddr_t)data, flag, p))
|
||||
#define wsevsrc_set_display(me, arg) \
|
||||
((me)->me_ops->dsetdisplay(&(me)->me_dv, arg))
|
||||
|
||||
#if NWSMUX > 0
|
||||
struct wsmux_softc {
|
||||
struct device sc_dv;
|
||||
struct wseventvar sc_events; /* event queue state */
|
||||
int sc_flags, sc_mode; /* open flags */
|
||||
struct wsevsrc sc_base;
|
||||
struct proc *sc_p; /* open proc */
|
||||
LIST_HEAD(, wsplink) sc_reals; /* list of real devices */
|
||||
struct wsmux_softc *sc_mux; /* if part of another mux */
|
||||
struct device *sc_displaydv; /* our display if part of one */
|
||||
CIRCLEQ_HEAD(, wsevsrc) sc_cld; /* list of children */
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
int sc_rawkbd; /* A hack to remember the kbd mode */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct wsmuxops {
|
||||
int (*dopen)(dev_t, int, int, struct proc *);
|
||||
int (*dclose)(struct device *, int, int, struct proc *);
|
||||
int (*dioctl)(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
int (*ddispioctl)(struct device *, u_long, caddr_t, int, struct proc *);
|
||||
int (*dsetdisplay)(struct device *, struct wsmux_softc *);
|
||||
};
|
||||
struct wsmux_softc *wsmux_getmux(int);
|
||||
struct wsmux_softc *wsmux_create(const char *, int);
|
||||
int wsmux_attach_sc(struct wsmux_softc *, struct wsevsrc *);
|
||||
void wsmux_detach_sc(struct wsevsrc *);
|
||||
|
||||
struct wsmux_softc *wsmux_getmux(int);
|
||||
struct wsmux_softc *wsmux_create(const char *, int);
|
||||
int wsmux_attach_sc(
|
||||
struct wsmux_softc *,
|
||||
int, struct device *, struct wseventvar *,
|
||||
struct wsmux_softc **,
|
||||
struct wsmuxops *);
|
||||
int wsmux_detach_sc(struct wsmux_softc *, struct device *);
|
||||
void wsmux_attach(
|
||||
int, int, struct device *, struct wseventvar *,
|
||||
struct wsmux_softc **,
|
||||
struct wsmuxops *);
|
||||
void wsmux_detach(int, struct device *);
|
||||
|
||||
int wsmux_displayioctl(struct device *dev, u_long cmd,
|
||||
caddr_t data, int flag, struct proc *p);
|
||||
|
||||
int wsmuxdoioctl(struct device *, u_long, caddr_t,int,struct proc *);
|
||||
|
||||
int wsmux_add_mux(int, struct wsmux_softc *);
|
||||
int wsmux_rem_mux(int, struct wsmux_softc *);
|
||||
int wskbd_add_mux(int, struct wsmux_softc *);
|
||||
int wskbd_rem_mux(int, struct wsmux_softc *);
|
||||
int wsmouse_add_mux(int, struct wsmux_softc *);
|
||||
int wsmouse_rem_mux(int, struct wsmux_softc *);
|
||||
|
||||
#endif /* NWSMUX > 0 */
|
||||
|
Loading…
Reference in New Issue
Block a user