static int set_typematic(keyboard_t *kbd) { int val, error; atkbd_state_t *state = kbd->kb_data; val = typematic(DEFAULT_DELAY, DEFAULT_RATE); error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, val); if (error == 0) { kbd->kb_delay1 = typematic_delay(val); kbd->kb_delay2 = typematic_rate(val); } return (error); }
/* some useful control functions */ static int atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) { /* translate LED_XXX bits into the device specific bits */ static u_char ledmap[8] = { 0, 4, 2, 6, 1, 5, 3, 7, }; atkbd_state_t *state = kbd->kb_data; int error; int s; int i; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) int ival; #endif s = spltty(); switch (cmd) { case KDGKBMODE: /* get keyboard mode */ *(int *)arg = state->ks_mode; break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) case _IO('K', 7): ival = IOCPARM_IVAL(arg); arg = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSKBMODE: /* set keyboard mode */ switch (*(int *)arg) { case K_XLATE: if (state->ks_mode != K_XLATE) { /* make lock key state and LED state match */ state->ks_state &= ~LOCK_MASK; state->ks_state |= KBD_LED_VAL(kbd); } /* FALLTHROUGH */ case K_RAW: case K_CODE: if (state->ks_mode != *(int *)arg) { atkbd_clear_state(kbd); state->ks_mode = *(int *)arg; } break; default: splx(s); return EINVAL; } break; case KDGETLED: /* get keyboard LED */ *(int *)arg = KBD_LED_VAL(kbd); break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) case _IO('K', 66): ival = IOCPARM_IVAL(arg); arg = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSETLED: /* set keyboard LED */ /* NOTE: lock key state in ks_state won't be changed */ if (*(int *)arg & ~LOCK_MASK) { splx(s); return EINVAL; } i = *(int *)arg; /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ if (state->ks_mode == K_XLATE && kbd->kb_keymap->n_keys > ALTGR_OFFSET) { if (i & ALKED) i |= CLKED; else i &= ~CLKED; } if (KBD_HAS_DEVICE(kbd)) { error = write_kbd(state->kbdc, KBDC_SET_LEDS, ledmap[i & LED_MASK]); if (error) { splx(s); return error; } } KBD_LED_VAL(kbd) = *(int *)arg; break; case KDGKBSTATE: /* get lock key state */ *(int *)arg = state->ks_state & LOCK_MASK; break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) case _IO('K', 20): ival = IOCPARM_IVAL(arg); arg = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSKBSTATE: /* set lock key state */ if (*(int *)arg & ~LOCK_MASK) { splx(s); return EINVAL; } state->ks_state &= ~LOCK_MASK; state->ks_state |= *(int *)arg; splx(s); /* set LEDs and quit */ return atkbd_ioctl(kbd, KDSETLED, arg); case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ splx(s); if (!KBD_HAS_DEVICE(kbd)) return 0; i = typematic(((int *)arg)[0], ((int *)arg)[1]); error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i); if (error == 0) { kbd->kb_delay1 = typematic_delay(i); kbd->kb_delay2 = typematic_rate(i); } return error; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) case _IO('K', 67): ival = IOCPARM_IVAL(arg); arg = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSETRAD: /* set keyboard repeat rate (old interface) */ splx(s); if (!KBD_HAS_DEVICE(kbd)) return 0; error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); if (error == 0) { kbd->kb_delay1 = typematic_delay(*(int *)arg); kbd->kb_delay2 = typematic_rate(*(int *)arg); } return error; case PIO_KEYMAP: /* set keyboard translation table */ case PIO_KEYMAPENT: /* set keyboard translation table entry */ case PIO_DEADKEYMAP: /* set accent key translation table */ state->ks_accents = 0; /* FALLTHROUGH */ default: splx(s); return genkbd_commonioctl(kbd, cmd, arg); } splx(s); return 0; }