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 + -
显示快捷键?