⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard.c

📁 《嵌入式系统设计与实例开发实验教材II:基于ARM9微处理器与Linux操作系统》——PS2键盘鼠标驱动实验
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (vc_cons_allocated(i))			break;	}	set_console(i);}static void incr_console(void){	int i;	for (i = fg_console+1; i != fg_console; i++) {		if (i == MAX_NR_CONSOLES)			i = 0;		if (vc_cons_allocated(i))			break;	}	set_console(i);}static void send_intr(void){	if (!tty)		return;	tty_insert_flip_char(tty, 0, TTY_BREAK);	con_schedule_flip(tty);}static void scroll_forw(void){	scrollfront(0);}static void scroll_back(void){	scrollback(0);}static void boot_it(void){	ctrl_alt_del();}static void compose(void){	dead_key_next = 1;}int spawnpid, spawnsig;static void spawn_console(void){        if (spawnpid)	   if(kill_proc(spawnpid, spawnsig, 1))	     spawnpid = 0;}static void SAK(void){	/*	 * SAK should also work in all raw modes and reset	 * them properly.	 */	do_SAK(tty);	reset_vc(fg_console);#if 0	do_unblank_screen();	/* not in interrupt routine? */#endif}static void do_ignore(unsigned char value, char up_flag){}static void do_null(void){	compute_shiftstate();}static void do_spec(unsigned char value, char up_flag){	if (up_flag)		return;	if (value >= SIZE(spec_fn_table))		return;	if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&	    !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))		return;	spec_fn_table[value]();}static void do_lowercase(unsigned char value, char up_flag){	printk(KERN_ERR "keyboard.c: do_lowercase was called - impossible\n");}static void do_self(unsigned char value, char up_flag){	if (up_flag)		return;		/* no action, if this is a key release */	if (diacr)		value = handle_diacr(value);	if (dead_key_next) {		dead_key_next = 0;		diacr = value;		return;	}	put_queue(value);}#define A_GRAVE  '`'#define A_ACUTE  '\''#define A_CFLEX  '^'#define A_TILDE  '~'#define A_DIAER  '"'#define A_CEDIL  ','static unsigned char ret_diacr[NR_DEAD] =	{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };/* Obsolete - for backwards compatibility only */static void do_dead(unsigned char value, char up_flag){	value = ret_diacr[value];	do_dead2(value,up_flag);}/* * Handle dead key. Note that we now may have several * dead keys modifying the same character. Very useful * for Vietnamese. */static void do_dead2(unsigned char value, char up_flag){	if (up_flag)		return;	diacr = (diacr ? handle_diacr(value) : value);}/* * We have a combining character DIACR here, followed by the character CH. * If the combination occurs in the table, return the corresponding value. * Otherwise, if CH is a space or equals DIACR, return DIACR. * Otherwise, conclude that DIACR was not combining after all, * queue it and return CH. */unsigned char handle_diacr(unsigned char ch){	int d = diacr;	int i;	diacr = 0;	for (i = 0; i < accent_table_size; i++) {		if (accent_table[i].diacr == d && accent_table[i].base == ch)			return accent_table[i].result;	}	if (ch == ' ' || ch == d)		return d;	put_queue(d);	return ch;}static void do_cons(unsigned char value, char up_flag){	if (up_flag)		return;	set_console(value);}static void do_fn(unsigned char value, char up_flag){	if (up_flag)		return;	if (value < SIZE(func_table)) {		if (func_table[value])			puts_queue(func_table[value]);	} else		printk(KERN_ERR "do_fn called with value=%d\n", value);}static void do_pad(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) && !k_down[KG_SHIFT]) {		applkey(app_map[value], 1);		return;	}	if (!vc_kbd_led(kbd,VC_NUMLOCK))		switch (value) {			case KVAL(K_PCOMMA):			case KVAL(K_PDOT):				do_fn(KVAL(K_REMOVE), 0);				return;			case KVAL(K_P0):				do_fn(KVAL(K_INSERT), 0);				return;			case KVAL(K_P1):				do_fn(KVAL(K_SELECT), 0);				return;			case KVAL(K_P2):				do_cur(KVAL(K_DOWN), 0);				return;			case KVAL(K_P3):				do_fn(KVAL(K_PGDN), 0);				return;			case KVAL(K_P4):				do_cur(KVAL(K_LEFT), 0);				return;			case KVAL(K_P6):				do_cur(KVAL(K_RIGHT), 0);				return;			case KVAL(K_P7):				do_fn(KVAL(K_FIND), 0);				return;			case KVAL(K_P8):				do_cur(KVAL(K_UP), 0);				return;			case KVAL(K_P9):				do_fn(KVAL(K_PGUP), 0);				return;			case KVAL(K_P5):				applkey('G', vc_kbd_mode(kbd, VC_APPLIC));				return;		}	put_queue(pad_chars[value]);	if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))		put_queue(10);}static void do_cur(unsigned char value, char up_flag){	static const char *cur_chars = "BDCA";	if (up_flag)		return;	applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));}static void do_shift(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 (k_down[value])			k_down[value]--;	} else		k_down[value]++;	if (k_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(npadch & 0xffff);		else		  put_queue(npadch & 0xff);		npadch = -1;	}}/* Called after returning from RAW mode or when changing consoles - * recompute k_down[] and shift_state from key_down[] * Maybe called when keymap is undefined so that shift key release is seen */void compute_shiftstate(void){	int i, j, k, sym, val;	shift_state = 0;	for(i=0; i < SIZE(k_down); i++)	  k_down[i] = 0;	for(i=0; i < SIZE(key_down); i++)	  if(key_down[i]) {	/* skip this word if not a single bit on */	    k = i*BITS_PER_LONG;	    for(j=0; j<BITS_PER_LONG; j++,k++)	      if(test_bit(k, key_down)) {		sym = U(key_maps[0][k]);		if(KTYP(sym) == KT_SHIFT || KTYP(sym) == KT_SLOCK) {		  val = KVAL(sym);		  if (val == KVAL(K_CAPSSHIFT))		    val = KVAL(K_SHIFT);		  k_down[val]++;		  shift_state |= (1<<val);		}	      }	  }}static void do_meta(unsigned char value, char up_flag){	if (up_flag)		return;	if (vc_kbd_mode(kbd, VC_META)) {		put_queue('\033');		put_queue(value);	} else		put_queue(value | 0x80);}static void do_ascii(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 do_lock(unsigned char value, char up_flag){	if (up_flag || rep)		return;	chg_vc_kbd_lock(kbd, value);}static void do_slock(unsigned char value, char up_flag){	do_shift(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);	}}/* * The leds display either * (i)   the status of NumLock, CapsLock, ScrollLock, or * (ii)  whatever pattern of lights people want to show using KDSETLED, or * (iii) specified bits of specified words in kernel memory. */static unsigned char ledstate = 0xff; /* undefined */static unsigned char ledioctl;unsigned char getledstate(void){    return ledstate;}//add by threewater for i2c ps2 keyboard modulesEXPORT_SYMBOL(getledstate);void setledstate(struct kbd_struct *kbd, unsigned int led){    if (!(led & ~7)) {	ledioctl = led;	kbd->ledmode = LED_SHOW_IOCTL;    } else	kbd->ledmode = LED_SHOW_FLAGS;    set_leds();}static struct ledptr {    unsigned int *addr;    unsigned int mask;    unsigned char valid:1;} ledptrs[3];void register_leds(int console, unsigned int led,		   unsigned int *addr, unsigned int mask){    struct kbd_struct *kbd = kbd_table + console;    if (led < 3) {	ledptrs[led].addr = addr;	ledptrs[led].mask = mask;	ledptrs[led].valid = 1;	kbd->ledmode = LED_SHOW_MEM;    } else	kbd->ledmode = LED_SHOW_FLAGS;}static inline unsigned char getleds(void){    struct kbd_struct *kbd = kbd_table + fg_console;    unsigned char leds;    if (kbd->ledmode == LED_SHOW_IOCTL)      return ledioctl;    leds = kbd->ledflagstate;    if (kbd->ledmode == LED_SHOW_MEM) {	if (ledptrs[0].valid) {	    if (*ledptrs[0].addr & ledptrs[0].mask)	      leds |= 1;	    else	      leds &= ~1;	}	if (ledptrs[1].valid) {	    if (*ledptrs[1].addr & ledptrs[1].mask)	      leds |= 2;	    else	      leds &= ~2;	}	if (ledptrs[2].valid) {	    if (*ledptrs[2].addr & ledptrs[2].mask)	      leds |= 4;	    else	      leds &= ~4;	}    }    return leds;}/* * This routine is the bottom half of the keyboard interrupt * routine, and runs with all interrupts enabled. It does * console changing, led setting and copy_to_cooked, which can * take a reasonably long time. * * Aside from timing (which isn't really that important for * keyboard interrupts as they happen often), using the software * interrupt routines for this thing allows us to easily mask * this when we don't want any of the above to happen. Not yet * used, but this allows for easy and efficient race-condition * prevention later on. */static void kbd_bh(unsigned long dummy){	unsigned char leds = getleds();	if (rep && kbd_repeatkeycode != -1) {		tty = ttytab? ttytab[fg_console]: NULL;		kbd = kbd_table + fg_console;		/* This prevents the kbd_key routine from being called		 * twice, once by this BH, and once by the interrupt		 * routine.		 */		kbd_disable_irq();		kbd_processkeycode(kbd_repeatkeycode, 0, 1);		kbd_enable_irq();	}	if (leds != ledstate) {		ledstate = leds;		kbd_leds(leds);		if (kbd_ledfunc) kbd_ledfunc(leds);	}}EXPORT_SYMBOL(keyboard_tasklet);DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);static void key_callback(unsigned long nr){	rep = 1;	tasklet_schedule(&keyboard_tasklet);}typedef void (pm_kbd_func) (void);pm_callback pm_kbd_request_override = NULL;int __init kbd_init(void){	int i;	struct kbd_struct kbd0;	extern struct tty_driver console_driver;	kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;	kbd0.ledmode = LED_SHOW_FLAGS;	kbd0.lockstate = KBD_DEFLOCK;	kbd0.slockstate = 0;	kbd0.modeflags = KBD_DEFMODE;	kbd0.kbdmode = VC_XLATE; 	for (i = 0 ; i < MAX_NR_CONSOLES ; i++)		kbd_table[i] = kbd0;	ttytab = console_driver.table;	kbd_init_hw();	tasklet_enable(&keyboard_tasklet);	tasklet_schedule(&keyboard_tasklet);	pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kbd_request_override);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -