static void adbkbd_cngetc(void *v, u_int *type, int *data) { struct adbkbd_softc *sc = v; int key, press, val; int s; s = splhigh(); KASSERT(sc->sc_poll); DPRINTF("polling..."); while (sc->sc_polled_chars == 0) { sc->sc_ops->poll(sc->sc_ops->cookie); } DPRINTF(" got one\n"); splx(s); key = sc->sc_pollbuf[0]; sc->sc_polled_chars--; memmove(sc->sc_pollbuf, sc->sc_pollbuf + 1, sc->sc_polled_chars); press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); *data = val; *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; }
void akbd_capslockwrapper(struct akbd_softc *sc, int key) { if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) sc->sc_caps ^= CL_DOWN_ADB; if (key != 0xff) akbd_input(sc, key); }
void akbd_input(struct akbd_softc *sc, int key) { int press, val; int type; press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; if (adb_polling) { adb_polledkey = key; #ifdef WSDISPLAY_COMPAT_RAWKBD } else if (sc->sc_rawkbd) { char cbuf[MAXKEYS *2]; int c, j, s; int npress; j = npress = 0; c = keyboard[val]; if (c == 0) { return; /* XXX */ } if (c & 0x80) cbuf[j++] = 0xe0; cbuf[j] = c & 0x7f; if (type == WSCONS_EVENT_KEY_UP) { cbuf[j] |= 0x80; } else { /* this only records last key pressed */ if (c & 0x80) sc->sc_rep[npress++] = 0xe0; sc->sc_rep[npress++] = c & 0x7f; } j++; s = spltty(); wskbd_rawinput(sc->sc_wskbddev, cbuf, j); splx(s); timeout_del(&sc->sc_rawrepeat_ch); sc->sc_nrep = npress; if (npress != 0) timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000); #endif } else { wskbd_input(sc->sc_wskbddev, type, val); } }
void akbd_input(struct akbd_softc *sc, int key) { int press, val; int type; press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); if (sc->sc_iso) val = akbd_iso_swap(val); type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; if (adb_polling) { adb_polledkey = key; #ifdef WSDISPLAY_COMPAT_RAWKBD } else if (sc->sc_rawkbd) { char cbuf[2]; int c, j, s; j = 0; c = keyboard[val]; if (c == 0) { return; /* XXX */ } if (c & 0x80) cbuf[j++] = 0xe0; cbuf[j] = c & 0x7f; if (type == WSCONS_EVENT_KEY_UP) cbuf[j] |= 0x80; j++; s = spltty(); wskbd_rawinput(sc->sc_wskbddev, cbuf, j); splx(s); #endif } else { wskbd_input(sc->sc_wskbddev, type, val); } }
/* * Given a keyboard ADB event, decode the keycodes and pass them to wskbd. */ void akbd_processevent(struct akbd_softc *sc, adb_event_t *event) { 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) { if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET)) SET(sc->sc_caps, CL_DOWN_RESET); else { if (ISSET(sc->sc_caps, CL_DOWN_RESET)) CLR(sc->sc_caps, CL_DOWN_RESET); else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) { akbd_input(sc, ISSET(sc->sc_caps, CL_DOWN_LOGICAL) ? ADBK_KEYDOWN(ADBK_CAPSLOCK) : ADBK_KEYUP(ADBK_CAPSLOCK)); sc->sc_caps ^= CL_DOWN_LOGICAL; } } } else { 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; } }
/* * 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(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) { callout_stop(&aed_sc->sc_repeat_ch); } aed_sc->sc_rptevent = *event; aed_sc->sc_repeating = kbd_key; callout_reset(&aed_sc->sc_repeat_ch, aed_sc->sc_rptdelay, aed_kbdrpt, (void *)aed_sc); } else { if (aed_sc->sc_repeating != -1) { aed_sc->sc_repeating = -1; callout_stop(&aed_sc->sc_repeat_ch); } aed_sc->sc_rptevent = *event; } aed_handoff(event); }
void akbd_cngetc(void *v, u_int *type, int *data) { int intbits, key, press, val; int s; extern int adb_intr(void *); extern void pm_intr(void *); s = splhigh(); adb_polledkey = -1; adb_polling = 1; while (adb_polledkey == -1) { intbits = via_reg(VIA1, vIFR); if (intbits & V1IF_ADBRDY) { adb_intr(NULL); via_reg(VIA1, vIFR) = V1IF_ADBRDY; } if (intbits & V1IF_ADBCLK) { pm_intr(NULL); via_reg(VIA1, vIFR) = 0x10; } } adb_polling = 0; splx(s); key = adb_polledkey; press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); *data = val; *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; }
/* * 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(adb_event_t *event) { static int emulmodkey_down; 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); } }
static inline void adbkbd_key(struct adbkbd_softc *sc, uint8_t k) { if (sc->sc_poll) { if (sc->sc_polled_chars >= 16) { aprint_error_dev(sc->sc_dev,"polling buffer is full\n"); } sc->sc_pollbuf[sc->sc_polled_chars] = k; sc->sc_polled_chars++; return; } #if NWSMOUSE > 0 /* translate some keys to mouse events */ if (sc->sc_wsmousedev != NULL) { if (ADBK_KEYVAL(k) == sc->sc_trans[1]) { wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 2 : 0, 0, 0, 0, 0, WSMOUSE_INPUT_DELTA); return; } if (ADBK_KEYVAL(k) == sc->sc_trans[2]) { wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 4 : 0, 0, 0, 0, 0, WSMOUSE_INPUT_DELTA); return; } } #endif #ifdef WSDISPLAY_COMPAT_RAWKBD if (sc->sc_rawkbd) { char cbuf[2]; int s; cbuf[0] = k; s = spltty(); wskbd_rawinput(sc->sc_wskbddev, cbuf, 1); splx(s); } else { #endif if (ADBK_KEYVAL(k) == 0x39) { /* caps lock - send up and down */ if (ADBK_PRESS(k) != sc->sc_capslock) { sc->sc_capslock = ADBK_PRESS(k); wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_DOWN, 0x39); wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_UP, 0x39); } } else { /* normal event */ int type; type = ADBK_PRESS(k) ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; wskbd_input(sc->sc_wskbddev, type, ADBK_KEYVAL(k)); } #ifdef WSDISPLAY_COMPAT_RAWKBD } #endif }