diff --git a/sys/dev/ic/pcdisplay_subr.c b/sys/dev/ic/pcdisplay_subr.c index a943d791f3ee..e07e218d3cc1 100644 --- a/sys/dev/ic/pcdisplay_subr.c +++ b/sys/dev/ic/pcdisplay_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: pcdisplay_subr.c,v 1.20 2001/11/13 13:14:43 lukem Exp $ */ +/* $NetBSD: pcdisplay_subr.c,v 1.21 2002/06/26 23:05:33 christos Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.20 2001/11/13 13:14:43 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.21 2002/06/26 23:05:33 christos Exp $"); #include #include @@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.20 2001/11/13 13:14:43 lukem Ex #include #include +#include #include @@ -272,3 +273,68 @@ pcdisplay_eraserows(id, startrow, nrows, fillattr) for (i = 0; i < count; i++) scr->mem[off + i] = val; } + +int +pcdisplay_getwschar(id, wschar) + void *id; + struct wsdisplay_char *wschar; +{ + struct pcdisplayscreen *scr = id; + bus_space_tag_t memt = scr->hdl->ph_memt; + bus_space_handle_t memh = scr->hdl->ph_memh; + int off; + uint16_t chardata; + uint8_t attrbyte; + + off = wschar->row * scr->type->ncols + wschar->col; + if (off >= scr->type->ncols * scr->type->nrows) + return -1; + + if (scr->active) + chardata = bus_space_read_2(memt, memh, + scr->dispoffset + off * 2); + else + chardata = scr->mem[off]; + + wschar->letter = (chardata & 0x00FF); + wschar->flags = 0; + attrbyte = (chardata & 0xFF00) >> 8; + if ((attrbyte & 0x08)) wschar->flags |= WSDISPLAY_CHAR_BRIGHT; + if ((attrbyte & 0x80)) wschar->flags |= WSDISPLAY_CHAR_BLINK; + wschar->foreground = attrbyte & 0x07; + wschar->background = (attrbyte >> 4) & 0x07; + + return 0; +} + +int +pcdisplay_putwschar(id, wschar) + void *id; + struct wsdisplay_char *wschar; +{ + struct pcdisplayscreen *scr = id; + bus_space_tag_t memt = scr->hdl->ph_memt; + bus_space_handle_t memh = scr->hdl->ph_memh; + int off; + uint16_t chardata; + uint8_t attrbyte; + + off = wschar->row * scr->type->ncols + wschar->col; + if (off >= (scr->type->ncols * scr->type->nrows)) + return -1; + + attrbyte = wschar->background & 0x07; + if (wschar->flags & WSDISPLAY_CHAR_BLINK) attrbyte |= 0x08; + attrbyte <<= 4; + attrbyte |= wschar->foreground & 0x07; + if (wschar->flags & WSDISPLAY_CHAR_BRIGHT) attrbyte |= 0x08; + chardata = (attrbyte << 8) | wschar->letter; + + if (scr->active) + bus_space_write_2(memt, memh, scr->dispoffset + off * 2, + chardata); + else + scr->mem[off] = chardata; + + return 0; +} diff --git a/sys/dev/ic/pcdisplayvar.h b/sys/dev/ic/pcdisplayvar.h index b5e4e557126d..c956cf8a41a9 100644 --- a/sys/dev/ic/pcdisplayvar.h +++ b/sys/dev/ic/pcdisplayvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: pcdisplayvar.h,v 1.8 2000/01/25 02:44:03 ad Exp $ */ +/* $NetBSD: pcdisplayvar.h,v 1.9 2002/06/26 23:05:33 christos Exp $ */ /* * Copyright (c) 1998 @@ -94,3 +94,6 @@ void pcdisplay_copycols __P((void *, int, int, int,int)); void pcdisplay_erasecols __P((void *, int, int, int, long)); void pcdisplay_copyrows __P((void *, int, int, int)); void pcdisplay_eraserows __P((void *, int, int, long)); +struct wsdisplay_char; +int pcdisplay_getwschar __P((void *, struct wsdisplay_char *)); +int pcdisplay_putwschar __P((void *, struct wsdisplay_char *)); diff --git a/sys/dev/ic/vga.c b/sys/dev/ic/vga.c index 9fbdbaac5894..1d83fd55834e 100644 --- a/sys/dev/ic/vga.c +++ b/sys/dev/ic/vga.c @@ -1,4 +1,4 @@ -/* $NetBSD: vga.c,v 1.52 2002/06/26 16:33:18 drochner Exp $ */ +/* $NetBSD: vga.c,v 1.53 2002/06/26 23:05:33 christos Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.52 2002/06/26 16:33:18 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.53 2002/06/26 23:05:33 christos Exp $"); #include #include @@ -247,6 +247,8 @@ static void vga_free_screen(void *, void *); static int vga_show_screen(void *, void *, int, void (*)(void *, int, int), void *); static int vga_load_font(void *, void *, struct wsdisplay_font *); +static int vga_getwschar(void *, struct wsdisplay_char *); +static int vga_putwschar(void *, struct wsdisplay_char *); void vga_doswitch(struct vga_config *); @@ -256,7 +258,10 @@ const struct wsdisplay_accessops vga_accessops = { vga_alloc_screen, vga_free_screen, vga_show_screen, - vga_load_font + vga_load_font, + NULL, + vga_getwschar, + vga_putwschar }; /* @@ -1303,3 +1308,21 @@ vga_mapchar(void *id, int uni, u_int *index) *index = idx1; return (res1); } + +int +vga_getwschar(void *cookie, struct wsdisplay_char *wschar) +{ + struct vgascreen *scr = cookie; + + if (scr == NULL) return 0; + return (pcdisplay_getwschar(&scr->pcs, wschar)); +} + +int +vga_putwschar(void *cookie, struct wsdisplay_char *wschar) +{ + struct vgascreen *scr = cookie; + + if (scr == NULL) return 0; + return (pcdisplay_putwschar(&scr->pcs, wschar)); +} diff --git a/sys/dev/wscons/files.wscons b/sys/dev/wscons/files.wscons index aeeb5f13b9eb..84f08ca4e565 100644 --- a/sys/dev/wscons/files.wscons +++ b/sys/dev/wscons/files.wscons @@ -1,4 +1,4 @@ -# $NetBSD: files.wscons,v 1.25 2001/11/28 10:21:25 lukem Exp $ +# $NetBSD: files.wscons,v 1.26 2002/06/26 23:05:35 christos Exp $ # # "Workstation Console" glue; attaches frame buffer to emulator & keyboard, @@ -19,6 +19,7 @@ defparam opt_wskernattr.h WS_KERNEL_FG WS_KERNEL_BG defflag opt_wsdisplay_compat.h WSDISPLAY_COMPAT_USL WSDISPLAY_COMPAT_RAWKBD WSDISPLAY_COMPAT_PCVT WSDISPLAY_COMPAT_SYSCONS + WSDISPLAY_CHARFUNCS WSCONS_SUPPORT_PCVTFONTS WSCONS_SUPPORT_ISO7FONTS defparam opt_wsdisplay_compat.h WSCOMPAT_USL_SYNCTIMEOUT diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h index bd3805e32005..b0eceb3b8965 100644 --- a/sys/dev/wscons/wsconsio.h +++ b/sys/dev/wscons/wsconsio.h @@ -1,4 +1,4 @@ -/* $NetBSD: wsconsio.h,v 1.50 2002/04/07 09:25:47 hannken Exp $ */ +/* $NetBSD: wsconsio.h,v 1.51 2002/06/26 23:05:36 christos Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -70,6 +70,7 @@ 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 */ +#define WSCONS_EVENT_SCREEN_SWITCH 12 /* New screen number */ /* @@ -375,6 +376,21 @@ struct wsdisplay_param { #define WSDISPLAYIO_GETPARAM _IOWR('W', 82, struct wsdisplay_param) #define WSDISPLAYIO_SETPARAM _IOWR('W', 83, struct wsdisplay_param) +#define WSDISPLAYIO_GETACTIVESCREEN _IOR('W', 84, int) + +/* Character functions */ +struct wsdisplay_char { + int row, col; + uint16_t letter; + uint8_t background, foreground; + char flags; +}; +#define WSDISPLAY_CHAR_BRIGHT 1 +#define WSDISPLAY_CHAR_BLINK 2 +#define WSDISPLAYIO_GETWSCHAR _IOWR('W', 85, struct wsdisplay_char) +#define WSDISPLAYIO_PUTWSCHAR _IOWR('W', 86, struct wsdisplay_char) + + /* XXX NOT YET DEFINED */ /* Mapping information retrieval. */ diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 2e621c95a8df..24f93415b874 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay.c,v 1.63 2002/04/07 09:25:47 hannken Exp $ */ +/* $NetBSD: wsdisplay.c,v 1.64 2002/06/26 23:05:36 christos Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.63 2002/04/07 09:25:47 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.64 2002/06/26 23:05:36 christos Exp $"); #include "opt_wsdisplay_compat.h" #include "opt_compat_netbsd.h" @@ -119,6 +119,8 @@ struct wsdisplay_softc { int sc_focusidx; /* available only if sc_focus isn't null */ struct wsscreen *sc_focus; + struct wseventvar evar; + int sc_isconsole; int sc_flags; @@ -167,6 +169,7 @@ static int wsdisplayparam(struct tty *, struct termios *); #define WSDISPLAYUNIT(dev) (minor(dev) >> 8) #define WSDISPLAYSCREEN(dev) (minor(dev) & 0xff) +#define ISWSDISPLAYSTAT(dev) (WSDISPLAYSCREEN(dev) == 254) #define ISWSDISPLAYCTL(dev) (WSDISPLAYSCREEN(dev) == 255) #define WSDISPLAYMINOR(unit, screen) (((unit) << 8) | (screen)) @@ -675,6 +678,12 @@ wsdisplayopen(dev_t dev, int flag, int mode, struct proc *p) if (sc == NULL) /* make sure it was attached */ return (ENXIO); + if (ISWSDISPLAYSTAT(dev)) { + wsevent_init(&sc->evar); + sc->evar.io = p; + return (0); + } + if (ISWSDISPLAYCTL(dev)) return (0); @@ -731,6 +740,11 @@ wsdisplayclose(dev_t dev, int flag, int mode, struct proc *p) sc = device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); + if (ISWSDISPLAYSTAT(dev)) { + wsevent_fini(&sc->evar); + return (0); + } + if (ISWSDISPLAYCTL(dev)) return (0); @@ -782,9 +796,15 @@ wsdisplayread(dev_t dev, struct uio *uio, int flag) struct wsdisplay_softc *sc; struct tty *tp; struct wsscreen *scr; + int error; sc = device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); + if (ISWSDISPLAYSTAT(dev)) { + error = wsevent_read(&sc->evar, uio, flag); + return (error); + } + if (ISWSDISPLAYCTL(dev)) return (0); @@ -806,6 +826,10 @@ wsdisplaywrite(dev_t dev, struct uio *uio, int flag) sc = device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); + if (ISWSDISPLAYSTAT(dev)) { + return (0); + } + if (ISWSDISPLAYCTL(dev)) return (0); @@ -827,6 +851,9 @@ wsdisplaypoll(dev_t dev, int events, struct proc *p) sc = device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); + if (ISWSDISPLAYSTAT(dev)) + return (wsevent_poll(&sc->evar, events, p)); + if (ISWSDISPLAYCTL(dev)) return (0); @@ -847,6 +874,9 @@ wsdisplaytty(dev_t dev) sc = device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); + if (ISWSDISPLAYSTAT(dev)) + panic("wsdisplaytty() on status device"); + if (ISWSDISPLAYCTL(dev)) panic("wsdisplaytty() on ctl device"); @@ -871,6 +901,9 @@ wsdisplayioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return (error); #endif + if (ISWSDISPLAYSTAT(dev)) + return (wsdisplay_stat_ioctl(sc, cmd, data, flag, p)); + if (ISWSDISPLAYCTL(dev)) return (wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)); @@ -984,6 +1017,26 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr, (scr->scr_dconf->wsemulcookie, WSEMUL_SYNCFONT); return (error); #undef d + +#if defined(WSDISPLAY_CHARFUNCS) + case WSDISPLAYIO_GETWSCHAR: +#define d ((struct wsdisplay_char *)data) + if (!sc->sc_accessops->getwschar) + return (EINVAL); + return ((*sc->sc_accessops->getwschar) + (scr->scr_dconf->emulcookie, d)); +#undef d + + case WSDISPLAYIO_PUTWSCHAR: +#define d ((struct wsdisplay_char *)data) + if (!sc->sc_accessops->putwschar) + return (EINVAL); + return ((*sc->sc_accessops->putwschar) + (scr->scr_dconf->emulcookie, d)); +#undef d + return 1; +#endif /* WSDISPLAY_CHARFUNCS */ + } /* check ioctls for display */ @@ -991,6 +1044,19 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr, flag, p)); } +int +wsdisplay_stat_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data, + int flag, struct proc *p) +{ + switch (cmd) { + case WSDISPLAYIO_GETACTIVESCREEN: + *(int*)data = wsdisplay_getactivescreen(sc); + return (0); + } + + return (EPASSTHROUGH); +} + int wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data, int flag, struct proc *p) @@ -1109,6 +1175,40 @@ wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data, return (EPASSTHROUGH); } +int +wsdisplay_stat_inject(struct device *dev, u_int type, int value) +{ + struct wsdisplay_softc *sc = (struct wsdisplay_softc *) dev; + struct wseventvar *evar; + struct wscons_event *ev; + struct timeval thistime; + int put; + + evar = &sc->evar; + + if (evar == NULL) + return (0); + + if (evar->q == NULL) + return (1); + + put = evar->put; + ev = &evar->q[put]; + put = (put + 1) % WSEVENT_QSIZE; + if (put == evar->get) { + log(LOG_WARNING, "wsdisplay: event queue overflow\n"); + return (1); + } + ev->type = type; + ev->value = value; + microtime(&thistime); + TIMEVAL_TO_TIMESPEC(&thistime, &ev->time); + evar->put = put; + WSEVENT_WAKEUP(evar); + + return (0); +} + paddr_t wsdisplaymmap(dev_t dev, off_t offset, int prot) { @@ -1116,6 +1216,9 @@ wsdisplaymmap(dev_t dev, off_t offset, int prot) device_lookup(&wsdisplay_cd, WSDISPLAYUNIT(dev)); struct wsscreen *scr; + if (ISWSDISPLAYSTAT(dev)) + return (-1); + if (ISWSDISPLAYCTL(dev)) return (-1); @@ -1484,6 +1587,8 @@ wsdisplay_switch(struct device *dev, int no, int waitok) (no < 0 || no >= WSDISPLAY_MAXSCREEN || !sc->sc_scr[no])) return (ENXIO); + wsdisplay_stat_inject(dev, WSCONS_EVENT_SCREEN_SWITCH, no); + s = spltty(); if ((sc->sc_focus && no == sc->sc_focusidx) || diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h index 4a496a967918..988edae0e610 100644 --- a/sys/dev/wscons/wsdisplayvar.h +++ b/sys/dev/wscons/wsdisplayvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplayvar.h,v 1.20 2001/10/13 15:56:15 augustss Exp $ */ +/* $NetBSD: wsdisplayvar.h,v 1.21 2002/06/26 23:05:37 christos Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -89,6 +89,7 @@ struct wsscreen_descr { }; struct wsdisplay_font; +struct wsdisplay_char; /* * Display access functions, invoked by user-land programs which require * direct device access, such as X11. @@ -107,6 +108,8 @@ struct wsdisplay_accessops { void (*) (void *, int, int), void *); int (*load_font)(void *, void *, struct wsdisplay_font *); void (*pollc)(void *, int); + int (*getwschar)(void *, struct wsdisplay_char *); + int (*putwschar)(void *, struct wsdisplay_char *); }; /* @@ -186,9 +189,14 @@ int wsdisplay_usl_ioctl1(struct wsdisplay_softc *, int wsdisplay_usl_ioctl2(struct wsdisplay_softc *, struct wsscreen *, u_long, caddr_t, int, struct proc *); +int wsdisplay_stat_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data, + int flag, struct proc *p); + int wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data, int flag, struct proc *p); +int wsdisplay_stat_inject(struct device *dev, u_int type, int value); + /* * for general use */