Beispiel #1
0
/*
 * Many other routines do put_queue, but I think either
 * they produce ASCII, or they produce some user-assigned
 * string, and in both cases we might assume that it is
 * in utf-8 already.
 */
static void to_utf8(ushort c) {
    if (c < 0x80)
	put_queue(c);			/*  0*******  */
    else if (c < 0x800) {
	put_queue(0xc0 | (c >> 6)); 	/*  110***** 10******  */
	put_queue(0x80 | (c & 0x3f));
    } else {
Beispiel #2
0
static void handle_kbd_command(ChannelState *s, int val)
{
    KBD_DPRINTF("Command %d\n", val);
    if (s->led_mode) { // Ignore led byte
        s->led_mode = 0;
        return;
    }
    switch (val) {
    case 1: // Reset, return type code
        clear_queue(s);
        put_queue(s, 0xff);
        put_queue(s, 4); // Type 4
        put_queue(s, 0x7f);
        break;
    case 0xe: // Set leds
        s->led_mode = 1;
        break;
    case 7: // Query layout
    case 0xf:
        clear_queue(s);
        put_queue(s, 0xfe);
        put_queue(s, 0); // XXX, layout?
        break;
    default:
        break;
    }
}
Beispiel #3
0
/*
 * Many other routines do put_queue, but I think either
 * they produce ASCII, or they produce some user-assigned
 * string, and in both cases we might assume that it is
 * in utf-8 already.
 */
void to_utf8 (ushort c, key_info* kinfo)
{
    if (c < 0x80)
        put_queue(c, kinfo);                /* 0*******  */
    else if (c < 0x800) {
        put_queue(0xc0 | (c >> 6), kinfo);  /*  110***** 10******  */
        put_queue(0x80 | (c & 0x3f), kinfo);
    } else {
Beispiel #4
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);
}
Beispiel #5
0
static void put_utf8(SDL_EVDEV_keyboard_state *kbd, uint c)
{
    if (c < 0x80)
        /*  0******* */
        put_queue(kbd, c);
    else if (c < 0x800) {
        /* 110***** 10****** */
        put_queue(kbd, 0xc0 | (c >> 6));
        put_queue(kbd, 0x80 | (c & 0x3f));
    } else if (c < 0x10000) {
/*
 * Many other routines do put_queue, but I think either
 * they produce ASCII, or they produce some user-assigned
 * string, and in both cases we might assume that it is
 * in utf-8 already.
 */
static void to_utf8(struct vc_data *vc, uint c)
{
	if (c < 0x80)
		/*  0******* */
		put_queue(vc, c);
	else if (c < 0x800) {
		/* 110***** 10****** */
		put_queue(vc, 0xc0 | (c >> 6));
		put_queue(vc, 0x80 | (c & 0x3f));
	} else if (c < 0x10000) {
Beispiel #7
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);
}
Beispiel #8
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
}
Beispiel #9
0
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, no joke... */
	if (up_flag && shift_state != old_state && npadch != -1) {
		put_queue(npadch & 0xff);
		npadch = -1;
	}
}
Beispiel #10
0
static
void
queue_init(av_queue *q)
{
	q->abort_request = 0;
	q->m_first_pkt = q->m_last_pkt = NULL;
	q->m_size = 0;

	pthread_mutex_init(&q->m_mutex, NULL);
	pthread_cond_init(&q->m_cond, NULL);

	if (q->m_type == QUEUE_PACKET)
		put_queue(q, (void*) &flush_pkt);
	else if (q->m_type == QUEUE_AVFRAME)
		put_queue(q, (void*) &flush_frm);
}
Beispiel #11
0
//方向键
void cursor(u8 scancode)
{
    u8 i;
    u8 ch;

    i = scancode - 0x47 ; // 方向键从71开始

    if (i > 12) {
        return;
    }

    
    if ((e0 == 1) || (! (leds & 0x2)) || (mode & 0x3)) {// 小键盘上的数字键没有lock
        ch = cursos_tab[i];

        if (ch <= '9') {
            ch = '~';
        }
        //形成移动序列
        ch = ch << 16 | 0x5b1b;   
    } else {                // 小键盘上的数字键
        ch = number_tab[i];
    }
    put_queue(ch);
    
    return;
}
Beispiel #12
0
static void handle_kbd_command(ChannelState *s, int val)
{
    KBD_DPRINTF("Command %d\n", val);
    switch (val) {
    case 1: // Reset, return type code
	put_queue(s, 0xff);
	put_queue(s, 5); // Type 5
	break;
    case 7: // Query layout
	put_queue(s, 0xfe);
	put_queue(s, 0x20); // XXX, layout?
	break;
    default:
	break;
    }
}
Beispiel #13
0
void * produce(void * arg)
{
    pthread_detach(pthread_self());
    int i=0;
    while(1){
        put_queue(&queue, (void*)i++);
    }
}
Beispiel #14
0
static void sunmouse_event(void *opaque, 
                               int dx, int dy, int dz, int buttons_state)
{
    ChannelState *s = opaque;
    int ch;

    /* XXX: SDL sometimes generates nul events: we delete them */
    if (dx == 0 && dy == 0 && dz == 0 && buttons_state == 0)
        return;
    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);

    ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */

    if (buttons_state & MOUSE_EVENT_LBUTTON)
        ch ^= 0x4;
    if (buttons_state & MOUSE_EVENT_MBUTTON)
        ch ^= 0x2;
    if (buttons_state & MOUSE_EVENT_RBUTTON)
        ch ^= 0x1;

    put_queue(s, ch);

    ch = dx;

    if (ch > 127)
        ch=127;
    else if (ch < -127)
        ch=-127;

    put_queue(s, ch & 0xff);

    ch = -dy;

    if (ch > 127)
        ch=127;
    else if (ch < -127)
        ch=-127;

    put_queue(s, ch & 0xff);

    // MSC protocol specify two extra motion bytes

    put_queue(s, 0);
    put_queue(s, 0);
}
Beispiel #15
0
void input_byte(command_queue_t *q, uint8_t data)
{
	int status = 0;
	if (empty_queue(q))
	{
		put_queue(q, new_node());
		status = set_node_command(last_node(q), data);
	}
	else if (!command_recieved(node_data(last_node(q))))
	{
		status = set_node_command(last_node(q), data);
	}
	else
	{
		put_queue(q, new_node());
		status = set_node_command(last_node(q), data);
	}
}
Beispiel #16
0
void UART0_task(INT8U my_id, INT8U my_state, INT8U my_event, INT8U my_data)
{
	while(uart0_rx_queue.length > 0)
	{
		INT8U contents = queue_get(&uart0_rx_queue);

		put_queue(Q_INPUT, contents, 0);
	}
}
Beispiel #17
0
void minus(u8 scancode)
{
    if (e0 != 1) {
        do_self(scancode);
    } else {
        put_queue((u32) '/');
    }
    return;
}
Beispiel #18
0
static void sunkbd_event(void *opaque, int ch)
{
    ChannelState *s = opaque;
    int release = ch & 0x80;

    ch = keycodes[ch & 0x7f];
    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
    put_queue(s, ch | release);
}
Beispiel #19
0
static void do_dead(unsigned char value, char up_flag)
{
	if (up_flag)
		return;

	value = ret_diacr[value];
	if (diacr == value) {   /* pressed twice */
		diacr = 0;
		put_queue(value);
		return;
	}
	diacr = value;
}
Beispiel #20
0
void do_self(u8 scancode)
{
    u8 *map;
    u8 ch;


    if (mode & 0x20) {        // alt 
        map = alt_map;
    } else if ((mode & 0x3)) {        // shift ^ caps  
        map = shift_map;
    } else {
        map = key_map;
    }

    ch = map[scancode & 0xff];
    if (ch == 0) {
        return;
    }

    if ((mode & 0x4c)) {
        //ctrl 或者caps
        if (((mode & 0x41) == 0x41) ||
            ((mode & 0x42) == 0x42) ||
            ((mode & 0x43) == 0x43)) {
            if ((ch <= 'Z' && ch >= 'A')) {
                //shift 和 caps 都起作用,则字母小写  
                ch += 0x20 ;
            }
        } else if ((ch <= 'z' && ch >= 'a')) {
            //如果只有 caps 都起作用,则字母大写  
            ch -= 0x20 ;
        } 

        if (mode & 0xc) {
            //如果按下ctrl,则加上ctrl标志
            ch -= 0x40;
        }
    }
    if (mode & 0x10) {
        //如果按下alt,则加上alt标志
        ch |= 0x80 ;
    } 

    ch &= 0xff;
    put_queue(ch);

    return;
}
Beispiel #21
0
int main(int argc, char **argv)
{
	init_chain_queue( &head, 100 );

	pthread_t tid;
	pthread_create( &tid, NULL, execute, NULL );

	char buf[100];
	while( 1 ) {
		gets( buf );
		pthread_mutex_lock( &mutex );
		put_queue( &head, buf );
		pthread_mutex_unlock( &mutex );
	}		

}
Beispiel #22
0
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);
}
Beispiel #23
0
unsigned char handle_diacr(unsigned char ch)
{
	int d = diacr;
	int i;

	diacr = 0;
	if (ch == ' ')
		return d;

	for (i = 0; i < accent_table_size; i++) {
		if (accent_table[i].diacr == d && accent_table[i].base == ch)
			return accent_table[i].result;
	}

	put_queue(d);
	return ch;
}
Beispiel #24
0
static void sunkbd_event(void *opaque, int ch)
{
    ChannelState *s = opaque;
    int release = ch & 0x80;

    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
                "press");
    switch (ch) {
    case 58: // Caps lock press
        s->caps_lock_mode ^= 1;
        if (s->caps_lock_mode == 2)
            return; // Drop second press
        break;
    case 69: // Num lock press
        s->num_lock_mode ^= 1;
        if (s->num_lock_mode == 2)
            return; // Drop second press
        break;
    case 186: // Caps lock release
        s->caps_lock_mode ^= 2;
        if (s->caps_lock_mode == 3)
            return; // Drop first release
        break;
    case 197: // Num lock release
        s->num_lock_mode ^= 2;
        if (s->num_lock_mode == 3)
            return; // Drop first release
        break;
    case 0xe0:
        s->e0_mode = 1;
        return;
    default:
        break;
    }
    if (s->e0_mode) {
        s->e0_mode = 0;
        ch = e0_keycodes[ch & 0x7f];
    } else {
        ch = keycodes[ch & 0x7f];
    }
    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
    put_queue(s, ch | release);
}
Beispiel #25
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
}
Beispiel #26
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 */
}
Beispiel #27
0
static void enter(void)
{
	put_queue(13);
	if (vc_kbd_mode(kbd,VC_CRLF))
		put_queue(10);
}
Beispiel #28
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);
}