summaryrefslogtreecommitdiff
path: root/sys/dev/wscons/wsdisplay.c
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 /sys/dev/wscons/wsdisplay.c
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.
Diffstat (limited to 'sys/dev/wscons/wsdisplay.c')
-rw-r--r--sys/dev/wscons/wsdisplay.c190
1 files changed, 176 insertions, 14 deletions
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 */
+}