keyboard.c
来自「linux 内核源代码」· C语言 代码 · 共 1,426 行 · 第 1/3 页
C
1,426 行
static void fn_hold(struct vc_data *vc){ struct tty_struct *tty = vc->vc_tty; if (rep || !tty) return; /* * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty); * these routines are also activated by ^S/^Q. * (And SCROLLOCK can also be set by the ioctl KDSKBLED.) */ if (tty->stopped) start_tty(tty); else stop_tty(tty);}static void fn_num(struct vc_data *vc){ if (vc_kbd_mode(kbd,VC_APPLIC)) applkey(vc, 'P', 1); else fn_bare_num(vc);}/* * Bind this to Shift-NumLock if you work in application keypad mode * but want to be able to change the NumLock flag. * Bind this to NumLock if you prefer that the NumLock key always * changes the NumLock flag. */static void fn_bare_num(struct vc_data *vc){ if (!rep) chg_vc_kbd_led(kbd, VC_NUMLOCK);}static void fn_lastcons(struct vc_data *vc){ /* switch to the last used console, ChN */ set_console(last_console);}static void fn_dec_console(struct vc_data *vc){ int i, cur = fg_console; /* Currently switching? Queue this next switch relative to that. */ if (want_console != -1) cur = want_console; for (i = cur - 1; i != cur; i--) { if (i == -1) i = MAX_NR_CONSOLES - 1; if (vc_cons_allocated(i)) break; } set_console(i);}static void fn_inc_console(struct vc_data *vc){ int i, cur = fg_console; /* Currently switching? Queue this next switch relative to that. */ if (want_console != -1) cur = want_console; for (i = cur+1; i != cur; i++) { if (i == MAX_NR_CONSOLES) i = 0; if (vc_cons_allocated(i)) break; } set_console(i);}static void fn_send_intr(struct vc_data *vc){ struct tty_struct *tty = vc->vc_tty; if (!tty) return; tty_insert_flip_char(tty, 0, TTY_BREAK); con_schedule_flip(tty);}static void fn_scroll_forw(struct vc_data *vc){ scrollfront(vc, 0);}static void fn_scroll_back(struct vc_data *vc){ scrollback(vc, 0);}static void fn_show_mem(struct vc_data *vc){ show_mem();}static void fn_show_state(struct vc_data *vc){ show_state();}static void fn_boot_it(struct vc_data *vc){ ctrl_alt_del();}static void fn_compose(struct vc_data *vc){ dead_key_next = 1;}static void fn_spawn_con(struct vc_data *vc){ spin_lock(&vt_spawn_con.lock); if (vt_spawn_con.pid) if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) { put_pid(vt_spawn_con.pid); vt_spawn_con.pid = NULL; } spin_unlock(&vt_spawn_con.lock);}static void fn_SAK(struct vc_data *vc){ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; schedule_work(SAK_work);}static void fn_null(struct vc_data *vc){ compute_shiftstate();}/* * Special key handlers */static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag){}static void k_spec(struct vc_data *vc, unsigned char value, char up_flag){ if (up_flag) return; if (value >= ARRAY_SIZE(fn_handler)) return; if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) && value != KVAL(K_SAK)) return; /* SAK is allowed even in raw mode */ fn_handler[value](vc);}static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag){ printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");}static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag){ if (up_flag) return; /* no action, if this is a key release */ if (diacr) value = handle_diacr(vc, value); if (dead_key_next) { dead_key_next = 0; diacr = value; return; } if (kbd->kbdmode == VC_UNICODE) to_utf8(vc, value); else { int c = conv_uni_to_8bit(value); if (c != -1) put_queue(vc, c); }}/* * Handle dead key. Note that we now may have several * dead keys modifying the same character. Very useful * for Vietnamese. */static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag){ if (up_flag) return; diacr = (diacr ? handle_diacr(vc, value) : value);}static void k_self(struct vc_data *vc, unsigned char value, char up_flag){ unsigned int uni; if (kbd->kbdmode == VC_UNICODE) uni = value; else uni = conv_8bit_to_uni(value); k_unicode(vc, uni, up_flag);}static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag){ k_deadunicode(vc, value, up_flag);}/* * Obsolete - for backwards compatibility only */static void k_dead(struct vc_data *vc, unsigned char value, char up_flag){ static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; value = ret_diacr[value]; k_deadunicode(vc, value, up_flag);}static void k_cons(struct vc_data *vc, unsigned char value, char up_flag){ if (up_flag) return; set_console(value);}static void k_fn(struct vc_data *vc, unsigned char value, char up_flag){ unsigned v; if (up_flag) return; v = value; if (v < ARRAY_SIZE(func_table)) { if (func_table[value]) puts_queue(vc, func_table[value]); } else printk(KERN_ERR "k_fn called with value=%d\n", value);}static void k_cur(struct vc_data *vc, unsigned char value, char up_flag){ static const char cur_chars[] = "BDCA"; if (up_flag) return; applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));}static void k_pad(struct vc_data *vc, unsigned char value, char up_flag){ static const char pad_chars[] = "0123456789+-*/\015,.?()#"; static const char app_map[] = "pqrstuvwxylSRQMnnmPQS"; if (up_flag) return; /* no action, if this is a key release */ /* kludge... shift forces cursor/number keys */ if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) { applkey(vc, app_map[value], 1); return; } if (!vc_kbd_led(kbd, VC_NUMLOCK)) switch (value) { case KVAL(K_PCOMMA): case KVAL(K_PDOT): k_fn(vc, KVAL(K_REMOVE), 0); return; case KVAL(K_P0): k_fn(vc, KVAL(K_INSERT), 0); return; case KVAL(K_P1): k_fn(vc, KVAL(K_SELECT), 0); return; case KVAL(K_P2): k_cur(vc, KVAL(K_DOWN), 0); return; case KVAL(K_P3): k_fn(vc, KVAL(K_PGDN), 0); return; case KVAL(K_P4): k_cur(vc, KVAL(K_LEFT), 0); return; case KVAL(K_P6): k_cur(vc, KVAL(K_RIGHT), 0); return; case KVAL(K_P7): k_fn(vc, KVAL(K_FIND), 0); return; case KVAL(K_P8): k_cur(vc, KVAL(K_UP), 0); return; case KVAL(K_P9): k_fn(vc, KVAL(K_PGUP), 0); return; case KVAL(K_P5): applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC)); return; } put_queue(vc, pad_chars[value]); if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF)) put_queue(vc, 10);}static void k_shift(struct vc_data *vc, unsigned char value, char up_flag){ int old_state = shift_state; if (rep) return; /* * Mimic typewriter: * a CapsShift key acts like Shift but undoes CapsLock */ if (value == KVAL(K_CAPSSHIFT)) { value = KVAL(K_SHIFT); if (!up_flag) clr_vc_kbd_led(kbd, VC_CAPSLOCK); } if (up_flag) { /* * handle the case that two shift or control * keys are depressed simultaneously */ if (shift_down[value]) shift_down[value]--; } else shift_down[value]++; if (shift_down[value]) shift_state |= (1 << value); else shift_state &= ~(1 << value); /* kludge */ if (up_flag && shift_state != old_state && npadch != -1) { if (kbd->kbdmode == VC_UNICODE) to_utf8(vc, npadch); else put_queue(vc, npadch & 0xff); npadch = -1; }}static void k_meta(struct vc_data *vc, unsigned char value, char up_flag){ if (up_flag) return; if (vc_kbd_mode(kbd, VC_META)) { put_queue(vc, '\033'); put_queue(vc, value); } else put_queue(vc, value | 0x80);}static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag){ int base; if (up_flag) return; if (value < 10) { /* decimal input of code, while Alt depressed */ base = 10; } else { /* hexadecimal input of code, while AltGr depressed */ value -= 10; base = 16; } if (npadch == -1) npadch = value; else npadch = npadch * base + value;}static void k_lock(struct vc_data *vc, unsigned char value, char up_flag){ if (up_flag || rep) return; chg_vc_kbd_lock(kbd, value);}static void k_slock(struct vc_data *vc, unsigned char value, char up_flag){ k_shift(vc, value, up_flag); if (up_flag || rep) return; chg_vc_kbd_slock(kbd, value); /* try to make Alt, oops, AltGr and such work */ if (!key_maps[kbd->lockstate ^ kbd->slockstate]) { kbd->slockstate = 0; chg_vc_kbd_slock(kbd, value); }}/* by default, 300ms interval for combination release */static unsigned brl_timeout = 300;MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");module_param(brl_timeout, uint, 0644);static unsigned brl_nbchords = 1;MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");module_param(brl_nbchords, uint, 0644);static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag){ static unsigned long chords; static unsigned committed; if (!brl_nbchords) k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag); else { committed |= pattern; chords++; if (chords == brl_nbchords) { k_unicode(vc, BRL_UC_ROW | committed, up_flag); chords = 0; committed = 0; } }}static void k_brl(struct vc_data *vc, unsigned char value, char up_flag){ static unsigned pressed,committing; static unsigned long releasestart; if (kbd->kbdmode != VC_UNICODE) { if (!up_flag) printk("keyboard mode must be unicode for braille patterns\n"); return; } if (!value) { k_unicode(vc, BRL_UC_ROW, up_flag); return; } if (value > 8) return; if (up_flag) { if (brl_timeout) { if (!committing || jiffies - releasestart > (brl_timeout * HZ) / 1000) { committing = pressed; releasestart = jiffies; } pressed &= ~(1 << (value - 1)); if (!pressed) { if (committing) { k_brlcommit(vc, committing, 0); committing = 0; } } } else { if (committing) { k_brlcommit(vc, committing, 0); committing = 0; } pressed &= ~(1 << (value - 1)); } } else { pressed |= 1 << (value - 1); if (!brl_timeout)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?