diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-01-28 19:49:46 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-01-28 19:49:46 +0000 |
commit | 26427514c0f9a58640eac6a4ed998aef181d9540 (patch) | |
tree | 94c34d46a7e38de3da3147c52eafe507d902847e /sys/arch/powerpc/mac | |
parent | 5f5938b7a6f8939702d75088e5edc87b21530025 (diff) |
Adding ADB keyboard/mouse/apple event drivers. From Nbsd with changes to build.
aed configures on newer systems. akbd and ams not tested on system which
has a real ADB bus.
Diffstat (limited to 'sys/arch/powerpc/mac')
-rw-r--r-- | sys/arch/powerpc/mac/aed.c | 615 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/aedvar.h | 91 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/akbd.c | 578 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/akbdmap.h | 190 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/ams.c | 582 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/amsvar.h | 66 | ||||
-rw-r--r-- | sys/arch/powerpc/mac/keyboard.h | 208 |
7 files changed, 2330 insertions, 0 deletions
diff --git a/sys/arch/powerpc/mac/aed.c b/sys/arch/powerpc/mac/aed.c new file mode 100644 index 00000000000..cd6e94c41a4 --- /dev/null +++ b/sys/arch/powerpc/mac/aed.c @@ -0,0 +1,615 @@ +/* $NetBSD: aed.c,v 1.5 2000/03/23 06:40:33 thorpej Exp $ */ + +/* + * Copyright (C) 1994 Bradley A. Grantham + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bradley A. Grantham. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> + +#include <machine/autoconf.h> +#include <machine/cpu.h> + +#include <powerpc/mac/keyboard.h> +#include <powerpc/mac/adbvar.h> +#include <powerpc/mac/aedvar.h> +#include <powerpc/mac/akbdvar.h> + +#define spladb splhigh + +/* + * Function declarations. + */ +#ifdef __NetBSD__ +static int aedmatch __P((struct device *, struct cfdata *, void *)); +#endif /* __NetBSD__ */ +#ifdef __OpenBSD__ +static int aedmatch __P((struct device *, void *, void *)); +#endif /* __OpenBSD__ */ +static void aedattach __P((struct device *, struct device *, void *)); +static void aed_emulate_mouse __P((adb_event_t *event)); +static void aed_kbdrpt __P((void *kstate)); +static void aed_dokeyupdown __P((adb_event_t *event)); +static void aed_handoff __P((adb_event_t *event)); +static void aed_enqevent __P((adb_event_t *event)); + +/* + * Global variables. + */ +extern int adb_polling; /* Are we polling? (Debugger mode) */ + +/* + * Local variables. + */ +static struct aed_softc *aed_sc = NULL; +static int aed_options = 0; /* | AED_MSEMUL; */ + +/* Driver definition */ +struct cfdriver aed_cd = { + NULL, "aed", DV_DULL +}; +/* Driver definition */ +struct cfattach aed_ca = { + sizeof(struct aed_softc), aedmatch, aedattach +}; + +extern struct cfdriver aed_cd; + +static int +aedmatch(parent, cf, aux) + struct device *parent; +#ifdef __NetBSD__ + struct cfdata *cf; +#endif /* __NetBSD__ */ +#ifdef __OpenBSD__ + void *cf; +#endif /* __OpenBSD__ */ + void *aux; +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; + static int aed_matched = 0; + + /* Allow only one instance. */ + if ((aa_args->origaddr == 0) && (!aed_matched)) { + aed_matched = 1; + return (1); + } else + return (0); +} + +static void +aedattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; + struct aed_softc *sc = (struct aed_softc *)self; + + timeout_set(&sc->sc_repeat_ch, aed_kbdrpt, aed_sc); + + sc->origaddr = aa_args->origaddr; + sc->adbaddr = aa_args->adbaddr; + sc->handler_id = aa_args->handler_id; + + sc->sc_evq_tail = 0; + sc->sc_evq_len = 0; + + sc->sc_rptdelay = 20; + sc->sc_rptinterval = 6; + sc->sc_repeating = -1; /* not repeating */ + + /* Pull in the options flags. */ + sc->sc_options = (sc->sc_dev.dv_cfdata->cf_flags | aed_options); + + sc->sc_ioproc = NULL; + + sc->sc_buttons = 0; + + sc->sc_open = 0; + + aed_sc = sc; + + printf("ADB Event device\n"); + + return; +} + +/* + * Given a keyboard ADB event, record the keycode and call the key + * repeat handler, optionally passing the event through the mouse + * button emulation handler first. Pass mouse events directly to + * the handoff function. + */ +void +aed_input(event) + adb_event_t *event; +{ + adb_event_t new_event = *event; + + switch (event->def_addr) { + case ADBADDR_KBD: + if (aed_sc->sc_options & AED_MSEMUL) + aed_emulate_mouse(&new_event); + else + aed_dokeyupdown(&new_event); + break; + case ADBADDR_MS: + new_event.u.m.buttons |= aed_sc->sc_buttons; + aed_handoff(&new_event); + break; + default: /* God only knows. */ +#ifdef DIAGNOSTIC + panic("aed: received event from unsupported device!\n"); +#endif + break; + } + +} + +/* + * Handles mouse button emulation via the keyboard. If the emulation + * modifier key is down, left and right arrows will generate 2nd and + * 3rd mouse button events while the 1, 2, and 3 keys will generate + * the corresponding mouse button event. + */ +static void +aed_emulate_mouse(event) + adb_event_t *event; +{ + static int emulmodkey_down = 0; + adb_event_t new_event; + + if (event->u.k.key == ADBK_KEYDOWN(ADBK_OPTION)) { + emulmodkey_down = 1; + } else if (event->u.k.key == ADBK_KEYUP(ADBK_OPTION)) { + /* key up */ + emulmodkey_down = 0; + if (aed_sc->sc_buttons & 0xfe) { + aed_sc->sc_buttons &= 1; + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + } + } else if (emulmodkey_down) { + switch(event->u.k.key) { +#ifdef ALTXBUTTONS + case ADBK_KEYDOWN(ADBK_1): + aed_sc->sc_buttons |= 1; /* left down */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; + case ADBK_KEYUP(ADBK_1): + aed_sc->sc_buttons &= ~1; /* left up */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; +#endif + case ADBK_KEYDOWN(ADBK_LEFT): +#ifdef ALTXBUTTONS + case ADBK_KEYDOWN(ADBK_2): +#endif + aed_sc->sc_buttons |= 2; /* middle down */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; + case ADBK_KEYUP(ADBK_LEFT): +#ifdef ALTXBUTTONS + case ADBK_KEYUP(ADBK_2): +#endif + aed_sc->sc_buttons &= ~2; /* middle up */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; + case ADBK_KEYDOWN(ADBK_RIGHT): +#ifdef ALTXBUTTONS + case ADBK_KEYDOWN(ADBK_3): +#endif + aed_sc->sc_buttons |= 4; /* right down */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; + case ADBK_KEYUP(ADBK_RIGHT): +#ifdef ALTXBUTTONS + case ADBK_KEYUP(ADBK_3): +#endif + aed_sc->sc_buttons &= ~4; /* right up */ + new_event.def_addr = ADBADDR_MS; + new_event.u.m.buttons = aed_sc->sc_buttons; + new_event.u.m.dx = new_event.u.m.dy = 0; + microtime(&new_event.timestamp); + aed_handoff(&new_event); + break; + case ADBK_KEYUP(ADBK_SHIFT): + case ADBK_KEYDOWN(ADBK_SHIFT): + case ADBK_KEYUP(ADBK_CONTROL): + case ADBK_KEYDOWN(ADBK_CONTROL): + case ADBK_KEYUP(ADBK_FLOWER): + case ADBK_KEYDOWN(ADBK_FLOWER): + /* ctrl, shift, cmd */ + aed_dokeyupdown(event); + break; + default: + if (event->u.k.key & 0x80) + /* ignore keyup */ + break; + + /* key down */ + new_event = *event; + + /* send option-down */ + new_event.u.k.key = ADBK_KEYDOWN(ADBK_OPTION); + new_event.bytes[0] = new_event.u.k.key; + microtime(&new_event.timestamp); + aed_dokeyupdown(&new_event); + + /* send key-down */ + new_event.u.k.key = event->bytes[0]; + new_event.bytes[0] = new_event.u.k.key; + microtime(&new_event.timestamp); + aed_dokeyupdown(&new_event); + + /* send key-up */ + new_event.u.k.key = + ADBK_KEYUP(ADBK_KEYVAL(event->bytes[0])); + microtime(&new_event.timestamp); + new_event.bytes[0] = new_event.u.k.key; + aed_dokeyupdown(&new_event); + + /* send option-up */ + new_event.u.k.key = ADBK_KEYUP(ADBK_OPTION); + new_event.bytes[0] = new_event.u.k.key; + microtime(&new_event.timestamp); + aed_dokeyupdown(&new_event); + break; + } + } else { + aed_dokeyupdown(event); + } +} + +/* + * Keyboard autorepeat timeout function. Sends key up/down events + * for the repeating key and schedules the next call at sc_rptinterval + * ticks in the future. + */ +static void +aed_kbdrpt(kstate) + void *kstate; +{ + struct aed_softc *aed_sc = (struct aed_softc *)kstate; + + aed_sc->sc_rptevent.bytes[0] |= 0x80; + microtime(&aed_sc->sc_rptevent.timestamp); + aed_handoff(&aed_sc->sc_rptevent); /* do key up */ + + aed_sc->sc_rptevent.bytes[0] &= 0x7f; + microtime(&aed_sc->sc_rptevent.timestamp); + aed_handoff(&aed_sc->sc_rptevent); /* do key down */ + + if (aed_sc->sc_repeating == aed_sc->sc_rptevent.u.k.key) { + timeout_add(&aed_sc->sc_repeat_ch, aed_sc->sc_rptinterval); + } +} + + +/* + * Cancels the currently repeating key event if there is one, schedules + * a new repeating key event if needed, and hands the event off to the + * appropriate subsystem. + */ +static void +aed_dokeyupdown(event) + adb_event_t *event; +{ + int kbd_key; + + kbd_key = ADBK_KEYVAL(event->u.k.key); + if (ADBK_PRESS(event->u.k.key) && keyboard[kbd_key][0] != 0) { + /* ignore shift & control */ + if (aed_sc->sc_repeating != -1) { + timeout_del(&aed_sc->sc_repeat_ch); + } + aed_sc->sc_rptevent = *event; + aed_sc->sc_repeating = kbd_key; + timeout_add(&aed_sc->sc_repeat_ch, aed_sc->sc_rptdelay); + } else { + if (aed_sc->sc_repeating != -1) { + aed_sc->sc_repeating = -1; + timeout_del(&aed_sc->sc_repeat_ch); + } + aed_sc->sc_rptevent = *event; + } + aed_handoff(event); +} + +/* + * Place the event in the event queue if a requesting device is open + * and we are not polling. + */ +static void +aed_handoff(event) + adb_event_t *event; +{ + if (aed_sc->sc_open && !adb_polling) + aed_enqevent(event); +} + +/* + * Place the event in the event queue and wakeup any waiting processes. + */ +static void +aed_enqevent(event) + adb_event_t *event; +{ + int s; + + s = spladb(); + +#ifdef DIAGNOSTIC + if (aed_sc->sc_evq_tail < 0 || aed_sc->sc_evq_tail >= AED_MAX_EVENTS) + panic("adb: event queue tail is out of bounds"); + + if (aed_sc->sc_evq_len < 0 || aed_sc->sc_evq_len > AED_MAX_EVENTS) + panic("adb: event queue len is out of bounds"); +#endif + + if (aed_sc->sc_evq_len == AED_MAX_EVENTS) { + splx(s); + return; /* Oh, well... */ + } + aed_sc->sc_evq[(aed_sc->sc_evq_len + aed_sc->sc_evq_tail) % + AED_MAX_EVENTS] = *event; + aed_sc->sc_evq_len++; + + selwakeup(&aed_sc->sc_selinfo); + if (aed_sc->sc_ioproc) + psignal(aed_sc->sc_ioproc, SIGIO); + + splx(s); +} + +int +aedopen(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int unit; + int error = 0; + int s; + + unit = minor(dev); + + if (unit != 0) + return (ENXIO); + + s = spladb(); + if (aed_sc->sc_open) { + splx(s); + return (EBUSY); + } + aed_sc->sc_evq_tail = 0; + aed_sc->sc_evq_len = 0; + aed_sc->sc_open = 1; + aed_sc->sc_ioproc = p; + splx(s); + + return (error); +} + + +int +aedclose(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int s = spladb(); + + aed_sc->sc_open = 0; + aed_sc->sc_ioproc = NULL; + splx(s); + + return (0); +} + + +int +aedread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + int s, error; + int willfit; + int total; + int firstmove; + int moremove; + + if (uio->uio_resid < sizeof(adb_event_t)) + return (EMSGSIZE); /* close enough. */ + + s = spladb(); + if (aed_sc->sc_evq_len == 0) { + splx(s); + return (0); + } + willfit = howmany(uio->uio_resid, sizeof(adb_event_t)); + total = (aed_sc->sc_evq_len < willfit) ? aed_sc->sc_evq_len : willfit; + + firstmove = (aed_sc->sc_evq_tail + total > AED_MAX_EVENTS) + ? (AED_MAX_EVENTS - aed_sc->sc_evq_tail) : total; + + error = uiomove((caddr_t) & aed_sc->sc_evq[aed_sc->sc_evq_tail], + firstmove * sizeof(adb_event_t), uio); + if (error) { + splx(s); + return (error); + } + moremove = total - firstmove; + + if (moremove > 0) { + error = uiomove((caddr_t) & aed_sc->sc_evq[0], + moremove * sizeof(adb_event_t), uio); + if (error) { + splx(s); + return (error); + } + } + aed_sc->sc_evq_tail = (aed_sc->sc_evq_tail + total) % AED_MAX_EVENTS; + aed_sc->sc_evq_len -= total; + splx(s); + return (0); +} + + +int +aedwrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + return 0; +} + + +int +aedioctl(dev, cmd, data, flag, p) + dev_t dev; + int cmd; + caddr_t data; + int flag; + struct proc *p; +{ + switch (cmd) { + case ADBIOCDEVSINFO: { + adb_devinfo_t *di; + ADBDataBlock adbdata; + int totaldevs; + int adbaddr; + int i; + + di = (void *)data; + + /* Initialize to no devices */ + for (i = 0; i < 16; i++) + di->dev[i].addr = -1; + + totaldevs = CountADBs(); + for (i = 1; i <= totaldevs; i++) { + adbaddr = GetIndADB(&adbdata, i); + di->dev[adbaddr].addr = adbaddr; + di->dev[adbaddr].default_addr = (int)(adbdata.origADBAddr); + di->dev[adbaddr].handler_id = (int)(adbdata.devType); + } + + /* Must call ADB Manager to get devices now */ + break; + } + + case ADBIOCGETREPEAT:{ + adb_rptinfo_t *ri; + + ri = (void *)data; + ri->delay_ticks = aed_sc->sc_rptdelay; + ri->interval_ticks = aed_sc->sc_rptinterval; + break; + } + + case ADBIOCSETREPEAT:{ + adb_rptinfo_t *ri; + + ri = (void *) data; + aed_sc->sc_rptdelay = ri->delay_ticks; + aed_sc->sc_rptinterval = ri->interval_ticks; + break; + } + + case ADBIOCRESET: + /* Do nothing for now */ + break; + + case ADBIOCLISTENCMD:{ + adb_listencmd_t *lc; + + lc = (void *)data; + } + + default: + return (EINVAL); + } + return (0); +} + + +int +aedpoll(dev, events, p) + dev_t dev; + int events; + struct proc *p; +{ + int s, revents; + + revents = events & (POLLOUT | POLLWRNORM); + + if ((events & (POLLIN | POLLRDNORM)) == 0) + return (revents); + + s = spladb(); + if (aed_sc->sc_evq_len > 0) + revents |= events & (POLLIN | POLLRDNORM); + else + selrecord(p, &aed_sc->sc_selinfo); + splx(s); + + return (revents); +} diff --git a/sys/arch/powerpc/mac/aedvar.h b/sys/arch/powerpc/mac/aedvar.h new file mode 100644 index 00000000000..ab3d7a569d2 --- /dev/null +++ b/sys/arch/powerpc/mac/aedvar.h @@ -0,0 +1,91 @@ +/* $NetBSD: aedvar.h,v 1.2 2000/03/23 06:40:33 thorpej Exp $ */ + +/* + * Copyright (C) 1994 Bradley A. Grantham + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bradley A. Grantham. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef __NetBSD__ +#include <sys/callout.h> +#endif /* __NetBSD__ */ +#ifdef __OpenBSD__ +#include <sys/timeout.h> +#endif /* __OpenBSD__ */ +#include <machine/adbsys.h> + +/* Event queue definitions */ +#ifndef AED_MAX_EVENTS +#define AED_MAX_EVENTS 200 /* Maximum events to be kept in queue */ + /* maybe should be higher for slower macs? */ +#endif /* AED_MAX_EVENTS */ + +struct aed_softc { + struct device sc_dev; + +#ifdef __NetBSD__ + struct callout sc_repeat_ch; +#endif /* __NetBSD__ */ +#ifdef __OpenBSD__ + struct timeout sc_repeat_ch; +#endif /* __OpenBSD__ */ + + /* ADB info */ + u_char origaddr; /* ADB device type (ADBADDR_AED) */ + u_char adbaddr; /* current ADB address */ + u_char handler_id; /* type of device */ + + /* ADB event queue */ + adb_event_t sc_evq[AED_MAX_EVENTS]; /* the queue */ + int sc_evq_tail; /* event queue tail pointer */ + int sc_evq_len; /* event queue length */ + + /* Keyboard repeat state */ + int sc_rptdelay; /* ticks before auto-repeat */ + int sc_rptinterval; /* ticks between auto-repeat */ + int sc_repeating; /* key that is auto-repeating */ + adb_event_t sc_rptevent; /* event to auto-repeat */ + + int sc_buttons; /* mouse button state */ + + struct selinfo sc_selinfo; /* select() info */ + struct proc * sc_ioproc; /* process to wakeup */ + + int sc_open; /* Are we queuing events? */ + int sc_options; /* config options */ +}; + +/* Options */ +#define AED_MSEMUL 0x1 /* emulate mouse buttons */ + +void aed_input __P((adb_event_t *event)); +int aedopen __P((dev_t dev, int flag, int mode, struct proc *p)); +int aedclose __P((dev_t dev, int flag, int mode, struct proc *p)); +int aedread __P((dev_t dev, struct uio *uio, int flag)); +int aedwrite __P((dev_t dev, struct uio *uio, int flag)); +int aedioctl __P((dev_t , int , caddr_t , int , struct proc *)); +int aedpoll __P((dev_t dev, int events, struct proc *p)); diff --git a/sys/arch/powerpc/mac/akbd.c b/sys/arch/powerpc/mac/akbd.c new file mode 100644 index 00000000000..fa04abc9aff --- /dev/null +++ b/sys/arch/powerpc/mac/akbd.c @@ -0,0 +1,578 @@ +/* $OpenBSD: akbd.c,v 1.1 2001/01/28 19:49:45 drahn Exp $ */ +/* $NetBSD: akbd.c,v 1.10 2000/09/01 16:00:38 tsubai Exp $ */ + +/* + * Copyright (C) 1998 Colin Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Colin Wood. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wskbdvar.h> +#include <dev/wscons/wsksymdef.h> +#include <dev/wscons/wsksymvar.h> + +#include <machine/autoconf.h> +#define KEYBOARD_ARRAY + +#include <powerpc/mac/keyboard.h> +#include <powerpc/mac/adbvar.h> +#include <powerpc/mac/aedvar.h> +#include <powerpc/mac/akbdmap.h> +#include <powerpc/mac/akbdvar.h> +#include <powerpc/mac/amsvar.h> + +#include "aed.h" + +/* + * Function declarations. + */ +static int akbdmatch __P((struct device *, void *, void *)); +static void akbdattach __P((struct device *, struct device *, void *)); +void kbd_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command)); +static void kbd_processevent __P((adb_event_t *event, struct akbd_softc *)); +#ifdef notyet +static u_char getleds __P((int)); +static int setleds __P((struct akbd_softc *, u_char)); +static void blinkleds __P((struct akbd_softc *)); +#endif + +/* + * Local variables. + */ +static volatile int kbd_done; /* Did ADBOp() complete? */ + +/* Driver definition. */ +struct cfdriver akbd_cd = { + NULL, "akbd", DV_DULL +}; + +/* Driver definition. */ +struct cfattach akbd_ca = { + sizeof(struct akbd_softc), akbdmatch, akbdattach +}; + +extern struct cfdriver akbd_cd; + +int akbd_enable __P((void *, int)); +void akbd_set_leds __P((void *, int)); +int akbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); + +struct wskbd_accessops akbd_accessops = { + akbd_enable, + akbd_set_leds, + akbd_ioctl, +}; + +void akbd_cngetc __P((void *, u_int *, int *)); +void akbd_cnpollc __P((void *, int)); + +struct wskbd_consops akbd_consops = { + akbd_cngetc, + akbd_cnpollc, +}; + +struct wskbd_mapdata akbd_keymapdata = { + akbd_keydesctab, +#ifdef AKBD_LAYOUT + AKBD_LAYOUT, +#else + KB_US, +#endif +}; + +static int akbd_is_console; + +static int +akbdmatch(parent, cf, aux) + struct device *parent; + void *cf; + void *aux; +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; + + if (aa_args->origaddr == ADBADDR_KBD) + return 1; + else + return 0; +} + +static void +akbdattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + ADBSetInfoBlock adbinfo; + struct akbd_softc *sc = (struct akbd_softc *)self; + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; + int count, error; + short cmd; + u_char buffer[9]; + struct wskbddev_attach_args a; + + sc->origaddr = aa_args->origaddr; + sc->adbaddr = aa_args->adbaddr; + sc->handler_id = aa_args->handler_id; + + sc->sc_leds = (u_int8_t)0x00; /* initially off */ + + adbinfo.siServiceRtPtr = (Ptr)kbd_adbcomplete; + adbinfo.siDataAreaAddr = (caddr_t)sc; + + switch (sc->handler_id) { + case ADB_STDKBD: + printf("standard keyboard\n"); + break; + case ADB_ISOKBD: + printf("standard keyboard (ISO layout)\n"); + break; + case ADB_EXTKBD: + kbd_done = 0; + cmd = (((sc->adbaddr << 4) & 0xf0) | 0x0d ); /* talk R1 */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&kbd_done, cmd); + + /* Wait until done, but no more than 2 secs */ + count = 40000; + while (!kbd_done && count-- > 0) + delay(50); + + /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ + if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) { + printf("Mouseman (non-EMP) pseudo keyboard\n"); + adbinfo.siServiceRtPtr = (Ptr)0; + adbinfo.siDataAreaAddr = (Ptr)0; + } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) { + printf("Trackman (non-EMP) pseudo keyboard\n"); + adbinfo.siServiceRtPtr = (Ptr)0; + adbinfo.siDataAreaAddr = (Ptr)0; + } else { + printf("extended keyboard\n"); +#ifdef notyet + blinkleds(sc); +#endif + } + break; + case ADB_EXTISOKBD: + printf("extended keyboard (ISO layout)\n"); +#ifdef notyet + blinkleds(sc); +#endif + break; + case ADB_KBDII: + printf("keyboard II\n"); + break; + case ADB_ISOKBDII: + printf("keyboard II (ISO layout)\n"); + break; + case ADB_PBKBD: + printf("PowerBook keyboard\n"); + break; + case ADB_PBISOKBD: + printf("PowerBook keyboard (ISO layout)\n"); + break; + case ADB_ADJKPD: + printf("adjustable keypad\n"); + break; + case ADB_ADJKBD: + printf("adjustable keyboard\n"); + break; + case ADB_ADJISOKBD: + printf("adjustable keyboard (ISO layout)\n"); + break; + case ADB_ADJJAPKBD: + printf("adjustable keyboard (Japanese layout)\n"); + break; + case ADB_PBEXTISOKBD: + printf("PowerBook extended keyboard (ISO layout)\n"); + break; + case ADB_PBEXTJAPKBD: + printf("PowerBook extended keyboard (Japanese layout)\n"); + break; + case ADB_JPKBDII: + printf("keyboard II (Japanese layout)\n"); + break; + case ADB_PBEXTKBD: + printf("PowerBook extended keyboard\n"); + break; + case ADB_DESIGNKBD: + printf("extended keyboard\n"); +#ifdef notyet + blinkleds(sc); +#endif + break; +#ifdef ADB_PBJPKBD + case ADB_PBJPKBD: + printf("PowerBook keyboard (Japanese layout)\n"); + break; +#endif /* ADB_PBJPKBD */ +#ifdef ADB_PBG3JPKBD + case ADB_PBG3JPKBD: + printf("PowerBook G3 keyboard (Japanese layout)\n"); + break; +#endif /* ADB_PBG3JPKBD */ + default: + printf("mapped device (%d)\n", sc->handler_id); + break; + } + error = SetADBInfo(&adbinfo, sc->adbaddr); +#ifdef ADB_DEBUG + if (adb_debug) + printf("kbd: returned %d from SetADBInfo\n", error); +#endif + + a.console = akbd_is_console; + a.keymap = &akbd_keymapdata; + a.accessops = &akbd_accessops; + a.accesscookie = sc; + + sc->sc_wskbddev = config_found(self, &a, wskbddevprint); +} + + +/* + * Handle putting the keyboard data received from the ADB into + * an ADB event record. + */ +void +kbd_adbcomplete(buffer, data_area, adb_command) + caddr_t buffer; + caddr_t data_area; + int adb_command; +{ + adb_event_t event; + struct akbd_softc *ksc; + int adbaddr; +#ifdef ADB_DEBUG + int i; + + if (adb_debug) + printf("adb: transaction completion\n"); +#endif + + adbaddr = (adb_command & 0xf0) >> 4; + ksc = (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("kbd: from %d at %d (org %d) %d:", event.addr, + event.hand_id, event.def_addr, 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. + */ +static void +kbd_processevent(event, ksc) + 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; + kbd_intr(&new_event); +#if NAED > 0 + aed_input(&new_event); +#endif + 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; + kbd_intr(&new_event); +#if NAED > 0 + aed_input(&new_event); +#endif + } + +} + +#ifdef notyet +/* + * Get the actual hardware LED state and convert it to softc format. + */ +static u_char +getleds(addr) + int addr; +{ + short cmd; + u_char buffer[9], leds; + + leds = 0x00; /* all off */ + buffer[0] = 0; + kbd_done = 0; + + /* talk R2 */ + cmd = ((addr & 0xf) << 4) | 0x0c | 0x02; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd); + while (!kbd_done) + /* busy-wait until done */ ; + + if (buffer[0] > 0) + leds = ~(buffer[2]) & 0x07; + + return (leds); +} + +/* + * Set the keyboard LED's. + * + * Automatically translates from ioctl/softc format to the + * actual keyboard register format + */ +static int +setleds(ksc, leds) + struct akbd_softc *ksc; + u_char leds; +{ + int addr; + short cmd; + u_char buffer[9]; + + if ((leds & 0x07) == (ksc->sc_leds & 0x07)) + return (0); + + addr = ksc->adbaddr; + buffer[0] = 0; + kbd_done = 0; + + /* talk R2 */ + cmd = ((addr & 0xf) << 4) | 0x0c | 0x02; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd); + while (!kbd_done) + /* busy-wait until done */ ; + + if (buffer[0] == 0) + return (EIO); + + leds = ~leds & 0x07; + buffer[2] &= 0xf8; + buffer[2] |= leds; + + /* listen R2 */ + cmd = ((addr & 0xf) << 4) | 0x08 | 0x02; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd); + while (!kbd_done) + /* busy-wait until done */ ; + + /* talk R2 */ + cmd = ((addr & 0xf) << 4) | 0x0c | 0x02; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd); + while (!kbd_done) + /* busy-wait until done */ ; + + if (buffer[0] == 0) + return (EIO); + + ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07; + + if ((buffer[2] & 0xf8) != leds) + return (EIO); + else + return (0); +} + +/* + * Toggle all of the LED's on and off, just for show. + */ +static void +blinkleds(ksc) + struct akbd_softc *ksc; +{ + 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; +} +#endif + +int +akbd_enable(v, on) + void *v; + int on; +{ + return 0; +} + +void +akbd_set_leds(v, on) + void *v; + int on; +{ +} + +int +akbd_ioctl(v, cmd, data, flag, p) + void *v; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + switch (cmd) { + + case WSKBDIO_GTYPE: + *(int *)data = 0; /* XXX */ + return 0; + case WSKBDIO_SETLEDS: + return 0; + case WSKBDIO_GETLEDS: + *(int *)data = 0; + return 0; + } + /* kbdioctl(...); */ + + return -1; +} + +static int polledkey; +extern int adb_polling; + +int +kbd_intr(event) + adb_event_t *event; +{ + int key, press, val; + int type; + + struct akbd_softc *sc = akbd_cd.cd_devs[0]; + + key = event->u.k.key; + press = ADBK_PRESS(key); + val = ADBK_KEYVAL(key); + + type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; + + switch (key) { + case 185: /* Caps Lock released */ + type = WSCONS_EVENT_KEY_DOWN; + wskbd_input(sc->sc_wskbddev, type, val); + type = WSCONS_EVENT_KEY_UP; + break; + case 245: + pm_eject_pcmcia(0); + break; + case 244: + pm_eject_pcmcia(1); + break; + } + + if (adb_polling) + polledkey = key; + else + wskbd_input(sc->sc_wskbddev, type, val); + + return 0; +} + +int +akbd_cnattach() +{ + + akbd_is_console = 1; + wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); + return 0; +} + +void +akbd_cngetc(v, type, data) + void *v; + u_int *type; + int *data; +{ + int key, press, val; + int s; + + s = splhigh(); + + polledkey = -1; + adb_polling = 1; + + while (polledkey == -1) { + adb_intr(); + DELAY(10000); /* XXX */ + } + + adb_polling = 0; + splx(s); + + key = polledkey; + press = ADBK_PRESS(key); + val = ADBK_KEYVAL(key); + + *data = val; + *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; +} + +void +akbd_cnpollc(v, on) + void *v; + int on; +{ +} diff --git a/sys/arch/powerpc/mac/akbdmap.h b/sys/arch/powerpc/mac/akbdmap.h new file mode 100644 index 00000000000..656c64f7433 --- /dev/null +++ b/sys/arch/powerpc/mac/akbdmap.h @@ -0,0 +1,190 @@ +/* $NetBSD: akbdmap.h,v 1.3 2000/09/01 16:00:39 tsubai Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Juergen Hannken-Illjes. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* XXX This list is incomplete. */ + +#define KC(n) KS_KEYCODE(n) + +static const keysym_t akbd_keydesc_us[] = { +/* pos command normal shifted */ + KC(0), KS_a, + KC(1), KS_s, + KC(2), KS_d, + KC(3), KS_f, + KC(4), KS_h, + KC(5), KS_g, + KC(6), KS_z, + KC(7), KS_x, + KC(8), KS_c, + KC(9), KS_v, + + KC(11), KS_b, + KC(12), KS_q, + KC(13), KS_w, + KC(14), KS_e, + KC(15), KS_r, + KC(16), KS_y, + KC(17), KS_t, + KC(18), KS_1, KS_exclam, + KC(19), KS_2, KS_at, + KC(20), KS_3, KS_numbersign, + KC(21), KS_4, KS_dollar, + KC(22), KS_6, KS_asciicircum, + KC(23), KS_5, KS_percent, + KC(24), KS_equal, KS_plus, + KC(25), KS_9, KS_parenleft, + KC(26), KS_7, KS_ampersand, + KC(27), KS_minus, KS_underscore, + KC(28), KS_8, KS_asterisk, + KC(29), KS_0, KS_parenright, + KC(30), KS_bracketright, KS_braceright, + KC(31), KS_o, + KC(32), KS_u, + KC(33), KS_bracketleft, KS_braceleft, + KC(34), KS_i, + KC(35), KS_p, + KC(36), KS_Return, + KC(37), KS_l, + KC(38), KS_j, + KC(39), KS_apostrophe, KS_quotedbl, + KC(40), KS_k, + KC(41), KS_semicolon, KS_colon, + KC(42), KS_backslash, KS_bar, + KC(43), KS_comma, KS_less, + KC(44), KS_slash, KS_question, + KC(45), KS_n, + KC(46), KS_m, + KC(47), KS_period, KS_greater, + KC(48), KS_Tab, + KC(49), KS_space, + KC(50), KS_grave, KS_asciitilde, + KC(51), KS_Delete, + + KC(53), KS_Escape, + KC(54), KS_Control_L, + KC(55), KS_Cmd, /* Command */ + KC(56), KS_Shift_L, + KC(57), KS_Caps_Lock, + KC(58), KS_Cmd1, /* Option */ + KC(59), KS_Left, + KC(60), KS_Right, + KC(61), KS_Down, + KC(62), KS_Up, + + KC(65), KS_KP_Decimal, + KC(67), KS_KP_Multiply, + KC(69), KS_KP_Add, + KC(71), KS_Clear, + KC(75), KS_KP_Divide, + KC(76), KS_KP_Enter, + KC(78), KS_KP_Subtract, + + KC(81), KS_KP_Equal, + KC(82), KS_KP_0, + KC(83), KS_KP_1, + KC(84), KS_KP_2, + KC(85), KS_KP_3, + KC(86), KS_KP_4, + KC(87), KS_KP_5, + KC(88), KS_KP_6, + KC(89), KS_KP_7, + + KC(91), KS_KP_8, + KC(92), KS_KP_9, + + KC(95), KS_comma, /* XXX KS_KP_comma */ + + KC(106), KS_KP_Enter, + + KC(127), KS_Cmd_Debugger, +}; + +static const keysym_t akbd_keydesc_fr[] = { +/* pos normal shifted altgr shift-altgr */ + KC(0), KS_q, + KC(6), KS_w, + KC(10), KS_at, KS_numbersign, + KC(12), KS_a, + KC(13), KS_z, + KC(18), KS_ampersand, KS_1, + KC(19), KS_eacute, KS_2, KS_asciitilde, + KC(20), KS_quotedbl, KS_3, KS_numbersign, + KC(21), KS_apostrophe, KS_4, KS_braceleft, + KC(22), KS_section, KS_6, KS_bar, + KC(23), KS_parenleft, KS_5, KS_bracketleft, KS_braceleft, + KC(24), KS_minus, KS_underscore, KS_braceright, + KC(25), KS_ccedilla, KS_9, KS_asciicircum, + KC(26), KS_egrave, KS_7, KS_grave, + KC(27), KS_parenright, KS_degree, KS_bracketright, KS_braceright, + KC(28), KS_exclam, KS_8, KS_bar, + KC(29), KS_agrave, KS_0, KS_at, + KC(30), KS_dollar, KS_asterisk, + KC(33), KS_dead_circumflex, KS_dead_diaeresis, + KC(39), KS_mu, KS_percent, + KC(40), KS_k, + KC(41), KS_m, + KC(42), KS_grave, KS_sterling, + KC(43), KS_semicolon, KS_period, + KC(44), KS_equal, KS_plus, + KC(46), KS_comma, KS_question, + KC(47), KS_colon, KS_slash, KS_backslash, + KC(50), KS_less, KS_greater, + KC(52), KS_Alt_R, + KC(55), KS_Meta_L, /* Command */ + KC(58), KS_Alt_R, /* Option */ +}; + +#if 0 +static const keysym_t akbd_keydesc_jp[] = { +/* pos command normal shifted */ + KC(42), KS_grave, KS_asciitilde, + KC(93), KS_backslash, KS_bar, +}; +#endif + +#define KBD_MAP(name, base, map) \ + { name, base, sizeof(map)/sizeof(keysym_t), map } + +static const struct wscons_keydesc akbd_keydesctab[] = { + KBD_MAP(KB_US, 0, akbd_keydesc_us), + KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr), + {0, 0, 0, 0} +}; + +#undef KBD_MAP +#undef KC diff --git a/sys/arch/powerpc/mac/ams.c b/sys/arch/powerpc/mac/ams.c new file mode 100644 index 00000000000..e8033ea4152 --- /dev/null +++ b/sys/arch/powerpc/mac/ams.c @@ -0,0 +1,582 @@ +/* $NetBSD: ams.c,v 1.8 2000/01/08 02:57:25 takemura Exp $ */ + +/* + * Copyright (C) 1998 Colin Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Colin Wood. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsmousevar.h> + +#include <machine/autoconf.h> + +#include <powerpc/mac/adbvar.h> +#include <powerpc/mac/aedvar.h> +#include <powerpc/mac/amsvar.h> + +#include "aed.h" + +/* + * Function declarations. + */ +static int amsmatch __P((struct device *, void *, void *)); +static void amsattach __P((struct device *, struct device *, void *)); +static void ems_init __P((struct ams_softc *)); +static void ms_processevent __P((adb_event_t *event, struct ams_softc *)); + +/* + * Global variables. + */ +extern int kbd_polling; /* Are we polling (Debugger mode)? from kbd.c */ + +/* + * Local variables. + */ +static volatile int extdms_done; /* Did ADBOp() complete? */ + + +/* Driver definition. */ +struct cfdriver ams_cd = { + NULL, "ams", DV_DULL +}; +/* Driver definition. */ +struct cfattach ams_ca = { + sizeof(struct ams_softc), amsmatch, amsattach +}; + +extern struct cfdriver ms_cd; + +int ams_enable __P((void *)); +int ams_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); +void ams_disable __P((void *)); + +const struct wsmouse_accessops ams_accessops = { + ams_enable, + ams_ioctl, + ams_disable, +}; + +static int +amsmatch(parent, cf, aux) + struct device *parent; + void *cf; + void *aux; +{ + struct adb_attach_args * aa_args = (struct adb_attach_args *)aux; + + if (aa_args->origaddr == ADBADDR_MS) + return 1; + else + return 0; +} + +static void +amsattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + ADBSetInfoBlock adbinfo; + struct ams_softc *sc = (struct ams_softc *)self; + struct adb_attach_args * aa_args = (struct adb_attach_args *)aux; + int error; + struct wsmousedev_attach_args a; + + sc->origaddr = aa_args->origaddr; + sc->adbaddr = aa_args->adbaddr; + sc->handler_id = aa_args->handler_id; + + sc->sc_class = MSCLASS_MOUSE; + sc->sc_buttons = 1; + sc->sc_res = 100; + sc->sc_devid[0] = 0; + sc->sc_devid[4] = 0; + + adbinfo.siServiceRtPtr = (Ptr)ms_adbcomplete; + adbinfo.siDataAreaAddr = (caddr_t)sc; + + ems_init(sc); + + /* print out the type of mouse we have */ + switch (sc->handler_id) { + case ADBMS_100DPI: + printf("%d-button, %d dpi mouse\n", sc->sc_buttons, + (int)(sc->sc_res)); + break; + case ADBMS_200DPI: + sc->sc_res = 200; + printf("%d-button, %d dpi mouse\n", sc->sc_buttons, + (int)(sc->sc_res)); + break; + case ADBMS_MSA3: + printf("Mouse Systems A3 mouse, %d-button, %d dpi\n", + sc->sc_buttons, (int)(sc->sc_res)); + break; + case ADBMS_USPEED: + printf("MicroSpeed mouse, default parameters\n"); + break; + case ADBMS_UCONTOUR: + printf("Contour mouse, default parameters\n"); + break; + case ADBMS_EXTENDED: + if (sc->sc_devid[0] == '\0') { + printf("Logitech "); + switch (sc->sc_class) { + case MSCLASS_MOUSE: + printf("MouseMan (non-EMP) mouse"); + break; + case MSCLASS_TRACKBALL: + printf("TrackMan (non-EMP) trackball"); + break; + default: + printf("non-EMP relative positioning device"); + break; + } + printf("\n"); + } else { + printf("EMP "); + switch (sc->sc_class) { + case MSCLASS_TABLET: + printf("tablet"); + break; + case MSCLASS_MOUSE: + printf("mouse"); + break; + case MSCLASS_TRACKBALL: + printf("trackball"); + break; + case MSCLASS_TRACKPAD: + printf("trackpad"); + break; + default: + printf("unknown device"); + break; + } + printf(" <%s> %d-button, %d dpi\n", sc->sc_devid, + sc->sc_buttons, (int)(sc->sc_res)); + } + break; + default: + printf("relative positioning device (mouse?) (%d)\n", + sc->handler_id); + break; + } + error = SetADBInfo(&adbinfo, sc->adbaddr); +#ifdef ADB_DEBUG + if (adb_debug) + printf("ms: returned %d from SetADBInfo\n", error); +#endif + + a.accessops = &ams_accessops; + a.accesscookie = sc; + sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); +} + + +/* + * Initialize extended mouse support -- probes devices as described + * in Inside Macintosh: Devices, Chapter 5 "ADB Manager". + * + * Extended Mouse Protocol is documented in TechNote HW1: + * "ADB - The Untold Story: Space Aliens Ate My Mouse" + * + * Supports: Extended Mouse Protocol, MicroSpeed Mouse Deluxe, + * Mouse Systems A^3 Mouse, Logitech non-EMP MouseMan + */ +void +ems_init(sc) + struct ams_softc *sc; +{ + int adbaddr, count; + short cmd; + u_char buffer[9]; + + adbaddr = sc->adbaddr; + if (sc->origaddr != ADBADDR_MS) + return; + if (sc->handler_id == ADBMS_USPEED || + sc->handler_id == ADBMS_UCONTOUR) { + /* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */ + cmd = ((adbaddr<<4)&0xF0)|0x9; /* listen 1 */ + + /* + * To setup the MicroSpeed or the Contour, it appears + * that we can send the following command to the mouse + * and then expect data back in the form: + * buffer[0] = 4 (bytes) + * buffer[1], buffer[2] as std. mouse + * buffer[3] = buffer[4] = 0xff when no buttons + * are down. When button N down, bit N is clear. + * buffer[4]'s locking mask enables a + * click to toggle the button down state--sort of + * like the "Easy Access" shift/control/etc. keys. + * buffer[3]'s alternative speed mask enables using + * different speed when the corr. button is down + */ + buffer[0] = 4; + buffer[1] = 0x00; /* Alternative speed */ + buffer[2] = 0x00; /* speed = maximum */ + buffer[3] = 0x10; /* enable extended protocol, + * lower bits = alt. speed mask + * = 0000b + */ + buffer[4] = 0x07; /* Locking mask = 0000b, + * enable buttons = 0111b + */ + extdms_done = 0; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + + sc->sc_buttons = 3; + sc->sc_res = 200; + return; + } + if ((sc->handler_id == ADBMS_100DPI) || + (sc->handler_id == ADBMS_200DPI)) { + /* found a mouse */ + cmd = ((adbaddr << 4) & 0xf0) | 0x3; + + extdms_done = 0; + cmd = (cmd & 0xf3) | 0x0c; /* talk command */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + + /* Wait until done, but no more than 2 secs */ + count = 40000; + while (!extdms_done && count-- > 0) + delay(50); + + if (!extdms_done) { +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: extdms_init timed out\n"); +#endif + return; + } + + /* Attempt to initialize Extended Mouse Protocol */ + buffer[2] = '\004'; /* make handler ID 4 */ + extdms_done = 0; + cmd = (cmd & 0xf3) | 0x08; /* listen command */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + + /* + * Check to see if successful, if not + * try to initialize it as other types + */ + cmd = ((adbaddr << 4) & 0xf0) | 0x3; + extdms_done = 0; + cmd = (cmd & 0xf3) | 0x0c; /* talk command */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + + if (buffer[2] == ADBMS_EXTENDED) { + sc->handler_id = ADBMS_EXTENDED; + extdms_done = 0; + /* talk register 1 */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, (adbaddr << 4) | 0xd); + while (!extdms_done) + /* busy-wait until done */; + if (buffer[0] == 8) { + /* we have a true EMP device */ + sc->sc_class = buffer[7]; + sc->sc_buttons = buffer[8]; + sc->sc_res = (int)*(short *)&buffer[5]; + bcopy(&(buffer[1]), sc->sc_devid, 4); + } else if (buffer[1] == 0x9a && + ((buffer[2] == 0x20) || (buffer[2] == 0x21))) { + /* + * Set up non-EMP Mouseman/Trackman to put + * button bits in 3rd byte instead of sending + * via pseudo keyboard device. + */ + extdms_done = 0; + /* listen register 1 */ + buffer[0]=2; + buffer[1]=0x00; + buffer[2]=0x81; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, (adbaddr << 4) | 0x9); + while (!extdms_done) + /* busy-wait until done */; + extdms_done = 0; + /* listen register 1 */ + buffer[0]=2; + buffer[1]=0x01; + buffer[2]=0x81; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, (adbaddr << 4) | 0x9); + while (!extdms_done) + /* busy-wait until done */; + extdms_done = 0; + /* listen register 1 */ + buffer[0]=2; + buffer[1]=0x02; + buffer[2]=0x81; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, (adbaddr << 4) | 0x9); + while (!extdms_done) + /* busy-wait until done */; + extdms_done = 0; + /* listen register 1 */ + buffer[0]=2; + buffer[1]=0x03; + buffer[2]=0x38; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, (adbaddr << 4) | 0x9); + while (!extdms_done) + /* busy-wait until done */; + sc->sc_buttons = 3; + sc->sc_res = 400; + if (buffer[2] == 0x21) + sc->sc_class = MSCLASS_TRACKBALL; + else + sc->sc_class = MSCLASS_MOUSE; + } else + /* unknown device? */; + } else { + /* Attempt to initialize as an A3 mouse */ + buffer[2] = 0x03; /* make handler ID 3 */ + extdms_done = 0; + cmd = (cmd & 0xf3) | 0x08; /* listen command */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + + /* + * Check to see if successful, if not + * try to initialize it as other types + */ + cmd = ((adbaddr << 4) & 0xf0) | 0x3; + extdms_done = 0; + cmd = (cmd & 0xf3) | 0x0c; /* talk command */ + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + + if (buffer[2] == ADBMS_MSA3) { + sc->handler_id = ADBMS_MSA3; + /* Initialize as above */ + cmd = ((adbaddr << 4) & 0xF0) | 0xA; + /* listen 2 */ + buffer[0] = 3; + buffer[1] = 0x00; + /* Irrelevant, buffer has 0x77 */ + buffer[2] = 0x07; + /* + * enable 3 button mode = 0111b, + * speed = normal + */ + extdms_done = 0; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + sc->sc_buttons = 3; + sc->sc_res = 300; + } else { + /* No special support for this mouse */ + } + } + } +} + +/* + * Handle putting the mouse data received from the ADB into + * an ADB event record. + */ +void +ms_adbcomplete(buffer, data_area, adb_command) + caddr_t buffer; + caddr_t data_area; + int adb_command; +{ + adb_event_t event; + struct ams_softc *msc; + int adbaddr; +#ifdef ADB_DEBUG + int i; + + if (adb_debug) + printf("adb: transaction completion\n"); +#endif + + adbaddr = (adb_command & 0xf0) >> 4; + msc = (struct ams_softc *)data_area; + + if ((msc->handler_id == ADBMS_EXTENDED) && (msc->sc_devid[0] == 0)) { + /* massage the data to look like EMP data */ + if ((buffer[3] & 0x04) == 0x04) + buffer[1] &= 0x7f; + else + buffer[1] |= 0x80; + if ((buffer[3] & 0x02) == 0x02) + buffer[2] &= 0x7f; + else + buffer[2] |= 0x80; + if ((buffer[3] & 0x01) == 0x01) + buffer[3] = 0x00; + else + buffer[3] = 0x80; + } + + event.addr = adbaddr; + event.hand_id = msc->handler_id; + event.def_addr = msc->origaddr; + event.byte_count = buffer[0]; + memcpy(event.bytes, buffer + 1, event.byte_count); + +#ifdef ADB_DEBUG + if (adb_debug) { + printf("ms: from %d at %d (org %d) %d:", event.addr, + event.hand_id, event.def_addr, buffer[0]); + for (i = 1; i <= buffer[0]; i++) + printf(" %x", buffer[i]); + printf("\n"); + } +#endif + + microtime(&event.timestamp); + + ms_processevent(&event, msc); +} + +/* + * Given a mouse ADB event, record the button settings, calculate the + * x- and y-axis motion, and handoff the event to the appropriate subsystem. + */ +static void +ms_processevent(event, msc) + adb_event_t *event; + struct ams_softc *msc; +{ + adb_event_t new_event; + int i, button_bit, max_byte, mask, buttons; + + new_event = *event; + buttons = 0; + + /* + * This should handle both plain ol' Apple mice and mice + * that claim to support the Extended Apple Mouse Protocol. + */ + max_byte = event->byte_count; + button_bit = 1; + switch (event->hand_id) { + case ADBMS_USPEED: + case ADBMS_UCONTOUR: + /* MicroSpeed mouse and Contour mouse */ + if (max_byte == 4) + buttons = (~event->bytes[2]) & 0xff; + else + buttons = (event->bytes[0] & 0x80) ? 0 : 1; + break; + case ADBMS_MSA3: + /* Mouse Systems A3 mouse */ + if (max_byte == 3) + buttons = (~event->bytes[2]) & 0x07; + else + buttons = (event->bytes[0] & 0x80) ? 0 : 1; + break; + default: + /* Classic Mouse Protocol (up to 2 buttons) */ + for (i = 0; i < 2; i++, button_bit <<= 1) + /* 0 when button down */ + if (!(event->bytes[i] & 0x80)) + buttons |= button_bit; + else + buttons &= ~button_bit; + /* Extended Protocol (up to 6 more buttons) */ + for (mask = 0x80; i < max_byte; + i += (mask == 0x80), button_bit <<= 1) { + /* 0 when button down */ + if (!(event->bytes[i] & mask)) + buttons |= button_bit; + else + buttons &= ~button_bit; + mask = ((mask >> 4) & 0xf) + | ((mask & 0xf) << 4); + } + break; + } + new_event.u.m.buttons = msc->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); + + if (msc->sc_wsmousedev) + wsmouse_input(msc->sc_wsmousedev, new_event.u.m.buttons, + new_event.u.m.dx, -new_event.u.m.dy, 0, + WSMOUSE_INPUT_DELTA); +#if NAED > 0 + aed_input(&new_event); +#endif +} + +int +ams_enable(v) + void *v; +{ + return 0; +} + +int +ams_ioctl(v, cmd, data, flag, p) + void *v; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + return -1; +} + +void +ams_disable(v) + void *v; +{ +} diff --git a/sys/arch/powerpc/mac/amsvar.h b/sys/arch/powerpc/mac/amsvar.h new file mode 100644 index 00000000000..3cce40f2c59 --- /dev/null +++ b/sys/arch/powerpc/mac/amsvar.h @@ -0,0 +1,66 @@ +/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */ + +/* + * Copyright (C) 1998 Colin Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Colin Wood. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MACPPC_AMSVAR_H_ +#define _MACPPC_AMSVAR_H_ + +/* + * State info, per mouse instance. + */ +struct ams_softc { + struct device sc_dev; + + /* ADB info */ + int origaddr; /* ADB device type (ADBADDR_MS) */ + int adbaddr; /* current ADB address */ + int handler_id; /* type of mouse */ + + /* Extended Mouse Protocol info, faked for non-EMP mice */ + u_int8_t sc_class; /* mouse class (mouse, trackball) */ + u_int8_t sc_buttons; /* number of buttons */ + u_int32_t sc_res; /* mouse resolution (dpi) */ + char sc_devid[5]; /* device indentifier */ + + int sc_mb; /* current button state */ + struct device *sc_wsmousedev; +}; + +/* EMP device classes */ +#define MSCLASS_TABLET 0 +#define MSCLASS_MOUSE 1 +#define MSCLASS_TRACKBALL 2 +#define MSCLASS_TRACKPAD 3 + +void ms_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command)); +void ms_handoff __P((adb_event_t *event, struct ams_softc *)); + +#endif /* _MACPPC_AMSVAR_H_ */ diff --git a/sys/arch/powerpc/mac/keyboard.h b/sys/arch/powerpc/mac/keyboard.h new file mode 100644 index 00000000000..cb2e9a4c600 --- /dev/null +++ b/sys/arch/powerpc/mac/keyboard.h @@ -0,0 +1,208 @@ +/* $NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */ + +/*- + * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, + * Michael L. Finch, Bradley A. Grantham, and + * Lawrence A. Kesteloot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Alice Group. + * 4. The names of the Alice Group or any of its members may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * 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_KEYVAL(key) ((key) & 0x7f) +#define ADBK_PRESS(key) (((key) & 0x80) == 0) +#define ADBK_KEYDOWN(key) (key) +#define ADBK_KEYUP(key) ((key) | 0x80) +#define ADBK_MODIFIER(key) ((((key) & 0x7f) == ADBK_SHIFT) || \ + (((key) & 0x7f) == ADBK_CONTROL) || \ + (((key) & 0x7f) == ADBK_FLOWER) || \ + (((key) & 0x7f) == ADBK_OPTION)) + +#ifndef KEYBOARD_ARRAY +extern unsigned char keyboard[128][3]; +#else +unsigned char keyboard[128][3] = { + /* Scan code Normal Shifted Controlled */ + { /* 0x00, */ 'a', 'A', 0x01 }, + { /* 0x01, */ 's', 'S', 0x13 }, + { /* 0x02, */ 'd', 'D', 0x04 }, + { /* 0x03, */ 'f', 'F', 0x06 }, + { /* 0x04, */ 'h', 'H', 0x08 }, + { /* 0x05, */ 'g', 'G', 0x07 }, + { /* 0x06, */ 'z', 'Z', 0x1A }, + { /* 0x07, */ 'x', 'X', 0x18 }, + { /* 0x08, */ 'c', 'C', 0x03 }, + { /* 0x09, */ 'v', 'V', 0x16 }, + { /* 0x0A, */ 0x00, 0x00, 0x00 }, + { /* 0x0B, */ 'b', 'B', 0x02 }, + { /* 0x0C, */ 'q', 'Q', 0x11 }, + { /* 0x0D, */ 'w', 'W', 0x17 }, + { /* 0x0E, */ 'e', 'E', 0x05 }, + { /* 0x0F, */ 'r', 'R', 0x12 }, + { /* 0x10, */ 'y', 'Y', 0x19 }, + { /* 0x11, */ 't', 'T', 0x14 }, + { /* 0x12, */ '1', '!', 0x00 }, + { /* 0x13, */ '2', '@', 0x00 }, + { /* 0x14, */ '3', '#', 0x00 }, + { /* 0x15, */ '4', '$', 0x00 }, + { /* 0x16, */ '6', '^', 0x1E }, + { /* 0x17, */ '5', '%', 0x00 }, + { /* 0x18, */ '=', '+', 0x00 }, + { /* 0x19, */ '9', '(', 0x00 }, + { /* 0x1A, */ '7', '&', 0x00 }, + { /* 0x1B, */ '-', '_', 0x1F }, + { /* 0x1C, */ '8', '*', 0x00 }, + { /* 0x1D, */ '0', ')', 0x00 }, + { /* 0x1E, */ ']', '}', 0x1D }, + { /* 0x1F, */ 'o', 'O', 0x0F }, + { /* 0x20, */ 'u', 'U', 0x15 }, + { /* 0x21, */ '[', '{', 0x1B }, + { /* 0x22, */ 'i', 'I', 0x09 }, + { /* 0x23, */ 'p', 'P', 0x10 }, + { /* 0x24, */ 0x0D, 0x0D, 0x0D }, + { /* 0x25, */ 'l', 'L', 0x0C }, + { /* 0x26, */ 'j', 'J', 0x0A }, + { /* 0x27, */ '\'', '"', 0x00 }, + { /* 0x28, */ 'k', 'K', 0x0B }, + { /* 0x29, */ ';', ':', 0x00 }, + { /* 0x2A, */ '\\', '|', 0x1C }, + { /* 0x2B, */ ',', '<', 0x00 }, + { /* 0x2C, */ '/', '?', 0x00 }, + { /* 0x2D, */ 'n', 'N', 0x0E }, + { /* 0x2E, */ 'm', 'M', 0x0D }, + { /* 0x2F, */ '.', '>', 0x00 }, + { /* 0x30, */ 0x09, 0x09, 0x09 }, + { /* 0x31, */ ' ', ' ', 0x00 }, + { /* 0x32, */ '`', '~', 0x00 }, + { /* 0x33, */ 0x7F, 0x7F, 0x7F }, /* Delete */ + { /* 0x34, */ 0x00, 0x00, 0x00 }, + { /* 0x35, */ 0x1B, 0x1B, 0x1B }, + { /* 0x36, */ 0x00, 0x00, 0x00 }, + { /* 0x37, */ 0x00, 0x00, 0x00 }, + { /* 0x38, */ 0x00, 0x00, 0x00 }, + { /* 0x39, */ 0x00, 0x00, 0x00 }, + { /* 0x3A, */ 0x00, 0x00, 0x00 }, + { /* 0x3B, */ 'h', 0x00, 0x00 }, /* Left */ + { /* 0x3C, */ 'l', 0x00, 0x00 }, /* Right */ + { /* 0x3D, */ 'j', 0x00, 0x00 }, /* Down */ + { /* 0x3E, */ 'k', 0x00, 0x00 }, /* Up */ + { /* 0x3F, */ 0x00, 0x00, 0x00 }, + { /* 0x40, */ 0x00, 0x00, 0x00 }, + { /* 0x41, */ '.', '.', 0x00 }, + { /* 0x42, */ 0x00, 0x00, 0x00 }, + { /* 0x43, */ '*', '*', 0x00 }, + { /* 0x44, */ 0x00, 0x00, 0x00 }, + { /* 0x45, */ '+', '+', 0x00 }, + { /* 0x46, */ 0x00, 0x00, 0x00 }, + { /* 0x47, */ 0x00, 0x00, 0x00 }, + { /* 0x48, */ 0x00, 0x00, 0x00 }, + { /* 0x49, */ 0x00, 0x00, 0x00 }, + { /* 0x4A, */ 0x00, 0x00, 0x00 }, + { /* 0x4B, */ '/', '/', 0x00 }, + { /* 0x4C, */ 0x0D, 0x0D, 0x0D }, + { /* 0x4D, */ 0x00, 0x00, 0x00 }, + { /* 0x4E, */ '-', '-', 0x00 }, + { /* 0x4F, */ 0x00, 0x00, 0x00 }, + { /* 0x50, */ 0x00, 0x00, 0x00 }, + { /* 0x51, */ '=', '=', 0x00 }, + { /* 0x52, */ '0', '0', 0x00 }, + { /* 0x53, */ '1', '1', 0x00 }, + { /* 0x54, */ '2', '2', 0x00 }, + { /* 0x55, */ '3', '3', 0x00 }, + { /* 0x56, */ '4', '4', 0x00 }, + { /* 0x57, */ '5', '5', 0x00 }, + { /* 0x58, */ '6', '6', 0x00 }, + { /* 0x59, */ '7', '7', 0x00 }, + { /* 0x5A, */ 0x00, 0x00, 0x00 }, + { /* 0x5B, */ '8', '8', 0x00 }, + { /* 0x5C, */ '9', '9', 0x00 }, + { /* 0x5D, */ 0x00, 0x00, 0x00 }, + { /* 0x5E, */ 0x00, 0x00, 0x00 }, + { /* 0x5F, */ 0x00, 0x00, 0x00 }, + { /* 0x60, */ 0x00, 0x00, 0x00 }, + { /* 0x61, */ 0x00, 0x00, 0x00 }, + { /* 0x62, */ 0x00, 0x00, 0x00 }, + { /* 0x63, */ 0x00, 0x00, 0x00 }, + { /* 0x64, */ 0x00, 0x00, 0x00 }, + { /* 0x65, */ 0x00, 0x00, 0x00 }, + { /* 0x66, */ 0x00, 0x00, 0x00 }, + { /* 0x67, */ 0x00, 0x00, 0x00 }, + { /* 0x68, */ 0x00, 0x00, 0x00 }, + { /* 0x69, */ 0x00, 0x00, 0x00 }, + { /* 0x6A, */ 0x00, 0x00, 0x00 }, + { /* 0x6B, */ 0x00, 0x00, 0x00 }, + { /* 0x6C, */ 0x00, 0x00, 0x00 }, + { /* 0x6D, */ 0x00, 0x00, 0x00 }, + { /* 0x6E, */ 0x00, 0x00, 0x00 }, + { /* 0x6F, */ 0x00, 0x00, 0x00 }, + { /* 0x70, */ 0x00, 0x00, 0x00 }, + { /* 0x71, */ 0x00, 0x00, 0x00 }, + { /* 0x72, */ 0x00, 0x00, 0x00 }, + { /* 0x73, */ 0x00, 0x00, 0x00 }, + { /* 0x74, */ 0x00, 0x00, 0x00 }, + { /* 0x75, */ 0x00, 0x00, 0x00 }, + { /* 0x76, */ 0x00, 0x00, 0x00 }, + { /* 0x77, */ 0x00, 0x00, 0x00 }, + { /* 0x78, */ 0x00, 0x00, 0x00 }, + { /* 0x79, */ 0x00, 0x00, 0x00 }, + { /* 0x7A, */ 0x00, 0x00, 0x00 }, + { /* 0x7B, */ 0x00, 0x00, 0x00 }, + { /* 0x7C, */ 0x00, 0x00, 0x00 }, + { /* 0x7D, */ 0x00, 0x00, 0x00 }, + { /* 0x7E, */ 0x00, 0x00, 0x00 }, + { /* 0x7F, */ 0x00, 0x00, 0x00 } +}; +#endif /* KEYBOARD_ARRAY */ |