summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-05-15 11:29:16 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-05-15 11:29:16 +0000
commite4ddca087cd9e76ce899c0b7980d802c4b72d54b (patch)
treed94f7a56579c717080dc242b5525b0898990a003 /sys
parentdb19eabbc0715bf1c47d38f4bb677afbbf751347 (diff)
Partial sync to the NetBSD wscons code, bringing a better wsmux behaviour
and bugfixes (the kqueue code, /dev/wsmuxctl and screen border color changes have not been picked), keeping local changes. Tested by many on alpha/cats/hp300/i386/macppc/sparc/sparc64/zaurus if not more.
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files10
-rw-r--r--sys/dev/wscons/files.wscons20
-rw-r--r--sys/dev/wscons/wscons_callbacks.h13
-rw-r--r--sys/dev/wscons/wsconsio.h38
-rw-r--r--sys/dev/wscons/wsdisplay.c623
-rw-r--r--sys/dev/wscons/wsdisplayvar.h8
-rw-r--r--sys/dev/wscons/wsevent.c40
-rw-r--r--sys/dev/wscons/wskbd.c703
-rw-r--r--sys/dev/wscons/wsksymdef.h3
-rw-r--r--sys/dev/wscons/wsmouse.c365
-rw-r--r--sys/dev/wscons/wsmux.c1003
-rw-r--r--sys/dev/wscons/wsmuxvar.h101
12 files changed, 1446 insertions, 1481 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 1f91d849951..1f85465e988 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.336 2005/05/10 01:16:31 brad Exp $
+# $OpenBSD: files,v 1.337 2005/05/15 11:29:12 miod Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -73,10 +73,10 @@ define ax88190 # AX88190-family Ethernet controllers
# a wscons output device; used later, but needs to be near the top for
# common file (e.g. vga) definitions.
-define wsdisplaydev {}
-define wsemuldisplaydev {[console = -1]}
-define wskbddev {[console = -1], [mux = -1]}
-define wsmousedev {[mux = -1]}
+define wsdisplaydev {[mux = 1]}
+define wsemuldisplaydev {[console = -1], [mux = 1]}
+define wskbddev {[console = -1], [mux = 1]}
+define wsmousedev {[mux = 0]}
define wsrasteremulops
# i2c device attributes
diff --git a/sys/dev/wscons/files.wscons b/sys/dev/wscons/files.wscons
index f8fd1d21220..fe6daa2fce9 100644
--- a/sys/dev/wscons/files.wscons
+++ b/sys/dev/wscons/files.wscons
@@ -1,5 +1,5 @@
-# $OpenBSD: files.wscons,v 1.8 2005/03/08 20:00:25 tdeval Exp $
-# $NetBSD: files.wscons,v 1.19 1999/12/12 08:17:28 scottr Exp $
+# $OpenBSD: files.wscons,v 1.9 2005/05/15 11:29:15 miod Exp $
+# $NetBSD: files.wscons,v 1.34 2005/05/04 01:52:16 augustss Exp $
#
# "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -22,7 +22,7 @@ attach wskbd at wskbddev
device wsmouse
attach wsmouse at wsmousedev
-file dev/wscons/wsdisplay.c wsdisplay needs-flag
+file dev/wscons/wsdisplay.c wsdisplay needs-flag
file dev/wscons/wsdisplay_compat_usl.c wsdisplay & wsdisplay_compat_usl
file dev/wscons/wsemulconf.c wsdisplay
file dev/wscons/wsemul_dumb.c wsdisplay & wsemul_dumb
@@ -30,10 +30,11 @@ file dev/wscons/wsemul_vt100.c wsdisplay & !wsemul_no_vt100
file dev/wscons/wsemul_vt100_subr.c wsdisplay & !wsemul_no_vt100
file dev/wscons/wsemul_vt100_chars.c wsdisplay & !wsemul_no_vt100
file dev/wscons/wsemul_vt100_keys.c wsdisplay & !wsemul_no_vt100
-file dev/wscons/wsevent.c wskbd | wsmouse
-file dev/wscons/wskbd.c wskbd needs-flag
-file dev/wscons/wskbdutil.c wskbd needs-flag
-file dev/wscons/wsmouse.c wsmouse needs-flag
+file dev/wscons/wsevent.c wsdisplay | wskbd |
+ wsmouse | wsmux
+file dev/wscons/wskbd.c wskbd needs-flag
+file dev/wscons/wskbdutil.c wskbd
+file dev/wscons/wsmouse.c wsmouse needs-flag
file dev/rcons/raster_op.c wsrasteremulops
file dev/rcons/raster_text.c wsrasteremulops
@@ -43,7 +44,8 @@ file dev/wscons/wscons_gallant19.c wsrasteremulops
file dev/wscons/wscons_font8x16.c wsrasteremulops
pseudo-device wsmux
-file dev/wscons/wsmux.c wsmux | wsdisplay needs-flag
+file dev/wscons/wsmux.c wsmux needs-flag
define wsemul_sun
-file dev/wscons/wsemul_sun.c wsdisplay & wsemul_sun needs-flag
+file dev/wscons/wsemul_sun.c wsdisplay &
+ wsemul_sun needs-flag
diff --git a/sys/dev/wscons/wscons_callbacks.h b/sys/dev/wscons/wscons_callbacks.h
index 916291eea47..4f2dd2eef35 100644
--- a/sys/dev/wscons/wscons_callbacks.h
+++ b/sys/dev/wscons/wscons_callbacks.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: wscons_callbacks.h,v 1.5 2002/03/14 03:16:08 millert Exp $ */
-/* $NetBSD: wscons_callbacks.h,v 1.12 2000/03/06 21:37:16 thorpej Exp $ */
+/* $OpenBSD: wscons_callbacks.h,v 1.6 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wscons_callbacks.h,v 1.16 2001/11/10 17:14:51 augustss Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -31,10 +31,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 *);
+void wsdisplay_set_console_kbd(struct wsevsrc *);
/*
* Calls to the display interface from the keyboard interface.
@@ -58,6 +60,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 *);
-int wskbd_pickfree(void);
+struct wsevsrc *wskbd_set_console_display(struct device *, struct wsevsrc *);
+int wskbd_pickfree(void);
diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h
index f72ec904c47..c8b2996375c 100644
--- a/sys/dev/wscons/wsconsio.h
+++ b/sys/dev/wscons/wsconsio.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsconsio.h,v 1.35 2005/04/22 11:59:11 miod Exp $ */
-/* $NetBSD: wsconsio.h,v 1.31.2.1 2000/07/07 09:49:17 hannken Exp $ */
+/* $OpenBSD: wsconsio.h,v 1.36 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -41,12 +41,14 @@
* 0-31 keyboard ioctls (WSKBDIO)
* 32-63 mouse ioctls (WSMOUSEIO)
* 64-95 display ioctls (WSDISPLAYIO)
- * 96-255 reserved for future use
+ * 96-127 mux ioctls (WSMUXIO)
+ * 128-255 reserved for future use
*/
#include <sys/types.h>
#include <sys/ioccom.h>
#include <dev/wscons/wsksymvar.h>
+
#include <sys/pciio.h>
#define WSSCREEN_NAME_SIZE 16
@@ -412,15 +414,6 @@ struct wsdisplay_delscreendata {
/* Display information: number of bytes per row, may be same as pixels */
#define WSDISPLAYIO_LINEBYTES _IOR('W', 95, u_int)
-/* Replaced by WSMUX_{ADD,REMOVE}_DEVICE */
-struct wsdisplay_kbddata {
- int op;
-#define _O_WSDISPLAY_KBD_ADD 0
-#define _O_WSDISPLAY_KBD_DEL 1
- int idx;
-};
-#define _O_WSDISPLAYIO_SETKEYBOARD _IOWR('W', 87, struct wsdisplay_kbddata)
-
/* Mouse console support */
#define WSDISPLAYIO_WSMOUSED _IOW('W', 88, struct wscons_event)
@@ -436,11 +429,17 @@ struct wsdisplay_param {
#define WSDISPLAYIO_GETPARAM _IOWR('W', 89, struct wsdisplay_param)
#define WSDISPLAYIO_SETPARAM _IOWR('W', 90, struct wsdisplay_param)
+#define WSDISPLAYIO_GPCIID _IOR('W', 91, struct pcisel)
+
/* XXX NOT YET DEFINED */
/* Mapping information retrieval. */
-/* Mux ioctls (96 - 127) */
-#define WSMUX_INJECTEVENT _IOW('W', 96, struct wscons_event)
+/*
+ * Mux ioctls (96 - 127)
+ */
+
+#define WSMUXIO_INJECTEVENT _IOW('W', 96, struct wscons_event)
+#define WSMUX_INJECTEVENT WSMUXIO_INJECTEVENT /* XXX compat */
struct wsmux_device {
int type;
@@ -449,16 +448,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 WSDISPLAYIO_GPCIID _IOR('W', 91, struct pcisel)
+#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_ */
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index e3e6a309111..23197024fc2 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsdisplay.c,v 1.56 2004/11/05 09:38:04 miod Exp $ */
-/* $NetBSD: wsdisplay.c,v 1.37.4.1 2000/06/30 16:27:53 simonb Exp $ */
+/* $OpenBSD: wsdisplay.c,v 1.57 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -61,6 +61,7 @@
#include <dev/ic/pcdisplay.h>
+#include "wsdisplay.h"
#include "wskbd.h"
#include "wsmouse.h"
#include "wsmux.h"
@@ -71,8 +72,8 @@
#endif
#if NWSMOUSE > 0
-#include "wsmousevar.h"
-#endif /* NWSMOUSE > 0 */
+#include <dev/wscons/wsmousevar.h>
+#endif
#include "wsmoused.h"
@@ -100,7 +101,7 @@ struct wsscreen {
#define SCR_OPEN 1 /* is it open? */
#define SCR_WAITACTIVE 2 /* someone waiting on activation */
#define SCR_GRAPHICS 4 /* graphics mode, no text (emulation) output */
-#define SCR_DUMBFB 8 /* in use as dumb framebuffer (iff SCR_GRAPHICS) */
+#define SCR_DUMBFB 8 /* in use as dumb fb (iff SCR_GRAPHICS) */
const struct wscons_syncops *scr_syncops;
void *scr_synccookie;
@@ -141,16 +142,18 @@ struct wsscreen {
#endif /* WSMOUSED_SUPPORT */
};
-struct wsscreen *wsscreen_attach(struct wsdisplay_softc *, int,
- const char *, const struct wsscreen_descr *, void *, int, int, long);
-void wsscreen_detach(struct wsscreen *);
-int wsdisplay_addscreen(struct wsdisplay_softc *, int, const char *, const char *);
-int wsdisplay_getscreen(struct wsdisplay_softc *, struct wsdisplay_addscreendata *);
-void wsdisplay_shutdownhook(void *);
-void wsdisplay_addscreen_print(struct wsdisplay_softc *, int, int);
-void wsdisplay_closescreen(struct wsdisplay_softc *, struct wsscreen *);
-int wsdisplay_delscreen(struct wsdisplay_softc *, int, int);
-void wsdisplay_burner(void *v);
+struct wsscreen *wsscreen_attach(struct wsdisplay_softc *, int, const char *,
+ const struct wsscreen_descr *, void *, int, int, long);
+void wsscreen_detach(struct wsscreen *);
+int wsdisplay_addscreen(struct wsdisplay_softc *, int, const char *,
+ const char *);
+int wsdisplay_getscreen(struct wsdisplay_softc *,
+ struct wsdisplay_addscreendata *);
+void wsdisplay_shutdownhook(void *);
+void wsdisplay_addscreen_print(struct wsdisplay_softc *, int, int);
+void wsdisplay_closescreen(struct wsdisplay_softc *, struct wsscreen *);
+int wsdisplay_delscreen(struct wsdisplay_softc *, int, int);
+void wsdisplay_burner(void *v);
struct wsdisplay_softc {
struct device sc_dv;
@@ -164,6 +167,8 @@ struct wsdisplay_softc {
int sc_focusidx; /* available only if sc_focus isn't null */
struct wsscreen *sc_focus;
+ struct wseventvar sc_evar;
+
struct timeout sc_burner;
int sc_burnoutintvl;
int sc_burninintvl;
@@ -180,7 +185,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
@@ -193,15 +198,12 @@ struct wsdisplay_softc {
};
extern struct cfdriver wsdisplay_cd;
-#if NWSMUX > 0
-extern struct wsmux_softc **wsmuxdevs;
-#endif /* NWSMUX > 0 */
/* Autoconfiguration definitions. */
-int wsdisplay_emul_match(struct device *, void *, void *);
-void wsdisplay_emul_attach(struct device *, struct device *, void *);
-int wsdisplay_noemul_match(struct device *, void *, void *);
-void wsdisplay_noemul_attach(struct device *, struct device *, void *);
+int wsdisplay_emul_match(struct device *, void *, void *);
+void wsdisplay_emul_attach(struct device *, struct device *, void *);
+int wsdisplay_noemul_match(struct device *, void *, void *);
+void wsdisplay_noemul_attach(struct device *, struct device *, void *);
struct cfdriver wsdisplay_cd = {
NULL, "wsdisplay", DV_TTY
@@ -217,9 +219,8 @@ struct cfattach wsdisplay_noemul_ca = {
wsdisplay_noemul_attach,
};
-void wsdisplaystart(struct tty *);
-int wsdisplayparam(struct tty *, struct termios *);
-
+void wsdisplaystart(struct tty *);
+int wsdisplayparam(struct tty *, struct termios *);
/* Internal macros, functions, and variables. */
#define WSDISPLAYUNIT(dev) (minor(dev) >> 8)
@@ -230,24 +231,24 @@ int wsdisplayparam(struct tty *, struct termios *);
#define WSSCREEN_HAS_EMULATOR(scr) ((scr)->scr_dconf->wsemul != NULL)
#define WSSCREEN_HAS_TTY(scr) ((scr)->scr_tty != NULL)
-void wsdisplay_common_attach(struct wsdisplay_softc *sc,
- int console, const struct wsscreen_list *,
+void wsdisplay_common_attach(struct wsdisplay_softc *sc,
+ int console, int mux, const struct wsscreen_list *,
const struct wsdisplay_accessops *accessops,
void *accesscookie);
#ifdef WSDISPLAY_COMPAT_RAWKBD
-int wsdisplay_update_rawkbd(struct wsdisplay_softc *, struct wsscreen *);
+int wsdisplay_update_rawkbd(struct wsdisplay_softc *, struct wsscreen *);
#endif
-int wsdisplay_console_initted;
+int wsdisplay_console_initted;
struct wsdisplay_softc *wsdisplay_console_device;
struct wsscreen_internal wsdisplay_console_conf;
-int wsdisplay_getc_dummy(dev_t);
-void wsdisplay_pollc(dev_t, int);
+int wsdisplay_getc_dummy(dev_t);
+void wsdisplay_pollc(dev_t, int);
-int wsdisplay_cons_pollmode;
-void (*wsdisplay_cons_kbd_pollc)(dev_t, int);
+int wsdisplay_cons_pollmode;
+void (*wsdisplay_cons_kbd_pollc)(dev_t, int);
struct consdev wsdisplay_cons = {
NULL, NULL, wsdisplay_getc_dummy, wsdisplay_cnputc,
@@ -255,15 +256,15 @@ struct consdev wsdisplay_cons = {
};
#ifndef WSDISPLAY_DEFAULTSCREENS
-# define WSDISPLAY_DEFAULTSCREENS 1
+#define WSDISPLAY_DEFAULTSCREENS 1
#endif
-int wsdisplay_defaultscreens = WSDISPLAY_DEFAULTSCREENS;
+int wsdisplay_defaultscreens = WSDISPLAY_DEFAULTSCREENS;
-int wsdisplay_switch1(void *, int, int);
-int wsdisplay_switch2(void *, int, int);
-int wsdisplay_switch3(void *, int, int);
+int wsdisplay_switch1(void *, int, int);
+int wsdisplay_switch2(void *, int, int);
+int wsdisplay_switch3(void *, int, int);
-int wsdisplay_clearonclose;
+int wsdisplay_clearonclose;
#ifdef WSMOUSED_SUPPORT
char *Copybuffer;
@@ -272,21 +273,16 @@ char Paste_avail;
#endif
struct wsscreen *
-wsscreen_attach(sc, console, emul, type, cookie, ccol, crow, defattr)
- struct wsdisplay_softc *sc;
- int console;
- const char *emul;
- const struct wsscreen_descr *type;
- void *cookie;
- int ccol, crow;
- long defattr;
+wsscreen_attach(struct wsdisplay_softc *sc, int console, const char *emul,
+ const struct wsscreen_descr *type, void *cookie, int ccol, int crow,
+ long defattr)
{
struct wsscreen_internal *dconf;
struct wsscreen *scr;
scr = malloc(sizeof(struct wsscreen), M_DEVBUF, M_NOWAIT);
if (!scr)
- return (scr);
+ return (NULL);
if (console) {
dconf = &wsdisplay_console_conf;
@@ -298,7 +294,7 @@ wsscreen_attach(sc, console, emul, type, cookie, ccol, crow, defattr)
(*dconf->wsemul->attach)(1, 0, 0, 0, 0, scr, 0);
} else { /* not console */
dconf = malloc(sizeof(struct wsscreen_internal),
- M_DEVBUF, M_NOWAIT);
+ M_DEVBUF, M_NOWAIT);
if (dconf == NULL) {
free(scr, M_DEVBUF);
return (NULL);
@@ -313,8 +309,8 @@ wsscreen_attach(sc, console, emul, type, cookie, ccol, crow, defattr)
return (NULL);
}
dconf->wsemulcookie =
- (*dconf->wsemul->attach)(0, type, cookie,
- ccol, crow, scr, defattr);
+ (*dconf->wsemul->attach)(0, type, cookie,
+ ccol, crow, scr, defattr);
} else
dconf->wsemul = NULL;
dconf->scrdata = type;
@@ -341,8 +337,7 @@ wsscreen_attach(sc, console, emul, type, cookie, ccol, crow, defattr)
}
void
-wsscreen_detach(scr)
- struct wsscreen *scr;
+wsscreen_detach(struct wsscreen *scr)
{
int ccol, crow; /* XXX */
@@ -352,15 +347,13 @@ wsscreen_detach(scr)
}
if (WSSCREEN_HAS_EMULATOR(scr))
(*scr->scr_dconf->wsemul->detach)(scr->scr_dconf->wsemulcookie,
- &ccol, &crow);
+ &ccol, &crow);
free(scr->scr_dconf, M_DEVBUF);
free(scr, M_DEVBUF);
}
const struct wsscreen_descr *
-wsdisplay_screentype_pick(scrdata, name)
- const struct wsscreen_list *scrdata;
- const char *name;
+wsdisplay_screentype_pick(const struct wsscreen_list *scrdata, const char *name)
{
int i;
const struct wsscreen_descr *scr;
@@ -383,9 +376,7 @@ wsdisplay_screentype_pick(scrdata, name)
* print info about attached screen
*/
void
-wsdisplay_addscreen_print(sc, idx, count)
- struct wsdisplay_softc *sc;
- int idx, count;
+wsdisplay_addscreen_print(struct wsdisplay_softc *sc, int idx, int count)
{
printf("%s: screen %d", sc->sc_dv.dv_xname, idx);
if (count > 1)
@@ -393,16 +384,14 @@ wsdisplay_addscreen_print(sc, idx, count)
printf(" added (%s", sc->sc_scr[idx]->scr_dconf->scrdata->name);
if (WSSCREEN_HAS_EMULATOR(sc->sc_scr[idx])) {
printf(", %s emulation",
- sc->sc_scr[idx]->scr_dconf->wsemul->name);
+ sc->sc_scr[idx]->scr_dconf->wsemul->name);
}
printf(")\n");
}
int
-wsdisplay_addscreen(sc, idx, screentype, emul)
- struct wsdisplay_softc *sc;
- int idx;
- const char *screentype, *emul;
+wsdisplay_addscreen(struct wsdisplay_softc *sc, int idx,
+ const char *screentype, const char *emul)
{
const struct wsscreen_descr *scrdesc;
int error;
@@ -421,15 +410,14 @@ wsdisplay_addscreen(sc, idx, screentype, emul)
if (!scrdesc)
return (ENXIO);
error = (*sc->sc_accessops->alloc_screen)(sc->sc_accesscookie,
- scrdesc, &cookie, &ccol, &crow, &defattr);
+ scrdesc, &cookie, &ccol, &crow, &defattr);
if (error)
return (error);
scr = wsscreen_attach(sc, 0, emul, scrdesc,
- cookie, ccol, crow, defattr);
+ cookie, ccol, crow, defattr);
if (scr == NULL) {
- (*sc->sc_accessops->free_screen)(sc->sc_accesscookie,
- cookie);
+ (*sc->sc_accessops->free_screen)(sc->sc_accesscookie, cookie);
return (ENXIO);
}
@@ -439,8 +427,7 @@ wsdisplay_addscreen(sc, idx, screentype, emul)
s = spltty();
if (!sc->sc_focus) {
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
- scr->scr_dconf->emulcookie,
- 0, 0, 0);
+ scr->scr_dconf->emulcookie, 0, 0, 0);
sc->sc_focusidx = idx;
sc->sc_focus = scr;
}
@@ -453,9 +440,8 @@ wsdisplay_addscreen(sc, idx, screentype, emul)
}
int
-wsdisplay_getscreen(sc, sd)
- struct wsdisplay_softc *sc;
- struct wsdisplay_addscreendata *sd;
+wsdisplay_getscreen(struct wsdisplay_softc *sc,
+ struct wsdisplay_addscreendata *sd)
{
struct wsscreen *scr;
@@ -477,9 +463,7 @@ wsdisplay_getscreen(sc, sd)
}
void
-wsdisplay_closescreen(sc, scr)
- struct wsdisplay_softc *sc;
- struct wsscreen *scr;
+wsdisplay_closescreen(struct wsdisplay_softc *sc, struct wsscreen *scr)
{
int maj, mn, idx;
@@ -508,9 +492,7 @@ wsdisplay_closescreen(sc, scr)
}
int
-wsdisplay_delscreen(sc, idx, flags)
- struct wsdisplay_softc *sc;
- int idx, flags;
+wsdisplay_delscreen(struct wsdisplay_softc *sc, int idx, int flags)
{
struct wsscreen *scr;
int s;
@@ -518,8 +500,7 @@ wsdisplay_delscreen(sc, idx, flags)
if (idx < 0 || idx >= WSDISPLAY_MAXSCREEN)
return (EINVAL);
- scr = sc->sc_scr[idx];
- if (!scr)
+ if ((scr = sc->sc_scr[idx]) == NULL)
return (ENXIO);
if (scr->scr_dconf == &wsdisplay_console_conf ||
@@ -556,8 +537,7 @@ wsdisplay_delscreen(sc, idx, flags)
wsscreen_detach(scr);
- (*sc->sc_accessops->free_screen)(sc->sc_accesscookie,
- cookie);
+ (*sc->sc_accessops->free_screen)(sc->sc_accesscookie, cookie);
printf("%s: screen %d deleted\n", sc->sc_dv.dv_xname, idx);
return (0);
@@ -567,22 +547,17 @@ wsdisplay_delscreen(sc, idx, flags)
* Autoconfiguration functions.
*/
int
-wsdisplay_emul_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+wsdisplay_emul_match(struct device *parent, void *match, void *aux)
{
struct cfdata *cf = match;
struct wsemuldisplaydev_attach_args *ap = aux;
- if (cf->wsemuldisplaydevcf_console !=
- WSEMULDISPLAYDEVCF_CONSOLE_UNK) {
+ if (cf->wsemuldisplaydevcf_console != WSEMULDISPLAYDEVCF_CONSOLE_UNK) {
/*
* If console-ness of device specified, either match
* exactly (at high priority), or fail.
*/
- if (cf->wsemuldisplaydevcf_console != 0 &&
- ap->console != 0)
+ if (cf->wsemuldisplaydevcf_console != 0 && ap->console != 0)
return (10);
else
return (0);
@@ -593,15 +568,14 @@ wsdisplay_emul_match(parent, match, aux)
}
void
-wsdisplay_emul_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+wsdisplay_emul_attach(struct device *parent, struct device *self, void *aux)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)self;
struct wsemuldisplaydev_attach_args *ap = aux;
- wsdisplay_common_attach(sc, ap->console, ap->scrdata,
- ap->accessops, ap->accesscookie);
+ wsdisplay_common_attach(sc, ap->console,
+ sc->sc_dv.dv_cfdata->wsemuldisplaydevcf_mux, ap->scrdata,
+ ap->accessops, ap->accesscookie);
if (ap->console && cn_tab == &wsdisplay_cons) {
int maj;
@@ -617,9 +591,7 @@ wsdisplay_emul_attach(parent, self, aux)
/* Print function (for parent devices). */
int
-wsemuldisplaydevprint(aux, pnp)
- void *aux;
- const char *pnp;
+wsemuldisplaydevprint(void *aux, const char *pnp)
{
#if 0 /* -Wunused */
struct wsemuldisplaydev_attach_args *ap = aux;
@@ -635,10 +607,7 @@ wsemuldisplaydevprint(aux, pnp)
}
int
-wsdisplay_noemul_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+wsdisplay_noemul_match(struct device *parent, void *match, void *aux)
{
#if 0 /* -Wunused */
struct wsdisplaydev_attach_args *ap = aux;
@@ -649,21 +618,19 @@ wsdisplay_noemul_match(parent, match, aux)
}
void
-wsdisplay_noemul_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+wsdisplay_noemul_attach(struct device *parent, struct device *self, void *aux)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)self;
struct wsdisplaydev_attach_args *ap = aux;
- wsdisplay_common_attach(sc, 0, NULL, ap->accessops, ap->accesscookie);
+ wsdisplay_common_attach(sc, 0,
+ sc->sc_dv.dv_cfdata->wsemuldisplaydevcf_mux, NULL,
+ ap->accessops, ap->accesscookie);
}
/* Print function (for parent devices). */
int
-wsdisplaydevprint(aux, pnp)
- void *aux;
- const char *pnp;
+wsdisplaydevprint(void *aux, const char *pnp)
{
#if 0 /* -Wunused */
struct wsdisplaydev_attach_args *ap = aux;
@@ -676,23 +643,35 @@ wsdisplaydevprint(aux, pnp)
}
void
-wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
- struct wsdisplay_softc *sc;
- int console;
- const struct wsscreen_list *scrdata;
- const struct wsdisplay_accessops *accessops;
- void *accesscookie;
+wsdisplay_common_attach(struct wsdisplay_softc *sc, int console, int kbdmux,
+ const struct wsscreen_list *scrdata,
+ const struct wsdisplay_accessops *accessops, void *accesscookie)
{
static int hookset = 0;
int i, start = 0;
#if NWSKBD > 0
- struct device *dv;
+ struct wsevsrc *kme;
+#if NWSMUX > 0
+ struct wsmux_softc *mux;
- sc->sc_muxdv = wsmux_create("dmux", sc->sc_dv.dv_unit);
- if (!sc->sc_muxdv)
+ if (kbdmux >= 0)
+ mux = wsmux_getmux(kbdmux);
+ else
+ mux = wsmux_create("dmux", sc->sc_dv.dv_unit);
+ /* XXX panic()ing isn't nice, but attach cannot fail */
+ if (mux == NULL)
panic("wsdisplay_common_attach: no memory");
- sc->sc_muxdv->sc_displaydv = &sc->sc_dv;
+ sc->sc_input = &mux->sc_base;
+ mux->sc_displaydv = &sc->sc_dv;
+ if (kbdmux >= 0)
+ printf(" mux %d", kbdmux);
+#else
+#if 0 /* not worth keeping, especially since the default value is not -1... */
+ if (kbdmux >= 0)
+ printf(" (mux ignored)");
#endif
+#endif /* NWSMUX > 0 */
+#endif /* NWSKBD > 0 */
sc->sc_isconsole = console;
@@ -710,8 +689,12 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
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;
@@ -720,6 +703,10 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
}
printf("\n");
+#if NWSKBD > 0 && NWSMUX > 0
+ wsmux_set_display(mux, &sc->sc_dv);
+#endif
+
sc->sc_accessops = accessops;
sc->sc_accesscookie = accesscookie;
sc->sc_scrdata = scrdata;
@@ -738,7 +725,7 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
wsdisplay_addscreen_print(sc, start, i-start);
sc->sc_burnoutintvl = (hz * WSDISPLAY_DEFBURNOUT) / 1000;
- sc->sc_burninintvl = (hz * WSDISPLAY_DEFBURNIN ) / 1000;
+ sc->sc_burninintvl = (hz * WSDISPLAY_DEFBURNIN ) / 1000;
sc->sc_burnflags = 0; /* off by default */
timeout_set(&sc->sc_burner, wsdisplay_burner, sc);
sc->sc_burnout = sc->sc_burnoutintvl;
@@ -750,11 +737,8 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
}
void
-wsdisplay_cnattach(type, cookie, ccol, crow, defattr)
- const struct wsscreen_descr *type;
- void *cookie;
- int ccol, crow;
- long defattr;
+wsdisplay_cnattach(const struct wsscreen_descr *type, void *cookie, int ccol,
+ int crow, long defattr)
{
const struct wsemul_ops *wsemul;
@@ -770,9 +754,8 @@ wsdisplay_cnattach(type, cookie, ccol, crow, defattr)
wsemul = wsemul_pick(""); /* default */
wsdisplay_console_conf.wsemul = wsemul;
- wsdisplay_console_conf.wsemulcookie = (*wsemul->cnattach)(type, cookie,
- ccol, crow,
- defattr);
+ wsdisplay_console_conf.wsemulcookie =
+ (*wsemul->cnattach)(type, cookie, ccol, crow, defattr);
cn_tab = &wsdisplay_cons;
@@ -783,10 +766,7 @@ wsdisplay_cnattach(type, cookie, ccol, crow, defattr)
* Tty and cdevsw functions.
*/
int
-wsdisplayopen(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
+wsdisplayopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct wsdisplay_softc *sc;
struct tty *tp;
@@ -803,8 +783,7 @@ wsdisplayopen(dev, flag, mode, p)
if (WSDISPLAYSCREEN(dev) >= WSDISPLAY_MAXSCREEN)
return (ENXIO);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
- if (!scr)
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
return (ENXIO);
if (WSSCREEN_HAS_TTY(scr)) {
@@ -846,10 +825,7 @@ wsdisplayopen(dev, flag, mode, p)
}
int
-wsdisplayclose(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
+wsdisplayclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct wsdisplay_softc *sc;
struct tty *tp;
@@ -862,7 +838,8 @@ wsdisplayclose(dev, flag, mode, p)
if (ISWSDISPLAYCTL(dev))
return (0);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (ENXIO);
if (WSSCREEN_HAS_TTY(scr)) {
if (scr->scr_hold_screen) {
@@ -895,7 +872,7 @@ wsdisplayclose(dev, flag, mode, p)
if (scr->scr_rawkbd) {
int kbmode = WSKBD_TRANSLATED;
(void) wsdisplay_internal_ioctl(sc, scr, WSKBDIO_SETMODE,
- (caddr_t)&kbmode, 0, p);
+ (caddr_t)&kbmode, 0, p);
}
#endif
@@ -912,10 +889,7 @@ wsdisplayclose(dev, flag, mode, p)
}
int
-wsdisplayread(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
+wsdisplayread(dev_t dev, struct uio *uio, int flag)
{
struct wsdisplay_softc *sc;
struct tty *tp;
@@ -928,7 +902,8 @@ wsdisplayread(dev, uio, flag)
if (ISWSDISPLAYCTL(dev))
return (0);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (ENXIO);
if (!WSSCREEN_HAS_TTY(scr))
return (ENODEV);
@@ -938,10 +913,7 @@ wsdisplayread(dev, uio, flag)
}
int
-wsdisplaywrite(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
+wsdisplaywrite(dev_t dev, struct uio *uio, int flag)
{
struct wsdisplay_softc *sc;
struct tty *tp;
@@ -954,7 +926,8 @@ wsdisplaywrite(dev, uio, flag)
if (ISWSDISPLAYCTL(dev))
return (0);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (ENXIO);
if (!WSSCREEN_HAS_TTY(scr))
return (ENODEV);
@@ -964,8 +937,7 @@ wsdisplaywrite(dev, uio, flag)
}
struct tty *
-wsdisplaytty(dev)
- dev_t dev;
+wsdisplaytty(dev_t dev)
{
struct wsdisplay_softc *sc;
int unit;
@@ -977,18 +949,14 @@ wsdisplaytty(dev)
if (ISWSDISPLAYCTL(dev))
panic("wsdisplaytty() on ctl device");
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (NULL);
return (scr->scr_tty);
}
int
-wsdisplayioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsdisplayioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct wsdisplay_softc *sc;
struct tty *tp;
@@ -1007,7 +975,8 @@ wsdisplayioctl(dev, cmd, data, flag, p)
if (ISWSDISPLAYCTL(dev))
return (wsdisplay_cfg_ioctl(sc, cmd, data, flag, p));
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (ENXIO);
if (WSSCREEN_HAS_TTY(scr)) {
tp = scr->scr_tty;
@@ -1036,28 +1005,23 @@ wsdisplayioctl(dev, cmd, data, flag, p)
}
int
-wsdisplay_param(dev, cmd, dp)
- struct device *dev;
- u_long cmd;
- struct wsdisplay_param *dp;
+wsdisplay_param(struct device *dev, u_long cmd, struct wsdisplay_param *dp)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
+
return ((*sc->sc_accessops->ioctl)(sc->sc_accesscookie, cmd,
- (caddr_t)dp, 0, NULL));
+ (caddr_t)dp, 0, NULL));
}
int
-wsdisplay_internal_ioctl(sc, scr, cmd, data, flag, p)
- struct wsdisplay_softc *sc;
- struct wsscreen *scr;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr,
+ u_long cmd, caddr_t data, int flag, struct proc *p)
{
int error;
#if NWSKBD > 0
+ struct wsevsrc *inp;
+
#ifdef WSDISPLAY_COMPAT_RAWKBD
switch (cmd) {
case WSKBDIO_SETMODE:
@@ -1069,7 +1033,10 @@ wsdisplay_internal_ioctl(sc, scr, cmd, data, flag, p)
return (0);
}
#endif
- error = wsmux_displayioctl(&sc->sc_muxdv->sc_dv, cmd, data, flag, p);
+ inp = sc->sc_input;
+ if (inp == NULL)
+ return (ENXIO);
+ error = wsevsrc_display_ioctl(inp, cmd, data, flag, p);
if (error >= 0)
return (error);
#endif /* NWSKBD > 0 */
@@ -1214,18 +1181,14 @@ wsdisplay_internal_ioctl(sc, scr, cmd, data, flag, p)
}
int
-wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
- struct wsdisplay_softc *sc;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data,
+ int flag, struct proc *p)
{
int error;
void *buf;
size_t fontsz;
-#if defined(COMPAT_14) && NWSKBD > 0
- struct wsmux_device wsmuxdata;
+#if NWSKBD > 0
+ struct wsevsrc *inp;
#endif
switch (cmd) {
@@ -1286,43 +1249,19 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
#undef d
#if NWSKBD > 0
-#ifdef COMPAT_14
- case _O_WSDISPLAYIO_SETKEYBOARD:
-#define d ((struct wsdisplay_kbddata *)data)
- switch (d->op) {
- case _O_WSDISPLAY_KBD_ADD:
- if (d->idx == -1) {
- d->idx = wskbd_pickfree();
- if (d->idx == -1)
- return (ENXIO);
- }
- 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
-#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;
+ if (inp == NULL)
+ return (ENXIO);
+ return (wsevsrc_ioctl(inp, cmd, data, flag,p));
#endif /* NWSKBD > 0 */
}
@@ -1330,10 +1269,7 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
}
paddr_t
-wsdisplaymmap(dev, offset, prot)
- dev_t dev;
- off_t offset;
- int prot;
+wsdisplaymmap(dev_t dev, off_t offset, int prot)
{
struct wsdisplay_softc *sc = wsdisplay_cd.cd_devs[WSDISPLAYUNIT(dev)];
struct wsscreen *scr;
@@ -1341,7 +1277,8 @@ wsdisplaymmap(dev, offset, prot)
if (ISWSDISPLAYCTL(dev))
return (-1);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (-1);
if (!(scr->scr_flags & SCR_GRAPHICS))
return (-1);
@@ -1351,10 +1288,7 @@ wsdisplaymmap(dev, offset, prot)
}
int
-wsdisplaypoll(dev, events, p)
- dev_t dev;
- int events;
- struct proc *p;
+wsdisplaypoll(dev_t dev, int events, struct proc *p)
{
struct wsdisplay_softc *sc = wsdisplay_cd.cd_devs[WSDISPLAYUNIT(dev)];
struct wsscreen *scr;
@@ -1362,18 +1296,17 @@ wsdisplaypoll(dev, events, p)
if (ISWSDISPLAYCTL(dev))
return (0);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (ENXIO);
- if (WSSCREEN_HAS_TTY(scr))
- return (ttpoll(dev, events, p));
- else
- return (0);
+ if (!WSSCREEN_HAS_TTY(scr))
+ return (ENODEV);
+
+ return (ttpoll(dev, events, p));
}
int
-wsdisplaykqfilter(dev, kn)
- dev_t dev;
- struct knote *kn;
+wsdisplaykqfilter(dev_t dev, struct knote *kn)
{
struct wsdisplay_softc *sc = wsdisplay_cd.cd_devs[WSDISPLAYUNIT(dev)];
struct wsscreen *scr;
@@ -1381,7 +1314,8 @@ wsdisplaykqfilter(dev, kn)
if (ISWSDISPLAYCTL(dev))
return (1);
- scr = sc->sc_scr[WSDISPLAYSCREEN(dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(dev)]) == NULL)
+ return (1);
if (WSSCREEN_HAS_TTY(scr))
return (ttkqfilter(dev, kn));
@@ -1390,8 +1324,7 @@ wsdisplaykqfilter(dev, kn)
}
void
-wsdisplaystart(tp)
- struct tty *tp;
+wsdisplaystart(struct tty *tp)
{
struct wsdisplay_softc *sc;
struct wsscreen *scr;
@@ -1411,7 +1344,10 @@ wsdisplaystart(tp)
if (tp->t_outq.c_cc == 0 && tp->t_wsel.si_selpid == 0)
goto low;
- scr = sc->sc_scr[WSDISPLAYSCREEN(tp->t_dev)];
+ if ((scr = sc->sc_scr[WSDISPLAYSCREEN(tp->t_dev)]) == NULL) {
+ splx(s);
+ return;
+ }
if (scr->scr_hold_screen) {
tp->t_state |= TS_TIMEOUT;
splx(s);
@@ -1463,13 +1399,14 @@ wsdisplaystart(tp)
s = spltty();
tp->t_state &= ~TS_BUSY;
-
- tp->t_state |= TS_TIMEOUT;
- timeout_add(&tp->t_rstrt_to, (hz > 128) ? (hz / 128) : 1);
-
+ /* Come back if there's more to do */
+ if (tp->t_outq.c_cc) {
+ tp->t_state |= TS_TIMEOUT;
+ timeout_add(&tp->t_rstrt_to, (hz > 128) ? (hz / 128) : 1);
+ }
if (tp->t_outq.c_cc <= tp->t_lowat) {
low:
- if (tp->t_state&TS_ASLEEP) {
+ if (tp->t_state & TS_ASLEEP) {
tp->t_state &= ~TS_ASLEEP;
wakeup((caddr_t)&tp->t_outq);
}
@@ -1479,9 +1416,7 @@ low:
}
int
-wsdisplaystop(tp, flag)
- struct tty *tp;
- int flag;
+wsdisplaystop(struct tty *tp, int flag)
{
int s;
@@ -1496,9 +1431,7 @@ wsdisplaystop(tp, flag)
/* Set line parameters. */
int
-wsdisplayparam(tp, t)
- struct tty *tp;
- struct termios *t;
+wsdisplayparam(struct tty *tp, struct termios *t)
{
tp->t_ispeed = t->c_ispeed;
@@ -1511,8 +1444,7 @@ wsdisplayparam(tp, t)
* Callbacks for the emulation code.
*/
void
-wsdisplay_emulbell(v)
- void *v;
+wsdisplay_emulbell(void *v)
{
struct wsscreen *scr = v;
@@ -1523,14 +1455,11 @@ wsdisplay_emulbell(v)
return;
(void) wsdisplay_internal_ioctl(scr->sc, scr, WSKBDIO_BELL, NULL,
- FWRITE, NULL);
+ FWRITE, NULL);
}
void
-wsdisplay_emulinput(v, data, count)
- void *v;
- const u_char *data;
- u_int count;
+wsdisplay_emulinput(void *v, const u_char *data, u_int count)
{
struct wsscreen *scr = v;
struct tty *tp;
@@ -1552,9 +1481,7 @@ wsdisplay_emulinput(v, data, count)
* Calls from the keyboard interface.
*/
void
-wsdisplay_kbdinput(dev, ks)
- struct device *dev;
- keysym_t ks;
+wsdisplay_kbdinput(struct device *dev, keysym_t ks)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
struct wsscreen *scr;
@@ -1583,35 +1510,40 @@ wsdisplay_kbdinput(dev, ks)
#ifdef WSDISPLAY_COMPAT_RAWKBD
int
-wsdisplay_update_rawkbd(sc, scr)
- struct wsdisplay_softc *sc;
- struct wsscreen *scr;
+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);
- if (scr != sc->sc_focus ||
- sc->sc_rawkbd == raw) {
+ if (scr != sc->sc_focus || sc->sc_rawkbd == raw) {
splx(s);
return (0);
}
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;
+ if (inp == NULL) {
+ splx(s);
+ return (ENXIO);
+ }
+ 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
int
-wsdisplay_switch3(arg, error, waitok)
- void *arg;
- int error, waitok;
+wsdisplay_switch3(void *arg, int error, int waitok)
{
struct wsdisplay_softc *sc = arg;
int no;
@@ -1640,7 +1572,7 @@ wsdisplay_switch3(arg, error, waitok)
#ifdef WSDISPLAY_COMPAT_RAWKBD
wsdisplay_update_rawkbd(sc, 0);
#endif
- sc->sc_flags &= ~SC_SWITCHPENDING;
+ sc->sc_flags &= ~SC_SWITCHPENDING;
return (error);
}
@@ -1657,9 +1589,7 @@ wsdisplay_switch3(arg, error, waitok)
}
int
-wsdisplay_switch2(arg, error, waitok)
- void *arg;
- int error, waitok;
+wsdisplay_switch2(void *arg, int error, int waitok)
{
struct wsdisplay_softc *sc = arg;
int no;
@@ -1705,7 +1635,8 @@ wsdisplay_switch2(arg, error, waitok)
#define wsswitch_cb3 ((void (*)(void *, int, int))wsdisplay_switch3)
if (scr->scr_syncops) {
error = (*scr->scr_syncops->attach)(scr->scr_synccookie, waitok,
- sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb3, sc);
+ sc->sc_isconsole && wsdisplay_cons_pollmode ?
+ 0 : wsswitch_cb3, sc);
if (error == EAGAIN) {
/* switch will be done asynchronously */
return (0);
@@ -1716,9 +1647,7 @@ wsdisplay_switch2(arg, error, waitok)
}
int
-wsdisplay_switch1(arg, error, waitok)
- void *arg;
- int error, waitok;
+wsdisplay_switch1(void *arg, int error, int waitok)
{
struct wsdisplay_softc *sc = arg;
int no;
@@ -1753,9 +1682,8 @@ wsdisplay_switch1(arg, error, waitok)
#define wsswitch_cb2 ((void (*)(void *, int, int))wsdisplay_switch2)
error = (*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
- scr->scr_dconf->emulcookie,
- waitok,
- sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb2, sc);
+ scr->scr_dconf->emulcookie, waitok,
+ sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb2, sc);
if (error == EAGAIN) {
/* switch will be done asynchronously */
return (0);
@@ -1765,18 +1693,18 @@ wsdisplay_switch1(arg, error, waitok)
}
int
-wsdisplay_switch(dev, no, waitok)
- struct device *dev;
- int no, waitok;
+wsdisplay_switch(struct device *dev, int no, int waitok)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
int s, res = 0;
struct wsscreen *scr;
-
- if (no != WSDISPLAY_NULLSCREEN &&
- (no < 0 || no >= WSDISPLAY_MAXSCREEN || !sc->sc_scr[no]))
- return (ENXIO);
+ if (no != WSDISPLAY_NULLSCREEN) {
+ if (no < 0 || no >= WSDISPLAY_MAXSCREEN)
+ return (EINVAL);
+ if (sc->sc_scr[no] == NULL)
+ return (ENXIO);
+ }
s = spltty();
@@ -1818,7 +1746,6 @@ wsdisplay_switch(dev, no, waitok)
* SCR_GRAPHICS when X-Window stops. In this case, the first of the
* three following 'if' statements is evaluated.
* We handle wsmoused(8) events the WSDISPLAYIO_SMODE ioctl.
- *
*/
if (!(scr->scr_flags & SCR_GRAPHICS) &&
@@ -1850,7 +1777,8 @@ wsdisplay_switch(dev, no, waitok)
#define wsswitch_cb1 ((void (*)(void *, int, int))wsdisplay_switch1)
if (scr->scr_syncops) {
res = (*scr->scr_syncops->detach)(scr->scr_synccookie, waitok,
- sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb1, sc);
+ sc->sc_isconsole && wsdisplay_cons_pollmode ?
+ 0 : wsswitch_cb1, sc);
if (res == EAGAIN) {
/* switch will be done asynchronously */
return (0);
@@ -1864,9 +1792,7 @@ wsdisplay_switch(dev, no, waitok)
}
void
-wsdisplay_reset(dev, op)
- struct device *dev;
- enum wsdisplay_resetops op;
+wsdisplay_reset(struct device *dev, enum wsdisplay_resetops op)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
struct wsscreen *scr;
@@ -1882,7 +1808,7 @@ wsdisplay_reset(dev, op)
if (!WSSCREEN_HAS_EMULATOR(scr))
break;
(*scr->scr_dconf->wsemul->reset)(scr->scr_dconf->wsemulcookie,
- WSEMUL_RESET);
+ WSEMUL_RESET);
break;
case WSDISPLAY_RESETCLOSE:
wsdisplay_closescreen(sc, scr);
@@ -1894,10 +1820,8 @@ wsdisplay_reset(dev, op)
* Interface for (external) VT switch / process synchronization code
*/
int
-wsscreen_attach_sync(scr, ops, cookie)
- struct wsscreen *scr;
- const struct wscons_syncops *ops;
- void *cookie;
+wsscreen_attach_sync(struct wsscreen *scr, const struct wscons_syncops *ops,
+ void *cookie)
{
if (scr->scr_syncops) {
/*
@@ -1913,8 +1837,7 @@ wsscreen_attach_sync(scr, ops, cookie)
}
int
-wsscreen_detach_sync(scr)
- struct wsscreen *scr;
+wsscreen_detach_sync(struct wsscreen *scr)
{
if (!scr->scr_syncops)
return (EINVAL);
@@ -1923,10 +1846,9 @@ wsscreen_detach_sync(scr)
}
int
-wsscreen_lookup_sync(scr, ops, cookiep)
- struct wsscreen *scr;
- const struct wscons_syncops *ops; /* used as ID */
- void **cookiep;
+wsscreen_lookup_sync(struct wsscreen *scr,
+ const struct wscons_syncops *ops, /* used as ID */
+ void **cookiep)
{
if (!scr->scr_syncops || ops != scr->scr_syncops)
return (EINVAL);
@@ -1938,16 +1860,13 @@ wsscreen_lookup_sync(scr, ops, cookiep)
* Interface to virtual screen stuff
*/
int
-wsdisplay_maxscreenidx(sc)
- struct wsdisplay_softc *sc;
+wsdisplay_maxscreenidx(struct wsdisplay_softc *sc)
{
return (WSDISPLAY_MAXSCREEN - 1);
}
int
-wsdisplay_screenstate(sc, idx)
- struct wsdisplay_softc *sc;
- int idx;
+wsdisplay_screenstate(struct wsdisplay_softc *sc, int idx)
{
if (idx < 0 || idx >= WSDISPLAY_MAXSCREEN)
return (EINVAL);
@@ -1957,16 +1876,13 @@ wsdisplay_screenstate(sc, idx)
}
int
-wsdisplay_getactivescreen(sc)
- struct wsdisplay_softc *sc;
+wsdisplay_getactivescreen(struct wsdisplay_softc *sc)
{
return (sc->sc_focus ? sc->sc_focusidx : WSDISPLAY_NULLSCREEN);
}
int
-wsscreen_switchwait(sc, no)
- struct wsdisplay_softc *sc;
- int no;
+wsscreen_switchwait(struct wsdisplay_softc *sc, int no)
{
struct wsscreen *scr;
int s, res = 0;
@@ -2000,9 +1916,7 @@ wsscreen_switchwait(sc, no)
}
void
-wsdisplay_kbdholdscreen(dev, hold)
- struct device *dev;
- int hold;
+wsdisplay_kbdholdscreen(struct device *dev, int hold)
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
struct wsscreen *scr;
@@ -2018,15 +1932,23 @@ wsdisplay_kbdholdscreen(dev, hold)
}
#if NWSKBD > 0
-struct device *
-wsdisplay_set_console_kbd(kbddv)
- struct device *kbddv;
+void
+wsdisplay_set_console_kbd(struct wsevsrc *src)
{
- if (!wsdisplay_console_device)
- return (0);
- if (wskbd_add_mux(kbddv->dv_unit, wsdisplay_console_device->sc_muxdv))
- return (0);
- return (&wsdisplay_console_device->sc_dv);
+ if (wsdisplay_console_device == NULL) {
+ src->me_dispdv = NULL;
+ return;
+ }
+#if NWSMUX > 0
+ if (wsmux_attach_sc((struct wsmux_softc *)
+ wsdisplay_console_device->sc_input, src)) {
+ src->me_dispdv = NULL;
+ return;
+ }
+#else
+ wsdisplay_console_device->sc_input = src;
+#endif
+ src->me_dispdv = &wsdisplay_console_device->sc_dv;
}
#endif /* NWSKBD > 0 */
@@ -2034,9 +1956,7 @@ wsdisplay_set_console_kbd(kbddv)
* Console interface.
*/
void
-wsdisplay_cnputc(dev, i)
- dev_t dev;
- int i;
+wsdisplay_cnputc(dev_t dev, int i)
{
struct wsscreen_internal *dc;
char c = i;
@@ -2045,6 +1965,7 @@ wsdisplay_cnputc(dev, i)
return;
if (wsdisplay_console_device != NULL &&
+ (wsdisplay_console_device->sc_scr[0] != NULL) &&
(wsdisplay_console_device->sc_scr[0]->scr_flags & SCR_GRAPHICS))
return;
@@ -2054,29 +1975,23 @@ wsdisplay_cnputc(dev, i)
}
int
-wsdisplay_getc_dummy(dev)
- dev_t dev;
+wsdisplay_getc_dummy(dev_t dev)
{
/* panic? */
return (0);
}
void
-wsdisplay_pollc(dev, on)
- dev_t dev;
- int on;
+wsdisplay_pollc(dev_t dev, int on)
{
- struct wsdisplay_softc *sc = NULL;
- int unit = WSDISPLAYUNIT(dev);
-
- if (unit < wsdisplay_cd.cd_ndevs)
- sc = wsdisplay_cd.cd_devs[unit];
wsdisplay_cons_pollmode = on;
/* notify to fb drivers */
- if (sc != NULL && sc->sc_accessops->pollc != NULL)
- (*sc->sc_accessops->pollc)(sc->sc_accesscookie, on);
+ if (wsdisplay_console_device != NULL &&
+ wsdisplay_console_device->sc_accessops->pollc != NULL)
+ (*wsdisplay_console_device->sc_accessops->pollc)
+ (wsdisplay_console_device->sc_accesscookie, on);
/* notify to kbd drivers */
if (wsdisplay_cons_kbd_pollc)
@@ -2084,10 +1999,8 @@ wsdisplay_pollc(dev, on)
}
void
-wsdisplay_set_cons_kbd(get, poll, bell)
- int (*get)(dev_t);
- void (*poll)(dev_t, int);
- void (*bell)(dev_t, u_int, u_int, u_int);
+wsdisplay_set_cons_kbd(int (*get)(dev_t), void (*poll)(dev_t, int),
+ void (*bell)(dev_t, u_int, u_int, u_int))
{
wsdisplay_cons.cn_getc = get;
wsdisplay_cons.cn_bell = bell;
@@ -2113,16 +2026,15 @@ wsdisplay_switchtoconsole()
if (wsdisplay_console_device != NULL) {
sc = wsdisplay_console_device;
- scr = sc->sc_scr[0];
+ if ((scr = sc->sc_scr[0]) == NULL)
+ return;
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
scr->scr_dconf->emulcookie, 0, NULL, NULL);
}
}
void
-wsscrollback(arg, op)
- void *arg;
- int op;
+wsscrollback(void *arg, int op)
{
struct wsdisplay_softc *sc = arg;
int lines;
@@ -2142,9 +2054,7 @@ wsscrollback(arg, op)
}
void
-wsdisplay_burn(v, flags)
- void *v;
- u_int flags;
+wsdisplay_burn(void *v, u_int flags)
{
struct wsdisplay_softc *sc = v;
@@ -2159,8 +2069,7 @@ wsdisplay_burn(v, flags)
}
void
-wsdisplay_burner(v)
- void *v;
+wsdisplay_burner(void *v)
{
struct wsdisplay_softc *sc = v;
int s;
@@ -2183,8 +2092,7 @@ wsdisplay_burner(v)
* Switch the console at shutdown.
*/
void
-wsdisplay_shutdownhook(arg)
- void *arg;
+wsdisplay_shutdownhook(void *arg)
{
wsdisplay_switchtoconsole();
}
@@ -2202,7 +2110,7 @@ static struct wsdisplay_softc *sc = NULL;
*/
int
wsmoused(struct wsdisplay_softc *ws_sc, u_long cmd, caddr_t data,
- int flag, struct proc *p)
+ int flag, struct proc *p)
{
int error = -1;
struct wscons_event mouse_event = *(struct wscons_event *)data;
@@ -2555,7 +2463,8 @@ static const int charClass[256] = {
/* d n~ o` o' o^ o~ o: -: */
48, 48, 48, 48, 48, 48, 48, 248,
/* o/ u` u' u^ u: y' P y: */
- 48, 48, 48, 48, 48, 48, 48, 48};
+ 48, 48, 48, 48, 48, 48, 48, 48
+};
/*
* Find the first blank beginning after the current cursor position
diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h
index 3b13326aa62..0a8e2e9f0cc 100644
--- a/sys/dev/wscons/wsdisplayvar.h
+++ b/sys/dev/wscons/wsdisplayvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsdisplayvar.h,v 1.14 2002/07/25 19:03:25 miod Exp $ */
-/* $NetBSD: wsdisplayvar.h,v 1.14.4.1 2000/06/30 16:27:53 simonb Exp $ */
+/* $OpenBSD: wsdisplayvar.h,v 1.15 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsdisplayvar.h,v 1.30 2005/02/04 02:10:49 perry Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -163,6 +163,10 @@ struct wsemuldisplaydev_attach_args {
#define WSEMULDISPLAYDEVCF_CONSOLE 0
#define wsemuldisplaydevcf_console cf_loc[WSEMULDISPLAYDEVCF_CONSOLE] /* spec'd as console? */
#define WSEMULDISPLAYDEVCF_CONSOLE_UNK -1
+#define WSDISPLAYDEVCF_MUX 0
+#define wsdisplaydevcf_mux cf_loc[WSDISPLAYDEVCF_MUX]
+#define WSEMULDISPLAYDEVCF_MUX 1
+#define wsemuldisplaydevcf_mux cf_loc[WSEMULDISPLAYDEVCF_MUX]
struct wscons_syncops {
int (*detach)(void *, int, void (*)(void *, int, int), void *);
diff --git a/sys/dev/wscons/wsevent.c b/sys/dev/wscons/wsevent.c
index 2d2948e96d9..627663f90ca 100644
--- a/sys/dev/wscons/wsevent.c
+++ b/sys/dev/wscons/wsevent.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsevent.c,v 1.3 2003/06/02 23:28:04 millert Exp $ */
-/* $NetBSD: wsevent.c,v 1.5 2000/03/30 12:45:44 augustss Exp $ */
+/* $OpenBSD: wsevent.c,v 1.4 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsevent.c,v 1.16 2003/08/07 16:31:29 agc Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -93,25 +93,35 @@
* Initialize a wscons_event queue.
*/
void
-wsevent_init(ev)
- struct wseventvar *ev;
+wsevent_init(struct wseventvar *ev)
{
+ if (ev->q != NULL) {
+#ifdef DIAGNOSTIC
+ printf("wsevent_init: already initialized\n");
+#endif
+ return;
+ }
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));
+ bzero((caddr_t)ev->q, WSEVENT_QSIZE * sizeof(struct wscons_event));
}
/*
* Tear down a wscons_event queue.
*/
void
-wsevent_fini(ev)
- struct wseventvar *ev;
+wsevent_fini(struct wseventvar *ev)
{
-
+ if (ev->q == NULL) {
+#ifdef DIAGNOSTIC
+ printf("wsevent_fini: already invoked\n");
+#endif
+ return;
+ }
free(ev->q, M_DEVBUF);
+ ev->q = NULL;
}
/*
@@ -119,10 +129,7 @@ wsevent_fini(ev)
* (User cannot write an event queue.)
*/
int
-wsevent_read(ev, uio, flags)
- struct wseventvar *ev;
- struct uio *uio;
- int flags;
+wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
{
int s, n, cnt, error;
@@ -138,7 +145,7 @@ wsevent_read(ev, uio, 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);
@@ -177,15 +184,12 @@ wsevent_read(ev, uio, flags)
}
int
-wsevent_poll(ev, events, p)
- struct wseventvar *ev;
- int events;
- struct proc *p;
+wsevent_poll(struct wseventvar *ev, int events, struct proc *p)
{
int revents = 0;
int s = splwsevent();
- if (events & (POLLIN | POLLRDNORM)) {
+ if (events & (POLLIN | POLLRDNORM)) {
if (ev->get != ev->put)
revents |= events & (POLLIN | POLLRDNORM);
else
diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c
index 21894d8077c..c011d8958c0 100644
--- a/sys/dev/wscons/wskbd.c
+++ b/sys/dev/wscons/wskbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wskbd.c,v 1.41 2004/06/24 19:35:24 tholo Exp $ */
-/* $NetBSD: wskbd.c,v 1.38 2000/03/23 07:01:47 thorpej Exp $ */
+/* $OpenBSD: wskbd.c,v 1.42 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -34,8 +34,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -103,9 +101,9 @@
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>
+#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wseventvar.h>
#include <dev/wscons/wscons_callbacks.h>
-#include <dev/wscons/wsdisplayvar.h>
#include "wsdisplay.h"
#include "wsmux.h"
@@ -131,7 +129,7 @@ struct wskbd_internal {
int t_composelen; /* remaining entries in t_composebuf */
keysym_t t_composebuf[2];
- int t_flags;
+ int t_flags;
#define WSKFL_METAESC 1
#define MAXKEYSYMSPERKEY 2 /* ESC <key> at max */
@@ -141,7 +139,7 @@ struct wskbd_internal {
};
struct wskbd_softc {
- struct device sc_dv;
+ struct wsevsrc sc_base;
struct wskbd_internal *id;
@@ -150,12 +148,7 @@ struct wskbd_softc {
int sc_ledstate;
- 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;
@@ -163,19 +156,17 @@ struct wskbd_softc {
int sc_repeating; /* we've called timeout() */
int sc_repkey;
struct timeout sc_repeat_ch;
+ u_int sc_repeat_type;
+ int sc_repeat_value;
int sc_translating; /* xlate to chars for emulation */
int sc_maplen; /* number of entries in sc_map */
struct wscons_keymap *sc_map; /* current translation map */
- kbd_t sc_layout; /* current layout */
+ kbd_t sc_layout; /* current layout */
- int sc_refcnt;
- u_char sc_dying; /* device is being detached */
-
-#if NWSMUX > 0 || NWSDISPLAY > 0
- struct wsmux_softc *sc_mux;
-#endif
+ int sc_refcnt;
+ u_char sc_dying; /* device is being detached */
};
#define MOD_SHIFT_L (1 << 0)
@@ -199,7 +190,6 @@ struct wskbd_softc {
#define MOD_ANYCONTROL (MOD_CONTROL_L | MOD_CONTROL_R)
#define MOD_ANYMETA (MOD_META_L | MOD_META_R)
- /* these should result in precise 0 or 1, see wskbd_translate() XXX */
#define MOD_ONESET(id, mask) (((id)->t_modifiers & (mask)) != 0)
#define MOD_ALLSET(id, mask) (((id)->t_modifiers & (mask)) == (mask))
@@ -210,26 +200,37 @@ void wskbd_attach(struct device *, struct device *, void *);
int wskbd_detach(struct device *, int);
int wskbd_activate(struct device *, enum devact);
-int wskbd_displayioctl(struct device *, u_long, caddr_t, int, struct proc *p);
-int wskbd_set_display(struct device *, struct wsmux_softc *);
-int wskbd_isset_display(struct device *);
+int wskbd_displayioctl(struct device *, u_long, caddr_t, int, struct proc *);
+#if NWSDISPLAY > 0
+int wskbd_set_display(struct device *, struct wsevsrc *);
+#else
+#define wskbd_set_display NULL
+#endif
-inline void update_leds(struct wskbd_internal *);
-inline void update_modifier(struct wskbd_internal *, u_int, int, int);
-int internal_command(struct wskbd_softc *, u_int *, keysym_t, keysym_t);
-int wskbd_translate(struct wskbd_internal *, u_int, int);
-int wskbd_enable(struct wskbd_softc *, int);
+void update_leds(struct wskbd_internal *);
+void update_modifier(struct wskbd_internal *, u_int, int, int);
+int internal_command(struct wskbd_softc *, u_int *, keysym_t, keysym_t);
+int wskbd_translate(struct wskbd_internal *, u_int, int);
+int wskbd_enable(struct wskbd_softc *, int);
#if NWSDISPLAY > 0
-void change_displayparam(struct wskbd_softc *, int, int, int);
-void wskbd_holdscreen(struct wskbd_softc *, int);
+void change_displayparam(struct wskbd_softc *, int, int, int);
+void wskbd_holdscreen(struct wskbd_softc *, int);
#endif
-int wskbd_do_ioctl(struct wskbd_softc *, u_long, caddr_t,
- int, struct proc *);
+int wskbd_do_ioctl_sc(struct wskbd_softc *, u_long, caddr_t, int,
+ struct proc *);
+void wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value);
+
+#if NWSMUX > 0
+int wskbd_mux_open(struct wsevsrc *, struct wseventvar *);
+int wskbd_mux_close(struct wsevsrc *);
+#else
+#define wskbd_mux_open NULL
+#define wskbd_mux_close NULL
+#endif
-int wskbddoclose(struct device *, int, int, struct proc *);
-int wskbddoioctl(struct device *, u_long, caddr_t, int,
- struct proc *);
+int wskbd_do_open(struct wskbd_softc *, struct wseventvar *);
+int wskbd_do_ioctl(struct device *, u_long, caddr_t, int, struct proc *);
struct cfdriver wskbd_cd = {
NULL, "wskbd", DV_TTY
@@ -240,8 +241,6 @@ struct cfattach wskbd_ca = {
wskbd_detach, wskbd_activate
};
-extern struct cfdriver wskbd_cd;
-
extern int kbd_reset;
#ifndef WSKBD_DEFAULT_BELL_PITCH
@@ -275,9 +274,10 @@ struct wskbd_keyrepeat_data wskbd_default_keyrepeat_data = {
};
#if NWSMUX > 0 || NWSDISPLAY > 0
-struct wsmuxops wskbd_muxops = {
- wskbdopen, wskbddoclose, wskbddoioctl, wskbd_displayioctl,
- wskbd_set_display, wskbd_isset_display
+struct wssrcops wskbd_srcops = {
+ WSMUX_KBD,
+ wskbd_mux_open, wskbd_mux_close, wskbd_do_ioctl,
+ wskbd_displayioctl, wskbd_set_display
};
#endif
@@ -289,14 +289,11 @@ static int wskbd_console_initted;
static struct wskbd_softc *wskbd_console_device;
static struct wskbd_internal wskbd_console_data;
-void wskbd_update_layout(struct wskbd_internal *, kbd_t);
+void wskbd_update_layout(struct wskbd_internal *, kbd_t);
void
-wskbd_update_layout(id, enc)
- struct wskbd_internal *id;
- kbd_t enc;
+wskbd_update_layout(struct wskbd_internal *id, kbd_t enc)
{
-
if (enc & KB_METAESC)
id->t_flags |= WSKFL_METAESC;
else
@@ -307,9 +304,7 @@ wskbd_update_layout(id, enc)
* Print function (for parent devices).
*/
int
-wskbddevprint(aux, pnp)
- void *aux;
- const char *pnp;
+wskbddevprint(void *aux, const char *pnp)
{
#if 0
struct wskbddev_attach_args *ap = aux;
@@ -325,10 +320,7 @@ wskbddevprint(aux, pnp)
}
int
-wskbd_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+wskbd_match(struct device *parent, void *match, void *aux)
{
struct cfdata *cf = match;
struct wskbddev_attach_args *ap = aux;
@@ -349,36 +341,40 @@ wskbd_match(parent, match, aux)
}
void
-wskbd_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+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 (ap->console) {
+ /* Ignore mux for console; it always goes to the console mux. */
+ /* printf(" (mux %d ignored for console)", mux); */
+ mux = -1;
}
- if (mux != WSKBDDEVCF_MUX_DEFAULT)
+ if (mux >= 0)
printf(" mux %d", mux);
+#else
+#if 0 /* not worth keeping, especially since the default value is not -1... */
+ if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
+ printf(" (mux ignored)");
#endif
+#endif /* NWSMUX > 0 */
if (ap->console) {
sc->id = &wskbd_console_data;
} else {
sc->id = malloc(sizeof(struct wskbd_internal),
- M_DEVBUF, M_WAITOK);
+ M_DEVBUF, M_WAITOK);
bzero(sc->id, sizeof(struct wskbd_internal));
sc->id->t_keymap = ap->keymap;
wskbd_update_layout(sc->id, ap->keymap->layout);
@@ -392,13 +388,12 @@ wskbd_attach(parent, self, aux)
sc->sc_accessops = ap->accessops;
sc->sc_accesscookie = ap->accesscookie;
- sc->sc_events.io = NULL; /* sanity */
sc->sc_repeating = 0;
sc->sc_translating = 1;
sc->sc_ledstate = -1; /* force update */
if (wskbd_load_keymap(sc->id->t_keymap,
- &sc->sc_map, &sc->sc_maplen) != 0)
+ &sc->sc_map, &sc->sc_maplen) != 0)
panic("cannot load keymap");
sc->sc_layout = sc->id->t_keymap->layout;
@@ -416,27 +411,26 @@ wskbd_attach(parent, self, aux)
printf(": console keyboard");
#if NWSDISPLAY > 0
- if ((sc->sc_displaydv = wsdisplay_set_console_kbd(self)))
+ wsdisplay_set_console_kbd(&sc->sc_base); /* sets me_dispdv */
+ if (sc->sc_displaydv != NULL)
printf(", using %s", sc->sc_displaydv->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);
- wsdisplay_set_console_kbd(self);
+ if (mux >= 0) {
+ 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
-wskbd_cnattach(consops, conscookie, mapdata)
- const struct wskbd_consops *consops;
- void *conscookie;
- const struct wskbd_mapdata *mapdata;
+wskbd_cnattach(const struct wskbd_consops *consops, void *conscookie,
+ const struct wskbd_mapdata *mapdata)
{
KASSERT(!wskbd_console_initted);
@@ -473,8 +467,7 @@ wskbd_cndetach()
#if NWSDISPLAY > 0
void
-wskbd_repeat(v)
- void *v;
+wskbd_repeat(void *v)
{
struct wskbd_softc *sc = (struct wskbd_softc *)v;
int s = spltty();
@@ -487,24 +480,33 @@ wskbd_repeat(v)
splx(s);
return;
}
- if (sc->sc_displaydv != NULL) {
- int i;
- for (i = 0; i < sc->sc_repeating; i++)
- wsdisplay_kbdinput(sc->sc_displaydv,
- sc->id->t_symbols[i]);
+ if (sc->sc_translating) {
+ /* deliver keys */
+ if (sc->sc_base.me_dispdv != NULL) {
+ int i;
+ for (i = 0; i < sc->sc_repeating; i++)
+ wsdisplay_kbdinput(sc->sc_base.me_dispdv,
+ sc->id->t_symbols[i]);
+ }
+ } else {
+ /* queue event */
+ wskbd_deliver_event(sc, sc->sc_repeat_type,
+ sc->sc_repeat_value);
}
- timeout_add(&sc->sc_repeat_ch,
- (hz * sc->sc_keyrepeat_data.delN) / 1000);
+ if (sc->sc_keyrepeat_data.delN != 0)
+ timeout_add(&sc->sc_repeat_ch,
+ (hz * sc->sc_keyrepeat_data.delN) / 1000);
splx(s);
}
#endif
int
-wskbd_activate(self, act)
- struct device *self;
- enum devact act;
+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);
}
@@ -517,24 +519,17 @@ wskbd_activate(self, act)
* vnode and return (which will deallocate the softc).
*/
int
-wskbd_detach(self, flags)
- struct device *self;
- int flags;
+wskbd_detach(struct device *self, int flags)
{
struct wskbd_softc *sc = (struct wskbd_softc *)self;
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->wskbddevcf_mux;
- if (mux != WSKBDDEVCF_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
#if NWSDISPLAY > 0
@@ -549,8 +544,8 @@ wskbd_detach(self, flags)
wskbd_console_device = NULL;
}
- 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. */
@@ -560,7 +555,7 @@ wskbd_detach(self, 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);
}
@@ -578,22 +573,21 @@ wskbd_detach(self, flags)
}
void
-wskbd_input(dev, type, value)
- struct device *dev;
- u_int type;
- int value;
+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;
#if NWSDISPLAY > 0
int num, i;
#endif
- int put;
#if NWSDISPLAY > 0
+ if (sc->sc_repeating) {
+ sc->sc_repeating = 0;
+ timeout_del(&sc->sc_repeat_ch);
+ }
+
/*
- * If /dev/wskbd is not connected in event mode translate and
+ * If /dev/wskbdN is not connected in event mode translate and
* send upstream.
*/
if (sc->sc_translating) {
@@ -601,49 +595,74 @@ wskbd_input(dev, type, value)
wsdisplay_burn(sc->sc_displaydv, WSDISPLAY_BURN_KBD);
num = wskbd_translate(sc->id, type, value);
if (num > 0) {
- if (sc->sc_displaydv != NULL) {
+ if (sc->sc_base.me_dispdv != NULL) {
/* XXX - Shift_R+PGUP(release) emits PrtSc */
if (sc->id->t_symbols[0] != KS_Print_Screen) {
- wsscrollback(sc->sc_displaydv,
+ wsscrollback(sc->sc_base.me_dispdv,
WSDISPLAY_SCROLL_RESET);
}
for (i = 0; i < num; i++) {
- wsdisplay_kbdinput(sc->sc_displaydv,
+ wsdisplay_kbdinput(sc->sc_base.me_dispdv,
sc->id->t_symbols[i]);
}
}
- sc->sc_repeating = num;
- timeout_add(&sc->sc_repeat_ch,
- (hz * sc->sc_keyrepeat_data.del1) / 1000);
+ if (sc->sc_keyrepeat_data.del1 != 0) {
+ sc->sc_repeating = num;
+ timeout_add(&sc->sc_repeat_ch,
+ (hz * sc->sc_keyrepeat_data.del1) / 1000);
+ }
}
return;
}
#endif
- /*
- * Keyboard is generating events. Turn this keystroke into an
- * event and put it in the queue. If the queue is full, the
- * keystroke is lost (sorry!).
- */
+ wskbd_deliver_event(sc, type, value);
+
+#if NWSDISPLAY > 0
+ /* Repeat key presses if enabled. */
+ if (type == WSCONS_EVENT_KEY_DOWN && sc->sc_keyrepeat_data.del1 != 0) {
+ sc->sc_repeat_type = type;
+ sc->sc_repeat_value = value;
+ sc->sc_repeating = 1;
+ timeout_add(&sc->sc_repeat_ch,
+ (hz * sc->sc_keyrepeat_data.del1) / 1000);
+ }
+#endif
+}
- /* no one to receive; punt!*/
- if (sc->sc_events.io == NULL)
+/*
+ * Keyboard is generating events. Turn this keystroke into an
+ * event and put it in the queue. If the queue is full, the
+ * keystroke is lost (sorry!).
+ */
+void
+wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
+{
+ struct wseventvar *evar;
+ struct wscons_event *ev;
+ int put;
+
+ 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
+#ifdef DIAGNOSTIC
+ if (evar->q == NULL) {
+ printf("wskbd_input: evar->q=NULL\n");
+ return;
+ }
#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;
@@ -655,17 +674,15 @@ wskbd_input(dev, type, value)
#ifdef WSDISPLAY_COMPAT_RAWKBD
void
-wskbd_rawinput(dev, buf, len)
- struct device *dev;
- u_char *buf;
- int len;
+wskbd_rawinput(struct device *dev, u_char *buf, int len)
{
#if NWSDISPLAY > 0
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
int i;
- for (i = 0; i < len; i++)
- wsdisplay_kbdinput(sc->sc_displaydv, buf[i]);
+ if (sc->sc_base.me_dispdv != NULL)
+ for (i = 0; i < len; i++)
+ wsdisplay_kbdinput(sc->sc_base.me_dispdv, buf[i]);
/* this is KS_GROUP_Ascii */
#endif
}
@@ -673,14 +690,12 @@ wskbd_rawinput(dev, buf, len)
#if NWSDISPLAY > 0
void
-wskbd_holdscreen(sc, hold)
- struct wskbd_softc *sc;
- int hold;
+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;
@@ -696,99 +711,136 @@ wskbd_holdscreen(sc, hold)
#endif
int
-wskbd_enable(sc, on)
- struct wskbd_softc *sc;
- int on;
+wskbd_enable(struct wskbd_softc *sc, int on)
{
- int res;
+ int error;
- /* XXX reference count? */
- if (!on && (!sc->sc_translating
#if NWSDISPLAY > 0
- || sc->sc_displaydv
+ if (sc->sc_base.me_dispdv != NULL)
+ return (0);
+
+ /* Always cancel auto repeat when fiddling with the kbd. */
+ if (sc->sc_repeating) {
+ sc->sc_repeating = 0;
+ timeout_del(&sc->sc_repeat_ch);
+ }
#endif
- ))
+
+ 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_dying)
+ return (EIO);
+
+ if (sc->sc_base.me_evp != NULL)
return (EBUSY);
- res = (*sc->sc_accessops->enable)(sc->sc_accesscookie, on);
- return (res);
+ return (wskbd_do_open(sc, evp));
}
+#endif
int
-wskbdopen(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
+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)
- return (EBUSY);
+ if (sc->sc_base.me_parent != NULL) {
+ /* Grab the keyboard out of the greedy hands of the mux. */
+ DPRINTF(("wskbdopen: detach\n"));
+ 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 */
-
- sc->sc_translating = 0;
+ evar = &sc->sc_base.me_evar;
+ wsevent_init(evar);
+ evar->io = p;
- wskbd_enable(sc, 1);
- return (0);
+ 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_fini(evar);
+ }
+ return (error);
}
int
-wskbdclose(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
+wskbd_do_open(struct wskbd_softc *sc, struct wseventvar *evp)
{
- return (wskbddoclose(wskbd_cd.cd_devs[minor(dev)], flags, mode, p));
+ sc->sc_base.me_evp = evp;
+ sc->sc_translating = 0;
+
+ return (wskbd_enable(sc, 1));
}
int
-wskbddoclose(dv, flags, mode, p)
- struct device *dv;
- int flags, mode;
- struct proc *p;
+wskbdclose(dev_t dev, int flags, int mode, struct proc *p)
{
- struct wskbd_softc *sc = (struct wskbd_softc *)dv;
+ struct wskbd_softc *sc =
+ (struct wskbd_softc *)wskbd_cd.cd_devs[minor(dev)];
+ struct wseventvar *evar = sc->sc_base.me_evp;
- if (!(flags & FREAD)) {
- /* Nothing to do, because open didn't do anything. */
+ if (evar == NULL)
+ /* not open for read */
return (0);
- }
+ sc->sc_base.me_evp = NULL;
sc->sc_translating = 1;
+ (void)wskbd_enable(sc, 0);
+ wsevent_fini(evar);
+
+ return (0);
+}
- wsevent_fini(&sc->sc_events);
- sc->sc_events.io = NULL;
+#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;
+ (void)wskbd_enable(sc, 0);
- wskbd_enable(sc, 0);
return (0);
}
+#endif
int
-wskbdread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
+wskbdread(dev_t dev, struct uio *uio, int flags)
{
struct wskbd_softc *sc = wskbd_cd.cd_devs[minor(dev)];
int error;
@@ -796,8 +848,15 @@ wskbdread(dev, uio, 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_evar, uio, flags);
if (--sc->sc_refcnt < 0) {
wakeup(sc);
error = EIO;
@@ -806,42 +865,29 @@ wskbdread(dev, uio, flags)
}
int
-wskbdioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+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(dv, cmd, data, flag, p)
- struct device *dv;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+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(sc, cmd, data, flag, p)
- 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;
@@ -853,11 +899,23 @@ wskbd_do_ioctl(sc, cmd, data, flag, p)
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 FIOSETOWN:
+ if (sc->sc_base.me_evp == NULL)
+ return (EINVAL);
+ if (-*(int *)data != sc->sc_base.me_evp->io->p_pgid &&
+ *(int *)data != sc->sc_base.me_evp->io->p_pid)
+ return (EPERM);
+ 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);
}
@@ -866,7 +924,7 @@ wskbd_do_ioctl(sc, cmd, data, flag, p)
* 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);
}
@@ -875,12 +933,8 @@ wskbd_do_ioctl(sc, cmd, data, flag, p)
* Some of these have no real effect in raw mode, however.
*/
int
-wskbd_displayioctl(dev, cmd, data, flag, p)
- struct device *dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wskbd_displayioctl(struct device *dev, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
{
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
struct wskbd_bell_data *ubdp, *kbdp;
@@ -961,11 +1015,6 @@ getbell:
kkdp = &sc->sc_keyrepeat_data;
setkeyrepeat:
ukdp = (struct wskbd_keyrepeat_data *)data;
- if ((ukdp->which & WSKBD_KEYREPEAT_DODEL1 &&
- (hz * ukdp->del1) / 1000 <= 0) ||
- (ukdp->which & WSKBD_KEYREPEAT_DODELN &&
- (hz * ukdp->delN) / 1000 <= 0))
- return (EINVAL);
SETKEYREPEAT(kkdp, ukdp, kkdp);
return (0);
@@ -995,7 +1044,8 @@ getkeyrepeat:
umdp = (struct wskbd_map_data *)data;
if (umdp->maplen > WSKBDIO_MAXMAPLEN)
return (EINVAL);
- len = umdp->maplen*sizeof(struct wscons_keymap);
+
+ len = umdp->maplen * sizeof(struct wscons_keymap);
buf = malloc(len, M_TEMP, M_WAITOK);
error = copyin(umdp->map, buf, len);
if (error == 0) {
@@ -1035,11 +1085,11 @@ getkeyrepeat:
return (EINVAL);
} else {
md = *(sc->id->t_keymap); /* structure assignment */
- md.layout = enc;
- error = wskbd_load_keymap(&md, &sc->sc_map,
- &sc->sc_maplen);
- if (error)
- return(error);
+ md.layout = enc;
+ error = wskbd_load_keymap(&md, &sc->sc_map,
+ &sc->sc_maplen);
+ if (error)
+ return(error);
}
sc->sc_layout = enc;
wskbd_update_layout(sc->id, enc);
@@ -1075,14 +1125,13 @@ getkeyrepeat:
}
int
-wskbdpoll(dev, events, p)
- dev_t dev;
- int events;
- struct proc *p;
+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
@@ -1102,120 +1151,86 @@ wskbd_pickfree()
return (-1);
}
-struct device *
-wskbd_set_console_display(displaydv, muxsc)
- 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(dv, muxsc)
- 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 odisp=%p disp=%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 = NULL;
error = wskbd_enable(sc, displaydv != NULL);
+ sc->sc_base.me_dispdv = displaydv;
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);
}
-int
-wskbd_isset_display(dv)
- struct device *dv;
-{
- struct wskbd_softc *sc = (struct wskbd_softc *)dv;
-
- if (sc->sc_displaydv != NULL)
- return (1);
-
- return (0);
-}
+#endif /* NWSDISPLAY > 0 */
+#if NWSMUX > 0
int
-wskbd_add_mux(unit, muxsc)
- int unit;
- struct wsmux_softc *muxsc;
+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));
-}
-
-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));
+ return (wsmux_attach_sc(muxsc, &sc->sc_base));
}
-
-#endif /* NWSDISPLAY > 0 */
+#endif
/*
* Console interface.
*/
int
-wskbd_cngetc(dev)
- dev_t dev;
+wskbd_cngetc(dev_t dev)
{
static int num = 0;
static int pos;
@@ -1233,7 +1248,8 @@ wskbd_cngetc(dev)
for(;;) {
if (num-- > 0) {
ks = wskbd_console_data.t_symbols[pos++];
- return (KS_VALUE(ks));
+ if (KS_GROUP(ks) == KS_GROUP_Ascii)
+ return (KS_VALUE(ks));
} else {
(*wskbd_console_data.t_consops->getc)
(wskbd_console_data.t_consaccesscookie,
@@ -1245,9 +1261,7 @@ wskbd_cngetc(dev)
}
void
-wskbd_cnpollc(dev, poll)
- dev_t dev;
- int poll;
+wskbd_cnpollc(dev_t dev, int poll)
{
if (!wskbd_console_initted)
@@ -1262,9 +1276,7 @@ wskbd_cnpollc(dev, poll)
}
void
-wskbd_cnbell(dev, pitch, period, volume)
- dev_t dev;
- u_int pitch, period, volume;
+wskbd_cnbell(dev_t dev, u_int pitch, u_int period, u_int volume)
{
if (!wskbd_console_initted)
return;
@@ -1275,9 +1287,8 @@ wskbd_cnbell(dev, pitch, period, volume)
volume);
}
-inline void
-update_leds(id)
- struct wskbd_internal *id;
+void
+update_leds(struct wskbd_internal *id)
{
int new_state;
@@ -1298,12 +1309,8 @@ update_leds(id)
}
}
-inline void
-update_modifier(id, type, toggle, mask)
- struct wskbd_internal *id;
- u_int type;
- int toggle;
- int mask;
+void
+update_modifier(struct wskbd_internal *id, u_int type, int toggle, int mask)
{
if (toggle) {
if (type == WSCONS_EVENT_KEY_DOWN)
@@ -1318,18 +1325,14 @@ update_modifier(id, type, toggle, mask)
#if NWSDISPLAY > 0
void
-change_displayparam(sc, param, updown, wraparound)
- struct wskbd_softc *sc;
- int param, updown, wraparound;
+change_displayparam(struct wskbd_softc *sc, int param, int updown,
+ int wraparound)
{
int res;
struct wsdisplay_param dp;
- if (sc->sc_displaydv == 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 */
@@ -1340,15 +1343,13 @@ change_displayparam(sc, param, updown, wraparound)
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
int
-internal_command(sc, type, ksym, ksym2)
- struct wskbd_softc *sc;
- u_int *type;
- keysym_t ksym, ksym2;
+internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym,
+ keysym_t ksym2)
{
switch (ksym) {
case KS_Cmd:
@@ -1394,17 +1395,21 @@ internal_command(sc, type, ksym, ksym2)
!MOD_ALLSET(sc->id, MOD_COMMAND1 | MOD_COMMAND2))
return (0);
- switch (ksym) {
#ifdef DDB
- case KS_Cmd_Debugger:
+ if (ksym == KS_Cmd_Debugger) {
if (sc->sc_isconsole && db_console)
Debugger();
/* discard this key (ddb discarded command modifiers) */
*type = WSCONS_EVENT_KEY_UP;
return (1);
+ }
#endif
#if NWSDISPLAY > 0
+ if (sc->sc_base.me_dispdv == NULL)
+ return (0);
+
+ switch (ksym) {
case KS_Cmd_Screen0:
case KS_Cmd_Screen1:
case KS_Cmd_Screen2:
@@ -1417,17 +1422,13 @@ internal_command(sc, type, ksym, ksym2)
case KS_Cmd_Screen9:
case KS_Cmd_Screen10:
case KS_Cmd_Screen11:
- if (sc->sc_displaydv != NULL)
- wsdisplay_switch(sc->sc_displaydv,
- ksym - KS_Cmd_Screen0, 0);
+ wsdisplay_switch(sc->sc_displaydv, ksym - KS_Cmd_Screen0, 0);
return (1);
case KS_Cmd_ResetEmul:
- if (sc->sc_displaydv != NULL)
- wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETEMUL);
+ wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETEMUL);
return (1);
case KS_Cmd_ResetClose:
- if (sc->sc_displaydv != NULL)
- wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETCLOSE);
+ wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETCLOSE);
return (1);
#if defined(__i386__) || defined(__amd64__)
case KS_Cmd_KbdReset:
@@ -1441,22 +1442,22 @@ internal_command(sc, type, ksym, ksym2)
case KS_Cmd_BacklightOff:
case KS_Cmd_BacklightToggle:
change_displayparam(sc, WSDISPLAYIO_PARAM_BACKLIGHT,
- ksym == KS_Cmd_BacklightOff ? -1 : 1,
- ksym == KS_Cmd_BacklightToggle ? 1 : 0);
+ ksym == KS_Cmd_BacklightOff ? -1 : 1,
+ ksym == KS_Cmd_BacklightToggle ? 1 : 0);
return (1);
case KS_Cmd_BrightnessUp:
case KS_Cmd_BrightnessDown:
case KS_Cmd_BrightnessRotate:
change_displayparam(sc, WSDISPLAYIO_PARAM_BRIGHTNESS,
- ksym == KS_Cmd_BrightnessDown ? -1 : 1,
- ksym == KS_Cmd_BrightnessRotate ? 1 : 0);
+ ksym == KS_Cmd_BrightnessDown ? -1 : 1,
+ ksym == KS_Cmd_BrightnessRotate ? 1 : 0);
return (1);
case KS_Cmd_ContrastUp:
case KS_Cmd_ContrastDown:
case KS_Cmd_ContrastRotate:
change_displayparam(sc, WSDISPLAYIO_PARAM_CONTRAST,
- ksym == KS_Cmd_ContrastDown ? -1 : 1,
- ksym == KS_Cmd_ContrastRotate ? 1 : 0);
+ ksym == KS_Cmd_ContrastDown ? -1 : 1,
+ ksym == KS_Cmd_ContrastRotate ? 1 : 0);
return (1);
#endif
}
@@ -1464,10 +1465,7 @@ internal_command(sc, type, ksym, ksym2)
}
int
-wskbd_translate(id, type, value)
- struct wskbd_internal *id;
- u_int type;
- int value;
+wskbd_translate(struct wskbd_internal *id, u_int type, int value)
{
struct wskbd_softc *sc = id->t_sc;
keysym_t ksym, res, *group;
@@ -1475,11 +1473,11 @@ wskbd_translate(id, type, value)
int gindex, iscommand = 0;
if (type == WSCONS_EVENT_ALL_KEYS_UP) {
- id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R
- | MOD_CONTROL_L | MOD_CONTROL_R
- | MOD_META_L | MOD_META_R
- | MOD_MODESHIFT | MOD_MODELOCK
- | MOD_COMMAND | MOD_COMMAND1 | MOD_COMMAND2);
+ id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R |
+ MOD_CONTROL_L | MOD_CONTROL_R |
+ MOD_META_L | MOD_META_R |
+ MOD_MODESHIFT | MOD_MODELOCK |
+ MOD_COMMAND | MOD_COMMAND1 | MOD_COMMAND2);
update_leds(id);
return (0);
}
@@ -1501,7 +1499,7 @@ wskbd_translate(id, type, value)
/* if this key has a command, process it first */
if (sc != NULL && kp->command != KS_voidSymbol)
iscommand = internal_command(sc, &type, kp->command,
- kp->group1[0]);
+ kp->group1[0]);
/* Now update modifiers */
switch (kp->group1[0]) {
@@ -1561,7 +1559,8 @@ wskbd_translate(id, type, value)
if (sc != NULL && sc->sc_repeating &&
((type == WSCONS_EVENT_KEY_UP && value != sc->sc_repkey) ||
(type == WSCONS_EVENT_KEY_DOWN && value == sc->sc_repkey)))
- return (0);
+ return (0);
+ break;
#endif
}
@@ -1678,7 +1677,7 @@ wskbd_translate(id, type, value)
id->t_symbols[1] = res;
return (2);
} else
- res |= 0x80;
+ res |= 0x80;
}
}
diff --git a/sys/dev/wscons/wsksymdef.h b/sys/dev/wscons/wsksymdef.h
index 18ef6e95d9b..903a12ce43d 100644
--- a/sys/dev/wscons/wsksymdef.h
+++ b/sys/dev/wscons/wsksymdef.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsksymdef.h,v 1.27 2005/05/12 09:26:48 miod Exp $ */
+/* $OpenBSD: wsksymdef.h,v 1.28 2005/05/15 11:29:15 miod Exp $ */
/* $NetBSD: wsksymdef.h,v 1.34.4.1 2000/07/07 09:49:54 hannken Exp $ */
/*-
@@ -673,6 +673,7 @@
#define KB_ENCODING(e) ((e) & 0x0000ff00)
#define KB_VARIANT(e) ((e) & 0xffff00ff)
+#define KB_NONE 0x0000
#define KB_USER 0x0100
#define KB_US 0x0200
#define KB_DE 0x0300
diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c
index ebbef486705..917414e6bd6 100644
--- a/sys/dev/wscons/wsmouse.c
+++ b/sys/dev/wscons/wsmouse.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsmouse.c,v 1.13 2004/06/24 19:35:24 tholo Exp $ */
-/* $NetBSD: wsmouse.c,v 1.12 2000/05/01 07:36:58 takemura Exp $ */
+/* $OpenBSD: wsmouse.c,v 1.14 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsmouse.c,v 1.35 2005/02/27 00:27:52 perry Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -96,13 +96,19 @@
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rndvar.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
@@ -110,14 +116,11 @@
#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 */
@@ -129,10 +132,6 @@ 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 *, void *, void *);
@@ -143,9 +142,14 @@ int wsmouse_activate(struct device *, enum devact);
int wsmouse_do_ioctl(struct wsmouse_softc *, u_long, caddr_t,
int, struct proc *);
-int wsmousedoclose(struct device *, int, int, struct proc *);
+#if NWSMUX > 0
+int wsmouse_mux_open(struct wsevsrc *, struct wseventvar *);
+int wsmouse_mux_close(struct wsevsrc *);
+#endif
+
int wsmousedoioctl(struct device *, u_long, caddr_t, int,
struct proc *);
+int wsmousedoopen(struct wsmouse_softc *, struct wseventvar *);
struct cfdriver wsmouse_cd = {
NULL, "wsmouse", DV_TTY
@@ -156,13 +160,10 @@ struct cfattach wsmouse_ca = {
wsmouse_detach, wsmouse_activate
};
-#if NWSMOUSE > 0
-extern struct cfdriver wsmouse_cd;
-#endif /* NWSMOUSE > 0 */
-
#if NWSMUX > 0
-struct wsmuxops wsmouse_muxops = {
- wsmouseopen, wsmousedoclose, wsmousedoioctl, 0, 0, 0
+struct wssrcops wsmouse_srcops = {
+ WSMUX_MOUSE,
+ wsmouse_mux_open, wsmouse_mux_close, wsmousedoioctl, NULL, NULL
};
#endif
@@ -170,9 +171,7 @@ struct wsmuxops wsmouse_muxops = {
* Print function (for parent devices).
*/
int
-wsmousedevprint(aux, pnp)
- void *aux;
- const char *pnp;
+wsmousedevprint(void *aux, const char *pnp)
{
if (pnp)
@@ -181,47 +180,50 @@ wsmousedevprint(aux, pnp)
}
int
-wsmouse_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+wsmouse_match(struct device *parent, void *match, void *aux)
{
return (1);
}
void
-wsmouse_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+wsmouse_attach(struct device *parent, struct device *self, void *aux)
{
- struct wsmouse_softc *sc = (struct wsmouse_softc *)self;
+ 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 0 /* not worth keeping, especially since the default value is not -1... */
+ if (sc->sc_base.me_dv.dv_cfdata->wsmousedevcf_mux >= 0)
+ printf(" (mux ignored)");
#endif
+#endif /* NWSMUX > 0 */
printf("\n");
}
int
-wsmouse_activate(self, act)
- struct device *self;
- enum devact act;
+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);
}
@@ -234,28 +236,24 @@ wsmouse_activate(self, act)
* vnode and return (which will deallocate the softc).
*/
int
-wsmouse_detach(self, flags)
- struct device *self;
- int flags;
+wsmouse_detach(struct device *self, int flags)
{
struct wsmouse_softc *sc = (struct wsmouse_softc *)self;
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) {
+ DPRINTF(("wsmouse_detach:\n"));
+ 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. */
@@ -265,7 +263,7 @@ wsmouse_detach(self, 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);
}
@@ -283,31 +281,34 @@ wsmouse_detach(self, flags)
}
void
-wsmouse_input(wsmousedev, btns, x, y, z, flags)
- struct device *wsmousedev;
- u_int btns; /* 0 is up */
- int x, y, z;
- u_int flags;
+wsmouse_input(struct device *wsmousedev, u_int btns, /* 0 is up */
+ int x, int y, int z, u_int flags)
{
struct wsmouse_softc *sc = (struct wsmouse_softc *)wsmousedev;
struct wscons_event *ev;
struct wseventvar *evar;
int mb, ub, d, get, put, any;
- /*
- * Discard input if not ready.
- */
- if (sc->sc_ready == 0)
+ add_mouse_randomness(x ^ y ^ z ^ btns);
+
+ /*
+ * Discard input if not ready.
+ */
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL)
return;
- add_mouse_randomness(x ^ y ^ z ^ btns);
+#ifdef DIAGNOSTIC
+ if (evar->q == NULL) {
+ printf("wsmouse_input: evar->q=NULL\n");
+ return;
+ }
+#endif
#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))
@@ -429,30 +430,35 @@ wsmouse_input(wsmousedev, btns, x, y, z, flags)
/* XXX fake wscons_event notifying wsmoused(8) to close mouse device */
if (flags & WSMOUSE_INPUT_WSMOUSED_CLOSE) {
- NEXT;
- ev->type = WSCONS_EVENT_WSMOUSED_CLOSE;
- ev->value = 0;
- TIMESTAMP;
- ADVANCE;
+ NEXT;
+ ev->type = WSCONS_EVENT_WSMOUSED_CLOSE;
+ ev->value = 0;
+ TIMESTAMP;
+ ADVANCE;
}
+#undef TIMESTAMP
+#undef ADVANCE
+#undef NEXT
+
out:
if (any) {
sc->sc_ub = ub;
evar->put = put;
WSEVENT_WAKEUP(evar);
/* wsdisplay_burn(sc->sc_displaydv, WSDISPLAY_BURN_MOUSE); */
+#if NWSMUX > 0
+ DPRINTFN(5,("wsmouse_input: %s wakeup evar=%p\n",
+ sc->sc_base.me_dv.dv_xname, evar));
+#endif
}
}
int
-wsmouseopen(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
+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);
@@ -460,6 +466,11 @@ wsmouseopen(dev, flags, mode, 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);
@@ -467,122 +478,88 @@ wsmouseopen(dev, flags, mode, p)
return (0); /* always allow open for write
so ioctl() is possible. */
-#if NWSMUX > 0
- if (sc->sc_mux)
- return (EBUSY);
-#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 */
-
- sc->sc_ready = 1; /* start accepting events */
- sc->sc_x = INVALID_X;
- sc->sc_y = INVALID_Y;
- sc->sc_z = INVALID_Z;
+ evar = &sc->sc_base.me_evar;
+ wsevent_init(evar);
+ evar->io = p;
- /* 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_fini(evar);
}
-
- return (0);
-#else
- return (ENXIO);
-#endif /* NWSMOUSE > 0 */
+ return (error);
}
int
-wsmouseclose(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
+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 */
+ 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_fini(evar);
+
+ return (0);
}
-#if NWSMOUSE > 0
int
-wsmousedoclose(dv, flags, mode, p)
- struct device *dv;
- int flags, mode;
- struct proc *p;
+wsmousedoopen(struct wsmouse_softc *sc, struct wseventvar *evp)
{
- struct wsmouse_softc *sc = (struct wsmouse_softc *)dv;
-
- if ((flags & (FREAD | FWRITE)) == FWRITE)
- return (0); /* see wsmouseopen() */
-
- (*sc->sc_accessops->disable)(sc->sc_accesscookie);
+ sc->sc_base.me_evp = evp;
+ sc->sc_x = INVALID_X;
+ sc->sc_y = INVALID_Y;
+ sc->sc_z = INVALID_Z;
- sc->sc_ready = 0; /* stop accepting events */
- wsevent_fini(&sc->sc_events);
- sc->sc_events.io = NULL;
- return (0);
+ /* enable the device, and punt if that's not possible */
+ return (*sc->sc_accessops->enable)(sc->sc_accesscookie);
}
-#endif /* NWSMOUSE > 0 */
int
-wsmouseread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
+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, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+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 */
+ cmd, data, flag, p));
}
-#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;
+wsmousedoioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
{
struct wsmouse_softc *sc = (struct wsmouse_softc *)dv;
int error;
@@ -595,12 +572,8 @@ wsmousedoioctl(dv, cmd, data, flag, p)
}
int
-wsmouse_do_ioctl(sc, cmd, data, flag, p)
- struct wsmouse_softc *sc;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsmouse_do_ioctl(struct wsmouse_softc *sc, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
{
int error;
@@ -615,11 +588,23 @@ wsmouse_do_ioctl(sc, cmd, data, flag, p)
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 FIOSETOWN:
+ if (sc->sc_base.me_evp == NULL)
+ return (EINVAL);
+ if (-*(int *)data != sc->sc_base.me_evp->io->p_pgid
+ && *(int *)data != sc->sc_base.me_evp->io->p_pid)
+ return (EPERM);
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);
}
@@ -632,46 +617,42 @@ wsmouse_do_ioctl(sc, cmd, data, flag, p)
data, flag, p);
return (error != -1 ? error : ENOTTY);
}
-#endif /* NWSMOUSE > 0 */
int
-wsmousepoll(dev, events, p)
- dev_t dev;
- int events;
- struct proc *p;
+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_add_mux(unit, muxsc)
- int unit;
- struct wsmux_softc *muxsc;
+wsmouse_mux_open(struct wsevsrc *me, struct wseventvar *evp)
{
- struct wsmouse_softc *sc;
-
- if (unit < 0 || unit >= wsmouse_cd.cd_ndevs ||
- (sc = wsmouse_cd.cd_devs[unit]) == NULL)
- return (ENXIO);
+ struct wsmouse_softc *sc = (struct wsmouse_softc *)me;
- if (sc->sc_mux || sc->sc_events.io)
+ if (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 wsmousedoopen(sc, evp);
}
int
-wsmouse_rem_mux(unit, muxsc)
- int unit;
- struct wsmux_softc *muxsc;
+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)
{
struct wsmouse_softc *sc;
@@ -679,7 +660,9 @@ wsmouse_rem_mux(unit, muxsc)
(sc = wsmouse_cd.cd_devs[unit]) == NULL)
return (ENXIO);
- return (wsmux_detach_sc(muxsc, &sc->sc_dv));
-}
+ if (sc->sc_base.me_parent != NULL || sc->sc_base.me_evp != NULL)
+ return (EBUSY);
-#endif
+ return (wsmux_attach_sc(muxsc, &sc->sc_base));
+}
+#endif /* NWSMUX > 0 */
diff --git a/sys/dev/wscons/wsmux.c b/sys/dev/wscons/wsmux.c
index 56118d9907f..ba2cd448657 100644
--- a/sys/dev/wscons/wsmux.c
+++ b/sys/dev/wscons/wsmux.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: wsmux.c,v 1.12 2004/06/24 19:35:24 tholo Exp $ */
-/* $NetBSD: wsmux.c,v 1.9 2000/05/28 10:33:14 takemura Exp $ */
+/* $OpenBSD: wsmux.c,v 1.13 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsmux.c,v 1.37 2005/04/30 03:47:12 augustss Exp $ */
/*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Author: Lennart Augustsson <augustss@carlstedt.se>
@@ -41,8 +41,6 @@
#include "wsdisplay.h"
#include "wskbd.h"
-#if NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0)
-
/*
* wscons mux device.
*
@@ -65,482 +63,332 @@
#include <sys/device.h>
#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsksymdef.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
+#define DPRINTFN(n,x) if (wsmuxdebug > (n)) printf x
int wsmuxdebug = 0;
#else
#define DPRINTF(x)
+#define DPRINTFN(n,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;
-};
+/*
+ * The wsmux pseudo device is used to multiplex events from several wsmouse,
+ * wskbd, and/or wsmux devices together.
+ * The devices connected together form a tree with muxes in the interior
+ * and real devices (mouse and kbd) at the leaves. The special case of
+ * a tree with one node (mux or other) is supported as well.
+ * Only the device at the root of the tree can be opened (if a non-root
+ * device is opened the subtree rooted at that point is severed from the
+ * containing tree). When the root is opened it allocates a wseventvar
+ * struct which all the nodes in the tree will send their events too.
+ * An ioctl() performed on the root is propagated to all the nodes.
+ * There are also ioctl() operations to add and remove nodes from a tree.
+ */
-int wsmuxdoclose(struct device *, int, int, struct proc *);
-int wsmux_set_display(struct device *, struct wsmux_softc *);
-int wsmux_isset_display(struct device *);
+int wsmux_mux_open(struct wsevsrc *, struct wseventvar *);
+int wsmux_mux_close(struct wsevsrc *);
-#if NWSMUX > 0
-void wsmuxattach(int);
+void wsmux_do_open(struct wsmux_softc *, struct wseventvar *);
-struct wsmuxops wsmux_muxops = {
- wsmuxopen, wsmuxdoclose, wsmuxdoioctl, wsmux_displayioctl,
- wsmux_set_display, wsmux_isset_display
+void wsmux_do_close(struct wsmux_softc *);
+#if NWSDISPLAY > 0
+int wsmux_evsrc_set_display(struct device *, struct wsevsrc *);
+#else
+#define wsmux_evsrc_set_display NULL
+#endif
+
+int wsmux_do_displayioctl(struct device *dev, u_long cmd, caddr_t data,
+ int flag, struct proc *p);
+int wsmux_do_ioctl(struct device *, u_long, caddr_t,int,struct proc *);
+
+int wsmux_add_mux(int, struct wsmux_softc *);
+
+void wsmuxattach(int);
+
+struct wssrcops wsmux_srcops = {
+ WSMUX_MUX,
+ wsmux_mux_open, wsmux_mux_close, wsmux_do_ioctl, wsmux_do_displayioctl,
+ wsmux_evsrc_set_display
};
-void wsmux_setmax(int n);
+/* From upper level */
+void
+wsmuxattach(int n)
+{
+}
+/* Keep track of all muxes that have been allocated */
int nwsmux = 0;
struct wsmux_softc **wsmuxdevs = NULL;
-void
-wsmux_setmax(n)
- int n;
+/* Return mux n, create if necessary */
+struct wsmux_softc *
+wsmux_getmux(int n)
{
+ struct wsmux_softc *sc;
+ struct wsmux_softc **new, **old;
int i;
- struct wsmux_softc **wsmuxdevs_tmp = NULL;
+ /* Make sure there is room for mux n in the table */
if (n >= nwsmux) {
- if (wsmuxdevs != NULL) {
- wsmuxdevs_tmp = malloc(nwsmux * sizeof(*wsmuxdevs_tmp),
- M_DEVBUF, M_NOWAIT);
- if (wsmuxdevs_tmp == 0)
- panic("wsmux_setmax: no mem");
- for (i = 0; i < nwsmux; i++)
- wsmuxdevs_tmp[i] = wsmuxdevs[i];
- free(wsmuxdevs, M_DEVBUF);
- }
-
- wsmuxdevs = malloc((n + 1) * sizeof(*wsmuxdevs),
- M_DEVBUF, M_NOWAIT);
- if (wsmuxdevs == NULL)
- panic("wsmux_setmax: no memory");
- memset(wsmuxdevs, 0, (n + 1) * sizeof(*wsmuxdevs));
- if (wsmuxdevs_tmp != NULL) {
- for (i = 0; i < nwsmux; i++)
- wsmuxdevs[i] = wsmuxdevs_tmp[i];
- free(wsmuxdevs_tmp, M_DEVBUF);
+ old = wsmuxdevs;
+ new = (struct wsmux_softc **)
+ malloc((n + 1) * sizeof (*wsmuxdevs), M_DEVBUF, M_NOWAIT);
+ if (new == NULL) {
+ printf("wsmux_getmux: no memory for mux %d\n", n);
+ return (NULL);
}
+ if (old != NULL)
+ bcopy(old, new, nwsmux * sizeof(*wsmuxdevs));
+ for (i = nwsmux; i < (n + 1); i++)
+ new[i] = NULL;
+ wsmuxdevs = new;
nwsmux = n + 1;
+ if (old != NULL)
+ free(old, M_DEVBUF);
}
-}
-/* From upper level */
-void
-wsmuxattach(n)
- int n;
-{
- int i;
-
- wsmux_setmax(n); /* Make sure we have room for all muxes. */
-
- /* Make sure all muxes are there. */
- for (i = 0; i < nwsmux; i++)
- if (wsmuxdevs[i] == NULL)
- wsmuxdevs[i] = wsmux_create("wsmux", i);
-}
-
-/* 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=%d\n", n));
- wsmux_setmax(n);
sc = wsmuxdevs[n];
- if (sc == 0) {
+ if (sc == NULL) {
sc = wsmux_create("wsmux", n);
- if (sc == 0) {
+ if (sc == NULL)
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);
-}
-
-/* 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
+ return (sc);
}
+/*
+ * open() of the pseudo device from device table.
+ */
int
-wsmuxopen(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
+wsmuxopen(dev_t dev, int flags, int mode, struct proc *p)
{
struct wsmux_softc *sc;
- struct wsplink *m;
- int unit, error, nopen, lasterror;
+ struct wseventvar *evar;
+ int unit;
unit = minor(dev);
- if (unit >= nwsmux || /* make sure it was attached */
- (sc = wsmuxdevs[unit]) == NULL)
+ sc = wsmux_getmux(unit);
+ if (sc == NULL)
return (ENXIO);
- DPRINTF(("wsmuxopen: %s: sc=%p\n", sc->sc_dv.dv_xname, sc));
- if (!(flags & FREAD)) {
+ DPRINTF(("wsmuxopen: %s: sc=%p p=%p\n", sc->sc_base.me_dv.dv_xname, sc, p));
+
+ if ((flags & (FREAD | FWRITE)) == FWRITE) {
/* Not opening for read, only ioctl is available. */
return (0);
}
- if (sc->sc_events.io)
+ if (sc->sc_base.me_parent != NULL) {
+ /* Grab the mux out of the greedy hands of the parent mux. */
+ DPRINTF(("wsmuxopen: detach\n"));
+ wsmux_detach_sc(&sc->sc_base);
+ }
+
+ if (sc->sc_base.me_evp != NULL)
+ /* Already open. */
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;
- }
- }
- }
+ evar = &sc->sc_base.me_evar;
+ wsevent_init(evar);
+ evar->io = p;
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ sc->sc_rawkbd = 0;
+#endif
- if (nopen == 0 && lasterror != 0) {
- wsevent_fini(&sc->sc_events);
- sc->sc_events.io = NULL;
- return (lasterror);
- }
+ wsmux_do_open(sc, evar);
return (0);
}
+/*
+ * Open of a mux via the parent mux.
+ */
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
-wsmuxread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
+wsmux_mux_open(struct wsevsrc *me, struct wseventvar *evar)
{
- struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
+ struct wsmux_softc *sc = (struct wsmux_softc *)me;
- if (!sc->sc_events.io)
- return (EACCES);
+#ifdef DIAGNOSTIC
+ if (sc->sc_base.me_evp != NULL) {
+ printf("wsmux_mux_open: busy\n");
+ return (EBUSY);
+ }
+ if (sc->sc_base.me_parent == NULL) {
+ printf("wsmux_mux_open: no parent\n");
+ return (EINVAL);
+ }
+#endif
- return (wsevent_read(&sc->sc_events, uio, flags));
-}
+ wsmux_do_open(sc, evar);
-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);
+ return (0);
}
-int
-wsmuxpoll(dev, events, p)
- dev_t dev;
- int events;
- struct proc *p;
+/* Common part of opening a mux. */
+void
+wsmux_do_open(struct wsmux_softc *sc, struct wseventvar *evar)
{
- struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
+ struct wsevsrc *me;
+ int error;
- if (!sc->sc_events.io)
- return (EACCES);
+ sc->sc_base.me_evp = evar; /* remember event variable, mark as open */
- return (wsevent_poll(&sc->sc_events, events, p));
+ /* Open all children. */
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+ DPRINTF(("wsmuxopen: %s: m=%p dev=%s\n",
+ sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname));
+#ifdef DIAGNOSTIC
+ if (me->me_evp != NULL) {
+ printf("wsmuxopen: dev already in use\n");
+ continue;
+ }
+ if (me->me_parent != sc) {
+ printf("wsmux_do_open: bad child=%p\n", me);
+ continue;
+ }
+ error = wsevsrc_open(me, evar);
+ if (error) {
+ DPRINTF(("wsmuxopen: open failed %d\n", error));
+ }
+#else
+ /* ignore errors, failing children will not be marked open */
+ (void)wsevsrc_open(me, evar);
+#endif
+ }
}
+/*
+ * close() of the pseudo device from device table.
+ */
int
-wsmux_add_mux(unit, muxsc)
- int unit;
- struct wsmux_softc *muxsc;
+wsmuxclose(dev_t dev, int flags, int mode, struct proc *p)
{
- 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);
+ struct wsmux_softc *sc =
+ (struct wsmux_softc *)wsmuxdevs[minor(dev)];
+ struct wseventvar *evar = sc->sc_base.me_evp;
- /* 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);
+ if (evar == NULL)
+ /* Not open for read */
+ return (0);
- return (wsmux_attach_sc(muxsc, WSMUX_MUX, &sc->sc_dv, &sc->sc_events,
- &sc->sc_mux, &wsmux_muxops));
+ wsmux_do_close(sc);
+ sc->sc_base.me_evp = NULL;
+ wsevent_fini(evar);
+ return (0);
}
+/*
+ * Close of a mux via the parent mux.
+ */
int
-wsmux_rem_mux(unit, muxsc)
- int unit;
- struct wsmux_softc *muxsc;
+wsmux_mux_close(struct wsevsrc *me)
{
- 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));
+ me->me_evp = NULL;
+ wsmux_do_close((struct wsmux_softc *)me);
+ return (0);
}
-#endif /* NWSMUX > 0 */
-
-struct wsmux_softc *
-wsmux_create(name, unit)
- const char *name;
- int unit;
+/* Common part of closing a mux. */
+void
+wsmux_do_close(struct wsmux_softc *sc)
{
- struct wsmux_softc *sc;
+ struct wsevsrc *me;
- 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);
-}
-
-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(("wsmuxclose: %s: sc=%p\n", sc->sc_base.me_dv.dv_xname, sc));
- 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
- }
+ /* Close all the children. */
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+ DPRINTF(("wsmuxclose %s: m=%p dev=%s\n",
+ sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname));
+#ifdef DIAGNOSTIC
+ if (me->me_parent != sc) {
+ printf("wsmuxclose: bad child=%p\n", me);
+ continue;
}
- } 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;
+#endif
+ (void)wsevsrc_close(me);
+ me->me_evp = NULL;
}
- DPRINTF(("wsmux_attach_sc: done sc=%p psp=%p *psp=%p\n",
- sc, psp, *psp));
-
- return (error);
}
+/*
+ * read() of the pseudo device from device table.
+ */
int
-wsmux_detach_sc(sc, dsc)
- struct wsmux_softc *sc;
- struct device *dsc;
+wsmuxread(dev_t dev, struct uio *uio, int flags)
{
- struct wsplink *m;
- int error = 0;
-
- 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
+ struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
+ struct wseventvar *evar;
+ int error;
- for (m = LIST_FIRST(&sc->sc_reals); m; m = LIST_NEXT(m, next)) {
- if (m->sc == dsc)
- break;
- }
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL) {
#ifdef DIAGNOSTIC
- if (!m) {
- printf("wsmux_detach_sc: not found\n");
- return (ENXIO);
- }
+ /* XXX can we get here? */
+ printf("wsmuxread: not open\n");
#endif
- if (sc->sc_displaydv ||
- (m->sc_ops->dissetdisplay && m->sc_ops->dissetdisplay(m->sc))) {
- 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;
+ return (EINVAL);
}
- LIST_REMOVE(m, next);
-
- free(m, M_DEVBUF);
- DPRINTF(("wsmux_detach_sc: done sc=%p\n", sc));
- return (0);
+ DPRINTFN(5,("wsmuxread: %s event read evar=%p\n",
+ sc->sc_base.me_dv.dv_xname, evar));
+ error = wsevent_read(evar, uio, flags);
+ DPRINTFN(5,("wsmuxread: %s event read ==> error=%d\n",
+ sc->sc_base.me_dv.dv_xname, error));
+ return (error);
}
-int wsmuxdoclose(dv, flags, mode, p)
- struct device *dv;
- int flags, mode;
- struct proc *p;
+/*
+ * ioctl of the pseudo device from device table.
+ */
+int
+wsmuxioctl(dev_t dev, u_long cmd, caddr_t data, int flag, 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)) {
- /* Nothing to do, because open didn't do anything. */
- 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);
+ return wsmux_do_ioctl(&wsmuxdevs[minor(dev)]->sc_base.me_dv, cmd, data, flag, p);
}
+/*
+ * ioctl of a mux via the parent mux, continuation of wsmuxioctl().
+ */
int
-wsmuxdoioctl(dv, cmd, data, flag, p)
- struct device *dv;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsmux_do_ioctl(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;
+ struct wsevsrc *me;
int error, ok;
int s, put, get, n;
struct wseventvar *evar;
struct wscons_event *ev;
struct wsmux_device_list *l;
- DPRINTF(("wsmuxdoioctl: %s: sc=%p, cmd=%08lx\n",
- sc->sc_dv.dv_xname, sc, cmd));
+ DPRINTF(("wsmux_do_ioctl: %s: enter sc=%p, cmd=%08lx\n",
+ sc->sc_base.me_dv.dv_xname, sc, cmd));
switch (cmd) {
- case WSMUX_INJECTEVENT:
+ case WSMUXIO_INJECTEVENT:
/* Inject an event, e.g., from moused. */
- if (!sc->sc_events.io)
- return (EACCES);
+ DPRINTF(("%s: inject\n", sc->sc_base.me_dv.dv_xname));
+
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL) {
+ /* No event sink, so ignore it. */
+ DPRINTF(("wsmux_do_ioctl: event ignored\n"));
+ return (0);
+ }
- evar = &sc->sc_events;
s = spltty();
get = evar->get;
put = evar->put;
+ ev = &evar->q[put];
if (++put % WSEVENT_QSIZE == get) {
put--;
splx(s);
@@ -548,15 +396,16 @@ wsmuxdoioctl(dv, cmd, data, flag, p)
}
if (put >= WSEVENT_QSIZE)
put = 0;
- ev = &evar->q[put];
*ev = *(struct wscons_event *)data;
nanotime(&ev->time);
evar->put = put;
WSEVENT_WAKEUP(evar);
splx(s);
return (0);
- case WSMUX_ADD_DEVICE:
+ case WSMUXIO_ADD_DEVICE:
#define d ((struct wsmux_device *)data)
+ DPRINTF(("%s: add type=%d, no=%d\n", sc->sc_base.me_dv.dv_xname,
+ d->type, d->idx));
switch (d->type) {
#if NWSMOUSE > 0
case WSMUX_MOUSE:
@@ -566,38 +415,35 @@ wsmuxdoioctl(dv, cmd, data, flag, p)
case WSMUX_KBD:
return (wskbd_add_mux(d->idx, sc));
#endif
-#if NWSMUX > 0
case WSMUX_MUX:
return (wsmux_add_mux(d->idx, sc));
-#endif
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
-#if NWSMUX > 0
- case WSMUX_MUX:
- return (wsmux_rem_mux(d->idx, sc));
-#endif
- default:
- return (EINVAL);
+ case WSMUXIO_REMOVE_DEVICE:
+ DPRINTF(("%s: rem type=%d, no=%d\n", sc->sc_base.me_dv.dv_xname,
+ d->type, d->idx));
+ /* Locate the device */
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+ if (me->me_ops->type == d->type &&
+ me->me_dv.dv_unit == d->idx) {
+ DPRINTF(("wsmux_do_ioctl: detach\n"));
+ wsmux_detach_sc(me);
+ return (0);
+ }
}
+ return (EINVAL);
#undef d
- case WSMUX_LIST_DEVICES:
+
+ case WSMUXIO_LIST_DEVICES:
+ DPRINTF(("%s: list\n", sc->sc_base.me_dv.dv_xname));
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 = 0;
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+ if (n >= WSMUX_MAXDEV)
+ break;
+ l->devices[n].type = me->me_ops->type;
+ l->devices[n].idx = me->me_dv.dv_unit;
n++;
}
l->ndevices = n;
@@ -605,79 +451,285 @@ wsmuxdoioctl(dv, cmd, data, flag, p)
#ifdef WSDISPLAY_COMPAT_RAWKBD
case WSKBDIO_SETMODE:
sc->sc_rawkbd = *(int *)data;
- DPRINTF(("wsmuxdoioctl: save rawkbd = %d\n", sc->sc_rawkbd));
+ DPRINTF(("wsmux_do_ioctl: save rawkbd = %d\n", sc->sc_rawkbd));
break;
#endif
+ case FIONBIO:
+ DPRINTF(("%s: FIONBIO\n", sc->sc_base.me_dv.dv_xname));
+ return (0);
+
case FIOASYNC:
- sc->sc_events.async = *(int *)data != 0;
+ DPRINTF(("%s: FIOASYNC\n", sc->sc_base.me_dv.dv_xname));
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL)
+ return (EINVAL);
+ evar->async = *(int *)data != 0;
+ return (0);
+ case FIOSETOWN:
+ DPRINTF(("%s: FIOSETOWN\n", sc->sc_base.me_dv.dv_xname));
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL)
+ return (EINVAL);
+ if (-*(int *)data != evar->io->p_pgid
+ && *(int *)data != evar->io->p_pid)
+ return (EPERM);
return (0);
case TIOCSPGRP:
- if (*(int *)data != sc->sc_events.io->p_pgid)
+ DPRINTF(("%s: TIOCSPGRP\n", sc->sc_base.me_dv.dv_xname));
+ evar = sc->sc_base.me_evp;
+ if (evar == NULL)
+ return (EINVAL);
+ if (*(int *)data != evar->io->p_pgid)
return (EPERM);
return (0);
default:
+ DPRINTF(("%s: unknown\n", sc->sc_base.me_dv.dv_xname));
break;
}
- if (sc->sc_events.io == NULL && sc->sc_displaydv == NULL)
+ if (sc->sc_base.me_evp == NULL
+#if NWSDISPLAY > 0
+ && sc->sc_displaydv == NULL
+#endif
+ )
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;
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+#ifdef DIAGNOSTIC
+ /* XXX check evp? */
+ if (me->me_parent != sc) {
+ printf("wsmux_do_ioctl: bad child %p\n", me);
+ continue;
}
+#endif
+ error = wsevsrc_ioctl(me, cmd, data, flag, p);
+ DPRINTF(("wsmux_do_ioctl: %s: me=%p dev=%s ==> %d\n",
+ sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname,
+ error));
+ if (!error)
+ ok = 1;
}
- if (ok)
+ if (ok) {
error = 0;
+ if (cmd == WSKBDIO_SETENCODING) {
+ sc->sc_kbd_layout = *((kbd_t *)data);
+ }
+
+ }
return (error);
}
+/*
+ * poll() of the pseudo device from device table.
+ */
+int
+wsmuxpoll(dev_t dev, int events, struct proc *p)
+{
+ struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
+
+ if (sc->sc_base.me_evp == NULL) {
+#ifdef DIAGNOSTIC
+ printf("wsmuxpoll: not open\n");
+#endif
+ return (EACCES);
+ }
+
+ return (wsevent_poll(sc->sc_base.me_evp, events, p));
+}
+
+/*
+ * Add mux unit as a child to muxsc.
+ */
+int
+wsmux_add_mux(int unit, struct wsmux_softc *muxsc)
+{
+ struct wsmux_softc *sc, *m;
+
+ sc = wsmux_getmux(unit);
+ if (sc == NULL)
+ return (ENXIO);
+
+ DPRINTF(("wsmux_add_mux: %s(%p) to %s(%p)\n",
+ sc->sc_base.me_dv.dv_xname, sc, muxsc->sc_base.me_dv.dv_xname,
+ muxsc));
+
+ if (sc->sc_base.me_parent != NULL || sc->sc_base.me_evp != NULL)
+ return (EBUSY);
+
+ /* The mux we are adding must not be an ancestor of itself. */
+ for (m = muxsc; m != NULL ; m = m->sc_base.me_parent)
+ if (m == sc)
+ return (EINVAL);
+
+ return (wsmux_attach_sc(muxsc, &sc->sc_base));
+}
+
+/* Create a new mux softc. */
+struct wsmux_softc *
+wsmux_create(const char *name, int unit)
+{
+ struct wsmux_softc *sc;
+
+ DPRINTF(("wsmux_create: allocating\n"));
+ sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
+ if (sc == NULL)
+ return (NULL);
+ bzero(sc, sizeof *sc);
+ CIRCLEQ_INIT(&sc->sc_cld);
+ snprintf(sc->sc_base.me_dv.dv_xname, sizeof sc->sc_base.me_dv.dv_xname,
+ "%s%d", name, unit);
+ sc->sc_base.me_dv.dv_unit = unit;
+ sc->sc_base.me_ops = &wsmux_srcops;
+ sc->sc_kbd_layout = KB_NONE;
+ return (sc);
+}
+
+/* Attach me as a child to sc. */
int
-wsmux_displayioctl(dv, cmd, data, flag, p)
- struct device *dv;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+wsmux_attach_sc(struct wsmux_softc *sc, struct wsevsrc *me)
+{
+ int error;
+
+ if (sc == NULL)
+ return (EINVAL);
+
+ DPRINTF(("wsmux_attach_sc: %s(%p): type=%d\n",
+ sc->sc_base.me_dv.dv_xname, sc, me->me_ops->type));
+
+#ifdef DIAGNOSTIC
+ if (me->me_parent != NULL) {
+ printf("wsmux_attach_sc: busy\n");
+ return (EBUSY);
+ }
+#endif
+ me->me_parent = sc;
+ CIRCLEQ_INSERT_TAIL(&sc->sc_cld, me, me_next);
+
+ error = 0;
+#if NWSDISPLAY > 0
+ if (sc->sc_displaydv != NULL) {
+ /* This is a display mux, so attach the new device to it. */
+ DPRINTF(("wsmux_attach_sc: %s: set display %p\n",
+ sc->sc_base.me_dv.dv_xname, sc->sc_displaydv));
+ if (me->me_ops->dsetdisplay != NULL) {
+ error = wsevsrc_set_display(me, &sc->sc_base);
+ /* Ignore that the console already has a display. */
+ if (error == EBUSY)
+ error = 0;
+ if (!error) {
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ DPRINTF(("wsmux_attach_sc: %s set rawkbd=%d\n",
+ me->me_dv.dv_xname, sc->sc_rawkbd));
+ (void)wsevsrc_ioctl(me, WSKBDIO_SETMODE,
+ &sc->sc_rawkbd, 0, 0);
+#endif
+ if (sc->sc_kbd_layout != KB_NONE)
+ (void)wsevsrc_ioctl(me,
+ WSKBDIO_SETENCODING,
+ &sc->sc_kbd_layout, FWRITE, 0);
+ }
+ }
+ }
+#endif
+ if (sc->sc_base.me_evp != NULL) {
+ /* Mux is open, so open the new subdevice */
+ DPRINTF(("wsmux_attach_sc: %s: calling open of %s\n",
+ sc->sc_base.me_dv.dv_xname, me->me_dv.dv_xname));
+ error = wsevsrc_open(me, sc->sc_base.me_evp);
+ } else {
+ DPRINTF(("wsmux_attach_sc: %s not open\n",
+ sc->sc_base.me_dv.dv_xname));
+ }
+
+ if (error) {
+ me->me_parent = NULL;
+ CIRCLEQ_REMOVE(&sc->sc_cld, me, me_next);
+ }
+
+ DPRINTF(("wsmux_attach_sc: %s(%p) done, error=%d\n",
+ sc->sc_base.me_dv.dv_xname, sc, error));
+ return (error);
+}
+
+/* Remove me from the parent. */
+void
+wsmux_detach_sc(struct wsevsrc *me)
+{
+ struct wsmux_softc *sc = me->me_parent;
+
+ DPRINTF(("wsmux_detach_sc: %s(%p) parent=%p\n",
+ me->me_dv.dv_xname, me, sc));
+
+#ifdef DIAGNOSTIC
+ if (sc == NULL) {
+ printf("wsmux_detach_sc: %s has no parent\n",
+ me->me_dv.dv_xname);
+ return;
+ }
+#endif
+
+#if NWSDISPLAY > 0
+ if (sc->sc_displaydv != NULL) {
+ if (me->me_ops->dsetdisplay != NULL)
+ /* ignore error, there's nothing we can do */
+ (void)wsevsrc_set_display(me, NULL);
+ } else
+#endif
+ if (me->me_evp != NULL) {
+ DPRINTF(("wsmux_detach_sc: close\n"));
+ /* mux device is open, so close multiplexee */
+ (void)wsevsrc_close(me);
+ }
+
+ CIRCLEQ_REMOVE(&sc->sc_cld, me, me_next);
+ me->me_parent = NULL;
+
+ DPRINTF(("wsmux_detach_sc: done sc=%p\n", sc));
+}
+
+/*
+ * Display ioctl() of a mux via the parent mux.
+ */
+int
+wsmux_do_displayioctl(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;
+ struct wsevsrc *me;
int error, ok;
- DPRINTF(("wsmux_displayioctl: %s: sc=%p, cmd=%08lx\n",
- sc->sc_dv.dv_xname, sc, cmd));
+ DPRINTF(("wsmux_displayioctl: %s: sc=%p, cmd=%08lx\n",
+ sc->sc_base.me_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.
* Return -1 if no mux component accepts the ioctl.
*/
error = -1;
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));
+ CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
+ DPRINTF(("wsmux_displayioctl: me=%p\n", me));
+#ifdef DIAGNOSTIC
+ if (me->me_parent != sc) {
+ printf("wsmux_displayioctl: bad child %p\n", me);
+ continue;
+ }
+#endif
+ if (me->me_ops->ddispioctl != NULL) {
+ error = wsevsrc_display_ioctl(me, cmd, data, flag, p);
+ DPRINTF(("wsmux_displayioctl: me=%p dev=%s ==> %d\n",
+ me, me->me_dv.dv_xname, error));
if (!error)
ok = 1;
}
@@ -688,54 +740,67 @@ wsmux_displayioctl(dv, cmd, data, flag, p)
return (error);
}
+#if NWSDISPLAY > 0
+/*
+ * Set display of a mux via the parent mux.
+ */
int
-wsmux_set_display(dv, muxsc)
- struct device *dv;
- struct wsmux_softc *muxsc;
+wsmux_evsrc_set_display(struct device *dv, struct wsevsrc *ame)
{
+ struct wsmux_softc *muxsc = (struct wsmux_softc *)ame;
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;
+ struct device *displaydv = muxsc ? muxsc->sc_displaydv : NULL;
DPRINTF(("wsmux_set_display: %s: displaydv=%p\n",
- sc->sc_dv.dv_xname, displaydv));
+ sc->sc_base.me_dv.dv_xname, displaydv));
- if (displaydv) {
- if (sc->sc_displaydv)
+ if (displaydv != NULL) {
+ if (sc->sc_displaydv != NULL)
return (EBUSY);
} else {
if (sc->sc_displaydv == NULL)
return (ENXIO);
}
+ return wsmux_set_display(sc, displaydv);
+}
+
+int
+wsmux_set_display(struct wsmux_softc *sc, struct device *displaydv)
+{
+ struct device *odisplaydv;
+ struct wsevsrc *me;
+ struct wsmux_softc *nsc = displaydv ? sc : NULL;
+ int error, ok;
+
odisplaydv = sc->sc_displaydv;
sc->sc_displaydv = displaydv;
- if (displaydv)
- printf("%s: connecting to %s\n",
- sc->sc_dv.dv_xname, displaydv->dv_xname);
+ if (displaydv) {
+ DPRINTF(("%s: connecting to %s\n",
+ sc->sc_base.me_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));
+ CIRCLEQ_FOREACH(me, &sc->sc_cld,me_next) {
+#ifdef DIAGNOSTIC
+ if (me->me_parent != sc) {
+ printf("wsmux_set_display: bad child parent %p\n", me);
+ continue;
+ }
+#endif
+ if (me->me_ops->dsetdisplay != NULL) {
+ error = wsevsrc_set_display(me, &nsc->sc_base);
+ DPRINTF(("wsmux_set_display: m=%p dev=%s error=%d\n",
+ me, me->me_dv.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);
+ DPRINTF(("wsmux_set_display: %s set rawkbd=%d\n"
+,
+ me->me_dv.dv_xname, sc->sc_rawkbd));
+ (void)wsevsrc_ioctl(me, WSKBDIO_SETMODE,
+ &sc->sc_rawkbd, 0, 0);
#endif
}
}
@@ -743,23 +808,11 @@ wsmux_set_display(dv, muxsc)
if (ok)
error = 0;
- if (displaydv == NULL)
- printf("%s: disconnecting from %s\n",
- sc->sc_dv.dv_xname, odisplaydv->dv_xname);
+ if (displaydv == NULL) {
+ DPRINTF(("%s: disconnecting from %s\n",
+ sc->sc_base.me_dv.dv_xname, odisplaydv->dv_xname));
+ }
return (error);
}
-
-int
-wsmux_isset_display(dv)
- struct device *dv;
-{
- struct wsmux_softc *sc = (struct wsmux_softc *)dv;
-
- if (sc->sc_displaydv != NULL)
- return (1);
-
- return (0);
-}
-
-#endif /* NWSMUX > 0 || (NWSDISPLAY > 0 && NWSKBD > 0) */
+#endif /* NWSDISPLAY > 0 */
diff --git a/sys/dev/wscons/wsmuxvar.h b/sys/dev/wscons/wsmuxvar.h
index 56a783482e3..fc7c01e4535 100644
--- a/sys/dev/wscons/wsmuxvar.h
+++ b/sys/dev/wscons/wsmuxvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: wsmuxvar.h,v 1.5 2002/03/14 01:27:03 millert Exp $ */
-/* $NetBSD: wsmuxvar.h,v 1.1 1999/07/29 18:20:43 augustss Exp $ */
+/* $OpenBSD: wsmuxvar.h,v 1.6 2005/05/15 11:29:15 miod Exp $ */
+/* $NetBSD: wsmuxvar.h,v 1.10 2005/04/30 03:47:12 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -37,62 +37,71 @@
* 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_evar; /* wseventvar opened directly */
+ struct wseventvar *me_evp; /* our wseventvar when open */
+#if NWSDISPLAY > 0
+ struct device *me_dispdv; /* our display if part of one */
+#define sc_displaydv sc_base.me_dispdv
+#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_open(me, evp) \
+ ((me)->me_ops->dopen((me), evp))
+#define wsevsrc_close(me) \
+ ((me)->me_ops->dclose((me)))
+#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 */
+ u_int32_t sc_kbd_layout; /* current layout of keyboard */
#ifdef WSDISPLAY_COMPAT_RAWKBD
- int sc_rawkbd; /* A hack to remember the kbd mode */
+ 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 *);
- int (*dissetdisplay)(struct device *);
-};
-
-
/*
* configure defines
*/
-#define WSKBDDEVCF_MUX_DEFAULT -1
#define WSMOUSEDEVCF_MUX 0
-#define WSMOUSEDEVCF_MUX_DEFAULT -1
-
-struct wsmux_softc *wsmux_create(const char *name, int no);
-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);
+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 *);
+int wsmux_set_display(struct wsmux_softc *, struct device *);
-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 */