Example #1
0
int
lk_add_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index, int keycode)
{
	struct lk_array *map;
	unsigned int code = keycode + 1;

	if (keycode == CODE_FOR_UNKNOWN_KSYM) {
		/* is safer not to be silent in this case, 
		 * it can be caused by coding errors as well. */
		ERR(ctx, _("lk_add_key called with bad keycode %d"), keycode);
		return -1;
	}

	if (!k_index && keycode == K_NOSUCHMAP)
		return 0;

	map = lk_array_get_ptr(ctx->keymap, k_table);
	if (!map) {
		if (ctx->keywords & LK_KEYWORD_KEYMAPS) {
			ERR(ctx, _("adding map %d violates explicit keymaps line"),
			    k_table);
			return -1;
		}

		if (lk_add_map(ctx, k_table) < 0)
			return -1;
	}

	if ((ctx->keywords & LK_KEYWORD_ALTISMETA) && keycode == K_HOLE &&
	    lk_key_exists(ctx, k_table, k_index))
		return 0;

	map = lk_array_get_ptr(ctx->keymap, k_table);

	if (lk_array_set(map, k_index, &code) < 0) {
		ERR(ctx, _("unable to set key %d for table %d"),
			k_index, k_table);
		return -1;
	}

	if (ctx->keywords & LK_KEYWORD_ALTISMETA) {
		unsigned int alttable = k_table | M_ALT;
		int type = KTYP(keycode);
		int val = KVAL(keycode);

		if (alttable != k_table && lk_map_exists(ctx, alttable) &&
		    !lk_key_exists(ctx, alttable, k_index) &&
		    (type == KT_LATIN || type == KT_LETTER) &&
		    val < 128) {
			if (lk_add_key(ctx, alttable, k_index, K(KT_META, val)) < 0)
				return -1;
		}
	}

	return 0;
}
Example #2
0
static DFBInputDeviceKeyIdentifier
keyboard_get_identifier( int code, unsigned short value )
{
     unsigned char type  = KTYP(value);
     unsigned char index = KVAL(value);

     if (type == KT_PAD) {
          if (index <= 9)
               return DIKI_KP_0 + index;

          switch (value) {
               case K_PSLASH: return DIKI_KP_DIV;
               case K_PSTAR:  return DIKI_KP_MULT;
               case K_PMINUS: return DIKI_KP_MINUS;
               case K_PPLUS:  return DIKI_KP_PLUS;
               case K_PENTER: return DIKI_KP_ENTER;
               case K_PCOMMA:
               case K_PDOT:   return DIKI_KP_DECIMAL;
          }
     }

     /* Looks like a hack, but don't know a better way yet. */
     switch (code) {
          case 12: return DIKI_MINUS_SIGN;
          case 13: return DIKI_EQUALS_SIGN;
          case 26: return DIKI_BRACKET_LEFT;
          case 27: return DIKI_BRACKET_RIGHT;
          case 39: return DIKI_SEMICOLON;
          case 40: return DIKI_QUOTE_RIGHT;
          case 41: return DIKI_QUOTE_LEFT;
          case 43: return DIKI_BACKSLASH;
          case 51: return DIKI_COMMA;
          case 52: return DIKI_PERIOD;
          case 53: return DIKI_SLASH;
          case 54: return DIKI_SHIFT_R;
          case 97: return DIKI_CONTROL_R;
          case 100: return DIKI_ALT_R;
          default:
               ;
     }

     /* special keys not in the map, hack? */
     if (code == 124)         /* keypad equal key */
          return DIKI_KP_EQUAL;

     if (code == 125)         /* left windows key */
          return DIKI_META_L;

     if (code == 126)         /* right windows key */
          return DIKI_META_R;

     if (code == 127)         /* context menu key */
          return DIKI_SUPER_R;

     return DIKI_UNKNOWN;
}
Example #3
0
/*
 * Fetch one entry from the kernel keymap.
 */
static DFBResult
driver_get_keymap_entry( CoreInputDevice               *device,
                         void                      *driver_data,
                         DFBInputDeviceKeymapEntry *entry )
{
    int                         code = entry->code;
    unsigned short              value;
    DFBInputDeviceKeyIdentifier identifier;

    /* fetch the base level */
    value = keyboard_read_value( driver_data, K_NORMTAB, code );

    /* get the identifier for basic mapping */
    identifier = keyboard_get_identifier( code, value );

    /* is CapsLock effective? */
    if (KTYP(value) == KT_LETTER)
        entry->locks |= DILS_CAPS;

    /* is NumLock effective? */
    if (identifier >= DIKI_KP_DECIMAL && identifier <= DIKI_KP_9)
        entry->locks |= DILS_NUM;

    /* write identifier to entry */
    entry->identifier = identifier;

    /* write base level symbol to entry */
    entry->symbols[DIKSI_BASE] = keyboard_get_symbol( code, value, DIKSI_BASE );


    /* fetch the shifted base level */
    value = keyboard_read_value( driver_data, K_SHIFTTAB, entry->code );

    /* write shifted base level symbol to entry */
    entry->symbols[DIKSI_BASE_SHIFT] = keyboard_get_symbol( code, value,
                                       DIKSI_BASE_SHIFT );


    /* fetch the alternative level */
    value = keyboard_read_value( driver_data, K_ALTTAB, entry->code );

    /* write alternative level symbol to entry */
    entry->symbols[DIKSI_ALT] = keyboard_get_symbol( code, value, DIKSI_ALT );


    /* fetch the shifted alternative level */
    value = keyboard_read_value( driver_data, K_ALTSHIFTTAB, entry->code );

    /* write shifted alternative level symbol to entry */
    entry->symbols[DIKSI_ALT_SHIFT] = keyboard_get_symbol( code, value,
                                      DIKSI_ALT_SHIFT );

    return DFB_OK;
}
Example #4
0
/*
 * Generate ascii -> ebcdic translation table from kbd_data.
 */
void
kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
{
	unsigned short *keymap, keysym;
	int i, j, k;

	memset(ascebc, 0x40, 256);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		keymap = kbd->key_maps[i];
		if (!keymap)
			continue;
		for (j = 0; j < NR_KEYS; j++) {
			k = ((i & 1) << 7) + j;
			keysym = keymap[j];
			if (KTYP(keysym) == (KT_LATIN | 0xf0) ||
			    KTYP(keysym) == (KT_LETTER | 0xf0))
				ascebc[KVAL(keysym)] = k;
			else if (KTYP(keysym) == (KT_DEAD | 0xf0))
				ascebc[ret_diacr[KVAL(keysym)]] = k;
		}
	}
}
Example #5
0
/*
 * Generate ebcdic -> ascii translation table from kbd_data.
 */
void
kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
{
	unsigned short *keymap, keysym;
	int i, j, k;

	memset(ebcasc, ' ', 256);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		keymap = kbd->key_maps[i];
		if (!keymap)
			continue;
		for (j = 0; j < NR_KEYS; j++) {
			keysym = keymap[j];
			k = ((i & 1) << 7) + j;
			if (KTYP(keysym) == (KT_LATIN | 0xf0) ||
			    KTYP(keysym) == (KT_LETTER | 0xf0))
				ebcasc[k] = KVAL(keysym);
			else if (KTYP(keysym) == (KT_DEAD | 0xf0))
				ebcasc[k] = ret_diacr[KVAL(keysym)];
		}
	}
}
Example #6
0
static int
do_constant_key(struct lk_ctx *ctx, int i, unsigned short key)
{
	int typ, val;
	unsigned int j;

	typ = KTYP(key);
	val = KVAL(key);

	if ((typ == KT_LATIN || typ == KT_LETTER) &&
	    ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'))) {
		unsigned short defs[16];
		defs[0] = K(KT_LETTER, val);
		defs[1] = K(KT_LETTER, val ^ 32);
		defs[2] = defs[0];
		defs[3] = defs[1];

		for (j = 4; j < 8; j++)
			defs[j] = K(KT_LATIN, val & ~96);

		for (j = 8; j < 16; j++)
			defs[j] = K(KT_META, KVAL(defs[j - 8]));

		for (j = 0; j < ctx->keymap->total; j++) {
			if (!lk_map_exists(ctx, j))
				continue;

			if (j > 0 && lk_key_exists(ctx, j, i))
				continue;

			if (lk_add_key(ctx, j, i, defs[j % 16]) < 0)
				return -1;
		}

	} else {
		/* do this also for keys like Escape,
		   as promised in the man page */
		for (j = 1; j < ctx->keymap->total; j++) {
			if (!lk_map_exists(ctx, j))
				continue;

			if (lk_key_exists(ctx, j, i))
				continue;

			if (lk_add_key(ctx, j, i, key) < 0)
				return -1;
		}
	}
	return 0;
}
Example #7
0
dword TranslateUnicode(dword keycode)
{
	int m = 0;

	if(modkeys & KMOD_SHIFT) m |= (1<<KG_SHIFT);
	if(modkeys & KMOD_CTRL) m |= (1<<KG_CTRL);
	if(modkeys & KMOD_LALT) m |= (1<<KG_ALT);
	if(modkeys & KMOD_RALT) m |= (1<<KG_ALTGR);

	//CAPS changes shift meaning in both directions
	if((modkeys & KMOD_CAPS) 
		&& KTYP(kmap[m][keycode]) == KT_LETTER
	)
		m ^= (1<<KG_SHIFT);

	//num pad handling stays same so far
	if((modkeys & KMOD_NUM)
		&& KTYP(kmap[m][keycode]) == KT_PAD
	)
		return KVAL(kmap[m][keycode]);
	else
		return KVAL(kmap[m][keycode]);
}
Example #8
0
File: kbd.c Project: kisom/pmon
void handle_scancode(unsigned char scancode, int down)
{
	unsigned char keycode;
	char up_flag = down ? 0 : 0200;

	/*
	 *  Convert scancode to keycode
	 */
	if (!kbd_translate(scancode, &keycode))
		goto out;

	/*
	 *  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 (1) {
		u_short keysym;
		u_char type;
		
		ushort *key_map = key_maps[shift_state];
		if (key_map != NULL) {
			keysym = key_map[keycode];
			type = KTYP(keysym);
	//		printf("keycode = %d\n",keycode);
	//		printf("[kbd] keysym %x\n", keysym);

			if (type >= 0xf0) {
				type -= 0xf0;
				if (type == KT_LETTER) {
					type = KT_LATIN;
				}
				if (*key_handler[type]) {
					(*key_handler[type]) (keysym & 0xff,
							      up_flag);
				}
			}
		}
	}
      out:;
}
Example #9
0
/* called after returning from RAW mode or when changing consoles -
   recompute k_down[] and shift_state from key_down[] */
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<<5);
	    for(j=0; j<32; j++,k++)
	      if(test_bit(k, key_down)) {
		sym = key_map[0][k];
		if(KTYP(sym) == KT_SHIFT) {
		  val = KVAL(sym);
		  k_down[val]++;
		  shift_state |= (1<<val);
		}
	      }
	  }
}
Example #10
0
unsigned short keypad_keysym_redirect(unsigned short keysym)
{
	if (applic_keypad || KTYP(keysym) != KT_PAD || KVAL(keysym) >= NR_PAD) return keysym;

	#define KL(val) K(KT_LATIN, val)
	static const unsigned short num_map[] = {
		KL('0'), KL('1'), KL('2'), KL('3'), KL('4'),
		KL('5'), KL('6'), KL('7'), KL('8'), KL('9'),
		KL('+'), KL('-'), KL('*'), KL('/'), K_ENTER,
		KL(','), KL('.'), KL('?'), KL('('), KL(')'),
		KL('#')
	};

	static const unsigned short fn_map[] = {
		K_INSERT, K_SELECT, K_DOWN, K_PGDN, K_LEFT,
		K_P5, K_RIGHT, K_FIND, K_UP, K_PGUP,
		KL('+'), KL('-'), KL('*'), KL('/'), K_ENTER,
		K_REMOVE, K_REMOVE, KL('?'), KL('('), KL(')'),
		KL('#')
	};

	if (lock_state & K_NUMLOCK) return num_map[keysym - K_P0];
	return fn_map[keysym - K_P0];
}
Example #11
0
/* maybe called when keymap is undefined, so that shiftkey release is seen */
void sun_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(plain_map[k]);
		if(KTYP(sym) == KT_SHIFT) {
		  val = KVAL(sym);
		  if (val == KVAL(K_CAPSSHIFT))
		    val = KVAL(K_SHIFT);
		  k_down[val]++;
		  shift_state |= (1<<val);
		}
	      }
	  }
}
Example #12
0
MMSKeySymbol MMSInputLISThread::getSymbol(int code, unsigned short value) {
	unsigned char type  = KTYP(value);
	unsigned char index = KVAL(value);

	TRACEOUT("MMSINPUT", "KEYCODE: TYPE=%d(0x%x), INDEX=%d(0x%x), value=%d(0x%x)", type, type, index, index, value, value);

	switch (type) {
		case KT_FN:
            if (index < 12)
         	   return (MMSKeySymbol)(MMSKEY_F1 + index);
			break;
		case KT_LETTER:
		case KT_LATIN:
			switch (index) {
			case 0x1c: return MMSKEY_PRINT;
			case 0x7f: return MMSKEY_BACKSPACE;
			case 0x08: return MMSKEY_BACKSPACE;
			case 0x09: return MMSKEY_TAB;
			case 0x0d: return MMSKEY_RETURN;
			case 0x18: return MMSKEY_CANCEL;
			case 0x1b: return MMSKEY_ESCAPE;
			case 0x20: return MMSKEY_SPACE;
			case 0x21: return MMSKEY_EXCLAMATION_MARK;
			case 0x22: return MMSKEY_QUOTATION;
			case 0x23: return MMSKEY_NUMBER_SIGN;
			case 0x24: return MMSKEY_DOLLAR_SIGN;
			case 0x25: return MMSKEY_PERCENT_SIGN;
			case 0x26: return MMSKEY_AMPERSAND;
			case 0x27: return MMSKEY_APOSTROPHE;
			case 0x28: return MMSKEY_PARENTHESIS_LEFT;
			case 0x29: return MMSKEY_PARENTHESIS_RIGHT;
			case 0x2a: return MMSKEY_ASTERISK;
			case 0x2b: return MMSKEY_PLUS_SIGN;
			case 0x2c: return MMSKEY_COMMA;
			case 0x2d: return MMSKEY_MINUS_SIGN;
			case 0x2e: return MMSKEY_PERIOD;
			case 0x2f: return MMSKEY_SLASH;
			case 0x30: return MMSKEY_0;
			case 0x31: return MMSKEY_1;
			case 0x32: return MMSKEY_2;
			case 0x33: return MMSKEY_3;
			case 0x34: return MMSKEY_4;
			case 0x35: return MMSKEY_5;
			case 0x36: return MMSKEY_6;
			case 0x37: return MMSKEY_7;
			case 0x38: return MMSKEY_8;
			case 0x39: return MMSKEY_9;
			case 0x3a: return MMSKEY_COLON;
			case 0x3b: return MMSKEY_SEMICOLON;
			case 0x3c: return MMSKEY_LESS_THAN_SIGN;
			case 0x3d: return MMSKEY_EQUALS_SIGN;
			case 0x3e: return MMSKEY_GREATER_THAN_SIGN;
			case 0x3f: return MMSKEY_QUESTION_MARK;
			case 0x40: return MMSKEY_AT;
			case 0x41: return MMSKEY_CAPITAL_A;
			case 0x42: return MMSKEY_CAPITAL_B;
			case 0x43: return MMSKEY_CAPITAL_C;
			case 0x44: return MMSKEY_CAPITAL_D;
			case 0x45: return MMSKEY_CAPITAL_E;
			case 0x46: return MMSKEY_CAPITAL_F;
			case 0x47: return MMSKEY_CAPITAL_G;
			case 0x48: return MMSKEY_CAPITAL_H;
			case 0x49: return MMSKEY_CAPITAL_I;
			case 0x4a: return MMSKEY_CAPITAL_J;
			case 0x4b: return MMSKEY_CAPITAL_K;
			case 0x4c: return MMSKEY_CAPITAL_L;
			case 0x4d: return MMSKEY_CAPITAL_M;
			case 0x4e: return MMSKEY_CAPITAL_N;
			case 0x4f: return MMSKEY_CAPITAL_O;
			case 0x50: return MMSKEY_CAPITAL_P;
			case 0x51: return MMSKEY_CAPITAL_Q;
			case 0x52: return MMSKEY_CAPITAL_R;
			case 0x53: return MMSKEY_CAPITAL_S;
			case 0x54: return MMSKEY_CAPITAL_T;
			case 0x55: return MMSKEY_CAPITAL_U;
			case 0x56: return MMSKEY_CAPITAL_V;
			case 0x57: return MMSKEY_CAPITAL_W;
			case 0x58: return MMSKEY_CAPITAL_X;
			case 0x59: return MMSKEY_CAPITAL_Y;
			case 0x5a: return MMSKEY_CAPITAL_Z;
			case 0x5b: return MMSKEY_SQUARE_BRACKET_LEFT;
			case 0x5c: return MMSKEY_BACKSLASH;
			case 0x5d: return MMSKEY_SQUARE_BRACKET_RIGHT;
			case 0x5e: return MMSKEY_CIRCUMFLEX_ACCENT;
			case 0x5f: return MMSKEY_UNDERSCORE;
			case 0x60: return MMSKEY_GRAVE_ACCENT;
			case 0x61: return MMSKEY_SMALL_A;
			case 0x62: return MMSKEY_SMALL_B;
			case 0x63: return MMSKEY_SMALL_C;
			case 0x64: return MMSKEY_SMALL_D;
			case 0x65: return MMSKEY_SMALL_E;
			case 0x66: return MMSKEY_SMALL_F;
			case 0x67: return MMSKEY_SMALL_G;
			case 0x68: return MMSKEY_SMALL_H;
			case 0x69: return MMSKEY_SMALL_I;
			case 0x6a: return MMSKEY_SMALL_J;
			case 0x6b: return MMSKEY_SMALL_K;
			case 0x6c: return MMSKEY_SMALL_L;
			case 0x6d: return MMSKEY_SMALL_M;
			case 0x6e: return MMSKEY_SMALL_N;
			case 0x6f: return MMSKEY_SMALL_O;
			case 0x70: return MMSKEY_SMALL_P;
			case 0x71: return MMSKEY_SMALL_Q;
			case 0x72: return MMSKEY_SMALL_R;
			case 0x73: return MMSKEY_SMALL_S;
			case 0x74: return MMSKEY_SMALL_T;
			case 0x75: return MMSKEY_SMALL_U;
			case 0x76: return MMSKEY_SMALL_V;
			case 0x77: return MMSKEY_SMALL_W;
			case 0x78: return MMSKEY_SMALL_X;
			case 0x79: return MMSKEY_SMALL_Y;
			case 0x7a: return MMSKEY_SMALL_Z;
			case 0x7b: return MMSKEY_CURLY_BRACKET_LEFT;
			case 0x7c: return MMSKEY_VERTICAL_BAR;
			case 0x7d: return MMSKEY_CURLY_BRACKET_RIGHT;
			case 0x7e: return MMSKEY_TILDE;
			default:   return MMSKEY_UNKNOWN;
			}
			break;
		case KT_PAD:
			switch (value) {
			case K_P0:      return MMSKEY_0;
			case K_P1:      return MMSKEY_1;
			case K_P2:      return MMSKEY_2;
			case K_P3:      return MMSKEY_3;
			case K_P4:      return MMSKEY_4;
			case K_P5:      return MMSKEY_5;
			case K_P6:      return MMSKEY_6;
			case K_P7:      return MMSKEY_7;
			case K_P8:      return MMSKEY_8;
			case K_P9:      return MMSKEY_9;
			case K_PPLUS:   return MMSKEY_PLUS_SIGN;
			case K_PMINUS:  return MMSKEY_MINUS_SIGN;
			case K_PSTAR:   return MMSKEY_ASTERISK;
			case K_PSLASH:  return MMSKEY_SLASH;
			case K_PENTER:  return MMSKEY_RETURN;
			case K_PCOMMA:  return MMSKEY_COMMA;
			case K_PDOT:    return MMSKEY_PERIOD;
			case K_PPARENL: return MMSKEY_PARENTHESIS_LEFT;
			case K_PPARENR: return MMSKEY_PARENTHESIS_RIGHT;
			default:   return MMSKEY_UNKNOWN;
			}
			break;
	}

	switch (value) {
		case K_LEFT:    return MMSKEY_CURSOR_LEFT;
		case K_RIGHT:   return MMSKEY_CURSOR_RIGHT;
		case K_UP:      return MMSKEY_CURSOR_UP;
		case K_DOWN:    return MMSKEY_CURSOR_DOWN;
		case K_ENTER:   return MMSKEY_RETURN;
		case K_CTRL:    return MMSKEY_CONTROL;
		case K_SHIFT:   return MMSKEY_SHIFT;
		case K_ALT:     return MMSKEY_ALT;
		case K_ALTGR:   return MMSKEY_ALTGR;
		case K_INSERT:  return MMSKEY_INSERT;
		case K_REMOVE:  return MMSKEY_DELETE;
		case K_FIND:    return MMSKEY_HOME;
		case K_SELECT:  return MMSKEY_END;
		case K_PGUP:    return MMSKEY_PAGE_UP;
		case K_PGDN:    return MMSKEY_PAGE_DOWN;
		case K_NUM:     return MMSKEY_NUM_LOCK;
		case K_HOLD:    return MMSKEY_SCROLL_LOCK;
		case K_PAUSE:   return MMSKEY_PAUSE;
		case K_BREAK:   return MMSKEY_BREAK;
		case K_CAPS:    return MMSKEY_CAPS_LOCK;
		case K_P0:      return MMSKEY_INSERT;
		case K_P1:      return MMSKEY_END;
		case K_P2:      return MMSKEY_CURSOR_DOWN;
		case K_P3:      return MMSKEY_PAGE_DOWN;
		case K_P4:      return MMSKEY_CURSOR_LEFT;
		case K_P5:      return MMSKEY_BEGIN;
		case K_P6:      return MMSKEY_CURSOR_RIGHT;
		case K_P7:      return MMSKEY_HOME;
		case K_P8:      return MMSKEY_CURSOR_UP;
		case K_P9:      return MMSKEY_PAGE_UP;
		case K_PPLUS:   return MMSKEY_PLUS_SIGN;
		case K_PMINUS:  return MMSKEY_MINUS_SIGN;
		case K_PSTAR:   return MMSKEY_ASTERISK;
		case K_PSLASH:  return MMSKEY_SLASH;
		case K_PENTER:  return MMSKEY_RETURN;
		case K_PCOMMA:  return MMSKEY_COMMA;
		case K_PDOT:    return MMSKEY_PERIOD;
		case K_PPARENL: return MMSKEY_PARENTHESIS_LEFT;
		case K_PPARENR: return MMSKEY_PARENTHESIS_RIGHT;
    }

	return MMSKEY_UNKNOWN;
}
Example #13
0
static uint8_t process_keyboard(inode_t* inode, struct tty_context* tio, int fd, int* pos) {
    keyboard_t k;
    if(sys_read(fd, &k, sizeof(keyboard_t)) == 0) {
        errno = EIO;
        return 0;
    }


    switch(k.vkey) {
        case KEY_LEFTALT:
            tty_keys = !!(k.down) ? tty_keys | K_ALT : tty_keys & ~K_ALT;
            return 0;
        case KEY_RIGHTALT:
            tty_keys = !!(k.down) ? tty_keys | K_ALTGR : tty_keys & ~K_ALTGR;
            return 0;
        case KEY_LEFTSHIFT:
        case KEY_RIGHTSHIFT:
            tty_keys = !!(k.down) ? tty_keys | K_SHIFT : tty_keys & ~K_SHIFT;
            return 0;
        case KEY_LEFTCTRL:
        case KEY_RIGHTCTRL:
            tty_keys = !!(k.down) ? tty_keys | K_CTRL : tty_keys & ~K_CTRL;
            return 0;
        case KEY_CAPSLOCK:
            tty_capslock = !(k.down) ? tty_capslock : !tty_capslock;
            return 0;
        default:
            break;
    }

    if(!k.down)
        return 0;


    int16_t key;
    uint8_t ch;

    switch(tty_keys) {
        #define _(x, y)    \
            case x : { key = tty_keymap.y[k.vkey] & 0x0FFF; break; }

        _(0, plain);
        _(K_SHIFT, shift);
        _(K_ALTGR, altgr);
        _(K_SHIFT | K_ALTGR, shift_altgr);
        _(K_CTRL, ctrl);
        _(K_SHIFT | K_CTRL, shift_ctrl);
        _(K_ALTGR | K_CTRL, altgr_ctrl);
        _(K_ALTGR | K_SHIFT | K_CTRL, altgr_shift_ctrl);
        _(K_ALT, alt);
        _(K_SHIFT | K_ALT, shift_alt);
        _(K_ALTGR | K_ALT, altgr_alt);
        _(K_ALTGR | K_SHIFT | K_ALT, altgr_shift_alt);
        _(K_CTRL | K_ALT, ctrl_alt);
        _(K_SHIFT | K_CTRL | K_ALT, shift_ctrl_alt);
        _(K_ALTGR | K_CTRL | K_ALT, altgr_ctrl_alt);
        _(K_ALTGR | K_SHIFT | K_CTRL | K_ALT, altgr_shift_ctrl_alt);
        
        default:
            key = 0;
            break;

        #undef _
    }



    ch = KVAL(key);
    switch(KTYP(key)) {
        case KT_LATIN:
        case KT_LETTER:
            if(tty_capslock) {
                if(tty_keys & K_SHIFT)
                    ch += ch >= 'A' && ch <= 'z' ? 32 : 0;
                else
                    ch -= ch >= 'a' && ch <= 'Z' ? 32 : 0;
            }
        case KT_ASCII:
            break;

        case KT_SPEC:
        case KT_PAD:
            if(!__kmap[KTYP(key)] || !__kmap[KTYP(key)][KVAL(key)])
                return 0;

            ch = __kmap[KTYP(key)][KVAL(key)][0];
            break;

        default:
            if(!__kmap[KTYP(key)] || !__kmap[KTYP(key)][KVAL(key)])
                return 0;


            fifo_write(&tio->in, __kmap[KTYP(key)][KVAL(key)], strlen(__kmap[KTYP(key)][KVAL(key)]));
            *pos = *pos + strlen(__kmap[KTYP(key)][KVAL(key)]);

            if(tio->ios.c_lflag & ECHO)
                tty_output_write(inode, __kmap[KTYP(key)][KVAL(key)], 0, strlen(__kmap[KTYP(key)][KVAL(key)]));

            return 0;
    }

    return ch;
}
Example #14
0
static void
readKernelMapping(KeySymsPtr pKeySyms, CARD8 *pModMap)
{
  KeySym        *k;
  int           i;
  static unsigned char tbl[GLYPHS_PER_KEY] =
  {
	0,	/* unshifted */
	1,	/* shifted */
	0,	/* modeswitch unshifted */
	0	/* modeswitch shifted */
  };

  /*
   * Read the mapping from the kernel.
   * Since we're still using the XFree86 scancode->AT keycode mapping
   * routines, we need to convert the AT keycodes to Linux keycodes,
   * then translate the Linux keysyms into X keysyms.
   *
   * First, figure out which tables to use for the modeswitch columns
   * above, from the XF86Config fields.
   */
  if (xf86Info.specialKeyMap[K_INDEX_RIGHTCTL] == KM_MODESHIFT ||
      xf86Info.specialKeyMap[K_INDEX_RIGHTCTL] == KM_MODELOCK)
    tbl[2] = 4;	/* control */
  else if (xf86Info.specialKeyMap[K_INDEX_RIGHTALT] == KM_MODESHIFT ||
           xf86Info.specialKeyMap[K_INDEX_RIGHTALT] == KM_MODELOCK)
    tbl[2] = 2;	/* AltGr */
  else
    tbl[2] = 8;	/* alt */
  tbl[3] = tbl[2] | 1;

#ifndef ASSUME_CUSTOM_KEYCODES
  for (i = 0, k = map+GLYPHS_PER_KEY; i < NUM_AT2LNX; ++i)
#else /* !ASSUME_CUSTOM_KEYCODES */
  for (i = 0, k = map; i < NUM_AT2LNX; ++i)
#endif /* !ASSUME_CUSTOM_KEYCODES */
  {
    struct kbentry kbe;
    int j;

#ifndef ASSUME_CUSTOM_KEYCODES
    kbe.kb_index = at2lnx[i];
#else /* !ASSUME_CUSTOM_KEYCODES */
    kbe.kb_index = i;
#endif /* !ASSUME_CUSTOM_KEYCODES */

    for (j = 0; j < GLYPHS_PER_KEY; ++j, ++k)
    {
      unsigned short kval;

      *k = NoSymbol;

      kbe.kb_table = tbl[j];
      if (
#ifndef ASSUME_CUSTOM_KEYCODES
	  kbe.kb_index == 0 ||
#endif /* !ASSUME_CUSTOM_KEYCODES */
	  ioctl(xf86Info.consoleFd, KDGKBENT, &kbe))
	continue;

      kval = KVAL(kbe.kb_value);
      switch (KTYP(kbe.kb_value))
      {
      case KT_LATIN:
      case KT_LETTER:
	*k = linux_to_x[kval];
	break;

      case KT_FN:
	if (kval <= 19)
	  *k = XK_F1 + kval;
	else switch (kbe.kb_value)
	{
	case K_FIND:
	  *k = XK_Home; /* or XK_Find */
	  break;
	case K_INSERT:
	  *k = XK_Insert;
	  break;
	case K_REMOVE:
	  *k = XK_Delete;
	  break;
	case K_SELECT:
	  *k = XK_End; /* or XK_Select */
	  break;
	case K_PGUP:
	  *k = XK_Prior;
	  break;
	case K_PGDN:
	  *k = XK_Next;
	  break;
	case K_HELP:
	  *k = XK_Help;
	  break;
	case K_DO:
	  *k = XK_Execute;
	  break;
	case K_PAUSE:
	  *k = XK_Pause;
	  break;
	case K_MACRO:
	  *k = XK_Menu;
	  break;
	default:
	  break;
	}
	break;

      case KT_SPEC:
	switch (kbe.kb_value)
	{
	case K_ENTER:
	  *k = XK_Return;
	  break;
	case K_BREAK:
	  *k = XK_Break;
	  break;
	case K_CAPS:
	  *k = XK_Caps_Lock;
	  break;
	case K_NUM:
	  *k = XK_Num_Lock;
	  break;
	case K_HOLD:
	  *k = XK_Scroll_Lock;
	  break;
	case K_COMPOSE:
          *k = XK_Multi_key;
	  break;
	default:
	  break;
	}
	break;

      case KT_PAD:
	switch (kbe.kb_value)
	{
	case K_PPLUS:
	  *k = XK_KP_Add;
	  break;
	case K_PMINUS:
	  *k = XK_KP_Subtract;
	  break;
	case K_PSTAR:
	  *k = XK_KP_Multiply;
	  break;
	case K_PSLASH:
	  *k = XK_KP_Divide;
	  break;
	case K_PENTER:
	  *k = XK_KP_Enter;
	  break;
	case K_PCOMMA:
	  *k = XK_KP_Separator;
	  break;
	case K_PDOT:
	  *k = XK_KP_Decimal;
	  break;
	case K_PPLUSMINUS:
	  *k = XK_KP_Subtract;
	  break;
	default:
	  if (kval <= 9)
	    *k = XK_KP_0 + kval;
	  break;
	}
	break;

      /*
       * KT_DEAD keys are for accelerated diacritical creation.
       */
      case KT_DEAD:
	switch (kbe.kb_value)
	  {
	  case K_DGRAVE:
	    *k = XK_dead_grave;
	    break;
	  case K_DACUTE:
	    *k = XK_dead_acute;
	    break;
	  case K_DCIRCM:
	    *k = XK_dead_circumflex;
	    break;
	  case K_DTILDE:
	    *k = XK_dead_tilde;
	    break;
	  case K_DDIERE:
	    *k = XK_dead_diaeresis;
	    break;
	  }
	break;

      case KT_CUR:
	switch (kbe.kb_value)
	{
	case K_DOWN:
	  *k = XK_Down;
	  break;
	case K_LEFT:
	  *k = XK_Left;
	  break;
	case K_RIGHT:
	  *k = XK_Right;
	  break;
	case K_UP:
	  *k = XK_Up;
	  break;
	}
	break;

      case KT_SHIFT:
	switch (kbe.kb_value)
	{
	case K_ALTGR:
	  *k = XK_Alt_R;
	  break;
	case K_ALT:
	  *k = (kbe.kb_index == 0x64 ?
		XK_Alt_R : XK_Alt_L);
	  break;
	case K_CTRL:
	  *k = (kbe.kb_index == 0x61 ?
		XK_Control_R : XK_Control_L);
	  break;
        case K_CTRLL:
	  *k = XK_Control_L;
	  break;
        case K_CTRLR:
	  *k = XK_Control_R;
	  break;
	case K_SHIFT:
	  *k = (kbe.kb_index == 0x36 ?
		XK_Shift_R : XK_Shift_L);
	  break;
        case K_SHIFTL:
	  *k = XK_Shift_L;
	  break;
        case K_SHIFTR:
	  *k = XK_Shift_R;
	  break;
	default:
	  break;
	}
	break;

      /*
       * KT_ASCII keys accumulate a 3 digit decimal number that gets
       * emitted when the shift state changes. We can't emulate that.
       */
      case KT_ASCII:
	break;

      case KT_LOCK:
	if (kbe.kb_value == K_SHIFTLOCK)
	  *k = XK_Shift_Lock;
	break;

      default:
	break;
      }
    }

    if (k[-1] == k[-2]) k[-1] = NoSymbol;
    if (k[-2] == k[-3]) k[-2] = NoSymbol;
    if (k[-3] == k[-4]) k[-3] = NoSymbol;
    if (k[-4] == k[-2] && k[-3] == k[-1]) k[-2] = k[-1] = NoSymbol;
    if (k[-1] == k[-4] && k[-2] == k[-3] && k[-2] == NoSymbol) k[-1] =NoSymbol;
  }
#ifdef ASSUME_CUSTOM_KEYCODES
  /*
   * Find the Mapping for the special server functions
   */
  for (i = 0; i < NR_KEYS; ++i) {
    struct kbentry kbe;
    int special = 0;

    kbe.kb_index = i;
    kbe.kb_table = 0; /* Plain map */
    if (!ioctl(xf86Info.consoleFd, KDGKBENT, &kbe))
      switch (kbe.kb_value) {
	case K(KT_LATIN,0x7f):	/* This catches DEL too... But who cares? */
	  special = KEY_BackSpace;
	  break;
	case K_PMINUS:
	  special = KEY_KP_Minus;
	  break;
	case K_PPLUS:
	  special = KEY_KP_Plus;
	  break;
	case K_F1:
	  special = KEY_F1;
	  break;
	case K_F2:
	  special = KEY_F2;
	  break;
	case K_F3:
	  special = KEY_F3;
	  break;
	case K_F4:
	  special = KEY_F4;
	  break;
	case K_F5:
	  special = KEY_F5;
	  break;
	case K_F6:
	  special = KEY_F6;
	  break;
	case K_F7:
	  special = KEY_F7;
	  break;
	case K_F8:
	  special = KEY_F8;
	  break;
	case K_F9:
	  special = KEY_F9;
	  break;
	case K_F10:
	  special = KEY_F10;
	  break;
	case K_F11:
	  special = KEY_F11;
	  break;
	case K_F12:
	  special = KEY_F12;
	  break;
	case K_ALT:
	  special = KEY_Alt;
	  break;
	case K_ALTGR:
	  special = KEY_AltLang;
	  break;
	case K_CONS:
	  special = KEY_SysReqest;
	  break;
      }
    SpecialServerMap[i] = special;
  }
#endif /* ASSUME_CUSTOM_KEYCODES */
}
Example #15
0
static inline gii_event_mask
GII_keyboard_handle_data(gii_input *inp, int code)
{
	linkbd_priv *priv = LINKBD_PRIV(inp);
	gii_event ev;
	struct kbentry entry;
	int symval, labelval;
	gii_event_mask mask;

	_giiEventBlank(&ev, sizeof(gii_key_event));

	if (code & 0x80) {
		code &= 0x7f;
		ev.key.type = evKeyRelease;
		priv->keydown_buf[code] = 0;
	} else if (priv->keydown_buf[code] == 0) {
		ev.key.type = evKeyPress;
		priv->keydown_buf[code] = 1;

	} else {
		ev.key.type = evKeyRepeat;
	}
	ev.key.button = code;
	/* First update modifiers here so linkey.c can use the value */
	ev.key.modifiers = priv->modifiers;

	if (ev.key.type == evKeyRelease &&
	    GII_KTYP(priv->keydown_sym[code]) != GII_KT_MOD &&
	    priv->keydown_sym[code] != GIIK_VOID) {
		/* We can use the cached values */
		ev.key.sym   = priv->keydown_sym[code];
		ev.key.label = priv->keydown_label[code];
	} else {
		/* Temporarily switch back to the old mode because
		   unicodes aren't available through table lookup in MEDIUMRAW
		*/
		if (ioctl(priv->fd, KDSKBMODE, priv->old_mode) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n");
			return 0;
		}
		/* Look up the keysym without modifiers, which will give us
		 * the key label (more or less).
		 */
		entry.kb_table = 0;
		entry.kb_index = code;
		if (ioctl(priv->fd, KDGKBENT, &entry) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n");
			return 0;
		}
		labelval = entry.kb_value;
		if (priv->old_mode == K_UNICODE) labelval &= 0x0fff;

		/* Now look up the full keysym in the kernel's table */

		/* calculate kernel-like shift value */
		entry.kb_table =
		  ((priv->modifiers & GII_MOD_SHIFT) ? (1<<KG_SHIFT)     : 0) |
		  ((priv->modifiers & GII_MOD_CTRL)  ? (1<<KG_CTRL)      : 0) |
		  ((priv->modifiers & GII_MOD_ALT)   ? (1<<KG_ALT)       : 0) |
		  ((priv->modifiers & GII_MOD_ALTGR) ? (1<<KG_ALTGR)     : 0) |
		  ((priv->modifiers & GII_MOD_META)  ? (1<<KG_ALT)       : 0) |
		  ((priv->modifiers & GII_MOD_CAPS)  ? (1<<KG_CAPSSHIFT) : 0);

		entry.kb_index = code;
		if (ioctl(priv->fd, KDGKBENT, &entry) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n");
			return 0;
		}

		/* Switch back to MEDIUMRAW */
		if (ioctl(priv->fd, KDSKBMODE, K_MEDIUMRAW) < 0) {
			DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n");
			return 0;
		}

		switch (entry.kb_value) {

		case K_HOLE:
			DPRINT_EVENTS("Linux-kbd: NOSUCHKEY\n");
			break;

		case K_NOSUCHMAP:
			DPRINT_EVENTS("Linux-kbd: NOSUCHMAP\n");
			entry.kb_value = K_HOLE;
			break;
		}
		symval = entry.kb_value;
		if (priv->old_mode == K_UNICODE) symval &= 0x0fff;

		_gii_linkey_trans(code, labelval, symval, &ev.key);

		if (ev.key.type == evKeyPress) {
			if (priv->accent) {
				if (GII_KTYP(ev.key.sym) != GII_KT_MOD) {
					handle_accent(priv, symval, &ev);
				}
			} else if (KTYP(symval) == KT_DEAD) {
				priv->accent = GII_KVAL(ev.key.sym);
			}
		}
		if (GII_KTYP(ev.key.sym) == GII_KT_DEAD) {
			ev.key.sym = GIIK_VOID;
		}
	}

	/* Keep track of modifier state */
	if (GII_KTYP(ev.key.label) == GII_KT_MOD) {
		/* Modifers don't repeat */
		if (ev.key.type == evKeyRepeat) return 0;

		handle_modifier(priv, &ev);
	}
	/* Now update modifiers again to get the value _after_ the current
	   event */
	ev.key.modifiers = priv->modifiers;

	if (ev.any.type == evKeyPress) {
		priv->keydown_sym[code]    = ev.key.sym;
		priv->keydown_label[code]  = ev.key.label;
	}

	DPRINT_EVENTS("KEY-%s button=0x%02x modifiers=0x%02x "
		"sym=0x%04x label=0x%04x\n",
		(ev.key.type == evKeyRelease) ? "UP" :
		((ev.key.type == evKeyPress) ? "DN" : "RP"),
		ev.key.button, ev.key.modifiers,
		ev.key.sym,  ev.key.label);

	if (priv->call_vtswitch) {
		if (ev.key.label == GIIK_CtrlL && priv->needctrl2switch) {
			if (ev.key.type == evKeyRelease) {
				priv->ctrlstate = 0;
			} else if (ev.key.type == evKeyPress) {
				priv->ctrlstate = 1;
			}
		}
		/* Check for console switch.  Unfortunately, the kernel doesn't
		 * recognize KT_CONS when the keyboard is in RAW or MEDIUMRAW
		 * mode, so _we_ have to.  Sigh.
		 */
		if ((ev.key.type == evKeyPress) &&
		    (KTYP(entry.kb_value) == KT_CONS) && priv->ctrlstate) {
			int rc;
			int new_cons = 1+KVAL(entry.kb_value);

			/* Clear the keydown buffer, since we'll never know
			   what keys the user pressed (or released) while they
			   were away.
			 */
			DPRINT_MISC("Flushing all keys.\n");
			rc = GII_keyboard_flush_keys(inp);

			DPRINT_MISC("Switching to console %d.\n", new_cons);

			if (ioctl(priv->fd, VT_ACTIVATE, new_cons) < 0) {
				perror("ioctl(VT_ACTIVATE)");
			}

			return rc;
		}
	}

	mask = (1 << ev.any.type);

	if (! (inp->curreventmask & mask)) return 0;

	/* finally queue the key event */
	ev.any.size   = sizeof(gii_key_event);
	ev.any.origin = inp->origin;

	_giiEvQueueAdd(inp, &ev);

	return (1 << ev.any.type);
}
Example #16
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 */
}
Example #17
0
static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
  u_char acia_stat;
  int scancode;
  int break_flag;

  /* save frame for register dump */
  kbd_pt_regs = fp;

 repeat:
  if (acia.mid_ctrl & ACIA_IRQ)
	if (atari_MIDI_interrupt_hook)
		atari_MIDI_interrupt_hook();
  acia_stat = acia.key_ctrl;
  /* check out if the interrupt came from this ACIA */
  if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
	return;

    if (acia_stat & ACIA_OVRN)
    {
	/* a very fast typist or a slow system, give a warning */
	/* ...happens often if interrupts were disabled for too long */
	printk( KERN_DEBUG "Keyboard overrun\n" );
	scancode = acia.key_data;
	/* Turn off autorepeating in case a break code has been lost */
	del_timer( &atakeyb_rep_timer );
	rep_scancode = 0;
	if (ikbd_self_test)
	    /* During self test, don't do resyncing, just process the code */
	    goto interpret_scancode;
	else if (IS_SYNC_CODE(scancode)) {
	    /* This code seem already to be the start of a new packet or a
	     * single scancode */
	    kb_state.state = KEYBOARD;
	    goto interpret_scancode;
	}
	else {
	    /* Go to RESYNC state and skip this byte */
	    kb_state.state = RESYNC;
	    kb_state.len = 1; /* skip max. 1 another byte */
	    goto repeat;
	}
    }

    if (acia_stat & ACIA_RDRF)	/* received a character */
    {
	scancode = acia.key_data;	/* get it or reset the ACIA, I'll get it! */
	mark_bh(KEYBOARD_BH);
      interpret_scancode:
	switch (kb_state.state)
	{
	  case KEYBOARD:
	    switch (scancode)
	    {
	      case 0xF7:
		kb_state.state = AMOUSE;
		kb_state.len = 0;
		break;

	      case 0xF8:
	      case 0xF9:
     	      case 0xFA:
	      case 0xFB:
		kb_state.state = RMOUSE;
	    	kb_state.len = 1;
		kb_state.buf[0] = scancode;
		break;

	      case 0xFC:
		kb_state.state = CLOCK;
		kb_state.len = 0;
		break;

	      case 0xFE:
	      case 0xFF:
		kb_state.state = JOYSTICK;
		kb_state.len = 1;
		kb_state.buf[0] = scancode;
		break;

	      case 0xF1:
		/* during self-test, note that 0xf1 received */
		if (ikbd_self_test) {
		    ++ikbd_self_test;
		    self_test_last_rcv = jiffies;
		    break;
		}
		/* FALL THROUGH */
		
	      default:
		break_flag = scancode & BREAK_MASK;
		scancode &= ~BREAK_MASK;

		if (ikbd_self_test) {
		    /* Scancodes sent during the self-test stand for broken
		     * keys (keys being down). The code *should* be a break
		     * code, but nevertheless some AT keyboard interfaces send
		     * make codes instead. Therefore, simply ignore
		     * break_flag...
		     * */
		    int keyval = plain_map[scancode], keytyp;
		    
		    set_bit( scancode, broken_keys );
		    self_test_last_rcv = jiffies;
		    keyval = plain_map[scancode];
		    keytyp = KTYP(keyval) - 0xf0;
		    keyval = KVAL(keyval);

		    printk( KERN_WARNING "Key with scancode %d ", scancode );
		    if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
			if (keyval < ' ')
			    printk( "('^%c') ", keyval + '@' );
			else
			    printk( "('%c') ", keyval );
		    }
		    printk( "is broken -- will be ignored.\n" );
		    break;
		}
		else if (test_bit( scancode, broken_keys ))
		    break;

		if (break_flag) {
		    del_timer( &atakeyb_rep_timer );
		    rep_scancode = 0;
		}
		else {
		    del_timer( &atakeyb_rep_timer );
		    rep_scancode = scancode;
		    atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
		    atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
		    add_timer( &atakeyb_rep_timer );
		}

		handle_scancode(break_flag | scancode);
		break;
	    }
	    break;

	  case AMOUSE:
	    kb_state.buf[kb_state.len++] = scancode;
	    if (kb_state.len == 5)
	    {
		kb_state.state = KEYBOARD;
		/* not yet used */
		/* wake up someone waiting for this */
	    }
	    break;	

	  case RMOUSE:
	    kb_state.buf[kb_state.len++] = scancode;
	    if (kb_state.len == 3)
	    {
		kb_state.state = KEYBOARD;
		if (atari_mouse_interrupt_hook)
			atari_mouse_interrupt_hook(kb_state.buf);
	    }
	    break;

	  case JOYSTICK:
	    kb_state.buf[1] = scancode;
	    kb_state.state = KEYBOARD;
	    atari_joystick_interrupt(kb_state.buf);
	    break;

	  case CLOCK:
	    kb_state.buf[kb_state.len++] = scancode;
	    if (kb_state.len == 6)
	    {
		kb_state.state = KEYBOARD;
		/* wake up someone waiting for this.
		   But will this ever be used, as Linux keeps its own time.
		   Perhaps for synchronization purposes? */
		/* wake_up_interruptible(&clock_wait); */
	    }
	    break;

	  case RESYNC:
	    if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
		kb_state.state = KEYBOARD;
		goto interpret_scancode;
	    }
	    kb_state.len--;
	    break;
	}
    }

#if 0
    if (acia_stat & ACIA_CTS)
	/* cannot happen */;
#endif

    if (acia_stat & (ACIA_FE | ACIA_PE))
    {
	printk("Error in keyboard communication\n");
    }

    /* handle_scancode() can take a lot of time, so check again if
	 * some character arrived
	 */
    goto repeat;
}
Example #18
0
/* this logic is pulled from kbd_keycode() in drivers/tty/vt/keyboard.c in the
   Linux kernel source */
static void SDL_EVDEV_do_text_input(unsigned short keycode) {
    char shift_state;
    int locks_state;
    struct kbentry kbe;
    unsigned char type;
    char text[2] = { 0 };
    
    if (_this->console_fd < 0)
        return;
    
    shift_state = TIOCL_GETSHIFTSTATE;
    if (ioctl(_this->console_fd, TIOCLINUX, &shift_state) < 0) {
        /* TODO: error */
        return;
    }

    kbe.kb_table = shift_state;
    kbe.kb_index = keycode;
    
    if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) {
        /* TODO: error */
        return;
    }
    
    type = KTYP(kbe.kb_value);
    
    if (type < 0xf0) {
        /* 
         * FIXME: keysyms with a type below 0xf0 represent a unicode character
         * which requires special handling due to dead characters, diacritics,
         * etc. For perfect input a proper way to deal with such characters
         * should be implemented.
         *
         * For reference, the only place I was able to find out about this
         * special 0xf0 value was in an unused? couple of patches listed below.
         *
         * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-keyboard.diff
         * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-console.diff
         */
        
        return;
    }
    
    type -= 0xf0;
    
    /* if type is KT_LETTER then it can be affected by Caps Lock */
    if (type == KT_LETTER) {
        type = KT_LATIN;
    
        if (ioctl(_this->console_fd, KDGKBLED, &locks_state) < 0) {
            /* TODO: error */
            return;
        }
        
        if (locks_state & K_CAPSLOCK) {
            kbe.kb_table = shift_state ^ (1 << KG_SHIFT);
            
            if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) {
                /* TODO: error */
                return;
            }
        }
    }
    
    /* TODO: convert values >= 0x80 from ISO-8859-1? to UTF-8 */
    if (type != KT_LATIN || KVAL(kbe.kb_value) >= 0x80)
        return;
    
    *text = KVAL(kbe.kb_value);
    SDL_SendKeyboardText(text);
}
Example #19
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);
}
Example #20
0
int
scan_push(unsigned char scancode)
{
   unsigned char keycode;

   unsigned char raw_mode = 1;

   int down = !(scancode & 0x80);

   unsigned char up_flag = down ? 0 : 0200;

   unsigned short keysym;

   u_char type;

   int shift_final, shift_local = 0;

   unsigned short *key_map;

   if (!first_key)
   {
      first_key = 1;
      if (scancode & 0x80)
	 return 0;
   }

#ifdef DBG0
   printf("scan_push: %d\r\n", scancode);
#endif
   /*
    *  Convert scancode to keycode
    */
   if (!kbd_translate(scancode, &keycode))
      return 1;

#ifdef DBG0
   printf("translated: down=%d, keycode=%x\r\n", down, keycode);
#endif

   /*
    * At this point the variable `keycode' contains the keycode.
    * Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
    * We keep track of the up/down status of the key, and
    * return the keycode if in MEDIUMRAW mode.
    */

   if (up_flag)
   {
      if (!test_and_clear_bit(keycode, key_down))
      {
	 rep = 0;
	 up_flag = kbd_unexpected_up(keycode);
      }
   }
   else
      rep = test_and_set_bit(keycode, key_down);

#ifdef DBG1
   printf("up_flag=%d, rep=%d, shift_state=%d\r\n", up_flag, rep, shift_state);
#endif

   /*if (rep)
      return; */

   /* the XOR below used to be an OR */
   shift_final = shift_state ^ lockstate ^ slockstate;
   shift_local = (shift_final & (1 << KG_SHIFTL)) | (shift_final & (1 << KG_SHIFTR));
   key_map = key_maps[shift_final];
   if (shift_local == 0)
      shift_local = (1 << KG_SHIFT);
   if (key_map == NULL)
   {
      shift_final = shift_state ^ lockstate ^ slockstate;
      shift_final = shift_final ^ shift_local;
      shift_local = 0;
      key_map = key_maps[shift_final];
   }
   if (key_map != NULL)
   {
      keysym = key_map[keycode];
      type = KTYP(keysym);
#ifdef DBG2
      printf("\ntype=%x,shift_state=%d,shift_final=%d,keykode=%d,shift_local=%d\r\n", type, shift_state, shift_final, keycode, shift_local);
#endif

      if (type >= 0xf0)
      {
	 type -= 0xf0;
	 if (type == KT_LETTER)
	 {
	    type = KT_LATIN;
	    if (capslock_state)
	    {
	       shift_final = shift_final ^ shift_local;
	       key_map = key_maps[shift_final];
	       //key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
	       if (key_map)
		  keysym = key_map[keycode];
#ifdef DBG2
	       printf("  caps=%d,keykode=%d,keysym=%d,kg_shift=%d\r\n", shift_final, keycode, keysym, KG_SHIFT);
#endif
	    }
	 }
#ifdef DBG
	 printf("key_handler[%d] call: %s, keysym=0x%x, up_flag=0x%x\r\n", type, key_handler_names[type], keysym & 0xff, up_flag);
#endif
	 /*
	    printf("\nA keysym=%d,type=%d,%d",keysym,type,KT_SHIFT);
	  */
	 (*key_handler[type]) (keysym & 0xff, up_flag);
	 if (type != KT_SLOCK)
	    slockstate = 0;
      }
      else
      {
	 /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
	 if (!up_flag && !raw_mode)
	    to_utf8(keysym);
      }
   }
   else
   {
      /* maybe beep? */
      /* we have at least to update shift_state */
      key_map = key_maps[0];
      keysym = key_map[keycode];
      type = KTYP(keysym);
      /*
         printf("\nB keysym=%d,type=%d,%d",keysym,type,KT_SHIFT);
       */
      /*check CTRL,SHIFT,ALT keys status */
      if (keysym >= 63234 && keysym <= 63237)
	 (*key_handler[KT_SHIFT]) (keysym & 0xff, up_flag);
      else
	 compute_shiftstate();
   }
   return 1;
}
Example #21
0
/*
 * Check if the keyboard controller has a keypress for us.
 * Some parts (Enter Release, LED change) are still blocking polled here,
 * but hopefully they are all short.
 */
static int get_kbd_char(void)
{
	int scancode, scanstatus;
	static int shift_lock;	/* CAPS LOCK state (0-off, 1-on) */
	static int shift_key;	/* Shift next keypress */
	static int ctrl_key;
	u_short keychar;
	extern u_short plain_map[], shift_map[], ctrl_map[];

	if (KDB_FLAG(NO_I8042) || KDB_FLAG(NO_VT_CONSOLE) ||
	    (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff)) {
		kbd_exists = 0;
		return -1;
	}
	kbd_exists = 1;

	if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
		return -1;

	/*
	 * Fetch the scancode
	 */
	scancode = inb(KBD_DATA_REG);
	scanstatus = inb(KBD_STATUS_REG);

	/*
	 * Ignore mouse events.
	 */
	if (scanstatus & KBD_STAT_MOUSE_OBF)
		return -1;

	/*
	 * Ignore release, trigger on make
	 * (except for shift keys, where we want to
	 *  keep the shift state so long as the key is
	 *  held down).
	 */

	if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
		/*
		 * Next key may use shift table
		 */
		if ((scancode & 0x80) == 0) {
			shift_key=1;
		} else {
			shift_key=0;
		}
		return -1;
	}

	if ((scancode&0x7f) == 0x1d) {
		/*
		 * Left ctrl key
		 */
		if ((scancode & 0x80) == 0) {
			ctrl_key = 1;
		} else {
			ctrl_key = 0;
		}
		return -1;
	}

	if ((scancode & 0x80) != 0)
		return -1;

	scancode &= 0x7f;

	/*
	 * Translate scancode
	 */

	if (scancode == 0x3a) {
		/*
		 * Toggle caps lock
		 */
		shift_lock ^= 1;

#ifdef	KDB_BLINK_LED
		kdb_toggleled(0x4);
#endif
		return -1;
	}

	if (scancode == 0x0e) {
		/*
		 * Backspace
		 */
		return 8;
	}

	/* Special Key */
	switch (scancode) {
	case 0xF: /* Tab */
		return 9;
	case 0x53: /* Del */
		return 4;
	case 0x47: /* Home */
		return 1;
	case 0x4F: /* End */
		return 5;
	case 0x4B: /* Left */
		return 2;
	case 0x48: /* Up */
		return 16;
	case 0x50: /* Down */
		return 14;
	case 0x4D: /* Right */
		return 6;
	}

	if (scancode == 0xe0) {
		return -1;
	}

	/*
	 * For Japanese 86/106 keyboards
	 * 	See comment in drivers/char/pc_keyb.c.
	 * 	- Masahiro Adegawa
	 */
	if (scancode == 0x73) {
		scancode = 0x59;
	} else if (scancode == 0x7d) {
		scancode = 0x7c;
	}

	if (!shift_lock && !shift_key && !ctrl_key) {
		keychar = plain_map[scancode];
	} else if (shift_lock || shift_key) {
		keychar = shift_map[scancode];
	} else if (ctrl_key) {
		keychar = ctrl_map[scancode];
	} else {
		keychar = 0x0020;
		kdb_printf("Unknown state/scancode (%d)\n", scancode);
	}
	keychar &= 0x0fff;
	if (keychar == '\t')
		keychar = ' ';
	switch (KTYP(keychar)) {
	case KT_LETTER:
	case KT_LATIN:
		if (isprint(keychar))
			break;		/* printable characters */
		/* drop through */
	case KT_SPEC:
		if (keychar == K_ENTER)
			break;
		/* drop through */
	default:
		return(-1);	/* ignore unprintables */
	}

	if ((scancode & 0x7f) == 0x1c) {
		/*
		 * enter key.  All done.  Absorb the release scancode.
		 */
		while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
			;

		/*
		 * Fetch the scancode
		 */
		scancode = inb(KBD_DATA_REG);
		scanstatus = inb(KBD_STATUS_REG);

		while (scanstatus & KBD_STAT_MOUSE_OBF) {
			scancode = inb(KBD_DATA_REG);
			scanstatus = inb(KBD_STATUS_REG);
		}

		if (scancode != 0x9c) {
			/*
			 * Wasn't an enter-release,  why not?
			 */
			kdb_printf("kdb: expected enter got 0x%x status 0x%x\n",
			       scancode, scanstatus);
		}

		kdb_printf("\n");
		return 13;
	}

	return keychar & 0xff;
}
Example #22
0
/* keycode_to_char: [fdwatch thread]
 *  Helper function.
 *  KEYCODE is a Linux kernel keycode, not an Allegro keycode.
 *
 *  In the process of doing the translation, we may find that the user
 *  has pressed a key that for VT switching. In that case a negative
 *  number is returned, the absolute value of which is the VT to
 *  switch to. Yes, ugly.
 */
static int keycode_to_char(int keycode)
{
   const unsigned int modifiers = the_keyboard.modifiers;
   struct kbentry kbe;
   int keymap;
   int ascii;

   /* build kernel keymap number */
   keymap = 0;
   if (modifiers & ALLEGRO_KEYMOD_SHIFT) keymap |= 1;
   if (modifiers & ALLEGRO_KEYMOD_ALTGR) keymap |= 2;
   if (modifiers & ALLEGRO_KEYMOD_CTRL)  keymap |= 4;
   if (modifiers & ALLEGRO_KEYMOD_ALT)   keymap |= 8;

   /* map keycode to type and value */
   kbe.kb_table = keymap;
   kbe.kb_index = keycode;
   ioctl(the_keyboard.fd, KDGKBENT, &kbe);

   if (keycode == KEY_BACKSPACE)
      ascii = 8;
   else {
      if (kbe.kb_value == K_NOSUCHMAP) {
         /* invalid keymaps */
         /* FIXME: Maybe we should just redo the */
         /*        ioctl with keymap 0? */
         ascii = 0;
      }
      else {
         /* most keys come here */
         ascii = KVAL(kbe.kb_value);
      }
   }

   /* finally do some things based on key type */
   switch (KTYP(kbe.kb_value)) {

      case KT_CONS:
         /* VT switch key -- return a negative number */
         return -( KVAL(kbe.kb_value)+1 );

      case KT_LETTER:
         /* apply capslock translation. */
         if (modifiers & ALLEGRO_KEYMOD_CAPSLOCK)
            return ascii ^ 0x20;
         else
            return ascii;

      case KT_LATIN:
      case KT_ASCII:
         return ascii;

      case KT_PAD:
      {
         int val = KVAL(kbe.kb_value);
         if (modifiers & ALLEGRO_KEYMOD_NUMLOCK) {
            if ((val >= 0) && (val < NUM_PAD_KEYS))
               ascii = pad_asciis[val];
         } else {
            if ((val >= 0) && (val < NUM_PAD_KEYS))
               ascii = pad_asciis_no_numlock[val];
         }
         return ascii;
      }

      case KT_SPEC:
         if (keycode == KEY_ENTER)
            return '\r';
         else
            return 0;

      default:
         /* dunno */
         return 0;
   }
}
Example #23
0
static DFBInputDeviceKeySymbol
keyboard_get_symbol( int                             code,
                     unsigned short                  value,
                     DFBInputDeviceKeymapSymbolIndex level )
{
     unsigned char type  = KTYP(value);
     unsigned char index = KVAL(value);
     int           base  = (level == DIKSI_BASE);

     switch (type) {
          case KT_FN:
               if (index < 20)
                    return DFB_FUNCTION_KEY( index + 1 );
               break;
          case KT_LETTER:
          case KT_LATIN:
               switch (index) {
                    case 0x1c:
                         return DIKS_PRINT;
                    case 0x7f:
                         return DIKS_BACKSPACE;
                    case 0xa4:
                         return 0x20ac; /* euro currency sign */
                    default:
                         return index;
               }
               break;
          case KT_DEAD:
               switch (value) {
                    case K_DGRAVE:
                         return DIKS_DEAD_GRAVE;

                    case K_DACUTE:
                         return DIKS_DEAD_ACUTE;

                    case K_DCIRCM:
                         return DIKS_DEAD_CIRCUMFLEX;

                    case K_DTILDE:
                         return DIKS_DEAD_TILDE;

                    case K_DDIERE:
                         return DIKS_DEAD_DIAERESIS;

                    case K_DCEDIL:
                         return DIKS_DEAD_CEDILLA;

                    default:
                         break;
               }
               break;
          case KT_PAD:
               if (index <= 9 && level != DIKSI_BASE)
                    return DIKS_0 + index;
               break;
          case 0xe: /* special IPAQ H3600 case - AH */
               switch (index) {
                    case 0x20:     return DIKS_CALENDAR;
                    case 0x1a:     return DIKS_BACK;
                    case 0x1c:     return DIKS_MEMO;
                    case 0x21:     return DIKS_POWER;
               }
               break;
          case 0xd: /* another special IPAQ H3600 case - AH */
               switch (index) {
                    case 0x2:     return DIKS_DIRECTORY;
                    case 0x1:     return DIKS_MAIL;  /* Q on older iPaqs */
               }
               break;
     }

     switch (value) {
          case K_LEFT:    return DIKS_CURSOR_LEFT;
          case K_RIGHT:   return DIKS_CURSOR_RIGHT;
          case K_UP:      return DIKS_CURSOR_UP;
          case K_DOWN:    return DIKS_CURSOR_DOWN;
          case K_ENTER:   return DIKS_ENTER;
          case K_CTRL:    return DIKS_CONTROL;
          case K_SHIFT:   return DIKS_SHIFT;
          case K_ALT:     return DIKS_ALT;
          case K_ALTGR:   return DIKS_ALTGR;
          case K_INSERT:  return DIKS_INSERT;
          case K_REMOVE:  return DIKS_DELETE;
          case K_FIND:    return DIKS_HOME;
          case K_SELECT:  return DIKS_END;
          case K_PGUP:    return DIKS_PAGE_UP;
          case K_PGDN:    return DIKS_PAGE_DOWN;
          case K_NUM:     return DIKS_NUM_LOCK;
          case K_HOLD:    return DIKS_SCROLL_LOCK;
          case K_PAUSE:   return DIKS_PAUSE;
          case K_BREAK:   return DIKS_BREAK;
          case K_CAPS:    return DIKS_CAPS_LOCK;

          case K_P0:      return DIKS_INSERT;
          case K_P1:      return DIKS_END;
          case K_P2:      return DIKS_CURSOR_DOWN;
          case K_P3:      return DIKS_PAGE_DOWN;
          case K_P4:      return DIKS_CURSOR_LEFT;
          case K_P5:      return DIKS_BEGIN;
          case K_P6:      return DIKS_CURSOR_RIGHT;
          case K_P7:      return DIKS_HOME;
          case K_P8:      return DIKS_CURSOR_UP;
          case K_P9:      return DIKS_PAGE_UP;
          case K_PPLUS:   return DIKS_PLUS_SIGN;
          case K_PMINUS:  return DIKS_MINUS_SIGN;
          case K_PSTAR:   return DIKS_ASTERISK;
          case K_PSLASH:  return DIKS_SLASH;
          case K_PENTER:  return DIKS_ENTER;
          case K_PCOMMA:  return base ? DIKS_DELETE : DIKS_COMMA;
          case K_PDOT:    return base ? DIKS_DELETE : DIKS_PERIOD;
          case K_PPARENL: return DIKS_PARENTHESIS_LEFT;
          case K_PPARENR: return DIKS_PARENTHESIS_RIGHT;
     }

     /* special keys not in the map, hack? */
     if (code == 99)
          return DIKS_PRINT;

     if (code == 124)         /* keypad equal key */
          return DIKS_EQUALS_SIGN;

     if (code == 125)         /* left windows key */
          return DIKS_META;

     if (code == 126)         /* right windows key */
          return DIKS_META;

     if (code == 127)         /* context menu key */
          return DIKS_SUPER;

     return DIKS_NULL;
}
Example #24
0
static int keyboard_notifier_call(struct notifier_block *blk,
				  unsigned long code, void *_param)
{
	struct keyboard_notifier_param *param = _param;
	struct vc_data *vc = param->vc;
	int ret = NOTIFY_OK;

	if (!param->down)
		return ret;

	switch (code) {
	case KBD_KEYCODE:
		if (console_show) {
			if (param->value == BRAILLE_KEY) {
				console_show = 0;
				beep(880);
				vc_maybe_cursor_moved(vc);
				vc_refresh(vc);
				ret = NOTIFY_STOP;
			}
		} else {
			ret = NOTIFY_STOP;
			switch (param->value) {
			case KEY_INSERT:
				beep(440);
				console_show = 1;
				lastVC = -1;
				braille_write(console_buf);
				break;
			case KEY_LEFT:
				if (vc_x > 0) {
					vc_x -= WIDTH;
					if (vc_x < 0)
						vc_x = 0;
				} else if (vc_y >= 1) {
					beep(880);
					vc_y--;
					vc_x = vc->vc_cols-WIDTH;
				} else
					beep(220);
				break;
			case KEY_RIGHT:
				if (vc_x + WIDTH < vc->vc_cols) {
					vc_x += WIDTH;
				} else if (vc_y + 1 < vc->vc_rows) {
					beep(880);
					vc_y++;
					vc_x = 0;
				} else
					beep(220);
				break;
			case KEY_DOWN:
				if (vc_y + 1 < vc->vc_rows)
					vc_y++;
				else
					beep(220);
				break;
			case KEY_UP:
				if (vc_y >= 1)
					vc_y--;
				else
					beep(220);
				break;
			case KEY_HOME:
				vc_follow_cursor(vc);
				break;
			case KEY_PAGEUP:
				vc_x = 0;
				vc_y = 0;
				break;
			case KEY_PAGEDOWN:
				vc_x = 0;
				vc_y = vc->vc_rows-1;
				break;
			default:
				ret = NOTIFY_OK;
				break;
			}
			if (ret == NOTIFY_STOP)
				vc_refresh(vc);
		}
		break;
	case KBD_POST_KEYSYM:
	{
		unsigned char type = KTYP(param->value) - 0xf0;
		if (type == KT_SPEC) {
			unsigned char val = KVAL(param->value);
			int on_off = -1;

			switch (val) {
			case KVAL(K_CAPS):
				on_off = vc_kbd_led(kbd_table + fg_console,
						VC_CAPSLOCK);
				break;
			case KVAL(K_NUM):
				on_off = vc_kbd_led(kbd_table + fg_console,
						VC_NUMLOCK);
				break;
			case KVAL(K_HOLD):
				on_off = vc_kbd_led(kbd_table + fg_console,
						VC_SCROLLOCK);
				break;
			}
			if (on_off == 1)
				beep(880);
			else if (on_off == 0)
				beep(440);
		}
	}
	case KBD_UNBOUND_KEYCODE:
	case KBD_UNICODE:
	case KBD_KEYSYM:
		/* Unused */
		break;
	}
	return ret;
}
Example #25
0
/* Keyboard support */
static int kbd_getc(void)
{
	unsigned char dt, brk, val;
	unsigned code;
loop:
	while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;

	dt = kbd_inb(KBD_DATA_REG);

	brk = dt & 0x80;	/* brk == 1 on key release */
	dt = dt & 0x7f;		/* keycode */

	if (console_global_data.shfts)
	    code = shift_map[dt];
	else if (console_global_data.ctls)
	    code = ctrl_map[dt];
	else
	    code = plain_map[dt];

	val = KVAL(code);
	switch (KTYP(code) & 0x0f) {
	    case KT_LATIN:
		if (brk)
		    break;
		if (console_global_data.alts)
		    val |= 0x80;
		if (val == 0x7f)	/* map delete to backspace */
		    val = '\b';
		return val;

	    case KT_LETTER:
		if (brk)
		    break;
		if (console_global_data.caps)
		    val -= 'a'-'A';
		return val;

	    case KT_SPEC:
		if (brk)
		    break;
		if (val == KVAL(K_CAPS))
		    console_global_data.caps = !console_global_data.caps;
		else if (val == KVAL(K_ENTER)) {
enter:		    /* Wait for key up */
		    while (1) {
			while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
			dt = kbd_inb(KBD_DATA_REG);
			if (dt & 0x80) /* key up */ break;
		    }
		    return 10;
		}
		break;

	    case KT_PAD:
		if (brk)
		    break;
		if (val < 10)
		    return val;
		if (val == KVAL(K_PENTER))
		    goto enter;
		break;

	    case KT_SHIFT:
		switch (val) {
		    case KG_SHIFT:
		    case KG_SHIFTL:
		    case KG_SHIFTR:
			console_global_data.shfts = brk ? 0 : 1;
			break;
		    case KG_ALT:
		    case KG_ALTGR:
			console_global_data.alts = brk ? 0 : 1;
			break;
		    case KG_CTRL:
		    case KG_CTRLL:
		    case KG_CTRLR:
			console_global_data.ctls = brk ? 0 : 1;
			break;
		}
		break;

	    case KT_LOCK:
		switch (val) {
		    case KG_SHIFT:
		    case KG_SHIFTL:
		    case KG_SHIFTR:
			if (brk)
			    console_global_data.shfts = !console_global_data.shfts;
			break;
		    case KG_ALT:
		    case KG_ALTGR:
			if (brk)
			    console_global_data.alts = !console_global_data.alts;
			break;
		    case KG_CTRL:
		    case KG_CTRLL:
		    case KG_CTRLR:
			if (brk)
			    console_global_data.ctls = !console_global_data.ctls;
			break;
		}
		break;
	}
	/* if (brk) return (0); */  /* Ignore initial 'key up' codes */
	goto loop;
}
Example #26
0
static int kbd(int noblock)
{
	unsigned char dt, brk, val;
	unsigned code;
loop:
	if (noblock) {
	    if ((inb(KBSTATP) & KBINRDY) == 0)
		return (-1);
	} else while((inb(KBSTATP) & KBINRDY) == 0) ;

	dt = inb(KBDATAP);

	brk = dt & 0x80;	/* brk == 1 on key release */
	dt = dt & 0x7f;		/* keycode */

	if (shfts)
	    code = shift_map[dt];
	else if (ctls)
	    code = ctrl_map[dt];
	else
	    code = plain_map[dt];

	val = KVAL(code);
	switch (KTYP(code) & 0x0f) {
	    case KT_LATIN:
		if (brk)
		    break;
		if (alts)
		    val |= 0x80;
		if (val == 0x7f)	/* map delete to backspace */
		    val = '\b';
		return val;

	    case KT_LETTER:
		if (brk)
		    break;
		if (caps)
		    val -= 'a'-'A';
		return val;

	    case KT_SPEC:
		if (brk)
		    break;
		if (val == KVAL(K_CAPS))
		    caps = !caps;
		else if (val == KVAL(K_ENTER)) {
enter:		    /* Wait for key up */
		    while (1) {
			while((inb(KBSTATP) & KBINRDY) == 0) ;
			dt = inb(KBDATAP);
			if (dt & 0x80) /* key up */ break;
		    }
		    return 10;
		}
		break;

	    case KT_PAD:
		if (brk)
		    break;
		if (val < 10)
		    return val;
		if (val == KVAL(K_PENTER))
		    goto enter;
		break;

	    case KT_SHIFT:
		switch (val) {
		    case KG_SHIFT:
		    case KG_SHIFTL:
		    case KG_SHIFTR:
			shfts = brk ? 0 : 1;
			break;
		    case KG_ALT:
		    case KG_ALTGR:
			alts = brk ? 0 : 1;
			break;
		    case KG_CTRL:
		    case KG_CTRLL:
		    case KG_CTRLR:
			ctls = brk ? 0 : 1;
			break;
		}
		break;

	    case KT_LOCK:
		switch (val) {
		    case KG_SHIFT:
		    case KG_SHIFTL:
		    case KG_SHIFTR:
			if (brk)
			    shfts = !shfts;
			break;
		    case KG_ALT:
		    case KG_ALTGR:
			if (brk)
			    alts = !alts;
			break;
		    case KG_CTRL:
		    case KG_CTRLL:
		    case KG_CTRLR:
			if (brk)
			    ctls = !ctls;
			break;
		}
		break;
	}
	if (brk) return (-1);  /* Ignore initial 'key up' codes */
	goto loop;
}
Example #27
0
int CLinuxInputDevice::KeyboardGetSymbol(unsigned short value)
{
  unsigned char type = KTYP(value);
  unsigned char index = KVAL(value);

  switch (type)
  {
  case KT_FN:
    if (index < 15)
      return XBMCK_F1 + index;
    break;
  case KT_LETTER:
  case KT_LATIN:
    switch (index)
    {
    case 0x1c:
      return XBMCK_PRINT;
    case 0x7f:
      return XBMCK_BACKSPACE;
    case 0xa4:
      return XBMCK_EURO; /* euro currency sign */
    default:
      return index;
    }
    break;

/*
  case KT_DEAD:
    switch (value)
    {
    case K_DGRAVE:
      return DIKS_DEAD_GRAVE;

    case K_DACUTE:
      return DIKS_DEAD_ACUTE;

    case K_DCIRCM:
      return DIKS_DEAD_CIRCUMFLEX;

    case K_DTILDE:
      return DIKS_DEAD_TILDE;

    case K_DDIERE:
      return DIKS_DEAD_DIAERESIS;

    case K_DCEDIL:
      return DIKS_DEAD_CEDILLA;

    default:
      break;
    }
    break;

  case KT_PAD:
    if (index <= 9 && level != DIKSI_BASE)
      return (DFBInputDeviceKeySymbol) (DIKS_0 + index);
    break;
*/
  }

  return XBMCK_UNKNOWN;
}
Example #28
0
static void kb_translate(_self, int code, int up)
{
  static int prev= 0;
  unsigned short *keyMap= self->keyMaps[self->state];
  int rep= (!up) && (prev == code);
  prev= up ? 0 : code;

  debugf("+++ code %d up %d prev %d rep %d map %p\n", code, up, prev, rep, keyMap);

  if (keyMap)
    {
      int sym=  keyMap[code];
      int type= KTYP(sym);
      debugf("+++ sym %x (%02x) type %d\n", sym, sym & 255, type);
      sym &= 255;
      if (type >= 0xf0)		// shiftable
	type -= 0xf0;
      if (KT_LETTER == type)	// lockable
	type= KT_LATIN;
      debugf("+++ type %d\n", type);
      switch (type)
	{
	case KT_LATIN:
	case KT_META:
	  kb_post(self, sym, up);
	  break;

	case KT_SHIFT:
	  if      (rep) break;
	  else if (up)  self->state &= ~(1 << sym);
	  else          self->state |=  (1 << sym);
	  updateModifiers(self->state);
	  break;

	case KT_FN:
	case KT_SPEC:
	case KT_CUR:
	  switch (K(type,sym))
	    {
	      // FN
	    case K_FIND:	kb_post(self,  1, up);	break;	// home
	    case K_INSERT:	kb_post(self,  5, up);	break;
	    case K_SELECT:	kb_post(self,  4, up);	break;	// end
	    case K_PGUP:	kb_post(self, 11, up);	break;
	    case K_PGDN:	kb_post(self, 12, up);	break;
	      // SPEC
	    case K_ENTER:	kb_post(self, 13, up);	break;
	      // CUR
	    case K_DOWN:	kb_post(self, 31, up);	break;
	    case K_LEFT:	kb_post(self, 28, up);	break;
	    case K_RIGHT:	kb_post(self, 29, up);	break;
	    case K_UP:		kb_post(self, 30, up);	break;
	    }
	  break;

	case KT_CONS:
	  if (self->vtSwitch && !self->vtLock)
	    kb_chvt(self, sym + 1);
	  break;

	default:
	  if (type > KT_SLOCK)
	    debugf("ignoring unknown scancode %d.%d\n", type, sym);
	  break;
	}
    }
}
Example #29
0
void 
SDL_EVDEV_Poll(void)
{
    struct input_event events[32];
    int i, len;
    SDL_evdevlist_item *item;
    SDL_Scancode scan_code;
    int mouse_button;
    SDL_Mouse *mouse;
#ifdef SDL_INPUT_LINUXKD
    Uint16 modstate;
    struct kbentry kbe;
    static char keysym[8];
    char *end;
    Uint32 kval;
#endif

#if SDL_USE_LIBUDEV
    SDL_UDEV_Poll();
#endif

    mouse = SDL_GetMouse();

    for (item = _this->first; item != NULL; item = item->next) {
        while ((len = read(item->fd, events, (sizeof events))) > 0) {
            len /= sizeof(events[0]);
            for (i = 0; i < len; ++i) {
                switch (events[i].type) {
                case EV_KEY:
                    if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) {
                        mouse_button = events[i].code - BTN_MOUSE;
                        if (events[i].value == 0) {
                            SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]);
                        } else if (events[i].value == 1) {
                            SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]);
                        }
                        break;
                    }

                    /* Probably keyboard */
                    scan_code = SDL_EVDEV_translate_keycode(events[i].code);
                    if (scan_code != SDL_SCANCODE_UNKNOWN) {
                        if (events[i].value == 0) {
                            SDL_SendKeyboardKey(SDL_RELEASED, scan_code);
                        } else if (events[i].value == 1 || events[i].value == 2 /* Key repeated */ ) {
                            SDL_SendKeyboardKey(SDL_PRESSED, scan_code);
#ifdef SDL_INPUT_LINUXKD
                            if (_this->console_fd >= 0) {
                                kbe.kb_index = events[i].code;
                                /* Convert the key to an UTF-8 char */
                                /* Ref: http://www.linuxjournal.com/article/2783 */
                                modstate = SDL_GetModState();
                                kbe.kb_table = 0;
                                
                                /* Ref: http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */
                                kbe.kb_table |= -( (modstate & KMOD_LCTRL) != 0) & (1 << KG_CTRLL | 1 << KG_CTRL);
                                kbe.kb_table |= -( (modstate & KMOD_RCTRL) != 0) & (1 << KG_CTRLR | 1 << KG_CTRL);
                                kbe.kb_table |= -( (modstate & KMOD_LSHIFT) != 0) & (1 << KG_SHIFTL | 1 << KG_SHIFT);
                                kbe.kb_table |= -( (modstate & KMOD_RSHIFT) != 0) & (1 << KG_SHIFTR | 1 << KG_SHIFT);
                                kbe.kb_table |= -( (modstate & KMOD_LALT) != 0) & (1 << KG_ALT);
                                kbe.kb_table |= -( (modstate & KMOD_RALT) != 0) & (1 << KG_ALTGR);

                                if (ioctl(_this->console_fd, KDGKBENT, (unsigned long)&kbe) == 0 && 
                                    ((KTYP(kbe.kb_value) == KT_LATIN) || (KTYP(kbe.kb_value) == KT_ASCII) || (KTYP(kbe.kb_value) == KT_LETTER))) 
                                {
                                    kval = KVAL(kbe.kb_value);
                                    
                                    /* While there's a KG_CAPSSHIFT symbol, it's not useful to build the table index with it
                                     * because 1 << KG_CAPSSHIFT overflows the 8 bits of kb_table 
                                     * So, we do the CAPS LOCK logic here. Note that isalpha depends on the locale!
                                     */
                                    if ( modstate & KMOD_CAPS && isalpha(kval) ) {
                                        if ( isupper(kval) ) {
                                            kval = tolower(kval);
                                        } else {
                                            kval = toupper(kval);
                                        }
                                    }
                                     
                                    /* Convert to UTF-8 and send */
                                    end = SDL_UCS4ToUTF8( kval, keysym);
                                    *end = '\0';
                                    SDL_SendKeyboardText(keysym);
                                }
                            }
#endif /* SDL_INPUT_LINUXKD */
                        }
                    }
                    break;
                case EV_ABS:
                    switch(events[i].code) {
                    case ABS_X:
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y);
                        break;
                    case ABS_Y:
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value);
                        break;
                    default:
                        break;
                    }
                    break;
                case EV_REL:
                    switch(events[i].code) {
                    case REL_X:
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, events[i].value, 0);
                        break;
                    case REL_Y:
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value);
                        break;
                    case REL_WHEEL:
                        SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value);
                        break;
                    case REL_HWHEEL:
                        SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0);
                        break;
                    default:
                        break;
                    }
                    break;
                case EV_SYN:
                    switch (events[i].code) {
                    case SYN_DROPPED:
                        SDL_EVDEV_sync_device(item);
                        break;
                    default:
                        break;
                    }
                    break;
                }
            }
        }    
    }
}
Example #30
0
static void keyboard_console_handler(void)
{
	unsigned char buffer[128], scancode;
	int pressed, repeated, num_bytes, i, key, extended;
	int vt, orig_vt;
	struct kbentry entry;
	struct vt_stat vt_state;

	num_bytes = read(key_fd, &buffer, sizeof(buffer));
	if (num_bytes > 0) {
		for (i = 0; i < num_bytes; i++) {
			scancode = kernel_to_scancode[buffer[i] & 0x7F];
			pressed = (buffer[i] & 0x80) ^ 0x80;
			repeated = pressed && key_state[scancode];
			key_state[scancode] = pressed;

			/* Since we took over keyboard control, we have to map our keypresses to ascii
			 * in order to report them in our own keyboard buffer */

			extended = 0;
			switch (scancode) {
			case SC_CAPSLOCK:   if (pressed) key_leds ^= LED_CAP; break;
			case SC_NUMLOCK:    if (pressed) key_leds ^= LED_NUM; break;
			case SC_SCROLLLOCK: if (pressed) key_leds ^= LED_SCR; break;
			default:
				extended = fb_hScancodeToExtendedKey( scancode );
				break;
			}

			/* Fill in kbentry struct for KDGKBENT query */
			entry.kb_table = 0; /* modifier table */
			if (key_state[SC_LSHIFT] || key_state[SC_RSHIFT])
				entry.kb_table |= 0x1;
			if (key_state[SC_ALTGR])
				entry.kb_table |= 0x2;
			if (key_state[SC_CONTROL])
				entry.kb_table |= 0x4;
			if (key_state[SC_ALT])
				entry.kb_table |= 0x8;
			entry.kb_index = scancode; /* keycode */
			ioctl(key_fd, KDGKBENT, &entry);

			if (scancode == SC_BACKSPACE)
				key = 8;
			else if (entry.kb_value == K_NOSUCHMAP)
				key = 0;
			else {
				key = KVAL(entry.kb_value);
				switch (KTYP(entry.kb_value)) {
					case KT_LETTER:
						if (key_leds & LED_CAP)
							key ^= 0x20;
						break;
					case KT_LATIN:
					case KT_ASCII:
						break;
					case KT_PAD:
						if (key < NUM_PAD_KEYS) {
							if (key_leds & LED_NUM)
								key = pad_numlock_ascii[key];
							else
								key = pad_ascii[key];
						}
						else
							key = 0;
						break;
					case KT_SPEC:
						if (scancode == SC_ENTER)
							key = '\r';
						break;
					case KT_CONS:
						vt = key + 1;
						if( pressed && (ioctl(key_fd, VT_GETSTATE, &vt_state) >= 0) ) {
							orig_vt = vt_state.v_active;
							if (vt != orig_vt) {
								if (__fb_con.gfx_exit) {
									gfx_save();
									ioctl(key_fd, KDSETMODE, KD_TEXT);
								}
								ioctl(key_fd, VT_ACTIVATE, vt);
								ioctl(key_fd, VT_WAITACTIVE, vt);
								while (ioctl(key_fd, VT_WAITACTIVE, orig_vt) < 0)
								    usleep(50000);
								if (__fb_con.gfx_exit) {
									ioctl(key_fd, KDSETMODE, KD_GRAPHICS);
									gfx_restore();
								}
								memset(key_state, FALSE, 128);
							} else {
								key_state[scancode] = FALSE;
							}
							extended = 0;
						}

					/* fallthrough */
					default:
						key = 0;
						break;
				}
			}

			if( extended )
				key = extended;

			if( pressed && key ) {
				key_buffer[key_tail] = key;
				if (((key_tail + 1) & (KEY_BUFFER_SIZE - 1)) == key_head)
					key_head = (key_head + 1) & (KEY_BUFFER_SIZE - 1);
				key_tail = (key_tail + 1) & (KEY_BUFFER_SIZE - 1);
			}

			if( gfx_key_handler )
				gfx_key_handler( pressed, repeated, scancode, key );
		}
	}

	/* CTRL + C */
	if( key_state[SC_CONTROL] && key_state[SC_C] )
		kill(main_pid, SIGINT);
}