Add the wsmux pseudo device.
This commit is contained in:
parent
d7f9efdafc
commit
3d3f77c49e
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.94 1999/07/17 07:09:40 itojun Exp $
|
||||
# $NetBSD: Makefile,v 1.95 1999/07/29 18:22:03 augustss Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
|
||||
MAN= ahb.4 ahc.4 aria.4 atalk.4 audio.4 bha.4 bpf.4 ccd.4 cd.4 ch.4 \
|
||||
|
@ -10,8 +10,8 @@ MAN= ahb.4 ahc.4 aria.4 atalk.4 audio.4 bha.4 bpf.4 ccd.4 cd.4 ch.4 \
|
|||
pcscp.4 pms.4 ppp.4 pty.4 puc.4 qsphy.4 raid.4 rnd.4 route.4 rtpphy.4 \
|
||||
scsi.4 sd.4 sl.4 sm.4 spp.4 sqphy.4 ss.4 st.4 sv.4 strip.4 tb.4 tcp.4 \
|
||||
termios.4 tl.4 tlphy.4 tp.4 tr.4 tty.4 tun.4 udp.4 uha.4 uk.4 unix.4 \
|
||||
vga.4 vnd.4 wd.4 wdc.4 wscons.4 wsdisplay.4 wskbd.4 wsmouse.4 ym.4 \
|
||||
zstty.4
|
||||
vga.4 vnd.4 wd.4 wdc.4 wscons.4 wsdisplay.4 wskbd.4 wsmouse.4 wsmux.4 \
|
||||
ym.4 zstty.4
|
||||
|
||||
# USB devices
|
||||
MAN+= uaudio.4 ugen.4 uhid.4 ukbd.4 ulpt.4 ums.4 usb.4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: wscons.4,v 1.8 1999/04/13 20:25:29 augustss Exp $
|
||||
.\" $NetBSD: wscons.4,v 1.9 1999/07/29 18:22:04 augustss Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -49,9 +49,11 @@
|
|||
.Cd options WSDISPLAY_COMPAT_USL
|
||||
.Cd options WSDISPLAY_COMPAT_RAWKBD
|
||||
|
||||
.Cd wsdisplay* at ...
|
||||
.Cd wskbd* at ...
|
||||
.Cd wsmouse* at ...
|
||||
.Cd "wsdisplay* at ..."
|
||||
.Cd "wskbd* at ... mux N"
|
||||
.Cd "wsmouse* at ... mux N"
|
||||
|
||||
.Cd pseudo-device wsmux N
|
||||
.Pp
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
|
@ -67,6 +69,9 @@ hardware support for display adapters, keyboards and mice, see
|
|||
.Xr wskbd 4 , and
|
||||
.Xr wsmouse 4
|
||||
.It
|
||||
input event multiplexor, see
|
||||
.Xr wsmux 4
|
||||
.It
|
||||
terminal emulation modules (see below), and
|
||||
.It
|
||||
compatibility options to support control operations and other low-level
|
||||
|
@ -161,12 +166,12 @@ emulator.
|
|||
.El
|
||||
.Pp
|
||||
The
|
||||
.Cd WSEMUL_DEFAULT
|
||||
.Va WSEMUL_DEFAULT
|
||||
kernel option allows to select one of the described terminal options
|
||||
as default choice. The default gets into effect in kernel startup, i.e.
|
||||
for the operating system console or additional screens allocated
|
||||
through the
|
||||
.Cd WSDISPLAY_DEFAULTSCREENS
|
||||
.Va WSDISPLAY_DEFAULTSCREENS
|
||||
option (see
|
||||
.Xr wsdisplay 4
|
||||
), or if no emulation type was passed to the
|
||||
|
@ -254,6 +259,7 @@ This man page is still extremely incomplete.
|
|||
.Xr wsdisplay 4 ,
|
||||
.Xr wskbd 4 ,
|
||||
.Xr wsmouse 4 ,
|
||||
.Xr wsmux 4 ,
|
||||
.Xr wsconscfg 8 ,
|
||||
.Xr wsconsctl 8 ,
|
||||
.Xr wsfontload 8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: wskbd.4,v 1.2 1999/04/08 16:29:56 drochner Exp $
|
||||
.\" $NetBSD: wskbd.4,v 1.3 1999/07/29 18:22:04 augustss Exp $
|
||||
|
||||
.Dd March 20, 1999
|
||||
.Os
|
||||
|
@ -8,13 +8,13 @@
|
|||
.Nd generic keyboard support in wscons
|
||||
|
||||
.Sh SYNOPSIS
|
||||
.Cd "wskbd* at pckbd? console ?"
|
||||
.Cd "wskbd* at pckbd? console ? mux 1"
|
||||
(standard PC keyboard)
|
||||
.Cd "wskbd* at ukbd? console ?"
|
||||
.Cd "wskbd* at ukbd? console ? mux 1"
|
||||
(USB keyboard)
|
||||
.Cd "wskbd0 at akbd? console ?"
|
||||
.Cd "wskbd0 at akbd? console ? mux 1"
|
||||
(Apple ADB keyboard)
|
||||
.Cd "wskbd0 at nextkbd? console ?"
|
||||
.Cd "wskbd0 at nextkbd? console ? mux 1"
|
||||
(NeXT keyboard)
|
||||
|
||||
.Sh DESCRIPTION
|
||||
|
@ -85,19 +85,9 @@ wskbd device instance.
|
|||
.Pa /usr/include/dev/wscons/wsconsio.h .
|
||||
.El
|
||||
|
||||
.Sh BUGS
|
||||
.Dq wskbd
|
||||
devices are connected logically to
|
||||
.Dq wsdisplay
|
||||
devices at boot time. There is little support for hot insertion and
|
||||
removal. It is not possible to feed a
|
||||
.Dq wsdisplay
|
||||
from multiple
|
||||
.Dq wskbd
|
||||
devices.
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr wscons 4 ,
|
||||
.Xr wsconsctl 8 ,
|
||||
.Xr wsmux 4 ,
|
||||
.Xr pckbd 4 ,
|
||||
.Xr ukbd 4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: wsmouse.4,v 1.1 1999/03/22 19:15:03 drochner Exp $
|
||||
.\" $NetBSD: wsmouse.4,v 1.2 1999/07/29 18:22:04 augustss Exp $
|
||||
|
||||
.Dd March 20, 1999
|
||||
.Os
|
||||
|
@ -8,19 +8,19 @@
|
|||
.Nd generic mouse support in wscons
|
||||
|
||||
.Sh SYNOPSIS
|
||||
.Cd "wsmouse* at pms?"
|
||||
.Cd "wsmouse* at pms? mux 0"
|
||||
(PS/2 mouse)
|
||||
.Cd "wsmouse* at pmsi?"
|
||||
.Cd "wsmouse* at pmsi? mux 0"
|
||||
(
|
||||
.Dq Intellimouse
|
||||
-compatible wheel mouse with PS/2 interface)
|
||||
.Cd "wsmouse* at ums?"
|
||||
.Cd "wsmouse* at ums? mux 0"
|
||||
(USB mouse)
|
||||
.Cd "wsmouse* at lms?"
|
||||
.Cd "wsmouse* at lms? mux 0"
|
||||
(Logitech bus mouse, i386 only)
|
||||
.Cd "wsmouse* at mms?"
|
||||
.Cd "wsmouse* at mms? mux 0"
|
||||
(Microsoft InPort mouse, i386 only)
|
||||
.Cd "wsmouse0 at ams?"
|
||||
.Cd "wsmouse0 at ams? mux 0"
|
||||
(Apple ADB mouse)
|
||||
|
||||
.Sh DESCRIPTION
|
||||
|
@ -57,6 +57,7 @@ removal.
|
|||
.Sh SEE ALSO
|
||||
.Xr wscons 4 ,
|
||||
.Xr wsconsctl 8 ,
|
||||
.Xr wsmux 4 ,
|
||||
.Xr pms 4 ,
|
||||
.Xr lms 4 ,
|
||||
.Xr mms 4 ,
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
.\" $NetBSD: wsmux.4,v 1.1 1999/07/29 18:22:04 augustss Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 26, 1999
|
||||
.Dt WSMUX 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm wsmux
|
||||
.Nd console keyboard/mouse multiplexor
|
||||
.Sh SYNOPSIS
|
||||
.Cd "wskbd* at ... mux N"
|
||||
.Cd "wsmouse* at ... mux N"
|
||||
|
||||
.Cd pseudo-device wsmux N
|
||||
.Pp
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
is a pseudo-device driver that allows several
|
||||
.Xr wscons 4
|
||||
input devices to have their events multiplexed into one stream.
|
||||
.Pp
|
||||
The typical usage for this device is to have two multiplexors, one
|
||||
for mouse events and one for keyboard events. All
|
||||
.Xr wsmouse 4
|
||||
devices should direct their events to the mouse mux (normally 0)
|
||||
and all keyboard devices, except the console, should direct their
|
||||
events to the keyboard mux (normally 1). A device will
|
||||
send its events to the mux indicated my the
|
||||
.Va mux
|
||||
locator. If none is given the device will not use a multiplexor.
|
||||
The keyboard multiplexor should be connected to the display, using
|
||||
the
|
||||
.Xr wsconscfg 8
|
||||
command. It will then recieve all keystrokes from all keyboards
|
||||
and, furthermore, keyboards can be dynamically attached and detached without
|
||||
further user interaction.
|
||||
In a similar way, the window system will open the mouse multiplexor
|
||||
and recieve all mouse events; mice can also be dynamically attached
|
||||
and detached.
|
||||
.Pp
|
||||
It is also possible to inject events into a multiplexor from a
|
||||
user program. This is used by the
|
||||
.Xr moused 8
|
||||
deamon to take data from a mouse connected to a serial port and
|
||||
make it appear on the standard mouse mux.
|
||||
.Pp
|
||||
.Sh FILES
|
||||
.Bl -item
|
||||
.It
|
||||
.Pa /dev/wsmouse
|
||||
.It
|
||||
.Pa /dev/wskbd
|
||||
.It
|
||||
.Pa /usr/include/dev/wscons/wsconsio.h .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr moused 8 ,
|
||||
.Xr wscons 4 ,
|
||||
.Xr wsdisplay 4 ,
|
||||
.Xr wskbd 4 ,
|
||||
.Xr wsmouse 4 ,
|
||||
.Xr wsconscfg 8 ,
|
||||
.Xr wsconsctl 8 ,
|
||||
.Xr wsfontload 8
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.wscons,v 1.15 1999/05/15 14:22:46 drochner Exp $
|
||||
# $NetBSD: files.wscons,v 1.16 1999/07/29 18:20:02 augustss Exp $
|
||||
|
||||
#
|
||||
# "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
|
||||
|
@ -52,3 +52,6 @@ file dev/rcons/raster_op.c wsrasteremulops
|
|||
file dev/rcons/raster_text.c wsrasteremulops
|
||||
file dev/wscons/wscons_rinit.c wsrasteremulops
|
||||
file dev/wscons/wscons_rops.c wsrasteremulops
|
||||
|
||||
defpseudo wsmux
|
||||
file dev/wscons/wsmux.c wsmux | wsdisplay needs-count
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wscons_callbacks.h,v 1.9 1999/05/15 14:22:46 drochner Exp $ */
|
||||
/* $NetBSD: wscons_callbacks.h,v 1.10 1999/07/29 18:20:02 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -53,12 +53,7 @@ void wsdisplay_set_cons_kbd __P((int (*get)(dev_t),
|
|||
/*
|
||||
* Calls to the keyboard interface from the glue code.
|
||||
*/
|
||||
int wskbd_set_display __P((int, struct device *, struct device **));
|
||||
struct device *wskbd_set_console_display __P((struct device *));
|
||||
struct wsmux_softc;
|
||||
struct device *wskbd_set_console_display
|
||||
__P((struct device *, struct wsmux_softc *));
|
||||
int wskbd_pickfree __P((void));
|
||||
|
||||
/*
|
||||
* Calls to the keyboard interface from the display interface.
|
||||
*/
|
||||
int wskbd_displayioctl __P((struct device *dev, u_long cmd,
|
||||
caddr_t data, int flag, struct proc *p));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wsconsio.h,v 1.18 1999/05/15 14:22:46 drochner Exp $ */
|
||||
/* $NetBSD: wsconsio.h,v 1.19 1999/07/29 18:20:02 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -295,15 +295,36 @@ struct wsdisplay_usefontdata {
|
|||
};
|
||||
#define WSDISPLAYIO_USEFONT _IOW('W', 80, struct wsdisplay_usefontdata)
|
||||
|
||||
/* Replaced by WSMUX_{ADD,REMOVE}_DEVICE */
|
||||
struct wsdisplay_kbddata {
|
||||
int op;
|
||||
#define WSDISPLAY_KBD_ADD 0
|
||||
#define WSDISPLAY_KBD_DEL 1
|
||||
#define _O_WSDISPLAY_KBD_ADD 0
|
||||
#define _O_WSDISPLAY_KBD_DEL 1
|
||||
int idx;
|
||||
};
|
||||
#define WSDISPLAYIO_SETKEYBOARD _IOWR('W', 81, struct wsdisplay_kbddata)
|
||||
#define _O_WSDISPLAYIO_SETKEYBOARD _IOWR('W', 81, struct wsdisplay_kbddata)
|
||||
|
||||
/* XXX NOT YET DEFINED */
|
||||
/* Mapping information retrieval. */
|
||||
|
||||
/* Mux ioctls (96 - 127) */
|
||||
#define WSMUX_INJECTEVENT _IOW('W', 96, struct wscons_event)
|
||||
|
||||
struct wsmux_device {
|
||||
int type;
|
||||
#define WSMUX_MOUSE 1
|
||||
#define WSMUX_KBD 2
|
||||
#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 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)
|
||||
|
||||
#endif /* _DEV_WSCONS_WSCONSIO_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wsdisplay.c,v 1.25 1999/05/17 16:53:43 drochner Exp $ */
|
||||
/* $NetBSD: wsdisplay.c,v 1.26 1999/07/29 18:20:02 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -33,7 +33,7 @@
|
|||
static const char _copyright[] __attribute__ ((unused)) =
|
||||
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
|
||||
static const char _rcsid[] __attribute__ ((unused)) =
|
||||
"$NetBSD: wsdisplay.c,v 1.25 1999/05/17 16:53:43 drochner Exp $";
|
||||
"$NetBSD: wsdisplay.c,v 1.26 1999/07/29 18:20:02 augustss Exp $";
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -60,6 +60,12 @@ static const char _rcsid[] __attribute__ ((unused)) =
|
|||
|
||||
#include "opt_wsdisplay_compat.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;
|
||||
|
@ -124,7 +130,7 @@ struct wsdisplay_softc {
|
|||
int sc_screenwanted, sc_oldscreen; /* valid with SC_SWITCHPENDING */
|
||||
|
||||
#if NWSKBD > 0
|
||||
struct device *sc_kbddv;
|
||||
struct wsmux_softc *sc_muxdv;
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
int sc_rawkbd;
|
||||
#endif
|
||||
|
@ -566,6 +572,14 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
|
|||
void *accesscookie;
|
||||
{
|
||||
int i = 0;
|
||||
#if NWSKBD > 0
|
||||
struct device *dv;
|
||||
|
||||
sc->sc_muxdv = wsmux_create("dmux", sc->sc_dv.dv_unit);
|
||||
if (!sc->sc_muxdv)
|
||||
panic("wsdisplay_common_attach: no memory\n");
|
||||
sc->sc_muxdv->sc_displaydv = &sc->sc_dv;
|
||||
#endif
|
||||
|
||||
sc->sc_isconsole = console;
|
||||
|
||||
|
@ -581,8 +595,8 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
|
|||
wsdisplay_console_conf.wsemul->name);
|
||||
|
||||
#if NWSKBD > 0
|
||||
if ((sc->sc_kbddv = wskbd_set_console_display(&sc->sc_dv)))
|
||||
printf(", using %s", sc->sc_kbddv->dv_xname);
|
||||
if ((dv = wskbd_set_console_display(&sc->sc_dv, sc->sc_muxdv)))
|
||||
printf(", using %s", dv->dv_xname);
|
||||
#endif
|
||||
|
||||
sc->sc_focusidx = 0;
|
||||
|
@ -861,13 +875,13 @@ wsdisplayioctl(dev, cmd, data, flag, p)
|
|||
/* do the line discipline ioctls first */
|
||||
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
return (error);
|
||||
|
||||
/* printf("tty\n"); */
|
||||
/* then the tty ioctls */
|
||||
error = ttioctl(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_USL
|
||||
|
@ -894,23 +908,20 @@ wsdisplay_internal_ioctl(sc, scr, cmd, data, flag, p)
|
|||
struct wsdisplay_font fd;
|
||||
|
||||
#if NWSKBD > 0
|
||||
if (sc->sc_kbddv != NULL) {
|
||||
/* check ioctls for keyboard */
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
switch (cmd) {
|
||||
case WSKBDIO_SETMODE:
|
||||
scr->scr_rawkbd = (*(int *)data == WSKBD_RAW);
|
||||
return (wsdisplay_update_rawkbd(sc, scr));
|
||||
case WSKBDIO_GETMODE:
|
||||
*(int *)data = (scr->scr_rawkbd ?
|
||||
WSKBD_RAW : WSKBD_TRANSLATED);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
error = wskbd_displayioctl(sc->sc_kbddv, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
switch (cmd) {
|
||||
case WSKBDIO_SETMODE:
|
||||
scr->scr_rawkbd = (*(int *)data == WSKBD_RAW);
|
||||
return (wsdisplay_update_rawkbd(sc, scr));
|
||||
case WSKBDIO_GETMODE:
|
||||
*(int *)data = (scr->scr_rawkbd ?
|
||||
WSKBD_RAW : WSKBD_TRANSLATED);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
error = wsmux_displayioctl(&sc->sc_muxdv->sc_dv, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
#endif /* NWSKBD > 0 */
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -972,8 +983,8 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
|
|||
int error;
|
||||
char *type, typebuf[16], *emul, emulbuf[16];
|
||||
void *buf;
|
||||
#if NWSKBD > 0
|
||||
struct device *kbddv;
|
||||
#if defined(COMPAT_14) && NWSKBD > 0
|
||||
struct wsmux_device wsmuxdata;
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -988,7 +999,7 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
|
|||
} else
|
||||
type = 0;
|
||||
if (d->emul) {
|
||||
error = copyinstr(d->emul, emulbuf, sizeof(emulbuf), 0);
|
||||
error = copyinstr(d->emul, emulbuf, sizeof(emulbuf),0);
|
||||
if (error)
|
||||
return (error);
|
||||
emul = emulbuf;
|
||||
|
@ -1028,37 +1039,43 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
|
|||
return (error);
|
||||
|
||||
#if NWSKBD > 0
|
||||
case WSDISPLAYIO_SETKEYBOARD:
|
||||
#ifdef COMPAT_14
|
||||
case _O_WSDISPLAYIO_SETKEYBOARD:
|
||||
#define d ((struct wsdisplay_kbddata *)data)
|
||||
switch (d->op) {
|
||||
case WSDISPLAY_KBD_ADD:
|
||||
if (sc->sc_kbddv)
|
||||
return (EBUSY);
|
||||
case _O_WSDISPLAY_KBD_ADD:
|
||||
if (d->idx == -1) {
|
||||
d->idx = wskbd_pickfree();
|
||||
if (d->idx == -1)
|
||||
return (ENXIO);
|
||||
}
|
||||
error = wskbd_set_display(d->idx, &sc->sc_dv, &kbddv);
|
||||
if (error)
|
||||
return (error);
|
||||
sc->sc_kbddv = kbddv;
|
||||
return (0);
|
||||
case WSDISPLAY_KBD_DEL:
|
||||
if (sc->sc_kbddv == NULL)
|
||||
return (ENXIO);
|
||||
if (d->idx == -1)
|
||||
d->idx = sc->sc_kbddv->dv_unit;
|
||||
error = wskbd_set_display(d->idx, 0, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
sc->sc_kbddv = NULL;
|
||||
return (0);
|
||||
wsmuxdata.type = WSMUX_KBD;
|
||||
wsmuxdata.idx = d->idx;
|
||||
return (wsmuxdoioctl(&sc->sc_muxdv->sc_dv,
|
||||
WSMUX_ADD_DEVICE,
|
||||
(caddr_t)&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));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
#undef d
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
case WSMUX_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));
|
||||
#endif /* NWSKBD > 0 */
|
||||
|
||||
}
|
||||
|
@ -1289,15 +1306,14 @@ wsdisplay_update_rawkbd(sc, scr)
|
|||
|
||||
raw = (scr ? scr->scr_rawkbd : 0);
|
||||
|
||||
if (!sc->sc_kbddv ||
|
||||
scr != sc->sc_focus ||
|
||||
if (scr != sc->sc_focus ||
|
||||
sc->sc_rawkbd == raw) {
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
data = (raw ? WSKBD_RAW : WSKBD_TRANSLATED);
|
||||
error = wskbd_displayioctl(sc->sc_kbddv, WSKBDIO_SETMODE,
|
||||
data = raw ? WSKBD_RAW : WSKBD_TRANSLATED;
|
||||
error = wsmux_displayioctl(&sc->sc_muxdv->sc_dv, WSKBDIO_SETMODE,
|
||||
(caddr_t)&data, 0, 0);
|
||||
if (!error)
|
||||
sc->sc_rawkbd = raw;
|
||||
|
@ -1609,7 +1625,8 @@ wsdisplay_set_console_kbd(kbddv)
|
|||
{
|
||||
if (!wsdisplay_console_device)
|
||||
return (0);
|
||||
wsdisplay_console_device->sc_kbddv = kbddv;
|
||||
if (wskbd_add_mux(kbddv->dv_unit, wsdisplay_console_device->sc_muxdv))
|
||||
return (0);
|
||||
return (&wsdisplay_console_device->sc_dv);
|
||||
}
|
||||
#endif /* NWSKBD > 0 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wskbd.c,v 1.26 1999/07/06 07:42:23 augustss Exp $ */
|
||||
/* $NetBSD: wskbd.c,v 1.27 1999/07/29 18:20:03 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -36,7 +36,7 @@
|
|||
static const char _copyright[] __attribute__ ((unused)) =
|
||||
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
|
||||
static const char _rcsid[] __attribute__ ((unused)) =
|
||||
"$NetBSD: wskbd.c,v 1.26 1999/07/06 07:42:23 augustss Exp $";
|
||||
"$NetBSD: wskbd.c,v 1.27 1999/07/29 18:20:03 augustss Exp $";
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -114,6 +114,18 @@ static const char _rcsid[] __attribute__ ((unused)) =
|
|||
#include "opt_wsdisplay_compat.h"
|
||||
|
||||
#include "wsdisplay.h"
|
||||
#include "wsmux.h"
|
||||
|
||||
#ifdef WSKBD_DEBUG
|
||||
#define DPRINTF(x) if (wskbddebug) printf x
|
||||
int wskbddebug = 0;
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
#endif
|
||||
|
||||
struct wskbd_internal {
|
||||
const struct wskbd_mapdata *t_keymap;
|
||||
|
@ -161,6 +173,9 @@ 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)
|
||||
|
@ -191,6 +206,10 @@ void wskbd_attach __P((struct device *, struct device *, void *));
|
|||
int wskbd_detach __P((struct device *, int));
|
||||
int wskbd_activate __P((struct device *, enum devact));
|
||||
|
||||
static int wskbd_displayioctl
|
||||
__P((struct device *, u_long, caddr_t, int, struct proc *p));
|
||||
int wskbd_set_display __P((struct device *, struct wsmux_softc *));
|
||||
|
||||
static inline void update_leds __P((struct wskbd_internal *));
|
||||
static inline void update_modifier __P((struct wskbd_internal *, u_int, int, int));
|
||||
static int internal_command __P((struct wskbd_softc *, u_int *, keysym_t));
|
||||
|
@ -203,6 +222,10 @@ static void wskbd_holdscreen __P((struct wskbd_softc *, int));
|
|||
int wskbd_do_ioctl __P((struct wskbd_softc *, u_long, caddr_t,
|
||||
int, struct proc *));
|
||||
|
||||
int wskbddoclose __P((struct device *, int, int, struct proc *));
|
||||
int wskbddoioctl __P((struct device *, u_long, caddr_t, int,
|
||||
struct proc *));
|
||||
|
||||
struct cfattach wskbd_ca = {
|
||||
sizeof (struct wskbd_softc), wskbd_match, wskbd_attach,
|
||||
wskbd_detach, wskbd_activate
|
||||
|
@ -242,6 +265,11 @@ struct wskbd_keyrepeat_data wskbd_default_keyrepeat_data = {
|
|||
|
||||
cdev_decl(wskbd);
|
||||
|
||||
struct wsmuxops wskbd_muxops = {
|
||||
wskbdopen, wskbddoclose, wskbddoioctl, wskbd_displayioctl,
|
||||
wskbd_set_display
|
||||
};
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
static void wskbd_repeat __P((void *v));
|
||||
#endif
|
||||
|
@ -301,26 +329,24 @@ wskbd_attach(parent, self, aux)
|
|||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)self;
|
||||
struct wskbddev_attach_args *ap = aux;
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
int mux;
|
||||
#endif
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
sc->sc_displaydv = NULL;
|
||||
#endif
|
||||
sc->sc_isconsole = ap->console;
|
||||
|
||||
if (ap->console) {
|
||||
KASSERT(wskbd_console_initted);
|
||||
KASSERT(wskbd_console_device == NULL);
|
||||
|
||||
wskbd_console_device = sc;
|
||||
|
||||
printf(": console keyboard");
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
if ((sc->sc_displaydv = wsdisplay_set_console_kbd(self)))
|
||||
printf(", using %s", sc->sc_displaydv->dv_xname);
|
||||
#endif
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
mux = sc->sc_dv.dv_cfdata->wskbddevcf_mux;
|
||||
if (sc->sc_isconsole && mux != WSKBDDEVCF_MUX_DEFAULT) {
|
||||
printf(" (mux ignored for console)");
|
||||
mux = WSKBDDEVCF_MUX_DEFAULT;
|
||||
}
|
||||
printf("\n");
|
||||
if (mux != WSKBDDEVCF_MUX_DEFAULT)
|
||||
printf(" mux %d", mux);
|
||||
#endif
|
||||
|
||||
if (ap->console) {
|
||||
sc->id = &wskbd_console_data;
|
||||
|
@ -349,6 +375,28 @@ wskbd_attach(parent, self, aux)
|
|||
/* set default bell and key repeat data */
|
||||
sc->sc_bell_data = wskbd_default_bell_data;
|
||||
sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;
|
||||
|
||||
if (ap->console) {
|
||||
KASSERT(wskbd_console_initted);
|
||||
KASSERT(wskbd_console_device == NULL);
|
||||
|
||||
wskbd_console_device = sc;
|
||||
|
||||
printf(": console keyboard");
|
||||
|
||||
#if NWSDISPLAY > 0
|
||||
if ((sc->sc_displaydv = wsdisplay_set_console_kbd(self)))
|
||||
printf(", using %s", sc->sc_displaydv->dv_xname);
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
if (mux != WSKBDDEVCF_MUX_DEFAULT)
|
||||
wsmux_attach(mux, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wskbd_muxops);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -408,11 +456,10 @@ wskbd_activate(self, act)
|
|||
/*
|
||||
* Detach a keyboard. To keep track of users of the softc we keep
|
||||
* a reference count that's incremented while inside, e.g., read.
|
||||
* If the mouse is active and the reference count is > 0 (0 is the
|
||||
* If the keyboard is active and the reference count is > 0 (0 is the
|
||||
* normal state) we post an event and then wait for the process
|
||||
* that had the reference to wake us up again. Then we blow away the
|
||||
* vnode and return (which will deallocate the softc).
|
||||
* XXX what should we do if we are connected to a display?
|
||||
*/
|
||||
int
|
||||
wskbd_detach(self, flags)
|
||||
|
@ -423,6 +470,13 @@ wskbd_detach(self, flags)
|
|||
struct wseventvar *evar;
|
||||
int maj, mn;
|
||||
int s;
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
int mux;
|
||||
|
||||
mux = sc->sc_dv.dv_cfdata->wskbddevcf_mux;
|
||||
if (mux != WSMOUSEDEVCF_MUX_DEFAULT)
|
||||
wsmux_detach(mux, &sc->sc_dv);
|
||||
#endif
|
||||
|
||||
evar = &sc->sc_events;
|
||||
if (evar->io) {
|
||||
|
@ -503,7 +557,12 @@ wskbd_input(dev, type, value)
|
|||
if (!sc->sc_ready)
|
||||
return;
|
||||
|
||||
evar = &sc->sc_events;
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
if (sc->sc_mux)
|
||||
evar = &sc->sc_mux->sc_events;
|
||||
else
|
||||
#endif
|
||||
evar = &sc->sc_events;
|
||||
|
||||
put = evar->put;
|
||||
ev = &evar->q[put];
|
||||
|
@ -599,6 +658,11 @@ wskbdopen(dev, flags, mode, p)
|
|||
if (sc->sc_dying)
|
||||
return (EIO);
|
||||
|
||||
#if NWSMUX > 0 || NWSDISPLAY > 0
|
||||
if (sc->sc_mux)
|
||||
return (EBUSY);
|
||||
#endif
|
||||
|
||||
if (sc->sc_events.io) /* and that it's not in use */
|
||||
return (EBUSY);
|
||||
|
||||
|
@ -618,7 +682,16 @@ wskbdclose(dev, flags, mode, p)
|
|||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wskbd_softc *sc = wskbd_cd.cd_devs[minor(dev)];
|
||||
return (wskbddoclose(wskbd_cd.cd_devs[minor(dev)], flags, mode, p));
|
||||
}
|
||||
|
||||
int
|
||||
wskbddoclose(dv, flags, mode, p)
|
||||
struct device *dv;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
|
||||
|
||||
sc->sc_ready = 0; /* stop accepting events */
|
||||
sc->sc_translating = 1;
|
||||
|
@ -659,7 +732,19 @@ wskbdioctl(dev, cmd, data, flag, p)
|
|||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wskbd_softc *sc = wskbd_cd.cd_devs[minor(dev)];
|
||||
return (wskbddoioctl(wskbd_cd.cd_devs[minor(dev)], cmd, data, flag,p));
|
||||
}
|
||||
|
||||
/* A wrapper around the ioctl() workhorse to make reference counting easy. */
|
||||
int
|
||||
wskbddoioctl(dv, cmd, data, flag, p)
|
||||
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++;
|
||||
|
@ -708,7 +793,7 @@ wskbd_do_ioctl(sc, cmd, data, flag, p)
|
|||
* WSKBDIO ioctls, handled in both emulation mode and in ``raw'' mode.
|
||||
* Some of these have no real effect in raw mode, however.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
wskbd_displayioctl(dev, cmd, data, flag, p)
|
||||
struct device *dev;
|
||||
u_long cmd;
|
||||
|
@ -912,45 +997,98 @@ wskbd_pickfree()
|
|||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_set_display(idx, displaydv, kbddv)
|
||||
int idx;
|
||||
struct device *displaydv, **kbddv;
|
||||
struct device *
|
||||
wskbd_set_console_display(displaydv, muxsc)
|
||||
struct device *displaydv;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
struct wskbd_softc *sc;
|
||||
struct wskbd_softc *sc = wskbd_console_device;
|
||||
|
||||
if (idx >= wskbd_cd.cd_ndevs || /* make sure it was attached */
|
||||
(sc = wskbd_cd.cd_devs[idx]) == NULL)
|
||||
return (ENXIO);
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_set_display(dv, muxsc)
|
||||
struct device *dv;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
|
||||
struct device *displaydv = muxsc ? muxsc->sc_displaydv : 0;
|
||||
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,
|
||||
sc->sc_isconsole));
|
||||
|
||||
if (sc->sc_isconsole)
|
||||
return (EBUSY);
|
||||
|
||||
if (displaydv) {
|
||||
if (sc->sc_displaydv)
|
||||
return (EBUSY);
|
||||
printf("%s: connecting to %s\n",
|
||||
sc->sc_dv.dv_xname, displaydv->dv_xname);
|
||||
} else {
|
||||
if (sc->sc_displaydv == NULL)
|
||||
return (ENXIO);
|
||||
printf("%s: disconnecting\n", sc->sc_dv.dv_xname);
|
||||
}
|
||||
|
||||
odisplaydv = sc->sc_displaydv;
|
||||
sc->sc_displaydv = displaydv;
|
||||
wskbd_enable(sc, displaydv != NULL);
|
||||
if (kbddv)
|
||||
*kbddv = &sc->sc_dv;
|
||||
|
||||
error = wskbd_enable(sc, displaydv != NULL);
|
||||
if (error) {
|
||||
sc->sc_displaydv = odisplaydv;
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (displaydv)
|
||||
printf("%s: connecting to %s\n",
|
||||
sc->sc_dv.dv_xname, displaydv->dv_xname);
|
||||
else
|
||||
printf("%s: disconnecting from %s\n",
|
||||
sc->sc_dv.dv_xname, odisplaydv->dv_xname);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct device *
|
||||
wskbd_set_console_display(displaydv)
|
||||
struct device *displaydv;
|
||||
int
|
||||
wskbd_add_mux(unit, muxsc)
|
||||
int unit;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
if (!wskbd_console_device)
|
||||
return (0);
|
||||
wskbd_console_device->sc_displaydv = displaydv;
|
||||
return (&wskbd_console_device->sc_dv);
|
||||
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)
|
||||
return (EBUSY);
|
||||
|
||||
return (wsmux_attach_sc(muxsc, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wskbd_muxops));
|
||||
}
|
||||
|
||||
int
|
||||
wskbd_rem_mux(unit, muxsc)
|
||||
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 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wskbdvar.h,v 1.6 1998/08/02 14:18:07 drochner Exp $ */
|
||||
/* $NetBSD: wskbdvar.h,v 1.7 1999/07/29 18:20:03 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -75,6 +75,8 @@ struct wskbddev_attach_args {
|
|||
#define wskbddevcf_console cf_loc[WSKBDDEVCF_CONSOLE] /* spec'd as console? */
|
||||
#define WSKBDDEVCF_CONSOLE_UNK (WSKBDDEVCF_CONSOLE_DEFAULT)
|
||||
|
||||
#define wskbddevcf_mux cf_loc[WSKBDDEVCF_MUX]
|
||||
|
||||
/*
|
||||
* Autoconfiguration helper functions.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wsmouse.c,v 1.7 1999/06/30 06:21:21 augustss Exp $ */
|
||||
/* $NetBSD: wsmouse.c,v 1.8 1999/07/29 18:20:03 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -33,7 +33,7 @@
|
|||
static const char _copyright[] __attribute__ ((unused)) =
|
||||
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
|
||||
static const char _rcsid[] __attribute__ ((unused)) =
|
||||
"$NetBSD: wsmouse.c,v 1.7 1999/06/30 06:21:21 augustss Exp $";
|
||||
"$NetBSD: wsmouse.c,v 1.8 1999/07/29 18:20:03 augustss Exp $";
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -101,6 +101,13 @@ static const char _rcsid[] __attribute__ ((unused)) =
|
|||
#include <dev/wscons/wseventvar.h>
|
||||
|
||||
#include "wsmouse.h"
|
||||
#include "wsmux.h"
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
#endif
|
||||
|
||||
struct wsmouse_softc {
|
||||
struct device sc_dv;
|
||||
|
@ -120,6 +127,9 @@ struct wsmouse_softc {
|
|||
int sc_refcnt;
|
||||
u_char sc_dying; /* device is being detached */
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
struct wsmux_softc *sc_mux;
|
||||
#endif
|
||||
};
|
||||
|
||||
int wsmouse_match __P((struct device *, struct cfdata *, void *));
|
||||
|
@ -130,6 +140,10 @@ int wsmouse_activate __P((struct device *, enum devact));
|
|||
int wsmouse_do_ioctl __P((struct wsmouse_softc *, u_long, caddr_t,
|
||||
int, struct proc *));
|
||||
|
||||
int wsmousedoclose __P((struct device *, int, int, struct proc *));
|
||||
int wsmousedoioctl __P((struct device *, u_long, caddr_t, int,
|
||||
struct proc *));
|
||||
|
||||
struct cfattach wsmouse_ca = {
|
||||
sizeof (struct wsmouse_softc), wsmouse_match, wsmouse_attach,
|
||||
wsmouse_detach, wsmouse_activate
|
||||
|
@ -141,6 +155,10 @@ extern struct cfdriver wsmouse_cd;
|
|||
|
||||
cdev_decl(wsmouse);
|
||||
|
||||
struct wsmuxops wsmouse_muxops = {
|
||||
wsmouseopen, wsmousedoclose, wsmousedoioctl, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Print function (for parent devices).
|
||||
*/
|
||||
|
@ -171,11 +189,23 @@ wsmouse_attach(parent, self, aux)
|
|||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)self;
|
||||
struct wsmousedev_attach_args *ap = aux;
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
int mux;
|
||||
#endif
|
||||
|
||||
sc->sc_accessops = ap->accessops;
|
||||
sc->sc_accesscookie = ap->accesscookie;
|
||||
sc->sc_ready = 0; /* sanity */
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -205,9 +235,18 @@ wsmouse_detach(self, flags)
|
|||
struct wseventvar *evar;
|
||||
int maj, mn;
|
||||
int s;
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
int mux;
|
||||
#endif
|
||||
|
||||
sc->sc_dying = 1;
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
mux = sc->sc_dv.dv_cfdata->wsmousedevcf_mux;
|
||||
if (mux != WSMOUSEDEVCF_MUX_DEFAULT)
|
||||
wsmux_detach(mux, &sc->sc_dv);
|
||||
#endif
|
||||
|
||||
evar = &sc->sc_events;
|
||||
if (evar->io) {
|
||||
s = spltty();
|
||||
|
@ -253,7 +292,12 @@ wsmouse_input(wsmousedev, btns, dx, dy, dz)
|
|||
if (sc->sc_ready == 0)
|
||||
return;
|
||||
|
||||
evar = &sc->sc_events;
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
if (sc->sc_mux)
|
||||
evar = &sc->sc_mux->sc_events;
|
||||
else
|
||||
#endif
|
||||
evar = &sc->sc_events;
|
||||
|
||||
sc->sc_mb = btns;
|
||||
sc->sc_dx += dx;
|
||||
|
@ -368,6 +412,11 @@ wsmouseopen(dev, flags, mode, p)
|
|||
return (0); /* always allow open for write
|
||||
so ioctl() is possible. */
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
if (sc->sc_mux)
|
||||
return (EBUSY);
|
||||
#endif
|
||||
|
||||
if (sc->sc_events.io) /* and that it's not in use */
|
||||
return (EBUSY);
|
||||
|
||||
|
@ -398,7 +447,21 @@ wsmouseclose(dev, flags, mode, p)
|
|||
struct proc *p;
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
struct wsmouse_softc *sc = wsmouse_cd.cd_devs[minor(dev)];
|
||||
return (wsmousedoclose(wsmouse_cd.cd_devs[minor(dev)],
|
||||
flags, mode, p));
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
#if NWSMOUSE > 0
|
||||
int
|
||||
wsmousedoclose(dv, flags, mode, p)
|
||||
struct device *dv;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)dv;
|
||||
|
||||
if ((flags & (FREAD | FWRITE)) == FWRITE)
|
||||
return (0); /* see wsmouseopen() */
|
||||
|
@ -409,10 +472,8 @@ wsmouseclose(dev, flags, mode, p)
|
|||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
return (0);
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
|
||||
int
|
||||
wsmouseread(dev, uio, flags)
|
||||
|
@ -448,7 +509,24 @@ wsmouseioctl(dev, cmd, data, flag, p)
|
|||
struct proc *p;
|
||||
{
|
||||
#if NWSMOUSE > 0
|
||||
struct wsmouse_softc *sc = wsmouse_cd.cd_devs[minor(dev)];
|
||||
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(dv, cmd, data, flag, p)
|
||||
struct device *dv;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmouse_softc *sc = (struct wsmouse_softc *)dv;
|
||||
int error;
|
||||
|
||||
sc->sc_refcnt++;
|
||||
|
@ -456,12 +534,8 @@ wsmouseioctl(dev, cmd, data, flag, p)
|
|||
if (--sc->sc_refcnt < 0)
|
||||
wakeup(sc);
|
||||
return (error);
|
||||
#else
|
||||
return (ENXIO);
|
||||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
#if NWSMOUSE > 0
|
||||
int
|
||||
wsmouse_do_ioctl(sc, cmd, data, flag, p)
|
||||
struct wsmouse_softc *sc;
|
||||
|
@ -517,3 +591,37 @@ wsmousepoll(dev, events, p)
|
|||
#endif /* NWSMOUSE > 0 */
|
||||
}
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
int
|
||||
wsmouse_add_mux(unit, muxsc)
|
||||
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);
|
||||
|
||||
if (sc->sc_mux || sc->sc_events.io)
|
||||
return (EBUSY);
|
||||
|
||||
return (wsmux_attach_sc(muxsc, WSMUX_KBD, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wsmouse_muxops));
|
||||
}
|
||||
|
||||
int
|
||||
wsmouse_rem_mux(unit, muxsc)
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wsmousevar.h,v 1.2 1998/07/27 22:33:22 drochner Exp $ */
|
||||
/* $NetBSD: wsmousevar.h,v 1.3 1999/07/29 18:20:03 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -56,8 +56,12 @@ struct wsmousedev_attach_args {
|
|||
void *accesscookie; /* access cookie */
|
||||
};
|
||||
|
||||
#include "locators.h"
|
||||
|
||||
#define wsmousedevcf_mux cf_loc[WSMOUSEDEVCF_MUX]
|
||||
|
||||
/*
|
||||
* Autoconfiugration helper functions.
|
||||
* Autoconfiguration helper functions.
|
||||
*/
|
||||
int wsmousedevprint __P((void *, const char *));
|
||||
|
||||
|
|
|
@ -0,0 +1,716 @@
|
|||
/* $NetBSD: wsmux.c,v 1.1 1999/07/29 18:20:03 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Lennart Augustsson <augustss@carlstedt.se>
|
||||
* Carlstedt Research & Technology
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "wsmux.h"
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
|
||||
#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
|
||||
|
||||
/*
|
||||
* wscons mux device.
|
||||
*
|
||||
* The mux device is a collection of real mice and keyboards and acts as
|
||||
* a merge point for all the events from the different real devices.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include "opt_wsdisplay_compat.h"
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wseventvar.h>
|
||||
#include <dev/wscons/wscons_callbacks.h>
|
||||
#include <dev/wscons/wsmuxvar.h>
|
||||
|
||||
#ifdef WSMUX_DEBUG
|
||||
#define DPRINTF(x) if (wsmuxdebug) printf x
|
||||
int wsmuxdebug = 0;
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
struct wsplink {
|
||||
LIST_ENTRY(wsplink) next;
|
||||
int type;
|
||||
struct wsmux_softc *mux; /* our mux device */
|
||||
/* The rest of the fields reflect a value in the multiplexee. */
|
||||
struct device *sc; /* softc */
|
||||
struct wseventvar *sc_mevents; /* event var */
|
||||
struct wsmux_softc **sc_muxp; /* pointer to us */
|
||||
struct wsmuxops *sc_ops;
|
||||
};
|
||||
|
||||
cdev_decl(wsmux);
|
||||
|
||||
int wsmuxdoclose __P((struct device *, int, int, struct proc *));
|
||||
int wsmux_set_display __P((struct device *, struct wsmux_softc *));
|
||||
|
||||
int nwsmux = NWSMUX;
|
||||
struct wsmux_softc *wsmuxdevs[NWSMUX];
|
||||
|
||||
void wsmuxattach __P((int));
|
||||
|
||||
struct wsmuxops wsmux_muxops = {
|
||||
wsmuxopen, wsmuxdoclose, wsmuxdoioctl, wsmux_displayioctl,
|
||||
wsmux_set_display
|
||||
};
|
||||
|
||||
/* From upper level */
|
||||
void
|
||||
wsmuxattach(n)
|
||||
int n;
|
||||
{
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
/* Called too late. We use static allocation instead. */
|
||||
nwsmux = n;
|
||||
wsmuxdevs = malloc(n * sizeof (struct wsmux_softc *),
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (wsmuxdevs == 0)
|
||||
panic("wsmuxattach: out of memory\n");
|
||||
#endif
|
||||
|
||||
/* Make sure all muxes are there. */
|
||||
for (i = 0; i < nwsmux; i++)
|
||||
if (!wsmuxdevs[i])
|
||||
wsmuxdevs[i] = wsmux_create("wsmux", i);
|
||||
}
|
||||
|
||||
struct wsmux_softc *
|
||||
wsmux_create(name, unit)
|
||||
const char *name;
|
||||
int unit;
|
||||
{
|
||||
struct wsmux_softc *sc;
|
||||
|
||||
DPRINTF(("wsmux_create: allocating\n"));
|
||||
sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
|
||||
if (!sc)
|
||||
return (0);
|
||||
memset(sc, 0, sizeof *sc);
|
||||
LIST_INIT(&sc->sc_reals);
|
||||
snprintf(sc->sc_dv.dv_xname, sizeof sc->sc_dv.dv_xname,
|
||||
"%s%d", name, unit);
|
||||
sc->sc_dv.dv_unit = unit;
|
||||
return (sc);
|
||||
}
|
||||
|
||||
/* From mouse or keyboard. */
|
||||
void
|
||||
wsmux_attach(n, type, dsc, ev, psp, ops)
|
||||
int n;
|
||||
int type;
|
||||
struct device *dsc;
|
||||
struct wseventvar *ev;
|
||||
struct wsmux_softc **psp;
|
||||
struct wsmuxops *ops;
|
||||
{
|
||||
struct wsmux_softc *sc;
|
||||
int error;
|
||||
|
||||
DPRINTF(("wsmux_attach\n"));
|
||||
if (n >= nwsmux || n < 0) {
|
||||
printf("wsmux: attach device %d is out of range (%d..%d)\n",
|
||||
n, 0, nwsmux-1);
|
||||
return;
|
||||
}
|
||||
sc = wsmuxdevs[n];
|
||||
if (sc == 0) {
|
||||
sc = wsmux_create("wsmux", n);
|
||||
if (sc == 0) {
|
||||
printf("wsmux: attach out of memory\n");
|
||||
return;
|
||||
}
|
||||
wsmuxdevs[n] = sc;
|
||||
}
|
||||
error = wsmux_attach_sc(sc, type, dsc, ev, psp, ops);
|
||||
if (error)
|
||||
printf("wsmux_attach: error=%d\n", error);
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_attach_sc(sc, type, dsc, ev, psp, ops)
|
||||
struct wsmux_softc *sc;
|
||||
int type;
|
||||
struct device *dsc;
|
||||
struct wseventvar *ev;
|
||||
struct wsmux_softc **psp;
|
||||
struct wsmuxops *ops;
|
||||
{
|
||||
struct wsplink *m;
|
||||
int error;
|
||||
|
||||
DPRINTF(("wsmux_attach_sc: %s: type=%d dsc=%p, *psp=%p\n",
|
||||
sc->sc_dv.dv_xname, type, dsc, *psp));
|
||||
m = malloc(sizeof *m, M_DEVBUF, M_NOWAIT);
|
||||
if (m == 0)
|
||||
return (ENOMEM);
|
||||
m->type = type;
|
||||
m->mux = sc;
|
||||
m->sc = dsc;
|
||||
m->sc_mevents = ev;
|
||||
m->sc_muxp = psp;
|
||||
m->sc_ops = ops;
|
||||
LIST_INSERT_HEAD(&sc->sc_reals, m, next);
|
||||
|
||||
if (sc->sc_displaydv) {
|
||||
/* This is a display mux, so attach the new device to it. */
|
||||
DPRINTF(("wsmux_attach_sc: %s: set display %p\n",
|
||||
sc->sc_dv.dv_xname, sc->sc_displaydv));
|
||||
error = 0;
|
||||
if (m->sc_ops->dsetdisplay) {
|
||||
error = m->sc_ops->dsetdisplay(m->sc, sc);
|
||||
/* Ignore that the console already has a display. */
|
||||
if (error == EBUSY)
|
||||
error = 0;
|
||||
if (!error) {
|
||||
*m->sc_muxp = sc;
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
DPRINTF(("wsmux_attach_sc: on %s set rawkbd=%d\n",
|
||||
m->sc->dv_xname, sc->sc_rawkbd));
|
||||
(void)m->sc_ops->dioctl(m->sc,
|
||||
WSKBDIO_SETMODE,
|
||||
(caddr_t)&sc->sc_rawkbd,
|
||||
0, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (sc->sc_events.io) {
|
||||
/* Mux is open, so open the new subdevice */
|
||||
DPRINTF(("wsmux_attach_sc: %s: calling open of %s\n",
|
||||
sc->sc_dv.dv_xname, m->sc->dv_xname));
|
||||
/* mux already open, join in */
|
||||
error = m->sc_ops->dopen(makedev(0, m->sc->dv_unit),
|
||||
sc->sc_flags, sc->sc_mode, sc->sc_p);
|
||||
if (!error)
|
||||
*m->sc_muxp = sc;
|
||||
} else {
|
||||
DPRINTF(("wsmux_attach_sc: %s not open\n",
|
||||
sc->sc_dv.dv_xname));
|
||||
error = 0;
|
||||
}
|
||||
DPRINTF(("wsmux_attach_sc: done sc=%p psp=%p *psp=%p\n",
|
||||
sc, psp, *psp));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* From mouse or keyboard. */
|
||||
void
|
||||
wsmux_detach(n, dsc)
|
||||
int n;
|
||||
struct device *dsc;
|
||||
{
|
||||
#ifdef DIAGNOSTIC
|
||||
int error;
|
||||
|
||||
if (n >= nwsmux || n < 0) {
|
||||
printf("wsmux_detach: detach is out of range\n");
|
||||
return;
|
||||
}
|
||||
if ((error = wsmux_detach_sc(wsmuxdevs[n], dsc)))
|
||||
printf("wsmux_detach: error=%d\n", error);
|
||||
#else
|
||||
(void)wsmux_detach_sc(wsmuxdevs[n], dsc);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_detach_sc(sc, dsc)
|
||||
struct wsmux_softc *sc;
|
||||
struct device *dsc;
|
||||
{
|
||||
struct wsplink *m;
|
||||
int error;
|
||||
|
||||
DPRINTF(("wsmux_detach_sc: %s: dsc=%p\n", sc->sc_dv.dv_xname, dsc));
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sc == 0) {
|
||||
printf("wsmux_detach_sc: not allocated\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
if (m->sc == dsc)
|
||||
break;
|
||||
}
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!m) {
|
||||
printf("wsmux_detach_sc: not found\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
#endif
|
||||
if (sc->sc_displaydv) {
|
||||
if (m->sc_ops->dsetdisplay)
|
||||
error = m->sc_ops->dsetdisplay(m->sc, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
*m->sc_muxp = 0;
|
||||
} else if (*m->sc_muxp) {
|
||||
DPRINTF(("wsmux_detach_sc: close\n"));
|
||||
/* mux device is open, so close multiplexee */
|
||||
m->sc_ops->dclose(m->sc, FREAD, 0, 0);
|
||||
*m->sc_muxp = 0;
|
||||
}
|
||||
|
||||
LIST_REMOVE(m, next);
|
||||
|
||||
free(m, M_DEVBUF);
|
||||
DPRINTF(("wsmux_detach_sc: done sc=%p\n", sc));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmux_softc *sc;
|
||||
struct wsplink *m;
|
||||
int unit, error, nopen, lasterror;
|
||||
|
||||
unit = minor(dev);
|
||||
if (unit >= nwsmux || /* make sure it was attached */
|
||||
(sc = wsmuxdevs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
DPRINTF(("wsmuxopen: %s: sc=%p\n", sc->sc_dv.dv_xname, sc));
|
||||
if (!(flags & FREAD)) {
|
||||
/* Not opening for read, only ioctl is available. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sc->sc_events.io)
|
||||
return (EBUSY);
|
||||
|
||||
sc->sc_events.io = p;
|
||||
sc->sc_flags = flags;
|
||||
sc->sc_mode = mode;
|
||||
sc->sc_p = p;
|
||||
wsevent_init(&sc->sc_events); /* may cause sleep */
|
||||
|
||||
nopen = 0;
|
||||
lasterror = 0;
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
if (!m->sc_mevents->io && !*m->sc_muxp) {
|
||||
DPRINTF(("wsmuxopen: %s: m=%p dev=%s\n",
|
||||
sc->sc_dv.dv_xname, m, m->sc->dv_xname));
|
||||
error = m->sc_ops->dopen(makedev(0, m->sc->dv_unit),
|
||||
flags, mode, p);
|
||||
if (error) {
|
||||
/* Ignore opens that fail */
|
||||
lasterror = error;
|
||||
DPRINTF(("wsmuxopen: open failed %d\n",
|
||||
error));
|
||||
} else {
|
||||
nopen++;
|
||||
*m->sc_muxp = sc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nopen == 0 && lasterror != 0) {
|
||||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
return (lasterror);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
return wsmuxdoclose(&wsmuxdevs[minor(dev)]->sc_dv, flags, mode, p);
|
||||
}
|
||||
|
||||
int wsmuxdoclose(dv, flags, mode, p)
|
||||
struct device *dv;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmux_softc *sc = (struct wsmux_softc *)dv;
|
||||
struct wsplink *m;
|
||||
|
||||
DPRINTF(("wsmuxclose: %s: sc=%p\n", sc->sc_dv.dv_xname, sc));
|
||||
if (!(flags & FREAD)) {
|
||||
/* Not closing read, so read still allowed. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
if (*m->sc_muxp == sc) {
|
||||
DPRINTF(("wsmuxclose %s: m=%p dev=%s\n",
|
||||
sc->sc_dv.dv_xname, m, m->sc->dv_xname));
|
||||
m->sc_ops->dclose(m->sc, flags, mode, p);
|
||||
*m->sc_muxp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wsevent_fini(&sc->sc_events);
|
||||
sc->sc_events.io = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxread(dev, uio, flags)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
|
||||
|
||||
if (!sc->sc_events.io)
|
||||
return (EACCES);
|
||||
|
||||
return (wsevent_read(&sc->sc_events, uio, flags));
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
return wsmuxdoioctl(&wsmuxdevs[minor(dev)]->sc_dv, cmd, data, flag, p);
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxdoioctl(dv, cmd, data, flag, p)
|
||||
struct device *dv;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmux_softc *sc = (struct wsmux_softc *)dv;
|
||||
struct wsplink *m;
|
||||
int error, ok;
|
||||
int s, put, get, n;
|
||||
struct wseventvar *evar;
|
||||
struct wscons_event *ev;
|
||||
struct timeval xxxtime;
|
||||
struct wsmux_device_list *l;
|
||||
|
||||
DPRINTF(("wsmuxdoioctl: %s: sc=%p, cmd=%08lx\n",
|
||||
sc->sc_dv.dv_xname, sc, cmd));
|
||||
|
||||
switch (cmd) {
|
||||
case WSMUX_INJECTEVENT:
|
||||
/* Inject an event, e.g., from moused. */
|
||||
if (!sc->sc_events.io)
|
||||
return (EACCES);
|
||||
|
||||
evar = &sc->sc_events;
|
||||
s = spltty();
|
||||
get = evar->get;
|
||||
put = evar->put;
|
||||
if (++put % WSEVENT_QSIZE == get) {
|
||||
put--;
|
||||
splx(s);
|
||||
return (ENOSPC);
|
||||
}
|
||||
if (put >= WSEVENT_QSIZE)
|
||||
put = 0;
|
||||
ev = &evar->q[put];
|
||||
*ev = *(struct wscons_event *)data;
|
||||
microtime(&xxxtime);
|
||||
TIMEVAL_TO_TIMESPEC(&xxxtime, &ev->time);
|
||||
evar->put = put;
|
||||
WSEVENT_WAKEUP(evar);
|
||||
splx(s);
|
||||
return (0);
|
||||
case WSMUX_ADD_DEVICE:
|
||||
#define d ((struct wsmux_device *)data)
|
||||
switch (d->type) {
|
||||
#if NWSMOUSE > 0
|
||||
case WSMUX_MOUSE:
|
||||
return (wsmouse_add_mux(d->idx, sc));
|
||||
#endif
|
||||
#if NWSKBD > 0
|
||||
case WSMUX_KBD:
|
||||
return (wskbd_add_mux(d->idx, sc));
|
||||
#endif
|
||||
case WSMUX_MUX:
|
||||
return (wsmux_add_mux(d->idx, sc));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
case WSMUX_REMOVE_DEVICE:
|
||||
switch (d->type) {
|
||||
#if NWSMOUSE > 0
|
||||
case WSMUX_MOUSE:
|
||||
return (wsmouse_rem_mux(d->idx, sc));
|
||||
#endif
|
||||
#if NWSKBD > 0
|
||||
case WSMUX_KBD:
|
||||
return (wskbd_rem_mux(d->idx, sc));
|
||||
#endif
|
||||
case WSMUX_MUX:
|
||||
return (wsmux_rem_mux(d->idx, sc));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
#undef d
|
||||
case WSMUX_LIST_DEVICES:
|
||||
l = (struct wsmux_device_list *)data;
|
||||
for (n = 0, m = LIST_FIRST(&sc->sc_reals);
|
||||
n < WSMUX_MAXDEV && m != NULL;
|
||||
m = LIST_NEXT(m, next)) {
|
||||
l->devices[n].type = m->type;
|
||||
l->devices[n].idx = m->sc->dv_unit;
|
||||
n++;
|
||||
}
|
||||
l->ndevices = n;
|
||||
return (0);
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
case WSKBDIO_SETMODE:
|
||||
sc->sc_rawkbd = *(int *)data;
|
||||
DPRINTF(("wsmuxdoioctl: save rawkbd = %d\n", sc->sc_rawkbd));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc->sc_events.io == NULL && sc->sc_displaydv == NULL)
|
||||
return (EACCES);
|
||||
|
||||
/* Return 0 if any of the ioctl() succeeds, otherwise the last error */
|
||||
error = 0;
|
||||
ok = 0;
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
DPRINTF(("wsmuxdoioctl: m=%p *m->sc_muxp=%p sc=%p\n",
|
||||
m, *m->sc_muxp, sc));
|
||||
if (*m->sc_muxp == sc) {
|
||||
DPRINTF(("wsmuxdoioctl: %s: m=%p dev=%s\n",
|
||||
sc->sc_dv.dv_xname, m, m->sc->dv_xname));
|
||||
error = m->sc_ops->dioctl(m->sc, cmd, data, flag, p);
|
||||
if (!error)
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
error = 0;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_displayioctl(dv, cmd, data, flag, p)
|
||||
struct device *dv;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmux_softc *sc = (struct wsmux_softc *)dv;
|
||||
struct wsplink *m;
|
||||
int error, ok;
|
||||
|
||||
DPRINTF(("wsmux_displayioctl: %s: sc=%p, cmd=%08lx\n",
|
||||
sc->sc_dv.dv_xname, sc, cmd));
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
if (cmd == WSKBDIO_SETMODE) {
|
||||
sc->sc_rawkbd = *(int *)data;
|
||||
DPRINTF(("wsmux_displayioctl: rawkbd = %d\n", sc->sc_rawkbd));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return 0 if any of the ioctl() succeeds, otherwise the last error */
|
||||
error = 0;
|
||||
ok = 0;
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
DPRINTF(("wsmux_displayioctl: m=%p sc=%p sc_muxp=%p\n",
|
||||
m, sc, *m->sc_muxp));
|
||||
if (m->sc_ops->ddispioctl && *m->sc_muxp == sc) {
|
||||
error = m->sc_ops->ddispioctl(m->sc, cmd, data,
|
||||
flag, p);
|
||||
DPRINTF(("wsmux_displayioctl: m=%p dev=%s ==> %d\n",
|
||||
m, m->sc->dv_xname, error));
|
||||
if (!error)
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
error = 0;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wsmuxpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
|
||||
|
||||
if (!sc->sc_events.io)
|
||||
return (EACCES);
|
||||
|
||||
return (wsevent_poll(&sc->sc_events, events, p));
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_set_display(dv, muxsc)
|
||||
struct device *dv;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
struct wsmux_softc *sc = (struct wsmux_softc *)dv;
|
||||
struct wsmux_softc *nsc = muxsc ? sc : 0;
|
||||
struct device *displaydv = muxsc ? muxsc->sc_displaydv : 0;
|
||||
struct device *odisplaydv;
|
||||
struct wsplink *m;
|
||||
int error, ok;
|
||||
|
||||
DPRINTF(("wsmux_set_display: %s: displaydv=%p\n",
|
||||
sc->sc_dv.dv_xname, displaydv));
|
||||
|
||||
if (displaydv) {
|
||||
if (sc->sc_displaydv)
|
||||
return (EBUSY);
|
||||
} else {
|
||||
if (sc->sc_displaydv == NULL)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
odisplaydv = sc->sc_displaydv;
|
||||
sc->sc_displaydv = displaydv;
|
||||
|
||||
if (displaydv)
|
||||
printf("%s: connecting to %s\n",
|
||||
sc->sc_dv.dv_xname, displaydv->dv_xname);
|
||||
ok = 0;
|
||||
error = 0;
|
||||
for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
|
||||
if (m->sc_ops->dsetdisplay &&
|
||||
(nsc ? m->sc_mevents->io == 0 && *m->sc_muxp == 0 :
|
||||
*m->sc_muxp == sc)) {
|
||||
error = m->sc_ops->dsetdisplay(m->sc, nsc);
|
||||
DPRINTF(("wsmux_set_display: m=%p dev=%s error=%d\n",
|
||||
m, m->sc->dv_xname, error));
|
||||
if (!error) {
|
||||
ok = 1;
|
||||
*m->sc_muxp = nsc;
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
DPRINTF(("wsmux_set_display: on %s set rawkbd=%d\n",
|
||||
m->sc->dv_xname, sc->sc_rawkbd));
|
||||
(void)m->sc_ops->dioctl(m->sc,
|
||||
WSKBDIO_SETMODE,
|
||||
(caddr_t)&sc->sc_rawkbd,
|
||||
0, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
error = 0;
|
||||
|
||||
if (displaydv == NULL)
|
||||
printf("%s: disconnecting from %s\n",
|
||||
sc->sc_dv.dv_xname, odisplaydv->dv_xname);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_add_mux(unit, muxsc)
|
||||
int unit;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
struct wsmux_softc *sc, *m;
|
||||
|
||||
if (unit < 0 || unit >= nwsmux || (sc = wsmuxdevs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
DPRINTF(("wsmux_add_mux: %s to %s\n", sc->sc_dv.dv_xname,
|
||||
muxsc->sc_dv.dv_xname));
|
||||
|
||||
if (sc->sc_mux || sc->sc_events.io)
|
||||
return (EBUSY);
|
||||
|
||||
/* The mux we are adding must not be an ancestor of it. */
|
||||
for (m = muxsc->sc_mux; m; m = m->sc_mux)
|
||||
if (m == sc)
|
||||
return (EINVAL);
|
||||
|
||||
return (wsmux_attach_sc(muxsc, WSMUX_MUX, &sc->sc_dv, &sc->sc_events,
|
||||
&sc->sc_mux, &wsmux_muxops));
|
||||
}
|
||||
|
||||
int
|
||||
wsmux_rem_mux(unit, muxsc)
|
||||
int unit;
|
||||
struct wsmux_softc *muxsc;
|
||||
{
|
||||
struct wsmux_softc *sc;
|
||||
|
||||
if (unit < 0 || unit >= nwsmux || (sc = wsmuxdevs[unit]) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
DPRINTF(("wsmux_rem_mux: %s from %s\n", sc->sc_dv.dv_xname,
|
||||
muxsc->sc_dv.dv_xname));
|
||||
|
||||
return (wsmux_detach_sc(muxsc, &sc->sc_dv));
|
||||
}
|
||||
|
||||
#endif /* NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0) */
|
|
@ -0,0 +1,88 @@
|
|||
/* $NetBSD: wsmuxvar.h,v 1.1 1999/07/29 18:20:43 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Lennart Augustsson <augustss@carlstedt.se>
|
||||
* Carlstedt Research & Technology
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct wsdisplay_softc;
|
||||
struct wsplink;
|
||||
|
||||
struct wsmux_softc {
|
||||
struct device sc_dv;
|
||||
struct wseventvar sc_events; /* event queue state */
|
||||
int sc_flags, sc_mode; /* open flags */
|
||||
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 */
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
int sc_rawkbd; /* A hack to remember the kbd mode */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct wsmuxops {
|
||||
int (*dopen) __P((dev_t, int, int, struct proc *));
|
||||
int (*dclose) __P((struct device *, int, int, struct proc *));
|
||||
int (*dioctl) __P((struct device *, u_long, caddr_t, int,
|
||||
struct proc *));
|
||||
int (*ddispioctl) __P((struct device *, u_long, caddr_t, int,
|
||||
struct proc *));
|
||||
int (*dsetdisplay) __P((struct device *, struct wsmux_softc *));
|
||||
};
|
||||
|
||||
struct wsmux_softc *wsmux_create __P((const char *name, int no));
|
||||
int wsmux_attach_sc __P((
|
||||
struct wsmux_softc *,
|
||||
int, struct device *, struct wseventvar *,
|
||||
struct wsmux_softc **,
|
||||
struct wsmuxops *));
|
||||
int wsmux_detach_sc __P((struct wsmux_softc *, struct device *));
|
||||
void wsmux_attach __P((
|
||||
int, int, struct device *, struct wseventvar *,
|
||||
struct wsmux_softc **,
|
||||
struct wsmuxops *));
|
||||
void wsmux_detach __P((int, struct device *));
|
||||
|
||||
int wsmux_displayioctl __P((struct device *dev, u_long cmd,
|
||||
caddr_t data, int flag, struct proc *p));
|
||||
|
||||
int wsmuxdoioctl __P((struct device *, u_long, caddr_t,int,struct proc *));
|
||||
|
||||
int wsmux_add_mux __P((int, struct wsmux_softc *));
|
||||
int wsmux_rem_mux __P((int, struct wsmux_softc *));
|
||||
int wskbd_add_mux __P((int, struct wsmux_softc *));
|
||||
int wskbd_rem_mux __P((int, struct wsmux_softc *));
|
||||
int wsmouse_add_mux __P((int, struct wsmux_softc *));
|
||||
int wsmouse_rem_mux __P((int, struct wsmux_softc *));
|
Loading…
Reference in New Issue