Exemplo n.º 1
0
static void do_pad(unsigned char value, char up_flag)
{
	static const char *pad_chars = "0123456789+-*/\015,.?";
	static const char *app_map = "pqrstuvwxylSRQMnn?";

	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);
}
Exemplo n.º 2
0
static void num(void)
{
	if (vc_kbd_mode(kbd,VC_APPLIC))
		applkey('P', 1);
	else
		bare_num();
}
Exemplo n.º 3
0
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));
}
Exemplo n.º 4
0
static void num(void)
{
	if (vc_kbd_mode(kbd,VC_APPLIC)) {
		applkey('P', 1);
		return;
	}
	if (!rep)	/* no autorepeat for numlock, ChN */
		chg_vc_kbd_led(kbd,VC_NUMLOCK);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
static void
enter(void)
{
   if (diacr)
   {
      put_queue(diacr);
      diacr = 0;
   }
   put_queue(13);
#if 0
   if (vc_kbd_mode(kbd, VC_CRLF))
      put_queue(10);
#endif
}
Exemplo n.º 7
0
static void
do_pad(unsigned char value, char up_flag)
{
   static const char pad_chars[] = "0123456789+-*/\015,.?()";

   /*static const char app_map[] = "pqrstuvwxylSRQMnnmPQ"; */

#ifdef DBG2
   printf("do_pad: %d\r\n", value);
#endif

   if (up_flag)
      return;			/* no action, if this is a key release */

#if 0
   /* kludge... shift forces cursor/number keys */
   if ( /*vc_kbd_mode(kbd,VC_APPLIC) */ applic_mode && !k_down[KG_SHIFT])
   {
      if (value < sizeof(app_map))
	 applkey(app_map[value], 1);
      return;
   }
#endif

   switch (value)
   {
   case KVAL(K_PPLUS):
      put_acqueue('+');
      return;
   case KVAL(K_PMINUS):
      put_acqueue('-');
      return;
   case KVAL(K_PSLASH):
      put_acqueue('/');
      return;
   case KVAL(K_PSTAR):
      put_acqueue('*');
      return;
   }

   if ((!scan_numlock_state	/*vc_kbd_led(kbd,VC_NUMLOCK) */
	&& !(shift_state & ((1 << KG_SHIFT) | (1 << KG_SHIFTL) | (1 << KG_SHIFTR)))) || (scan_numlock_state && (shift_state & ((1 << KG_CTRL) | (1 << KG_CTRLL) | (1 << KG_CTRLR)))))
   {
      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) */ applic_mode);
	 return;
      }
   }

   if (value < sizeof(pad_chars))
      /*put_fqueue(pad_chars[value]); */
      put_queue(pad_chars[value]);
#if 0
   if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
      put_queue(10);
#endif
}
Exemplo n.º 8
0
static void enter(void)
{
	put_queue(13);
	if (vc_kbd_mode(kbd,VC_CRLF))
		put_queue(10);
}
Exemplo n.º 9
0
/* This is our keyboard 'interrupt' routine.
 * Must run under sunkbd_lock.
 */
static void __sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
{
	unsigned char keycode;
	char up_flag;                          /* 0 or SUNKBD_UBIT */
	char raw_mode;

	if(ch == SKBD_RESET) {
		kbd_reset_pending = 1;
		goto out;
	}
	if(ch == SKBD_LYOUT) {
		kbd_layout_pending = 1;
		goto out;
	}
	if(kbd_reset_pending) {
		sunkbd_type = ch;
		kbd_reset_pending = 0;
		if(ch == SUNKBD_TYPE4)
			send_cmd(SKBDCMD_GLAYOUT);
		goto out;
	} else if(kbd_layout_pending) {
		sunkbd_layout = ch;
		kbd_layout_pending = 0;
		goto out;
	} else if(ch == SKBD_ALLUP) {
		del_timer (&auto_repeat_timer);
		memset(key_down, 0, sizeof(key_down));
		sun_compute_shiftstate();
		goto out;
	}
#ifdef SKBD_DEBUG
	if(ch == 0x7f)
		printk("KBD<ALL KEYS UP>");
	else
		printk("KBD<%x %s>", ch,
		       ((ch&0x80) ? "UP" : "DOWN"));
#endif

	/* Whee, a real character. */
	if(regs) {
		pt_regs = regs;
		last_keycode = keycode = ch;
	} else {
		keycode = ch;
	}
	
	do_poke_blanked_console = 1;
	tasklet_schedule(&console_tasklet);
	add_keyboard_randomness(keycode);

	tty = ttytab? ttytab[fg_console]: NULL;
	if (tty && (!tty->driver_data)) {
		/* This is to workaround ugly bug in tty_io.c, which
                   does not do locking when it should */
		tty = NULL;
	}
	kbd = kbd_table + fg_console;
	if((raw_mode = (kbd->kbdmode == VC_RAW))) {
		if (kbd_redirected == fg_console+1)
			push_kbd (keycode);
		else
			put_queue(keycode);
		/* we do not return yet, because we want to maintain
		 * the key_down array, so that we have the correct
		 * values  when finishing RAW mode or when changing VT's.
		 */
	}
	up_flag = (keycode & SUNKBD_UBIT);  /* The 'up' bit */
	keycode &= SUNKBD_KMASK;            /* all the rest */
	del_timer (&auto_repeat_timer);
	if(up_flag) {
		rep = 0;
		clear_bit(keycode, key_down);
	} else {
		if (!norepeat_keys[keycode]) {
			if (kbd_rate_ticks) {
				auto_repeat_timer.expires =
						jiffies + kbd_delay_ticks;
				add_timer (&auto_repeat_timer);
			}
		}
		rep = test_and_set_bit(keycode, key_down);
	}

#ifdef CONFIG_MAGIC_SYSRQ			/* Handle the SysRq hack */
	if (l1a_state.l1_down) {
		if (!up_flag)
			handle_sysrq(sun_sysrq_xlate[keycode], pt_regs, kbd, tty);
		goto out;
	}
#endif

	if(raw_mode)
		goto out;

	if(kbd->kbdmode == VC_MEDIUMRAW) {
		put_queue(keycode + up_flag);
		goto out;
	}

 	/*
	 * Small change in philosophy: earlier we defined repetition by
	 *	 rep = keycode == prev_keycode;
	 *	 prev_keycode = keycode;
	 * but now by the fact that the depressed key was down already.
	 * Does this ever make a difference? Yes.
	 */

	/*
 	 *  Repeat a key only if the input buffers are empty or the
 	 *  characters get echoed locally. This makes key repeat usable
 	 *  with slow applications and under heavy loads.
	 */
	if (!rep ||
	    (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
	     (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
		u_short keysym;
		u_char type;

		/* the XOR below used to be an OR */
		int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
		ushort *key_map = key_maps[shift_final];

		if (key_map != NULL) {
			keysym = key_map[keycode];
			type = KTYP(keysym);

			if (type >= 0xf0) {
			    type -= 0xf0;
			    if (type == KT_LETTER) {
				type = KT_LATIN;
				if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
				    key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
				    if (key_map)
				      keysym = key_map[keycode];
				}
			    }
			    (*key_handler[type])(keysym & 0xff, up_flag);
			    if (type != KT_SLOCK)
			      kbd->slockstate = 0;
			}
		} else {
			/* maybe beep? */
			/* we have at least to update shift_state */
			sun_compute_shiftstate();
		}
	}
out:
	tasklet_schedule(&keyboard_tasklet);
}
Exemplo n.º 10
0
static void keyboard_interrupt(int int_pt_regs)
{
	unsigned char scancode;
	static unsigned int prev_scancode = 0;   /* remember E0, E1 */
	char up_flag;				 /* 0 or 0200 */
	char raw_mode;

	pt_regs = (struct pt_regs *) int_pt_regs;
	send_cmd(0xAD);		/* disable keyboard */
	kb_wait();
	if ((inb_p(0x64) & kbd_read_mask) != 0x01)
		goto end_kbd_intr;
	scancode = inb(0x60);
	mark_bh(KEYBOARD_BH);
	if (scancode == 0xfa) {
		acknowledge = 1;
		goto end_kbd_intr;
	} else if (scancode == 0xfe) {
		resend = 1;
		goto end_kbd_intr;
	} else if (scancode == 0) {
#ifdef KBD_REPORT_ERR
		printk("keyboard buffer overflow\n");
#endif
		goto end_kbd_intr;
	} else if (scancode == 0xff) {
#ifdef KBD_REPORT_ERR
		printk("keyboard error\n");
#endif
		prev_scancode = 0;
		goto end_kbd_intr;
	}
	tty = ttytab[fg_console];
 	kbd = kbd_table + fg_console;
	if ((raw_mode = vc_kbd_mode(kbd,VC_RAW))) {
 		put_queue(scancode);
		/* we do not return yet, because we want to maintain
		   the key_down array, so that we have the correct
		   values when finishing RAW mode or when changing VT's */
 	}
	if (scancode == 0xe0 || scancode == 0xe1) {
		prev_scancode = scancode;
		goto end_kbd_intr;
 	}

 	/*
	 *  Convert scancode to keysym, using prev_scancode.
 	 */
	up_flag = (scancode & 0200);
 	scancode &= 0x7f;

	if (prev_scancode) {
	  /*
	   * usually it will be 0xe0, but a Pause key generates
	   * e1 1d 45 e1 9d c5 when pressed, and nothing when released
	   */
	  if (prev_scancode != 0xe0) {
	      if (prev_scancode == 0xe1 && scancode == 0x1d) {
		  prev_scancode = 0x100;
		  goto end_kbd_intr;
	      } else if (prev_scancode == 0x100 && scancode == 0x45) {
		  scancode = E1_PAUSE;
		  prev_scancode = 0;
	      } else {
		  printk("keyboard: unknown e1 escape sequence\n");
		  prev_scancode = 0;
		  goto end_kbd_intr;
	      }
	  } else {
	      prev_scancode = 0;
	      /*
	       *  The keyboard maintains its own internal caps lock and
	       *  num lock statuses. In caps lock mode E0 AA precedes make
	       *  code and E0 2A follows break code. In num lock mode,
	       *  E0 2A precedes make code and E0 AA follows break code.
	       *  We do our own book-keeping, so we will just ignore these.
	       */
	      /*
	       *  For my keyboard there is no caps lock mode, but there are
	       *  both Shift-L and Shift-R modes. The former mode generates
	       *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
	       *  So, we should also ignore the latter. - [email protected]
	       */
	      if (scancode == 0x2a || scancode == 0x36)
		goto end_kbd_intr;

	      if (e0_keys[scancode])
		scancode = e0_keys[scancode];
	      else if (!raw_mode) {
#ifdef KBD_REPORT_UNKN
		  printk("keyboard: unknown scancode e0 %02x\n", scancode);
#endif
		  goto end_kbd_intr;
	      }
	  }
	} else if (scancode >= E0_BASE && !raw_mode) {
#ifdef KBD_REPORT_UNKN
	  printk("keyboard: scancode (%02x) not in range 00 - %2x\n",
		 scancode, E0_BASE - 1);
#endif
	  goto end_kbd_intr;
 	}

	/*
	 * At this point the variable `scancode' contains the keysym.
	 * We keep track of the up/down status of the key, and
	 * return the keysym if in MEDIUMRAW mode.
	 * (Note: earlier kernels had a bug and did not pass the up/down
	 * bit to applications.)
	 */

	if (up_flag) {
 		clear_bit(scancode, key_down);
		rep = 0;
	} else
 		rep = set_bit(scancode, key_down);

	if (raw_mode)
		goto end_kbd_intr;

 	if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) {
 		put_queue(scancode + up_flag);
		goto end_kbd_intr;
 	}

 	/*
	 * Small change in philosophy: earlier we defined repetition by
	 *	 rep = scancode == prev_keysym;
	 *	 prev_keysym = scancode;
	 * but now by the fact that the depressed key was down already.
	 * Does this ever make a difference?
	 */

	/*
 	 *  Repeat a key only if the input buffers are empty or the
 	 *  characters get echoed locally. This makes key repeat usable
 	 *  with slow applications and under heavy loads.
	 */
	if (!rep ||
	    (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
	     (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
		u_short key_code;
		u_char type;

		/* the XOR below used to be an OR */
		int shift_final = shift_state ^ kbd->lockstate;

		key_code = key_map[shift_final][scancode];
		type = KTYP(key_code);

		if (type == KT_LETTER) {
		    type = KT_LATIN;
		    if (vc_kbd_led(kbd,VC_CAPSLOCK))
			key_code = key_map[shift_final ^ (1<<KG_SHIFT)][scancode];
		}
		(*key_handler[type])(key_code & 0xff, up_flag);
	}

end_kbd_intr:
	send_cmd(0xAE);         /* enable keyboard */
}