int wskbd_translate(struct wskbd_internal *id, u_int type, int value) { struct wskbd_softc *sc = id->t_sc; keysym_t ksym, res, *group; struct wscons_keymap kpbuf, *kp; int gindex, iscommand = 0; if (type == WSCONS_EVENT_ALL_KEYS_UP) { #if NWSDISPLAY > 0 if (sc != NULL && sc->sc_repeating) { sc->sc_repeating = 0; timeout_del(&sc->sc_repeat_ch); } #endif id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R | MOD_CONTROL_L | MOD_CONTROL_R | MOD_META_L | MOD_META_R | MOD_MODESHIFT | MOD_MODELOCK | MOD_COMMAND | MOD_COMMAND1 | MOD_COMMAND2); return (0); } if (sc != NULL) { if (value < 0 || value >= sc->sc_maplen) { #ifdef DEBUG printf("wskbd_translate: keycode %d out of range\n", value); #endif return (0); } kp = sc->sc_map + value; } else { kp = &kpbuf; wskbd_get_mapentry(&id->t_keymap, value, kp); } /* if this key has a command, process it first */ if (sc != NULL && kp->command != KS_voidSymbol) iscommand = internal_command(sc, &type, kp->command, kp->group1[0]); /* Now update modifiers */ switch (kp->group1[0]) { case KS_Shift_L: update_modifier(id, type, 0, MOD_SHIFT_L); break; case KS_Shift_R: update_modifier(id, type, 0, MOD_SHIFT_R); break; case KS_Shift_Lock: update_modifier(id, type, 1, MOD_SHIFTLOCK); break; case KS_Caps_Lock: update_modifier(id, type, 1, MOD_CAPSLOCK); break; case KS_Control_L: update_modifier(id, type, 0, MOD_CONTROL_L); break; case KS_Control_R: update_modifier(id, type, 0, MOD_CONTROL_R); break; case KS_Alt_L: update_modifier(id, type, 0, MOD_META_L); break; case KS_Alt_R: update_modifier(id, type, 0, MOD_META_R); break; case KS_Mode_switch: update_modifier(id, type, 0, MOD_MODESHIFT); break; case KS_Mode_Lock: update_modifier(id, type, 1, MOD_MODELOCK); break; case KS_Num_Lock: update_modifier(id, type, 1, MOD_NUMLOCK); break; #if NWSDISPLAY > 0 case KS_Hold_Screen: if (sc != NULL) { update_modifier(id, type, 1, MOD_HOLDSCREEN); if (sc->sc_displaydv != NULL) wsdisplay_kbdholdscreen(sc->sc_displaydv, id->t_modifiers & MOD_HOLDSCREEN); } break; default: if (sc != NULL && sc->sc_repeating && ((type == WSCONS_EVENT_KEY_UP && value != sc->sc_repkey) || (type == WSCONS_EVENT_KEY_DOWN && value == sc->sc_repkey))) return (0); break; #endif } #if NWSDISPLAY > 0 if (sc != NULL) { if (sc->sc_repeating) { sc->sc_repeating = 0; timeout_del(&sc->sc_repeat_ch); } sc->sc_repkey = value; } #endif /* If this is a key release or we are in command mode, we are done */ if (type != WSCONS_EVENT_KEY_DOWN || iscommand) return (0); /* Get the keysym */ if (id->t_modifiers & (MOD_MODESHIFT|MOD_MODELOCK) && !MOD_ONESET(id, MOD_ANYCONTROL)) group = & kp->group2[0]; else group = & kp->group1[0]; if ((id->t_modifiers & MOD_NUMLOCK) && KS_GROUP(group[1]) == KS_GROUP_Keypad) { gindex = !MOD_ONESET(id, MOD_ANYSHIFT); ksym = group[gindex]; } else { /* CAPS alone should only affect letter keys */ if ((id->t_modifiers & (MOD_CAPSLOCK | MOD_ANYSHIFT)) == MOD_CAPSLOCK) { gindex = 0; ksym = ksym_upcase(group[0]); } else { gindex = MOD_ONESET(id, MOD_ANYSHIFT); ksym = group[gindex]; } } /* Submit Audio keys for hotkey processing */ if (KS_GROUP(ksym) == KS_GROUP_Function) { switch (ksym) { #if NAUDIO > 0 case KS_AudioMute: wskbd_set_mixervolume(0, 1); return (0); case KS_AudioLower: wskbd_set_mixervolume(-1, 1); return (0); case KS_AudioRaise: wskbd_set_mixervolume(1, 1); return (0); #endif default: break; } } /* Process compose sequence and dead accents */ res = KS_voidSymbol; switch (KS_GROUP(ksym)) { case KS_GROUP_Ascii: case KS_GROUP_Keypad: case KS_GROUP_Function: res = ksym; break; case KS_GROUP_Mod: if (ksym == KS_Multi_key) { update_modifier(id, 1, 0, MOD_COMPOSE); id->t_composelen = 2; } break; case KS_GROUP_Dead: if (id->t_composelen == 0) { update_modifier(id, 1, 0, MOD_COMPOSE); id->t_composelen = 1; id->t_composebuf[0] = ksym; } else res = ksym; break; } if (res == KS_voidSymbol) return (0); if (id->t_composelen > 0) { /* * If the compose key also serves as AltGr (i.e. set to both * KS_Multi_key and KS_Mode_switch), and would provide a valid, * distinct combination as AltGr, leave compose mode. */ if (id->t_composelen == 2 && group == &kp->group2[0]) { if (kp->group1[gindex] != kp->group2[gindex]) id->t_composelen = 0; } if (id->t_composelen != 0) { id->t_composebuf[2 - id->t_composelen] = res; if (--id->t_composelen == 0) { res = wskbd_compose_value(id->t_composebuf); update_modifier(id, 0, 0, MOD_COMPOSE); } else { return (0); } } } /* We are done, return the symbol */ if (KS_GROUP(res) == KS_GROUP_Ascii) { if (MOD_ONESET(id, MOD_ANYCONTROL)) { if ((res >= KS_at && res <= KS_z) || res == KS_space) res = res & 0x1f; else if (res == KS_2) res = 0x00; else if (res >= KS_3 && res <= KS_7) res = KS_Escape + (res - KS_3); else if (res == KS_8) res = KS_Delete; } if (MOD_ONESET(id, MOD_ANYMETA)) { if (id->t_flags & WSKFL_METAESC) { id->t_symbols[0] = KS_Escape; id->t_symbols[1] = res; return (2); } else res |= 0x80; } } id->t_symbols[0] = res; return (1); }
static int wskbd_translate(struct wskbd_internal *id, u_int type, int value) { struct wskbd_softc *sc = id->t_sc; keysym_t ksym, res, *group; struct wscons_keymap kpbuf, *kp; int iscommand = 0; int ishotkey = 0; if (type == WSCONS_EVENT_ALL_KEYS_UP) { id->t_modifiers &= ~(MOD_SHIFT_L | MOD_SHIFT_R | MOD_CONTROL_L | MOD_CONTROL_R | MOD_META_L | MOD_META_R | MOD_MODESHIFT | MOD_COMMAND | MOD_COMMAND1 | MOD_COMMAND2); update_leds(id); return (0); } if (sc != NULL) { if (sc->sc_hotkey != NULL) ishotkey = sc->sc_hotkey(sc, sc->sc_hotkeycookie, type, value); if (ishotkey) return 0; if (value < 0 || value >= sc->sc_maplen) { #ifdef DEBUG printf("%s: keycode %d out of range\n", __func__, value); #endif return (0); } kp = sc->sc_map + value; } else { kp = &kpbuf; wskbd_get_mapentry(id->t_keymap, value, kp); } /* if this key has a command, process it first */ if (sc != NULL && kp->command != KS_voidSymbol) iscommand = internal_command(sc, &type, kp->command, kp->group1[0]); /* Now update modifiers */ switch (kp->group1[0]) { case KS_Shift_L: update_modifier(id, type, 0, MOD_SHIFT_L); break; case KS_Shift_R: update_modifier(id, type, 0, MOD_SHIFT_R); break; case KS_Shift_Lock: update_modifier(id, type, 1, MOD_SHIFTLOCK); break; case KS_Caps_Lock: update_modifier(id, type, 1, MOD_CAPSLOCK); break; case KS_Control_L: update_modifier(id, type, 0, MOD_CONTROL_L); break; case KS_Control_R: update_modifier(id, type, 0, MOD_CONTROL_R); break; case KS_Alt_L: update_modifier(id, type, 0, MOD_META_L); break; case KS_Alt_R: update_modifier(id, type, 0, MOD_META_R); break; case KS_Mode_switch: update_modifier(id, type, 0, MOD_MODESHIFT); break; case KS_Num_Lock: update_modifier(id, type, 1, MOD_NUMLOCK); break; #if NWSDISPLAY > 0 case KS_Hold_Screen: if (sc != NULL) { update_modifier(id, type, 1, MOD_HOLDSCREEN); wskbd_holdscreen(sc, id->t_modifiers & MOD_HOLDSCREEN); } break; #endif } /* If this is a key release or we are in command mode, we are done */ if (type != WSCONS_EVENT_KEY_DOWN || iscommand) { update_leds(id); return (0); } /* Get the keysym */ if (id->t_modifiers & MOD_MODESHIFT) group = & kp->group2[0]; else group = & kp->group1[0]; if ((id->t_modifiers & MOD_NUMLOCK) != 0 && KS_GROUP(group[1]) == KS_GROUP_Keypad) { if (MOD_ONESET(id, MOD_ANYSHIFT)) ksym = group[0]; else ksym = group[1]; } else if (! MOD_ONESET(id, MOD_ANYSHIFT | MOD_CAPSLOCK)) { ksym = group[0]; } else if (MOD_ONESET(id, MOD_CAPSLOCK)) { if (! MOD_ONESET(id, MOD_SHIFT_L | MOD_SHIFT_R)) ksym = group[0]; else ksym = group[1]; if (ksym >= KS_a && ksym <= KS_z) ksym += KS_A - KS_a; else if (ksym >= KS_agrave && ksym <= KS_thorn && ksym != KS_division) ksym += KS_Agrave - KS_agrave; } else if (MOD_ONESET(id, MOD_ANYSHIFT)) { ksym = group[1]; } else { ksym = group[0]; } /* Process compose sequence and dead accents */ res = KS_voidSymbol; switch (KS_GROUP(ksym)) { case KS_GROUP_Plain: case KS_GROUP_Keypad: case KS_GROUP_Function: res = ksym; break; case KS_GROUP_Mod: if (ksym == KS_Multi_key) { update_modifier(id, 1, 0, MOD_COMPOSE); id->t_composelen = 2; } break; case KS_GROUP_Dead: if (id->t_composelen == 0) { update_modifier(id, 1, 0, MOD_COMPOSE); id->t_composelen = 1; id->t_composebuf[0] = ksym; } else res = ksym; break; } if (res == KS_voidSymbol) { update_leds(id); return (0); } if (id->t_composelen > 0) { id->t_composebuf[2 - id->t_composelen] = res; if (--id->t_composelen == 0) { res = wskbd_compose_value(id->t_composebuf); update_modifier(id, 0, 0, MOD_COMPOSE); } else { return (0); } } update_leds(id); /* We are done, return the symbol */ if (KS_GROUP(res) == KS_GROUP_Plain) { if (MOD_ONESET(id, MOD_ANYCONTROL)) { if ((res >= KS_at && res <= KS_z) || res == KS_space) res = res & 0x1f; else if (res == KS_2) res = 0x00; else if (res >= KS_3 && res <= KS_7) res = KS_Escape + (res - KS_3); else if (res == KS_8) res = KS_Delete; /* convert CTL-/ to ^_ as xterm does (undo in emacs) */ else if (res == KS_slash) res = KS_underscore & 0x1f; } if (MOD_ONESET(id, MOD_ANYMETA)) { if (id->t_flags & WSKFL_METAESC) { id->t_symbols[0] = KS_Escape; id->t_symbols[1] = res; return (2); } else res |= 0x80; } } id->t_symbols[0] = res; return (1); }
int internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym, keysym_t ksym2) { switch (ksym) { case KS_Cmd: update_modifier(sc->id, *type, 0, MOD_COMMAND); ksym = ksym2; break; case KS_Cmd1: update_modifier(sc->id, *type, 0, MOD_COMMAND1); break; case KS_Cmd2: update_modifier(sc->id, *type, 0, MOD_COMMAND2); break; } if (*type != WSCONS_EVENT_KEY_DOWN) return (0); #ifdef HAVE_SCROLLBACK_SUPPORT #if NWSDISPLAY > 0 switch (ksym) { case KS_Cmd_ScrollBack: if (MOD_ONESET(sc->id, MOD_ANYSHIFT)) { if (sc->sc_displaydv != NULL) wsscrollback(sc->sc_displaydv, WSDISPLAY_SCROLL_BACKWARD); return (1); } break; case KS_Cmd_ScrollFwd: if (MOD_ONESET(sc->id, MOD_ANYSHIFT)) { if (sc->sc_displaydv != NULL) wsscrollback(sc->sc_displaydv, WSDISPLAY_SCROLL_FORWARD); return (1); } break; } #endif #endif #if NWSDISPLAY > 0 /* mod commands */ if (!MOD_ONESET(sc->id, MOD_COMMAND) && !MOD_ALLSET(sc->id, MOD_COMMAND2)) return (0); if (sc->sc_displaydv == NULL) return (0); switch (ksym) { case KS_Cmd_Screen0: case KS_Cmd_Screen1: case KS_Cmd_Screen2: case KS_Cmd_Screen3: case KS_Cmd_Screen4: case KS_Cmd_Screen5: case KS_Cmd_Screen6: case KS_Cmd_Screen7: case KS_Cmd_Screen8: case KS_Cmd_Screen9: case KS_Cmd_Screen10: case KS_Cmd_Screen11: wsdisplay_switch(sc->sc_displaydv, ksym - KS_Cmd_Screen0, 0); return (1); } #endif /* ctrl-mod commands */ if (!MOD_ONESET(sc->id, MOD_COMMAND) && !MOD_ALLSET(sc->id, MOD_COMMAND1 | MOD_COMMAND2)) return (0); #ifdef DDB if (ksym == KS_Cmd_Debugger) { if (sc->sc_isconsole && db_console) Debugger(); /* discard this key (ddb discarded command modifiers) */ *type = WSCONS_EVENT_KEY_UP; return (1); } #endif #if NWSDISPLAY > 0 if (sc->sc_displaydv == NULL) return (0); switch (ksym) { case KS_Cmd_ResetEmul: wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETEMUL); return (1); case KS_Cmd_ResetClose: wsdisplay_reset(sc->sc_displaydv, WSDISPLAY_RESETCLOSE); return (1); #if defined(__i386__) || defined(__amd64__) case KS_Cmd_KbdReset: switch (kbd_reset) { #ifdef DDB case 2: if (sc->sc_isconsole && db_console) Debugger(); /* discard this key (ddb discarded command modifiers) */ *type = WSCONS_EVENT_KEY_UP; break; #endif case 1: kbd_reset = 0; psignal(initproc, SIGUSR1); break; default: break; } return (1); #endif case KS_Cmd_BacklightOn: case KS_Cmd_BacklightOff: case KS_Cmd_BacklightToggle: change_displayparam(sc, WSDISPLAYIO_PARAM_BACKLIGHT, ksym == KS_Cmd_BacklightOff ? -1 : 1, ksym == KS_Cmd_BacklightToggle ? 1 : 0); return (1); case KS_Cmd_BrightnessUp: case KS_Cmd_BrightnessDown: case KS_Cmd_BrightnessRotate: change_displayparam(sc, WSDISPLAYIO_PARAM_BRIGHTNESS, ksym == KS_Cmd_BrightnessDown ? -1 : 1, ksym == KS_Cmd_BrightnessRotate ? 1 : 0); return (1); case KS_Cmd_ContrastUp: case KS_Cmd_ContrastDown: case KS_Cmd_ContrastRotate: change_displayparam(sc, WSDISPLAYIO_PARAM_CONTRAST, ksym == KS_Cmd_ContrastDown ? -1 : 1, ksym == KS_Cmd_ContrastRotate ? 1 : 0); return (1); } #endif return (0); }
static int internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym, keysym_t ksym2) { #if NWSDISPLAY > 0 && defined(WSDISPLAY_SCROLLSUPPORT) u_int state = 0; #endif switch (ksym) { case KS_Cmd_VolumeToggle: if (*type == WSCONS_EVENT_KEY_DOWN) pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_TOGGLE); break; case KS_Cmd_VolumeUp: if (*type == WSCONS_EVENT_KEY_DOWN) pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_UP); break; case KS_Cmd_VolumeDown: if (*type == WSCONS_EVENT_KEY_DOWN) pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_DOWN); break; #if NWSDISPLAY > 0 && defined(WSDISPLAY_SCROLLSUPPORT) case KS_Cmd_ScrollFastUp: case KS_Cmd_ScrollFastDown: if (*type == WSCONS_EVENT_KEY_DOWN) { GETMODSTATE(sc->id->t_modifiers, state); if ((sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_HOLD && MOD_ONESET(sc->id, MOD_HOLDSCREEN)) || (sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_NORMAL && sc->sc_scroll_data.modifier == state)) { update_modifier(sc->id, *type, 0, MOD_COMMAND); wsdisplay_scroll(sc->sc_base.me_dispdv, (ksym == KS_Cmd_ScrollFastUp) ? WSDISPLAY_SCROLL_BACKWARD : WSDISPLAY_SCROLL_FORWARD); return (1); } else { return (0); } } case KS_Cmd_ScrollSlowUp: case KS_Cmd_ScrollSlowDown: if (*type == WSCONS_EVENT_KEY_DOWN) { GETMODSTATE(sc->id->t_modifiers, state); if ((sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_HOLD && MOD_ONESET(sc->id, MOD_HOLDSCREEN)) || (sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_NORMAL && sc->sc_scroll_data.modifier == state)) { update_modifier(sc->id, *type, 0, MOD_COMMAND); wsdisplay_scroll(sc->sc_base.me_dispdv, (ksym == KS_Cmd_ScrollSlowUp) ? WSDISPLAY_SCROLL_BACKWARD | WSDISPLAY_SCROLL_LOW: WSDISPLAY_SCROLL_FORWARD | WSDISPLAY_SCROLL_LOW); return (1); } else { return (0); } } #endif case KS_Cmd: update_modifier(sc->id, *type, 0, MOD_COMMAND); ksym = ksym2; break; case KS_Cmd1: update_modifier(sc->id, *type, 0, MOD_COMMAND1); break; case KS_Cmd2: update_modifier(sc->id, *type, 0, MOD_COMMAND2); break; } if (*type != WSCONS_EVENT_KEY_DOWN || (! MOD_ONESET(sc->id, MOD_COMMAND) && ! MOD_ALLSET(sc->id, MOD_COMMAND1 | MOD_COMMAND2))) return (0); #if defined(DDB) || defined(KGDB) if (ksym == KS_Cmd_Debugger) { if (sc->sc_isconsole) { #ifdef DDB console_debugger(); #endif #ifdef KGDB kgdb_connect(1); #endif } /* discard this key (ddb discarded command modifiers) */ *type = WSCONS_EVENT_KEY_UP; return (1); } #endif #if NWSDISPLAY > 0 if (sc->sc_base.me_dispdv == NULL) return (0); switch (ksym) { case KS_Cmd_Screen0: case KS_Cmd_Screen1: case KS_Cmd_Screen2: case KS_Cmd_Screen3: case KS_Cmd_Screen4: case KS_Cmd_Screen5: case KS_Cmd_Screen6: case KS_Cmd_Screen7: case KS_Cmd_Screen8: case KS_Cmd_Screen9: wsdisplay_switch(sc->sc_base.me_dispdv, ksym - KS_Cmd_Screen0, 0); return (1); case KS_Cmd_ResetEmul: wsdisplay_reset(sc->sc_base.me_dispdv, WSDISPLAY_RESETEMUL); return (1); case KS_Cmd_ResetClose: wsdisplay_reset(sc->sc_base.me_dispdv, WSDISPLAY_RESETCLOSE); return (1); case KS_Cmd_BacklightOn: case KS_Cmd_BacklightOff: case KS_Cmd_BacklightToggle: change_displayparam(sc, WSDISPLAYIO_PARAM_BACKLIGHT, ksym == KS_Cmd_BacklightOff ? -1 : 1, ksym == KS_Cmd_BacklightToggle ? 1 : 0); return (1); case KS_Cmd_BrightnessUp: case KS_Cmd_BrightnessDown: case KS_Cmd_BrightnessRotate: change_displayparam(sc, WSDISPLAYIO_PARAM_BRIGHTNESS, ksym == KS_Cmd_BrightnessDown ? -1 : 1, ksym == KS_Cmd_BrightnessRotate ? 1 : 0); return (1); case KS_Cmd_ContrastUp: case KS_Cmd_ContrastDown: case KS_Cmd_ContrastRotate: change_displayparam(sc, WSDISPLAYIO_PARAM_CONTRAST, ksym == KS_Cmd_ContrastDown ? -1 : 1, ksym == KS_Cmd_ContrastRotate ? 1 : 0); return (1); } #endif return (0); }