void __init kbd_init(void){ kbd_q.size = KEYB_BUFFER; kbd_q.cir_buff = kbd_q.data; kbd_q.raw_cir_buff = kbd_q.raw_data; set_standard_keyboard(); request_irq (1, &keyb_interrupt, "KEYB",INTERRUPT_IRQ,NULL); }
/* Hardware level keyboard interrupt handler */ static int keyb_interrupt(int irq,void *device,struct thread_regs *regs) { int code = kbd_wait_read(); int origcode, mycode, flag = 0, numlock, i = 0; if(code < 0 ) goto end; if ( IS_KEY_EXTENDED(code) ) { /* flag that the next key will be an extended one */ key_extended = 1; goto end; } /* convert from hardware to readable format */ if ( key_extended ) { mycode = hw_to_mycode_ex[ code & 0x7F ]; key_extended = 0; } else { mycode = hw_to_mycode[ code & 0x7F ]; } if ( !mycode ) { goto end; } origcode = mycode; /*If its a modifier key, get the bitmask*/ if ( mycode >= KEY_MODIFIERS ) { flag = modifier_table[ mycode - KEY_MODIFIERS ]; } numlock = (key_shifts & KB_NUMLOCK_FLAG) ; /* handle released keys */ if ( code & 0x80 ) { if ( flag & KB_ALT_FLAG ) { /* end of an alt+numpad numeric entry sequence */ if ( key_shifts & KB_INALTSEQ_FLAG ) { key_shifts &= ~KB_INALTSEQ_FLAG; ub_inq( key_pad_seq, code); } } if ( flag & KB_MODIFIERS ) { /* turn off the shift state for this key */ key_shifts &= ~flag; if ( mycode == KEY_ALTGR ) { key_altgr = 0; } } goto end; } /*Ctrl+ALT+F1 ->sets the standard keyboard layout :*/ if ( ( mycode == KEY_F1 ) && ( ( key_shifts & KB_CTRL_ALT ) == KB_CTRL_ALT ) ) { /* switch to the standard keyboard layout */ ub_inq( key_shifts, KEY_F1 ); set_standard_keyboard(); goto end; } /*FOR PC: Its ctrl F1 through ctrl F12*/ #ifndef BOCHS if(IS_KEY_F1(mycode,key_shifts) ){ printf("\n"); printhelp(0); } /*display the slab cache stats*/ if(IS_KEY_F2(mycode,key_shifts) ) { printf("\n"); display_slab_caches_stats(); } /*display free mem*/ if(IS_KEY_F3(mycode,key_shifts) ) { printf("\n"); display_mem_stats(); } if(IS_KEY_F4(mycode,key_shifts) ) { printf("\n"); display_e820(); } #else /*for bochs : its key F1- F12*/ if( (! (key_shifts & KB_CTRL_FLAG) ) && (mycode >= KEY_F1 && mycode <= KEY_F12) ) { static struct tasklet_struct tasklet; register_tasklet(&tasklet,terminal_tasklet,(void *)mycode - KEY_F1); } #endif /*check for the modifier bitmasks*/ if ( flag & KB_MODIFIERS ) { /* turn on a modifier key */ key_shifts |= flag; if ( mycode == KEY_ALTGR ) { key_altgr = 1; } ub_inq(key_shifts,mycode); goto end; } if ( IS_KEY_LED(flag)) { /* toggle caps/num/scroll lock */ key_shifts ^= flag; ub_inq(key_shifts, mycode ); set_leds( key_shifts ); goto end; } if ( key_shifts & KB_ALT_FLAG ) { if ( ( mycode >= KEY_0_PAD ) && ( mycode <= KEY_9_PAD ) ) { /* alt+numpad numeric entry */ if ( key_shifts & KB_INALTSEQ_FLAG ) { key_pad_seq = key_pad_seq * 10 + mycode - KEY_0_PAD; } else { key_shifts |= KB_INALTSEQ_FLAG; key_pad_seq = mycode - KEY_0_PAD; } ub_inq( key_shifts, mycode ); goto end; } else { /* check for alt+key: function key mappings are ignored. The handling is a bit different for the right ALT key */ i = key_shifts; #if 0 if ( key_altgr && key_ascii_table[mycode] != 0xffff ) { i = key_altgr_lower_table[ mycode ]; } #endif } } else if ( ( mycode >= KEY_0_PAD ) && ( mycode <= KEY_9_PAD ) ) { /* handle numlock number -> arrow conversions */ i = mycode - KEY_0_PAD; if(numlock) { mycode = numlock_table[ i ]; i = key_shifts; } else { i = key_ascii_table[ mycode ]; } } else if ( mycode == KEY_DEL_PAD ) { /* handle numlock logic for the del key */ if ( numlock ) { i = key_shifts; } else { i = key_ascii_table[ KEY_DEL_PAD ]; } } else if ( key_shifts & KB_CTRL_FLAG ) { /* ctrl+key */ if ( mycode >= KEY_F1 && mycode <= KEY_F12 ) { /*switch virtual consoles*/ static struct tasklet_struct tasklet; register_tasklet(&tasklet,terminal_tasklet,(void *)mycode - KEY_F1); goto end; } i = key_control_table[ mycode ]; } else if ( key_shifts & KB_SHIFT_FLAG ) { /* shift + key */ if ( key_shifts & KB_CAPSLOCK_FLAG ) { if ( key_ascii_table[ mycode ] == key_capslock_table[ mycode ] ) { i = key_shift_table[ mycode ]; } else { i = key_ascii_table[ mycode ]; } } else { i = key_shift_table[ mycode ]; } } else if ( key_shifts & KB_CAPSLOCK_FLAG ) { /* capslock + key */ i = key_capslock_table[ mycode ]; } else { /* normal key */ if(mycode == KEY_UP) { if(current_term->scroll_up) { current_term->scroll_up(1); } goto end; } if(mycode == KEY_DOWN) { if(current_term->scroll_down) { current_term->scroll_down(1); } goto end; } i = key_ascii_table[ mycode ]; } key_shifts &= ~KB_INALTSEQ_FLAG; ub_inq( i, mycode ); end: /* reboot */ if ( ( code == 0x4F || code == 0x53 ) && ( key_shifts & KB_CTRL_ALT ) == KB_CTRL_ALT ) { mir_reboot(); } return 0; }
/* _handle_pckey: * Handles PC keyboard input, in the same format it comes from the * keyboard controller hardware (raw scancodes, top bit set means the * key was released, special escapes for extended keys, pause, etc). * This routine translates the data using the current mapping table, * and calls routines from keyboard.c as required. */ void _handle_pckey(int code) { int origcode, mycode, flag, numflag, i=0; unsigned short *table; if (key_pause_loop) { /* skip multiple codes generated by the pause key */ key_pause_loop--; return; } if (code == 0xE1) { /* the pause key requires special handling */ if (key_paused) _handle_key_release(KEY_PAUSE); else _handle_key_press(0, KEY_PAUSE); key_paused = !key_paused; key_pause_loop = 5; return; } if (code == 0xE0) { /* flag that the next key will be an extended one */ key_extended = TRUE; return; } /* convert from hardware to Allegro format */ if (key_extended) { mycode = hw_to_mycode_ex[code & 0x7F]; key_extended = FALSE; } else mycode = hw_to_mycode[code & 0x7F]; if (!mycode) return; origcode = mycode; if (mycode >= KEY_MODIFIERS) flag = modifier_table[mycode - KEY_MODIFIERS]; else flag = 0; numflag = ((_key_shifts & KB_NUMLOCK_FLAG) != 0) == ((_key_shifts & KB_SHIFT_FLAG) != 0); /* handle released keys */ if (code & 0x80) { if (flag & KB_ALT_FLAG) { /* end of an alt+numpad numeric entry sequence */ if (_key_shifts & KB_INALTSEQ_FLAG) { _key_shifts &= ~KB_INALTSEQ_FLAG; _handle_key_press(key_pad_seq, 0); } } if (flag & KB_MODIFIERS) { /* turn off the shift state for this key */ _key_shifts &= ~flag; if (mycode == KEY_ALTGR) key_altgr = FALSE; } /* update the key array for a released key */ _handle_key_release(mycode); return; } if ((mycode == KEY_F1) && ((_key_shifts & KB_CTRL_ALT) == KB_CTRL_ALT)) { /* switch to the standard keyboard layout */ _handle_key_press(-1, KEY_F1); set_standard_keyboard(); return; } if ((mycode == KEY_F2) && ((_key_shifts & KB_CTRL_ALT) == KB_CTRL_ALT)) { /* switch to the custom keyboard layout */ _handle_key_press(-1, KEY_F2); set_custom_keyboard(); return; } if (flag & KB_MODIFIERS) { /* turn on a modifier key */ _key_shifts |= flag; if (mycode == KEY_ALTGR) key_altgr = TRUE; _handle_key_press(-1, origcode); return; } if ((flag & KB_LED_FLAGS) && (key_led_flag)) { /* toggle caps/num/scroll lock */ _key_shifts ^= flag; _handle_key_press(-1, origcode); return; } /* new ACCENT stuff */ if (!_key_standard_kb) { if ((mycode == _key_accent1) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent1_flag)) { _key_shifts |= KB_ACCENT1_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent2) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent2_flag)) { _key_shifts |= KB_ACCENT2_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent3) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent3_flag)) { _key_shifts |= KB_ACCENT3_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent4) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent4_flag)) { _key_shifts |= KB_ACCENT4_FLAG; _handle_key_press(-1, origcode); return; } } if (_key_shifts & KB_ACCENTS) { /* accented character input */ if (((_key_shifts & KB_SHIFT_FLAG) != 0) ^ ((_key_shifts & KB_CAPSLOCK_FLAG) != 0)) { if (_key_shifts & KB_ACCENT1_FLAG) table = _key_accent1_upper_table; else if (_key_shifts & KB_ACCENT2_FLAG) table = _key_accent2_upper_table; else if (_key_shifts & KB_ACCENT3_FLAG) table = _key_accent3_upper_table; else if (_key_shifts & KB_ACCENT4_FLAG) table = _key_accent4_upper_table; else table = NULL; } else { if (_key_shifts & KB_ACCENT1_FLAG) table = _key_accent1_lower_table; else if (_key_shifts & KB_ACCENT2_FLAG) table = _key_accent2_lower_table; else if (_key_shifts & KB_ACCENT3_FLAG) table = _key_accent3_lower_table; else if (_key_shifts & KB_ACCENT4_FLAG) table = _key_accent4_lower_table; else table = NULL; } if (table[mycode]) { /* simple accented char */ _key_shifts &= ~KB_ACCENTS; _handle_key_press(table[mycode], origcode); return; } else { /* add the accent as an individual character */ if (_key_shifts & (KB_ACCENT1_FLAG)) i = _key_accent1; else if (_key_shifts & (KB_ACCENT2_FLAG)) i = _key_accent2; else if (_key_shifts & (KB_ACCENT3_FLAG)) i = _key_accent3; else if (_key_shifts & (KB_ACCENT4_FLAG)) i = _key_accent4; _handle_key_press(_key_ascii_table[i], i); _key_shifts &= ~KB_ACCENTS; } } if (_key_shifts & KB_ALT_FLAG) { if ((mycode >= KEY_0_PAD) && (mycode <= KEY_9_PAD)) { /* alt+numpad numeric entry */ if (_key_shifts & KB_INALTSEQ_FLAG) { key_pad_seq = key_pad_seq*10 + mycode - KEY_0_PAD; } else { _key_shifts |= KB_INALTSEQ_FLAG; key_pad_seq = mycode - KEY_0_PAD; } _handle_key_press(-1, origcode); return; } else { /* alt+key */ if (_key_ascii_table[mycode] == 0xFFFF) i = 0xFFFF; else if (key_altgr) { if (((_key_shifts & KB_SHIFT_FLAG) != 0) ^ ((_key_shifts & KB_CAPSLOCK_FLAG) != 0)) i = _key_altgr_upper_table[mycode]; else i = _key_altgr_lower_table[mycode]; } else i = 0; } } else if ((mycode >= KEY_0_PAD) && (mycode <= KEY_9_PAD)) { /* handle numlock number->arrow conversions */ i = mycode - KEY_0_PAD; if ((_key_shifts & KB_CTRL_FLAG) || (numflag)) { mycode = numlock_table[i]; i = 0xFFFF; } else i = _key_ascii_table[mycode]; } else if (mycode == KEY_DEL_PAD) { /* handle numlock logic for the del key */ if (numflag) { mycode = KEY_DEL; i = 0xFFFF; } else i = _key_ascii_table[KEY_DEL_PAD]; } else if (_key_shifts & KB_CTRL_FLAG) { /* ctrl+key */ i = _key_control_table[mycode]; } else if (_key_shifts & KB_SHIFT_FLAG) { /* shift+key */ if (_key_shifts & KB_CAPSLOCK_FLAG) { if (_key_ascii_table[mycode] == _key_capslock_table[mycode]) i = _key_shift_table[mycode]; else i = _key_ascii_table[mycode]; } else i = _key_shift_table[mycode]; } else if (_key_shifts & KB_CAPSLOCK_FLAG) { /* capslock+key */ i = _key_capslock_table[mycode]; } else { /* normal key */ i = _key_ascii_table[mycode]; } /* use the current modifier state in place of the key code? */ if (i == 0xFFFF) i = _key_shifts & KB_MODIFIERS; _key_shifts &= ~KB_INALTSEQ_FLAG; /* phew! */ _handle_key_press(i, origcode); }