PR/17402: Add wsmoused support by providing get/set char and events.

This commit is contained in:
christos 2002-06-26 23:05:33 +00:00
parent cd85109523
commit 71dcc987cd
7 changed files with 233 additions and 11 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.20 2001/11/13 13:14:43 lukem Ex
#include <dev/ic/mc6845reg.h>
#include <dev/ic/pcdisplayvar.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
@ -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;
}

View File

@ -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 *));

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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));
}

View File

@ -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

View File

@ -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. */

View File

@ -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 <sys/cdefs.h>
__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) ||

View File

@ -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
*/