예제 #1
0
/* maybe called when keymap is undefined, so that shiftkey release is seen */
static 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 * BITS_PER_LONG;
	 for (j = 0; j < BITS_PER_LONG; j++, k++)
	    if (test_bit(k, key_down))
	    {
	       sym = 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);
	       }
	    }
      }
#ifdef DBG2
   printf("compute shift_state=%ld\r\n", shift_state);
#endif
}
예제 #2
0
파일: sunkbd.c 프로젝트: dmgerman/original
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;
	}
}
예제 #3
0
/*
 * Fetch one entry from the kernel keymap.
 */
bool CLinuxInputDevice::GetKeymapEntry(KeymapEntry& entry)
{
  int code = entry.code;
  unsigned short value;
  //DFBInputDeviceKeyIdentifier identifier;

  if (m_vt_fd < 0)
    return false;

  // to support '+'  and '/' with Boxee's remote control we do something ugly like this for now
  if (KVAL(code) == 98)
  {
    code = K(KTYP(code),53);
  }

  /* fetch the base level */
  value = KeyboardGetSymbol(KeyboardReadValue(K_NORMTAB, code));
  //printf("base=%d typ=%d code %d\n", KVAL(value), KTYP(value), code);

  /* write base level symbol to entry */
  entry.base = value; //KeyboardGetSymbol(code, value, LI_KEYLEVEL_BASE);

  /* fetch the shifted base level */
  value = KeyboardGetSymbol(KeyboardReadValue(K_SHIFTTAB, entry.code));
  //printf("shift=%d\n", value);

  /* write shifted base level symbol to entry */
  entry.shift = value; //KeyboardGetSymbol(code, value, LI_KEYLEVEL_SHIFT);

  // to support '+'  and '/' with Boxee's remote control we could do ugly something like this for now
  if (KVAL(code) == 78)
  {
    //code = K(KTYP(code),13);
    //entry.code = K(KTYP(code),13);
    entry.base = K(KTYP(code),43);
  }

  /* fetch the alternative level */
  value = KeyboardGetSymbol(KeyboardReadValue(K_ALTTAB, entry.code));
  //printf("alt=%d\n", value);

  /* write alternative level symbol to entry */
  entry.alt = value; //KeyboardGetSymbol(code, value, LI_KEYLEVEL_ALT);

  /* fetch the shifted alternative level */
  value = KeyboardGetSymbol(KeyboardReadValue(K_ALTSHIFTTAB, entry.code));
  //printf("altshift=%d\n", value);

  /* write shifted alternative level symbol to entry */
  entry.altShift = value; //KeyboardGetSymbol(code, value, LI_KEYLEVEL_ALT_SHIFT);

  return true;
}
예제 #4
0
파일: kmap.c 프로젝트: maxinbjohn/kbd
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;
}
예제 #5
0
static int  		print_keysym(int *key, int state, int *lockers, int socket)
{
	static int		modifier = 0;
	int				code;
	int 			type;
	int 			value;

	code = key[modifier];
	type = KTYP(code);
	value = KVAL(code);
	if (type >= syms_size) {
		code = code ^ 0xf000;
		if (code < 0)
			return dprintf(socket, "<(null)>");
		if (code < 0x80)
			return dprintf(socket, "%s", iso646_syms[code]);
		return dprintf(socket, "[%#04x]", code);
	}
	if (type == KT_LETTER)
		type = KT_LATIN;
	if (type < syms_size && value < syms[type].size) {
		if (type == KT_SHIFT)
			return shift_handler(value, state, &modifier);
		if (type == KT_LOCK)
			return lock_handler(value, state, &modifier, lockers);
		if (state)
			return dprintf(socket, "%s", syms[type].table[value]);
	}
	if (type == KT_META && value < syms[0].size)
		return dprintf(socket, "<Meta_%s>", syms[0].table[value]);
	if (state)
		return dprintf(socket, "[%#04x]", code);
	return 1;
}
예제 #6
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;
}
예제 #7
0
파일: kmap.c 프로젝트: maxinbjohn/kbd
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;
}
예제 #8
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)];
		}
	}
}
예제 #9
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;
		}
	}
}
예제 #10
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]);
}
예제 #11
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);
		}
	      }
	  }
}
예제 #12
0
파일: keycode.c 프로젝트: Dalrik/fbterm
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];
}
예제 #13
0
u_char vmklnx_map_key(u_char value, u_char keytype)
{
   u_char map_value = KEYBOARD_INVALID_VALUE;
	
   /* function keys */
   if (keytype == KT_FN) {
      switch (value) {
         case KVAL(K_FIND):
            map_value = VMK_INPUT_KEY_HOME;
            break;
         case KVAL(K_PGUP):
            map_value = VMK_INPUT_KEY_PAGEUP;
            break;
         case KVAL(K_SELECT):
            map_value = VMK_INPUT_KEY_END;
            break;
         case KVAL(K_PGDN):
            map_value = VMK_INPUT_KEY_PAGEDOWN;
            break;
         case KVAL(K_INSERT):
            map_value = VMK_INPUT_KEY_INSERT;
            break;
         case KVAL(K_REMOVE):
            map_value = VMK_INPUT_KEY_DELETE;
            break;
         default:
            if ((char)value >= KVAL(K_F1) && value <= KVAL(K_F12)) {
               map_value = value - K_F1 + VMK_INPUT_KEY_F1;
            } else {
               vmk_InputPutsQueue(func_table[value]);
            }
            break;
         }
      }

      /* cursor */
      if (keytype == KT_CUR) {
         switch (value) {
            case KVAL(K_UP):
               map_value = VMK_INPUT_KEY_UP;
               break;
            case KVAL(K_LEFT):
               map_value = VMK_INPUT_KEY_LEFT;
               break;
            case KVAL(K_RIGHT):
               map_value = VMK_INPUT_KEY_RIGHT;
               break;
            case KVAL(K_DOWN):
		map_value = VMK_INPUT_KEY_DOWN;
		break;
	     default:
		printk("Unknown cursor key\n");
		break;
         }
   }

   /* console */
   if (keytype == KT_CONS) {
      if ((char)value >= KVAL(K_F1) && value <= KVAL(K_F12)) {
         map_value = value - K_F1 + VMK_INPUT_KEY_ALT_F1;
      }
   }
	
   if (map_value != KEYBOARD_INVALID_VALUE) {
      vmk_InputPutQueue(map_value);
   }

   return map_value;
}
예제 #14
0
파일: kbd.c 프로젝트: anarsoul/xynth-server
int s_video_helper_kbd_update (s_video_input_data_t *keybd)
{
	int i;
	int led = 0;
	int pressed;
	int scancode;
	int bytesread;
	unsigned char buf;

	int map = 0;
	s_keyboard_flag_t keycode_flag;
	
	bytesread = read(s_video_helper_keybd.fd, &buf, 1);

	for (i = 0; i < bytesread; i++) {
		scancode = buf & 0x7f;
		pressed = (buf & 0x80) ? EVENT_TYPE_KEYBOARD_RELEASED : EVENT_TYPE_KEYBOARD_PRESSED;

                keybd->keybd.state = pressed;
		keybd->keybd.scancode = scancode;
		keybd->keybd.button = s_video_helper_keybd_keycode_[scancode][KEYCODE_PLAIN];
		keybd->keybd.keycode = s_video_helper_keybd_keycode_[scancode][KEYCODE_PLAIN];

		keycode_flag = xynth_server->window->event->keybd->flag;
		switch (keybd->keybd.button) {
			case KEYBOARD_BUTTON_LEFTSHIFT:
			case KEYBOARD_BUTTON_RIGHTSHIFT:
			case KEYBOARD_BUTTON_LEFTCONTROL:
			case KEYBOARD_BUTTON_RIGHTCONTROL:
			case KEYBOARD_BUTTON_ALT:
			case KEYBOARD_BUTTON_ALTGR:
			case KEYBOARD_BUTTON_CAPS_LOCK:
				goto keycode_plain;
			default:
				break;
		}
		if (keycode_flag & KEYBOARD_FLAG_SHIFT) {
			keybd->keybd.button = s_video_helper_keybd_keycode_[scancode][KEYCODE_SHIFT];
			map |= (1 << KG_SHIFT);
		}
		if (keycode_flag & KEYBOARD_FLAG_CTRL) {
			map |= (1 << KG_CTRL);
		}
		if (keycode_flag & KEYBOARD_FLAG_LEFTALT) {
			map |= (1 << KG_ALT);
		}
		if (keycode_flag & KEYBOARD_FLAG_ALTGR) {
			keybd->keybd.button = s_video_helper_keybd_keycode_[scancode][KEYCODE_ALTGR];
			map |= (1 << KG_ALTGR);
		}
keycode_plain:
		if (KTYP(s_video_helper_keybd_keymap[map][scancode]) == KT_LETTER) {
			if (keycode_flag & KEYBOARD_FLAG_CAPSLOCK) {
				map ^= (1 << KG_SHIFT);
			}
		}
		if (KTYP(s_video_helper_keybd_keymap[map][scancode]) == KT_PAD) {
			if (keycode_flag & KEYBOARD_FLAG_NUMLOCK) {
				keybd->keybd.ascii = KVAL(s_video_helper_keybd_keymap[map][scancode]);
			}
		} else {
			keybd->keybd.ascii = KVAL(s_video_helper_keybd_keymap[map][scancode]);
		}

		ioctl(s_video_helper_keybd.fd, KDGETLED, &led);
		if (keycode_flag & KEYBOARD_FLAG_CAPSLOCK) {
			led |= LED_CAP;
		} else {
			led &= ~LED_CAP;
		}
		if (keycode_flag & KEYBOARD_FLAG_NUMLOCK) {
			led |= LED_NUM;
		} else {
			led &= ~LED_NUM;
		}
		ioctl(s_video_helper_keybd.fd, KDSETLED, led);
	}
	return 0;
}
예제 #15
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;
}
예제 #16
0
파일: SDL_evdev.c 프로젝트: abakobo/monkey2
/* 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);
}
예제 #17
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
}
예제 #18
0
파일: sunkbd.c 프로젝트: dmgerman/original
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);
}
예제 #19
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;
}
예제 #20
0
파일: tty_read.c 프로젝트: WareX97/aPlus
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;
}
예제 #21
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;
}
예제 #22
0
파일: input.c 프로젝트: Nekrofage/DoomRPi
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);
}
예제 #23
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 */
}
예제 #24
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;
                }
            }
        }    
    }
}
예제 #25
0
파일: lkeybdnu.c 프로젝트: allefant/allegro
/* 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;
   }
}
예제 #26
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;
}
예제 #27
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;
}
예제 #28
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;
}
예제 #29
0
파일: kbd.c 프로젝트: 12019/hg556a_source
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;
}
예제 #30
0
파일: io_multikey.c 프로젝트: dkoksal/fbc
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);
}