Allow attaching wskbd at kbd, idea from Valeriy Ushakov.

This allows us to use both the old sun keyboard events (/dev/kbd) as
new wscons events (/dev/wskbd*).

TODO: Not implemented for the kbd at zstty attachment.
Wskbd as console does not yet work.
This commit is contained in:
martin 2002-10-26 19:11:13 +00:00
parent b1aed1c393
commit 6837231089
4 changed files with 222 additions and 30 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.sun,v 1.5 2002/10/03 16:13:25 uwe Exp $
# $NetBSD: files.sun,v 1.6 2002/10/26 19:11:13 martin Exp $
#
# Configuration file for devices found on Sun machines.
#
@ -15,10 +15,12 @@ file dev/sun/event.c firm_events
# upper layer of sun kbd driver
# examples for lower and middle layers follows. cannot move them here
# because zs/zstty attachments are slightly different on each sun port.
device kbd: firm_events
device kbd: firm_events, wskbddev
file dev/sun/kbd.c kbd needs-flag
file dev/sun/kbd_tables.c kbd
file dev/sun/wskbdmap_sun.c kbd & wskbd
# e.g. - lower layer: sun keyboard at zs
#attach kbd at zs with kbd_zs
#file dev/sun/kbd_zs.c kbd_zs

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbd.c,v 1.34 2002/10/23 09:13:56 jdolecek Exp $ */
/* $NetBSD: kbd.c,v 1.35 2002/10/26 19:11:13 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -51,7 +51,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.34 2002/10/23 09:13:56 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.35 2002/10/26 19:11:13 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -69,6 +69,8 @@ __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.34 2002/10/23 09:13:56 jdolecek Exp $");
#include <sys/poll.h>
#include <sys/file.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/sun/kbd_reg.h>
#include <dev/sun/kbio.h>
#include <dev/sun/vuid_event.h>
@ -92,6 +94,40 @@ const struct cdevsw kbd_cdevsw = {
nostop, notty, kbdpoll, nommap, kbdkqfilter
};
#if NWSKBD > 0
int wssunkbd_enable __P((void *, int));
void wssunkbd_set_leds __P((void *, int));
int wssunkbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
void sunkbd_wskbd_cngetc __P((void *, u_int *, int *));
void sunkbd_wskbd_cnpollc __P((void *, int));
void sunkbd_wskbd_cnbell __P((void *, u_int, u_int, u_int));
static void sunkbd_bell_off(void *v);
const struct wskbd_accessops sunkbd_wskbd_accessops = {
wssunkbd_enable,
wssunkbd_set_leds,
wssunkbd_ioctl,
};
extern const struct wscons_keydesc wssun_keydesctab[];
const struct wskbd_mapdata sunkbd_wskbd_keymapdata = {
wssun_keydesctab,
#ifdef SUNKBD_LAYOUT
SUNKBD_LAYOUT,
#else
KB_US,
#endif
};
const struct wskbd_consops sunkbd_wskbd_consops = {
sunkbd_wskbd_cngetc,
sunkbd_wskbd_cnpollc,
sunkbd_wskbd_cnbell,
};
void kbd_wskbd_attach(struct kbd_softc *k, int isconsole);
#endif
/* ioctl helpers */
static int kbd_iockeymap(struct kbd_state *ks,
@ -114,6 +150,10 @@ static void kbd_input_string(struct kbd_softc *, char *);
static void kbd_input_funckey(struct kbd_softc *, int);
static void kbd_update_leds(struct kbd_softc *);
#if NWSKBD > 0
static void kbd_input_wskbd(struct kbd_softc *, int);
#endif
/* firm events input */
static void kbd_input_event(struct kbd_softc *, int);
@ -434,36 +474,43 @@ kbd_input(k, code)
struct kbd_softc *k;
int code;
{
/*
* TODO: wscons support: check if attached wskbd has called
* enable() and pass input to wskbd_input() if it has. But
* check for k_evmode first(!) - see the comment in kbdopen().
*/
if (k->k_evmode) {
/*
* If /dev/kbd is not connected in event mode,
* translate and send upstream (to console).
*/
if (!k->k_evmode) {
kbd_input_console(k, code);
#ifdef KBD_IDLE_EVENTS
/*
* XXX: is this still true?
* IDLEs confuse the MIT X11R4 server badly, so we must drop them.
* This is bad as it means the server will not automatically resync
* on all-up IDLEs, but I did not drop them before, and the server
* goes crazy when it comes time to blank the screen....
*/
if (code == KBD_IDLE)
return;
#endif
/*
* Keyboard is generating firm events. Turn this keystroke
* into an event and put it in the queue.
*/
kbd_input_event(k, code);
return;
}
/*
* XXX: is this still true?
* IDLEs confuse the MIT X11R4 server badly, so we must drop them.
* This is bad as it means the server will not automatically resync
* on all-up IDLEs, but I did not drop them before, and the server
* goes crazy when it comes time to blank the screen....
*/
if (code == KBD_IDLE)
#if NWSKBD > 0
if (k->k_wskbd != NULL && k->k_wsenabled) {
/*
* We are using wskbd input mode, pass the event up.
*/
kbd_input_wskbd(k, code);
return;
}
#endif
/*
* Keyboard is generating firm events. Turn this keystroke
* into an event and put it in the queue.
* If /dev/kbd is not connected in event mode, or wskbd mode,
* translate and send upstream (to console).
*/
kbd_input_event(k, code);
kbd_input_console(k, code);
}
@ -892,3 +939,127 @@ kbd_bell(on)
(void)(*k->k_ops->docmd)(k, on ? KBD_CMD_BELL : KBD_CMD_NOBELL, 0);
}
#if NWSKBD > 0
static void
kbd_input_wskbd(struct kbd_softc *k, int code)
{
int type, key;
type = KEY_UP(code) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
key = KEY_CODE(code);
wskbd_input(k->k_wskbd, type, key);
}
int
wssunkbd_enable(v, on)
void *v;
int on;
{
struct kbd_softc *k = v;
k->k_wsenabled = on;
if (on) {
/* open actual underlying device */
if (k->k_ops != NULL && k->k_ops->open != NULL)
(*k->k_ops->open)(k);
ev_init(&k->k_events);
k->k_evmode = 0; /* XXX: OK? */
} else {
/* close underlying device */
if (k->k_ops != NULL && k->k_ops->close != NULL)
(*k->k_ops->close)(k);
}
return 0;
}
void
wssunkbd_set_leds(v, leds)
void *v;
int leds;
{
struct kbd_softc *k = v;
int l = 0;
if (leds & WSKBD_LED_CAPS)
l |= LED_CAPS_LOCK;
if (leds & WSKBD_LED_NUM)
l |= LED_NUM_LOCK;
if (leds & WSKBD_LED_SCROLL)
l |= LED_SCROLL_LOCK;
if (leds & WSKBD_LED_COMPOSE)
l |= LED_COMPOSE;
if (k->k_ops != NULL && k->k_ops->setleds != NULL)
(*k->k_ops->setleds)(k, l, 0);
}
int
wssunkbd_ioctl(v, cmd, data, flag, p)
void *v;
u_long cmd;
caddr_t data;
int flag;
struct proc *p;
{
return EPASSTHROUGH;
}
void
sunkbd_wskbd_cngetc(v, type, data)
void *v;
u_int *type;
int *data;
{
/* struct kbd_sun_softc *k = v; */
}
void
sunkbd_wskbd_cnpollc(v, on)
void *v;
int on;
{
}
static void
sunkbd_bell_off(v)
void *v;
{
struct kbd_softc *k = v;
k->k_ops->docmd(k, KBD_CMD_NOBELL, 0);
}
void
sunkbd_wskbd_cnbell(v, pitch, period, volume)
void *v;
u_int pitch, period, volume;
{
struct kbd_softc *k = v;
callout_reset(&k->k_wsbell, period*1000/hz, sunkbd_bell_off, v);
k->k_ops->docmd(k, KBD_CMD_BELL, 0);
}
void
kbd_wskbd_attach(k, isconsole)
struct kbd_softc *k;
int isconsole;
{
struct wskbddev_attach_args a;
a.console = isconsole;
if (a.console)
wskbd_cnattach(&sunkbd_wskbd_consops, k, &sunkbd_wskbd_keymapdata);
a.keymap = &sunkbd_wskbd_keymapdata;
a.accessops = &sunkbd_wskbd_accessops;
a.accesscookie = k;
/* Attach the wskbd */
k->k_wskbd = config_found(&k->k_dev, &a, wskbddevprint);
k->k_wsenabled = 0;
callout_init(&k->k_wsbell);
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbdvar.h,v 1.10 2002/10/21 15:36:35 uwe Exp $ */
/* $NetBSD: kbdvar.h,v 1.11 2002/10/26 19:11:13 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,10 @@
* @(#)kbd.c 8.2 (Berkeley) 10/30/93
*/
#include "wskbd.h" /* for NWSKBD */
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
struct kbd_softc {
struct device k_dev; /* required first: base device */
@ -54,6 +58,12 @@ struct kbd_softc {
int k_evmode; /* set if we should produce events */
struct evvar k_events; /* event queue state */
#if NWSKBD > 0
struct device * k_wskbd;/* handle for wskbd, if it is attached */
int k_wsenabled; /* set if we are using wskbd */
struct callout k_wsbell;/* to shut the bell off */
#endif
/* ACSII translation state */
struct kbd_state k_state;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sunkbd.c,v 1.14 2002/10/21 15:36:35 uwe Exp $ */
/* $NetBSD: sunkbd.c,v 1.15 2002/10/26 19:11:13 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.14 2002/10/21 15:36:35 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.15 2002/10/26 19:11:13 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -81,7 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.14 2002/10/21 15:36:35 uwe Exp $");
#include <dev/sun/kbdsunvar.h>
#include <dev/sun/kbd_ms_ttyvar.h>
/****************************************************************
* Interface to the lower layer (ttycc)
****************************************************************/
@ -91,6 +90,10 @@ static void sunkbd_attach(struct device *, struct device *, void *);
static void sunkbd_write_data(struct kbd_sun_softc *, int);
static int sunkbdiopen(struct device *, int mode);
#if NWSKBD > 0
void kbd_wskbd_attach(struct kbd_softc *k, int isconsole);
#endif
int sunkbdinput(int, struct tty *);
int sunkbdstart(struct tty *);
@ -104,6 +107,7 @@ struct linesw sunkbd_disc =
{ "sunkbd", 7, ttylopen, ttylclose, ttyerrio, ttyerrio, ttynullioctl,
sunkbdinput, sunkbdstart, nullmodem, ttpoll }; /* 7- SUNKBDDISC */
/*
* sunkbd_match: how is this tty channel configured?
*/
@ -181,8 +185,13 @@ sunkbd_attach(parent, self, aux)
kd_attach_input(cc);
}
printf("\n");
#if NWSKBD > 0
kbd_wskbd_attach(&k->k_kbd, args->kmta_consdev != NULL);
#endif
/* Do this before any calls to kbd_rint(). */
kbd_xlate_init(&k->k_kbd.k_state);