diff options
author | jbm <jbm@cvs.openbsd.org> | 2002-03-27 18:54:10 +0000 |
---|---|---|
committer | jbm <jbm@cvs.openbsd.org> | 2002-03-27 18:54:10 +0000 |
commit | d4740433243c6484c98ad8fd0e38747c00f346c1 (patch) | |
tree | f39c18c01c179725f35dd68a4b4315853d0ae362 | |
parent | 7e700aa642609180b1c262e4ba1ac73f6554b5f5 (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.h | 13 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 190 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplayvar.h | 5 | ||||
-rw-r--r-- | sys/dev/wscons/wsmouse.c | 12 | ||||
-rw-r--r-- | sys/dev/wscons/wsmoused.h | 5 | ||||
-rw-r--r-- | sys/dev/wscons/wsmousevar.h | 5 | ||||
-rw-r--r-- | usr.sbin/wsmoused/wsmoused.8 | 12 | ||||
-rw-r--r-- | usr.sbin/wsmoused/wsmoused.c | 62 |
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 */ |