summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjbm <jbm@cvs.openbsd.org>2002-03-27 18:54:10 +0000
committerjbm <jbm@cvs.openbsd.org>2002-03-27 18:54:10 +0000
commitd4740433243c6484c98ad8fd0e38747c00f346c1 (patch)
treef39c18c01c179725f35dd68a4b4315853d0ae362
parent7e700aa642609180b1c262e4ba1ac73f6554b5f5 (diff)
Add X-Window support to wsmoused(8). This allows running wsmoused(8) and
X-Window at the same time, removing the need to kill wsmoused(8) before starting X-Window.
-rw-r--r--sys/dev/wscons/wsconsio.h13
-rw-r--r--sys/dev/wscons/wsdisplay.c190
-rw-r--r--sys/dev/wscons/wsdisplayvar.h5
-rw-r--r--sys/dev/wscons/wsmouse.c12
-rw-r--r--sys/dev/wscons/wsmoused.h5
-rw-r--r--sys/dev/wscons/wsmousevar.h5
-rw-r--r--usr.sbin/wsmoused/wsmoused.812
-rw-r--r--usr.sbin/wsmoused/wsmoused.c62
8 files changed, 277 insertions, 27 deletions
diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h
index 3c49f52370e..d36a48966fe 100644
--- a/sys/dev/wscons/wsconsio.h
+++ b/sys/dev/wscons/wsconsio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsio.h,v 1.14 2002/01/16 14:55:38 jason Exp $ */
+/* $OpenBSD: wsconsio.h,v 1.15 2002/03/27 18:54:09 jbm Exp $ */
/* $NetBSD: wsconsio.h,v 1.31.2.1 2000/07/07 09:49:17 hannken Exp $ */
/*
@@ -73,8 +73,15 @@ struct wscons_event {
#define WSCONS_EVENT_MOUSE_ABSOLUTE_Y 9 /* Y location */
#define WSCONS_EVENT_MOUSE_DELTA_Z 10 /* Z delta amount */
#define WSCONS_EVENT_MOUSE_ABSOLUTE_Z 11 /* Z location */
+/*
+ * Following events are not real wscons_event but are used as parameters of the
+ * WSDISPLAYIO_WSMOUSED ioctl
+ */
#define WSCONS_EVENT_WSMOUSED_ON 12 /* wsmoused(8) active */
#define WSCONS_EVENT_WSMOUSED_OFF 13 /* wsmoused(8) inactive */
+#define WSCONS_EVENT_WSMOUSED_SLEEP 14 /* wsmoused(8) sleeping */
+#define WSCONS_EVENT_WSMOUSED_CLOSE 15 /* notify wsmoused(8) to close
+ mouse device */
#define IS_MOTION_EVENT(type) (((type) == WSCONS_EVENT_MOUSE_DELTA_X) || \
((type) == WSCONS_EVENT_MOUSE_DELTA_Y) || \
@@ -82,7 +89,9 @@ struct wscons_event {
#define IS_BUTTON_EVENT(type) (((type) == WSCONS_EVENT_MOUSE_UP) || \
((type) == WSCONS_EVENT_MOUSE_DOWN))
#define IS_CTRL_EVENT(type) ((type == WSCONS_EVENT_WSMOUSED_ON) || \
- (type == WSCONS_EVENT_WSMOUSED_OFF))
+ (type == WSCONS_EVENT_WSMOUSED_OFF)|| \
+ (type == WSCONS_EVENT_WSMOUSED_SLEEP))
+
/*
* Keyboard ioctls (0 - 31)
*/
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 804b862bebd..50ac76f1cd5 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsdisplay.c,v 1.40 2002/03/16 22:11:55 mickey Exp $ */
+/* $OpenBSD: wsdisplay.c,v 1.41 2002/03/27 18:54:09 jbm Exp $ */
/* $NetBSD: wsdisplay.c,v 1.37.4.1 2000/06/30 16:27:53 simonb Exp $ */
/*
@@ -60,6 +60,7 @@
#include <dev/ic/pcdisplay.h>
#include "wskbd.h"
+#include "wsmouse.h"
#include "wsmux.h"
#if NWSKBD > 0
@@ -67,8 +68,16 @@
#include <dev/wscons/wsmuxvar.h>
#endif
+#if NWSMOUSE > 0
+#include "wsmousevar.h"
+#endif /* NWSMOUSE > 0 */
+
#include "wsmoused.h"
+#if NWSMOUSE > 0
+extern struct cfdriver wsmouse_cd;
+#endif /* NWSMOUSE > 0 */
+
struct wsscreen_internal {
const struct wsdisplay_emulops *emulops;
void *emulcookie;
@@ -138,9 +147,6 @@ void wsdisplay_closescreen(struct wsdisplay_softc *, struct wsscreen *);
int wsdisplay_delscreen(struct wsdisplay_softc *, int, int);
void wsdisplay_burner(void *v);
-#define WSDISPLAY_MAXSCREEN 12
-#define WSDISPLAY_MAXFONT 8
-
struct wsdisplay_softc {
struct device sc_dv;
@@ -174,9 +180,15 @@ struct wsdisplay_softc {
int sc_rawkbd;
#endif
#endif /* NWSKBD > 0 */
+
+ dev_t wsmoused_dev; /* device opened by wsmoused(8), when active */
+ int wsmoused_sleep; /* true when wsmoused(8) is sleeping */
};
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 *);
@@ -1065,8 +1077,22 @@ wsdisplay_internal_ioctl(sc, scr, cmd, data, flag, p)
if (WSSCREEN_HAS_EMULATOR(scr)) {
scr->scr_flags &= ~SCR_GRAPHICS;
- if (d == WSDISPLAYIO_MODE_MAPPED)
+ if (d == WSDISPLAYIO_MODE_MAPPED) {
scr->scr_flags |= SCR_GRAPHICS;
+ /*
+ * wsmoused cohabitation with X-Window support
+ * X-Window is starting
+ */
+ wsmoused_release(sc);
+ }
+ else {
+ /*
+ * wsmoused cohabitation with X-Window support
+ * X-Window is ending
+ */
+
+ wsmoused_wakeup(sc);
+ }
} else if (d == WSDISPLAYIO_MODE_EMUL)
return (EINVAL);
@@ -1731,6 +1757,48 @@ wsdisplay_switch(dev, no, waitok)
} else
sc->sc_oldscreen = sc->sc_focusidx;
+
+ /*
+ * wsmoused cohabitation with X-Window support
+ *
+ * Detect switch from a graphic to text console and vice-versa
+ * This only happen when switching from X-Window to text mode and
+ * switching back from text mode to X-Window.
+ *
+ * scr_flags is not yet flagged with SCR_GRAPHICS when X-Window starts
+ * (KD_GRAPHICS ioctl happens after VT_ACTIVATE ioctl in
+ * xf86OpenPcvt()). Conversely, scr_flags is no longer flagged with
+ * 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) &&
+ (!(sc->sc_scr[no]->scr_flags & SCR_GRAPHICS))) {
+ /* switching from a text console to another text console */
+ /* XXX evaluated when the X-server starts or stops, see above */
+
+ /* remove a potential wsmoused(8) selection */
+ mouse_remove(sc);
+ }
+
+ if (!(scr->scr_flags & SCR_GRAPHICS) &&
+ (sc->sc_scr[no]->scr_flags & SCR_GRAPHICS)) {
+ /* switching from a text console to a graphic console */
+
+ /* remote a potential wsmoused(8) selection */
+ mouse_remove(sc);
+ wsmoused_release(sc);
+ }
+
+ if ((scr->scr_flags & SCR_GRAPHICS) &&
+ !(sc->sc_scr[no]->scr_flags & SCR_GRAPHICS)) {
+ /* switching from a graphic console to a text console */
+
+ wsmoused_wakeup(sc);
+ }
+
#define wsswitch_cb1 ((void (*)(void *, int, int))wsdisplay_switch1)
if (scr->scr_syncops) {
res = (*scr->scr_syncops->detach)(scr->scr_synccookie, waitok,
@@ -1744,12 +1812,6 @@ wsdisplay_switch(dev, no, waitok)
res = EBUSY;
}
- if (IS_SEL_EXISTS(sc->sc_focus))
- /* hide a potential selection */
- remove_selection(sc);
-
- mouse_hide(sc); /* hide a potential mouse cursor */
-
return (wsdisplay_switch1(sc, res, waitok));
}
@@ -2080,9 +2142,10 @@ wsdisplay_shutdownhook(arg)
}
/*
- * mouse console support functions
+ * wsmoused(8) support functions
*/
+
/* pointer to the current screen wsdisplay_softc structure */
static struct wsdisplay_softc *sc = NULL;
@@ -2200,21 +2263,34 @@ button_event(int button, int clicks)
int
ctrl_event(u_int type, int value, struct wsdisplay_softc *ws_sc, struct proc *p)
{
- int i;
+ int i, error;
if (type == WSCONS_EVENT_WSMOUSED_ON) {
if (!ws_sc->sc_accessops->getchar)
- /* no wsmoused support in the display driver */
+ /* no wsmoused(8) support in the display driver */
return (1);
/* initialization of globals */
sc = ws_sc;
allocate_copybuffer(sc);
Paste_avail = 0;
+ ws_sc->wsmoused_dev = value;
}
if (type == WSCONS_EVENT_WSMOUSED_OFF) {
Paste_avail = 0;
+ ws_sc->wsmoused_dev = 0;
return (0);
}
+ if (type == WSCONS_EVENT_WSMOUSED_SLEEP) {
+ /* sleeping until next switch to text mode */
+ ws_sc->wsmoused_sleep = 1;
+ while (ws_sc->wsmoused_sleep && error == 0)
+ error = tsleep(&ws_sc->wsmoused_sleep, PPAUSE,
+ "wsmoused_sleep", 0);
+ if (error)
+ return error;
+ else
+ return (0);
+ }
for (i = 0 ; i < WSDISPLAY_DEFAULTSCREENS ; i++)
if (sc->sc_scr[i]) {
sc->sc_scr[i]->mouse =
@@ -3044,3 +3120,89 @@ allocate_copybuffer(struct wsdisplay_softc *sc)
Copybuffer_size = size;
splx(s);
}
+
+
+/* Remove selection and cursor on current screen */
+void
+mouse_remove(struct wsdisplay_softc *sc)
+{
+ if (IS_SEL_EXISTS(sc->sc_focus))
+ remove_selection(sc);
+
+ mouse_hide(sc);
+}
+
+
+
+/* Send a wscons event to notify wsmoused(8) to release the mouse device */
+void
+wsmoused_release(struct wsdisplay_softc *sc)
+{
+#if NWSMOUSE > 0
+ struct device *wsms_dev = NULL;
+ struct device **wsms_dev_list;
+ int is_wsmouse = 0;
+#if NWSMUX > 0
+ int is_wsmux = 0;
+#endif /* NWSMUX > 0 */
+
+ if (sc->wsmoused_dev) {
+ /* wsmoused(8) is running */
+
+ wsms_dev_list = (struct device **) wsmouse_cd.cd_devs;
+ if (!wsms_dev_list)
+ /* no wsmouse device exists */
+ return ;
+
+ /* test whether device opened by wsmoused(8) is a wsmux device
+ * (/dev/wsmouse) or a wsmouse device (/dev/wsmouse{0..n} */
+
+#if NWSMUX > 0
+ /* obtain major of /dev/wsmouse multiplexor device */
+ /* XXX first member of wsmux_softc is of type struct device */
+ if (cdevsw[major(sc->wsmoused_dev)].d_open == wsmuxopen)
+ is_wsmux = 1;
+
+ if (is_wsmux && (minor(sc->wsmoused_dev) == WSMOUSEDEVCF_MUX)) {
+ /* /dev/wsmouse case */
+ /* XXX at least, wsmouse0 exist */
+ wsms_dev = wsms_dev_list[0];
+ }
+#endif /* NWSMUX > 0 */
+
+ /* obtain major of /dev/wsmouse{0..n} devices */
+ if (wsmouse_cd.cd_ndevs > 0) {
+ if (cdevsw[major(sc->wsmoused_dev)].d_open ==
+ wsmouseopen)
+ is_wsmouse = 1;
+ }
+
+ if (is_wsmouse && (minor(sc->wsmoused_dev) <= NWSMOUSE)) {
+ /* /dev/wsmouseX case */
+ if (minor(sc->wsmoused_dev) <= wsmouse_cd.cd_ndevs) {
+ wsms_dev =
+ wsms_dev_list[minor(sc->wsmoused_dev)];
+ }
+ else
+ /* no corresponding /dev/wsmouseX device */
+ return;
+ }
+
+ /* inject event to notify wsmoused(8) to close mouse device */
+ wsmouse_input(wsms_dev, 0, 0, 0, 0,
+ WSMOUSE_INPUT_WSMOUSED_CLOSE);
+ }
+#endif /* NWSMOUSE > 0 */
+}
+
+/* Wakeup wsmoused(8), so that the mouse device can be reopened */
+void
+wsmoused_wakeup(struct wsdisplay_softc *sc)
+{
+#if NWSMOUSE > 0
+ if (sc->wsmoused_dev) {
+ sc->wsmoused_sleep = 0;
+ wakeup(&sc->wsmoused_sleep);
+ }
+#endif /* NWSMOUSE > 0 */
+}
diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h
index 149cd7c1963..867a5e90349 100644
--- a/sys/dev/wscons/wsdisplayvar.h
+++ b/sys/dev/wscons/wsdisplayvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsdisplayvar.h,v 1.12 2002/03/14 03:16:08 millert Exp $ */
+/* $OpenBSD: wsdisplayvar.h,v 1.13 2002/03/27 18:54:09 jbm Exp $ */
/* $NetBSD: wsdisplayvar.h,v 1.14.4.1 2000/06/30 16:27:53 simonb Exp $ */
/*
@@ -37,6 +37,9 @@ struct device;
* WSDISPLAY interfaces
*/
+#define WSDISPLAY_MAXSCREEN 12
+#define WSDISPLAY_MAXFONT 8
+
/*
* Emulation functions, for displays that can support glass-tty terminal
* emulations. These are character oriented, with row and column
diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c
index bb502260101..e0dedad1500 100644
--- a/sys/dev/wscons/wsmouse.c
+++ b/sys/dev/wscons/wsmouse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsmouse.c,v 1.8 2002/03/14 01:27:03 millert Exp $ */
+/* $OpenBSD: wsmouse.c,v 1.9 2002/03/27 18:54:09 jbm Exp $ */
/* $NetBSD: wsmouse.c,v 1.12 2000/05/01 07:36:58 takemura Exp $ */
/*
@@ -435,6 +435,16 @@ wsmouse_input(wsmousedev, btns, x, y, z, flags)
ADVANCE;
ub ^= d;
}
+
+ /* 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;
+ }
+
out:
if (any) {
sc->sc_ub = ub;
diff --git a/sys/dev/wscons/wsmoused.h b/sys/dev/wscons/wsmoused.h
index 30316809a02..d791f3e7387 100644
--- a/sys/dev/wscons/wsmoused.h
+++ b/sys/dev/wscons/wsmoused.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsmoused.h,v 1.3 2002/03/14 04:55:21 mickey Exp $ */
+/* $OpenBSD: wsmoused.h,v 1.4 2002/03/27 18:54:09 jbm Exp $ */
/*
* Copyright (c) 2001 Jean-Baptiste Marchand, Julien Montagne and Jerome Verdon
@@ -73,6 +73,9 @@ void mouse_paste(void);
void mouse_zaxis(int);
void allocate_copybuffer(struct wsdisplay_softc *);
+void mouse_remove(struct wsdisplay_softc *);
+void wsmoused_release(struct wsdisplay_softc *);
+void wsmoused_wakeup(struct wsdisplay_softc *);
void sysbeep(int, int);
diff --git a/sys/dev/wscons/wsmousevar.h b/sys/dev/wscons/wsmousevar.h
index 92f2779edec..cc20831bb11 100644
--- a/sys/dev/wscons/wsmousevar.h
+++ b/sys/dev/wscons/wsmousevar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsmousevar.h,v 1.3 2002/03/14 01:27:03 millert Exp $ */
+/* $OpenBSD: wsmousevar.h,v 1.4 2002/03/27 18:54:09 jbm Exp $ */
/* $NetBSD: wsmousevar.h,v 1.4 2000/01/08 02:57:24 takemura Exp $ */
/*
@@ -71,5 +71,8 @@ int wsmousedevprint(void *, const char *);
#define WSMOUSE_INPUT_ABSOLUTE_X (1<<0)
#define WSMOUSE_INPUT_ABSOLUTE_Y (1<<1)
#define WSMOUSE_INPUT_ABSOLUTE_Z (1<<2)
+#define WSMOUSE_INPUT_WSMOUSED_CLOSE (1<<3) /* notify wsmoused(8) to close
+ mouse device */
+
void wsmouse_input(struct device *kbddev, u_int btns,
int x, int y, int z, u_int flags);
diff --git a/usr.sbin/wsmoused/wsmoused.8 b/usr.sbin/wsmoused/wsmoused.8
index 33670507210..abfef185280 100644
--- a/usr.sbin/wsmoused/wsmoused.8
+++ b/usr.sbin/wsmoused/wsmoused.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: wsmoused.8,v 1.5 2001/08/20 06:09:32 mpech Exp $
+.\" $OpenBSD: wsmoused.8,v 1.6 2002/03/27 18:54:09 jbm Exp $
.\"
.Dd April 8, 2001
.Dt WSMOUSED 8 i386
@@ -137,6 +137,16 @@ Kensington ThinkingMouse protocol.
Hitachi tablet protocol.
.El
.El
+
+.Nm
+will happily coexist with X-Window, provided that the mouse device is
+supported by
+.Xr wsmouse 4 .
+Serial mice do not have a
+.Xr wsmouse 4
+compatible driver, so
+.Nm
+has to be killed before starting X-Window.
.Sh SEE ALSO
.Xr wscons 4 ,
.Xr wsmouse 4
diff --git a/usr.sbin/wsmoused/wsmoused.c b/usr.sbin/wsmoused/wsmoused.c
index 9ad291e12f0..b20ef981b3b 100644
--- a/usr.sbin/wsmoused/wsmoused.c
+++ b/usr.sbin/wsmoused/wsmoused.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsmoused.c,v 1.10 2002/03/14 06:51:42 mpech Exp $ */
+/* $OpenBSD: wsmoused.c,v 1.11 2002/03/27 18:54:09 jbm Exp $ */
/*
* Copyright (c) 2001 Jean-Baptiste Marchand, Julien Montagne and Jerome Verdon
@@ -51,6 +51,7 @@
*/
#include <sys/ioctl.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/tty.h>
@@ -220,7 +221,7 @@ terminate(int sig)
if (mouse.mfd != -1) {
event.type = WSCONS_EVENT_WSMOUSED_OFF;
- ioctl(mouse.mfd, WSDISPLAYIO_WSMOUSED, &event);
+ ioctl(mouse.cfd, WSDISPLAYIO_WSMOUSED, &event);
res = WSMOUSE_RES_DEFAULT;
ioctl(mouse.mfd, WSMOUSEIO_SRES, &res);
close(mouse.mfd);
@@ -315,17 +316,23 @@ normalize_event(struct wscons_event *event)
}
/* send a wscons_event to the kernel */
-static void
+static int
treat_event(struct wscons_event *event)
{
struct wscons_event mapped_event;
if (IS_MOTION_EVENT(event->type)) {
ioctl(mouse.cfd, WSDISPLAYIO_WSMOUSED, event);
+ return 1;
} else if (IS_BUTTON_EVENT(event->type)) {
mouse_map(event, &mapped_event);
mouse_click(&mapped_event);
+ return 1;
}
+ if (event->type == WSCONS_EVENT_WSMOUSED_CLOSE)
+ /* we have to close mouse fd */
+ return 0;
+ return 1;
}
/* split a full mouse event into multiples wscons events */
@@ -382,6 +389,7 @@ wsmoused(void)
int res;
u_char b;
FILE *fp;
+ struct stat mdev_stat;
if (!nodaemon && !background) {
if (daemon(0, 0)) {
@@ -402,10 +410,24 @@ wsmoused(void)
/* initialization */
event.type = WSCONS_EVENT_WSMOUSED_ON;
+ if (IS_WSMOUSE_DEV(mouse.portname)) {
+
+ /* get major and minor of mouse device */
+ res = stat(mouse.portname, &mdev_stat);
+ if (res != -1)
+ event.value = mdev_stat.st_rdev;
+ else
+ event.value = 0;
+ }
+ else
+ /* X-Window won't start using wsmoused(8) with a serial mouse */
+ event.value = 0;
+
+ /* notify kernel to start wsmoused */
res = ioctl(mouse.cfd, WSDISPLAYIO_WSMOUSED, &event);
if (res != 0) {
/* the display driver has no getchar() method */
- logerr(1, "this display driver has no support for wsmoused");
+ logerr(1, "this display driver has no support for wsmoused(8)");
}
bzero(&action, sizeof(action));
@@ -422,9 +444,37 @@ wsmoused(void)
if (IS_WSMOUSE_DEV(mouse.portname)) {
/* wsmouse supported mouse */
read(mouse.mfd, &event, sizeof(event));
- treat_event(&event);
+ res = treat_event(&event);
+ if (!res) {
+ /* close mouse device and sleep until
+ the X server release it */
+
+ struct wscons_event sleeping;
+
+ /* restore mouse resolution to default value */
+ res = WSMOUSE_RES_DEFAULT;
+ ioctl(mouse.mfd, WSMOUSEIO_SRES, &res);
+
+ close(mouse.mfd);
+ mouse.mfd = -1;
+
+ /* sleep until X server releases mouse device */
+ sleeping.type = WSCONS_EVENT_WSMOUSED_SLEEP;
+ sleeping.value = 0;
+ ioctl(mouse.cfd, WSDISPLAYIO_WSMOUSED,
+ &sleeping);
+
+ /* waiting for availability of mouse device */
+ sleep(1);
+
+ if ((mouse.mfd = open(mouse.portname,
+ O_RDONLY | O_NONBLOCK, 0)) == -1)
+ logerr(1, "unable to open %s",
+ mouse.portname);
+ mouse_init();
+ }
} else {
- /* serial mouse (not wsmouse supported) */
+ /* serial mouse (not supported by wsmouse) */
res = read(mouse.mfd, &b, 1);
/* if we have a full mouse event */