diff options
-rw-r--r-- | sys/dev/adb/adb.h | 18 | ||||
-rw-r--r-- | sys/dev/adb/akbd.c | 229 | ||||
-rw-r--r-- | sys/dev/adb/ams.c | 37 | ||||
-rw-r--r-- | sys/dev/adb/keyboard.h | 30 |
4 files changed, 131 insertions, 183 deletions
diff --git a/sys/dev/adb/adb.h b/sys/dev/adb/adb.h index e18e61cc0ea..e675281628f 100644 --- a/sys/dev/adb/adb.h +++ b/sys/dev/adb/adb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adb.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $OpenBSD: adb.h,v 1.2 2006/02/12 18:06:23 miod Exp $ */ /* $NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $ */ /*- @@ -39,8 +39,6 @@ #ifdef _KERNEL -#include <sys/time.h> /* timeval stuff */ - /* * Arguments used to attach a device to the Apple Desktop Bus */ @@ -57,22 +55,8 @@ struct adb_attach_args { /* an ADB event */ typedef struct adb_event_s { - int addr; /* device address */ - int hand_id; /* handler id */ - int def_addr; /* default address */ int byte_count; /* number of bytes */ unsigned char bytes[8]; /* bytes from register 0 */ - struct timeval timestamp; /* time event was acquired */ - union { - struct adb_keydata_s { - int key; /* ADB key code */ - } k; - struct adb_mousedata_s { - int dx; /* mouse delta x */ - int dy; /* mouse delta y */ - int buttons; /* buttons (down << (buttonnum)) */ - } m; - } u; /* courtesy interpretation */ } adb_event_t; /* Interesting default addresses */ diff --git a/sys/dev/adb/akbd.c b/sys/dev/adb/akbd.c index 1b37910e2a0..2edf2e97f4f 100644 --- a/sys/dev/adb/akbd.c +++ b/sys/dev/adb/akbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: akbd.c,v 1.2 2006/02/06 21:25:40 miod Exp $ */ +/* $OpenBSD: akbd.c,v 1.3 2006/02/12 18:06:24 miod Exp $ */ /* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */ /* @@ -35,11 +35,6 @@ #include <sys/timeout.h> #include <sys/kernel.h> #include <sys/device.h> -#include <sys/fcntl.h> -#include <sys/poll.h> -#include <sys/selinfo.h> -#include <sys/proc.h> -#include <sys/signalvar.h> #include <sys/systm.h> #include <dev/wscons/wsconsio.h> @@ -62,13 +57,6 @@ */ int akbdmatch(struct device *, void *, void *); void akbdattach(struct device *, struct device *, void *); -void kbd_adbcomplete(caddr_t, caddr_t, int); -void kbd_processevent(adb_event_t *, struct akbd_softc *); -#ifdef notyet -u_char getleds(int); -int setleds(struct akbd_softc *, u_char); -void blinkleds(struct akbd_softc *); -#endif /* Driver definition. */ struct cfattach akbd_ca = { @@ -78,11 +66,9 @@ struct cfdriver akbd_cd = { NULL, "akbd", DV_DULL }; -int akbd_enable(void *, int); -void akbd_set_leds(void *, int); -int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *); -int akbd_intr(adb_event_t *, struct akbd_softc *); -void akbd_rawrepeat(void *v); +int akbd_enable(void *, int); +void akbd_set_leds(void *, int); +int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *); struct wskbd_accessops akbd_accessops = { @@ -100,15 +86,26 @@ struct wskbd_mapdata akbd_keymapdata = { #endif }; +void akbd_adbcomplete(caddr_t, caddr_t, int); +void akbd_capslockwrapper(struct akbd_softc *, int); +void akbd_input(struct akbd_softc *, int); +void akbd_processevent(struct akbd_softc *, adb_event_t *); +void akbd_rawrepeat(void *v); +#ifdef notyet +u_char getleds(int); +int setleds(struct akbd_softc *, u_char); +void blinkleds(struct akbd_softc *); +#endif + int akbdmatch(struct device *parent, void *vcf, void *aux) { struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; if (aa_args->origaddr == ADBADDR_KBD) - return 1; + return (1); else - return 0; + return (0); } void @@ -130,7 +127,7 @@ akbdattach(struct device *parent, struct device *self, void *aux) sc->sc_leds = (u_int8_t)0x00; /* initially off */ - adbinfo.siServiceRtPtr = (Ptr)kbd_adbcomplete; + adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete; adbinfo.siDataAreaAddr = (caddr_t)sc; printf(": "); @@ -259,10 +256,10 @@ akbdattach(struct device *parent, struct device *self, void *aux) * an ADB event record. */ void -kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) +akbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) { adb_event_t event; - struct akbd_softc *ksc; + struct akbd_softc *sc; int adbaddr; #ifdef ADB_DEBUG int i; @@ -272,52 +269,23 @@ kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) #endif adbaddr = ADB_CMDADDR(adb_command); - ksc = (struct akbd_softc *)data_area; + sc = (struct akbd_softc *)data_area; - event.addr = adbaddr; - event.hand_id = ksc->handler_id; - event.def_addr = ksc->origaddr; event.byte_count = buffer[0]; memcpy(event.bytes, buffer + 1, event.byte_count); #ifdef ADB_DEBUG if (adb_debug) { - printf("akbd: from %d at %d (org %d) %d:", event.addr, - event.hand_id, event.def_addr, buffer[0]); + printf("akbd: from %d at %d (org %d) %d:", adbaddr, + sc->handler_id, sc->origaddr, buffer[0]); for (i = 1; i <= buffer[0]; i++) printf(" %x", buffer[i]); printf("\n"); } #endif - microtime(&event.timestamp); - - kbd_processevent(&event, ksc); -} - -/* - * Given a keyboard ADB event, record the keycodes and call the key - * repeat handler, optionally passing the event through the mouse - * button emulation handler first. - */ -void -kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) -{ - adb_event_t new_event; - - new_event = *event; - new_event.u.k.key = event->bytes[0]; - new_event.bytes[1] = 0xff; - if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ - akbd_intr(&new_event, ksc); - if (event->bytes[1] != 0xff) { - new_event.u.k.key = event->bytes[1]; - new_event.bytes[0] = event->bytes[1]; - new_event.bytes[1] = 0xff; - if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ - akbd_intr(&new_event, ksc); - } - + if (sc->sc_wskbddev != NULL) + akbd_processevent(sc, &event); } #ifdef notyet @@ -348,16 +316,13 @@ getleds(int addr) * actual keyboard register format */ int -setleds(struct akbd_softc *ksc, u_char leds) +setleds(struct akbd_softc *sc, u_char leds) { int addr; short cmd; u_char buffer[9]; - if ((leds & 0x07) == (ksc->sc_leds & 0x07)) - return (0); - - addr = ksc->adbaddr; + addr = sc->adbaddr; buffer[0] = 0; cmd = ADBTALK(addr, 2); @@ -376,8 +341,6 @@ setleds(struct akbd_softc *ksc, u_char leds) if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0) return (EIO); - ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07; - if ((buffer[2] & 0xf8) != leds) return (EIO); else @@ -388,27 +351,21 @@ setleds(struct akbd_softc *ksc, u_char leds) * Toggle all of the LED's on and off, just for show. */ void -blinkleds(struct akbd_softc *ksc) +blinkleds(struct akbd_softc *sc) { - int addr, i; - u_char blinkleds, origleds; - - addr = ksc->adbaddr; - origleds = getleds(addr); - blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK; - - (void)setleds(ksc, blinkleds); - - for (i = 0; i < 10000; i++) - delay(50); - - /* make sure that we restore the LED settings */ - i = 10; - do { - (void)setleds(ksc, (u_char)0x00); - } while (setleds(ksc, (u_char)0x00) && (i-- > 0)); - - return; + u_char origleds; + + origleds = getleds(sc->adbaddr); + setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK); + delay(400000); + setleds(sc, origleds); + + if (origleds & LED_NUMLOCK) + sc->sc_leds |= WSKBD_LED_NUM; + if (origleds & LED_CAPSLOCK) + sc->sc_leds |= WSKBD_LED_CAPS; + if (origleds & LED_SCROLL_LOCK) + sc->sc_leds |= WSKBD_LED_SCROLL; } #endif @@ -421,14 +378,31 @@ akbd_enable(void *v, int on) void akbd_set_leds(void *v, int on) { +#ifdef notyet + struct akbd_softc *sc = v; + int leds; + + if (sc->sc_extended) { + if (sc->sc_leds == on) + return; + + leds = 0; + if (on & WSKBD_LED_NUM) + leds |= LED_NUMLOCK; + if (on & WSKBD_LED_CAPS) + leds |= LED_CAPSLOCK; + if (on & WSKBD_LED_SCROLL) + leds |= LED_SCROLL_LOCK; + + setleds(sc, leds); + } +#endif } int akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) { -#ifdef WSDISPLAY_COMPAT_RAWKBD struct akbd_softc *sc = v; -#endif switch (cmd) { @@ -436,9 +410,10 @@ akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) *(int *)data = WSKBD_TYPE_ADB; return 0; case WSKBDIO_SETLEDS: + akbd_set_leds(v, *(int *)data); return 0; case WSKBDIO_GETLEDS: - *(int *)data = 0; + *(int *)data = sc->sc_leds; return 0; #ifdef WSDISPLAY_COMPAT_RAWKBD case WSKBDIO_SETMODE: @@ -475,35 +450,64 @@ akbd_rawrepeat(void *v) } #endif -int adb_polledkey; -int -akbd_intr(adb_event_t *event, struct akbd_softc *sc) +/* + * Given a keyboard ADB event, decode the keycodes and pass them to wskbd. + */ +void +akbd_processevent(struct akbd_softc *sc, adb_event_t *event) { - int key, press, val; - int type; - static int shift; + switch (event->byte_count) { + case 1: + akbd_capslockwrapper(sc, event->bytes[0]); + break; + case 2: + /* + * The reset (or power) key sends 0x7f7f on press and + * 0xffff on release, and we ignore it. + */ + if (event->bytes[0] == event->bytes[1] && + ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) + break; + akbd_capslockwrapper(sc, event->bytes[0]); + akbd_capslockwrapper(sc, event->bytes[1]); + break; + default: +#ifdef DIAGNOSTIC + printf("%s: unexpected message length %d\n", + sc->sc_dev.dv_xname, event->byte_count); +#endif + break; + } - key = event->u.k.key; +} +void +akbd_capslockwrapper(struct akbd_softc *sc, int key) +{ /* - * Caps lock is weird. The key sequence generated is: - * press: down(57) [57] (LED turns on) - * release: up(127) [255] - * press: up(127) [255] - * release: up(57) [185] (LED turns off) + * Caps lock is special: since on earlier keyboards, the physical + * key stays down when pressed, we will get a notification of the + * key press, but not of the key release. Then, when it is pressed + * again, we will not get a notification of the key press, but will + * see the key release. + * For proper wskbd operation, we should report each capslock + * notification as both events (press and release). */ - if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) - shift = 0; - - if (key == 255) { - if (shift == 0) { - key = ADBK_KEYUP(ADBK_CAPSLOCK); - shift = 1; - } else { - key = ADBK_KEYDOWN(ADBK_CAPSLOCK); - shift = 0; - } + if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) { + akbd_input(sc, ADBK_KEYDOWN(ADBK_CAPSLOCK)); + akbd_input(sc, ADBK_KEYUP(ADBK_CAPSLOCK)); + } else { + if (key != 0xff) + akbd_input(sc, key); } +} + +int adb_polledkey; +void +akbd_input(struct akbd_softc *sc, int key) +{ + int press, val; + int type; press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); @@ -522,7 +526,7 @@ akbd_intr(adb_event_t *event, struct akbd_softc *sc) c = keyboard[val][3]; if (c == 0) { - return 0; /* XXX */ + return; /* XXX */ } if (c & 0x80) cbuf[j++] = 0xe0; @@ -543,11 +547,8 @@ akbd_intr(adb_event_t *event, struct akbd_softc *sc) sc->sc_nrep = npress; if (npress != 0) timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000); - return 0; #endif } else { wskbd_input(sc->sc_wskbddev, type, val); } - - return 0; } diff --git a/sys/dev/adb/ams.c b/sys/dev/adb/ams.c index 114f5cebe98..a85db149ac5 100644 --- a/sys/dev/adb/ams.c +++ b/sys/dev/adb/ams.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ams.c,v 1.2 2006/02/03 21:51:50 matthieu Exp $ */ +/* $OpenBSD: ams.c,v 1.3 2006/02/12 18:06:24 miod Exp $ */ /* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $ */ /* @@ -33,11 +33,6 @@ #include <sys/param.h> #include <sys/device.h> -#include <sys/fcntl.h> -#include <sys/poll.h> -#include <sys/selinfo.h> -#include <sys/proc.h> -#include <sys/signalvar.h> #include <sys/systm.h> #include <machine/autoconf.h> @@ -423,24 +418,19 @@ ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) buffer[3] = 0x80; } - event.addr = adbaddr; - event.hand_id = sc->handler_id; - event.def_addr = sc->origaddr; event.byte_count = buffer[0]; memcpy(event.bytes, buffer + 1, event.byte_count); #ifdef ADB_DEBUG if (adb_debug) { - printf("ams: from %d at %d (org %d) %d:", event.addr, - event.hand_id, event.def_addr, buffer[0]); + printf("ams: from %d at %d (org %d) %d:", adbaddr, + sc->handler_id, sc->origaddr, buffer[0]); for (i = 1; i <= buffer[0]; i++) printf(" %x", buffer[i]); printf("\n"); } #endif - microtime(&event.timestamp); - ms_processevent(&event, sc); } @@ -451,10 +441,9 @@ ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) void ms_processevent(adb_event_t *event, struct ams_softc *sc) { - adb_event_t new_event; - int i, button_bit, max_byte, mask, buttons; + int i, button_bit, max_byte, mask; + int dx, dy, buttons; - new_event = *event; buttons = 0; /* @@ -463,7 +452,7 @@ ms_processevent(adb_event_t *event, struct ams_softc *sc) */ max_byte = event->byte_count; button_bit = 1; - switch (event->hand_id) { + switch (sc->handler_id) { case ADBMS_USPEED: case ADBMS_UCONTOUR: /* MicroSpeed mouse and Contour mouse */ @@ -501,15 +490,15 @@ ms_processevent(adb_event_t *event, struct ams_softc *sc) } break; } - new_event.u.m.buttons = sc->sc_mb | buttons; - new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) - - ((event->bytes[1] & 0x40) ? 64 : 0); - new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) - - ((event->bytes[0] & 0x40) ? 64 : 0); + + buttons |= sc->sc_mb; + dx = ((signed int) (event->bytes[1] & 0x3f)) - + ((event->bytes[1] & 0x40) ? 64 : 0); + dy = ((signed int) (event->bytes[0] & 0x3f)) - + ((event->bytes[0] & 0x40) ? 64 : 0); if (sc->sc_wsmousedev) - wsmouse_input(sc->sc_wsmousedev, new_event.u.m.buttons, - new_event.u.m.dx, -new_event.u.m.dy, 0, + wsmouse_input(sc->sc_wsmousedev, buttons, dx, -dy, 0, WSMOUSE_INPUT_DELTA); } diff --git a/sys/dev/adb/keyboard.h b/sys/dev/adb/keyboard.h index ae158f92b63..b348cd5572b 100644 --- a/sys/dev/adb/keyboard.h +++ b/sys/dev/adb/keyboard.h @@ -1,4 +1,4 @@ -/* $OpenBSD: keyboard.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $OpenBSD: keyboard.h,v 1.2 2006/02/12 18:06:24 miod Exp $ */ /* $NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */ /*- @@ -34,34 +34,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define ADBK_LEFT 0x3B -#define ADBK_RIGHT 0x3C -#define ADBK_UP 0x3E -#define ADBK_DOWN 0x3D -#define ADBK_PGUP 0x74 -#define ADBK_PGDN 0x79 -#define ADBK_HOME 0x73 -#define ADBK_END 0x77 -#define ADBK_CONTROL 0x36 -#define ADBK_FLOWER 0x37 -#define ADBK_SHIFT 0x38 #define ADBK_CAPSLOCK 0x39 -#define ADBK_OPTION 0x3A -#define ADBK_F 0x03 -#define ADBK_O 0x1F -#define ADBK_P 0x23 -#define ADBK_Q 0x0C -#define ADBK_V 0x09 -#define ADBK_1 0x12 -#define ADBK_2 0x13 -#define ADBK_3 0x14 -#define ADBK_4 0x15 -#define ADBK_5 0x17 -#define ADBK_6 0x16 -#define ADBK_7 0x1A -#define ADBK_8 0x1C -#define ADBK_9 0x19 -#define ADBK_0 0x1D +#define ADBK_RESET 0x7f #define ADBK_KEYVAL(key) ((key) & 0x7f) #define ADBK_PRESS(key) (((key) & 0x80) == 0) |