Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
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);
}