From 77c8051ec65bc0d407775afb31c368301fb6f252 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 6 Sep 2014 14:09:09 -0700 Subject: [PATCH] Add support for keyboard and mouse combo devices in raw input mode --- src/com/limelight/Game.java | 13 ++ .../binding/input/evdev/EvdevEvent.java | 6 + .../binding/input/evdev/EvdevHandler.java | 31 ++++ .../binding/input/evdev/EvdevListener.java | 1 + .../binding/input/evdev/EvdevTranslator.java | 139 ++++++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 src/com/limelight/binding/input/evdev/EvdevTranslator.java diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index 30dd1df2..66feeb2a 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -696,4 +696,17 @@ public class Game extends Activity implements SurfaceHolder.Callback, public void mouseScroll(byte amount) { conn.sendMouseScroll(amount); } + + @Override + public void keyboardEvent(boolean buttonDown, short keyCode) { + short keyMap = keybTranslator.translate(keyCode); + if (keyMap != 0) { + if (buttonDown) { + keybTranslator.sendKeyDown(keyMap, (byte) 0); + } + else { + keybTranslator.sendKeyUp(keyMap, (byte) 0); + } + } + } } diff --git a/src/com/limelight/binding/input/evdev/EvdevEvent.java b/src/com/limelight/binding/input/evdev/EvdevEvent.java index ed5e8a4b..ea51aa9f 100644 --- a/src/com/limelight/binding/input/evdev/EvdevEvent.java +++ b/src/com/limelight/binding/input/evdev/EvdevEvent.java @@ -8,6 +8,7 @@ public class EvdevEvent { public static final short EV_SYN = 0x00; public static final short EV_KEY = 0x01; public static final short EV_REL = 0x02; + public static final short EV_MSC = 0x04; /* Relative axes */ public static final short REL_X = 0x00; @@ -18,6 +19,11 @@ public class EvdevEvent { public static final short BTN_LEFT = 0x110; public static final short BTN_RIGHT = 0x111; public static final short BTN_MIDDLE = 0x112; + public static final short BTN_SIDE = 0x113; + public static final short BTN_EXTRA = 0x114; + public static final short BTN_FORWARD = 0x115; + public static final short BTN_BACK = 0x116; + public static final short BTN_TASK = 0x117; public short type; public short code; diff --git a/src/com/limelight/binding/input/evdev/EvdevHandler.java b/src/com/limelight/binding/input/evdev/EvdevHandler.java index be081a35..6e71d176 100644 --- a/src/com/limelight/binding/input/evdev/EvdevHandler.java +++ b/src/com/limelight/binding/input/evdev/EvdevHandler.java @@ -96,7 +96,37 @@ public class EvdevHandler { listener.mouseButtonEvent(EvdevListener.BUTTON_RIGHT, event.value != 0); break; + + case EvdevEvent.BTN_SIDE: + case EvdevEvent.BTN_EXTRA: + case EvdevEvent.BTN_FORWARD: + case EvdevEvent.BTN_BACK: + case EvdevEvent.BTN_TASK: + // Other unhandled mouse buttons + break; + + default: + // We got some unrecognized button. This means + // someone is trying to use the other device in this + // "combination" input device. We'll try to handle + // it via keyboard, but we're not going to disconnect + // if we can't + short keyCode = EvdevTranslator.translateEvdevKeyCode(event.code); + if (keyCode != 0) { + listener.keyboardEvent(event.value != 0, keyCode); + } + break; } + break; + + case EvdevEvent.EV_MSC: + break; + + default: + // We got some unrecognized event. This means + // someone is trying to use the other device in this + // "combination" input device. We'll disconnect now + return; } } } finally { @@ -105,6 +135,7 @@ public class EvdevHandler { } } finally { // Close the file + LimeLog.warning("Evdev handler is terminating for: "+absolutePath); EvdevReader.close(fd); } } diff --git a/src/com/limelight/binding/input/evdev/EvdevListener.java b/src/com/limelight/binding/input/evdev/EvdevListener.java index b7bdb120..909627a5 100644 --- a/src/com/limelight/binding/input/evdev/EvdevListener.java +++ b/src/com/limelight/binding/input/evdev/EvdevListener.java @@ -8,4 +8,5 @@ public interface EvdevListener { public void mouseMove(int deltaX, int deltaY); public void mouseButtonEvent(int buttonId, boolean down); public void mouseScroll(byte amount); + public void keyboardEvent(boolean buttonDown, short keyCode); } diff --git a/src/com/limelight/binding/input/evdev/EvdevTranslator.java b/src/com/limelight/binding/input/evdev/EvdevTranslator.java new file mode 100644 index 00000000..00961e6e --- /dev/null +++ b/src/com/limelight/binding/input/evdev/EvdevTranslator.java @@ -0,0 +1,139 @@ +package com.limelight.binding.input.evdev; + +import android.view.KeyEvent; + +public class EvdevTranslator { + + public static final short EVDEV_KEY_CODES[] = { + 0, //KeyEvent.VK_RESERVED + KeyEvent.KEYCODE_ESCAPE, + KeyEvent.KEYCODE_1, + KeyEvent.KEYCODE_2, + KeyEvent.KEYCODE_3, + KeyEvent.KEYCODE_4, + KeyEvent.KEYCODE_5, + KeyEvent.KEYCODE_6, + KeyEvent.KEYCODE_7, + KeyEvent.KEYCODE_8, + KeyEvent.KEYCODE_9, + KeyEvent.KEYCODE_0, + KeyEvent.KEYCODE_MINUS, + KeyEvent.KEYCODE_EQUALS, + KeyEvent.KEYCODE_DEL, + KeyEvent.KEYCODE_TAB, + KeyEvent.KEYCODE_Q, + KeyEvent.KEYCODE_W, + KeyEvent.KEYCODE_E, + KeyEvent.KEYCODE_R, + KeyEvent.KEYCODE_T, + KeyEvent.KEYCODE_Y, + KeyEvent.KEYCODE_U, + KeyEvent.KEYCODE_I, + KeyEvent.KEYCODE_O, + KeyEvent.KEYCODE_P, + KeyEvent.KEYCODE_LEFT_BRACKET, + KeyEvent.KEYCODE_RIGHT_BRACKET, + KeyEvent.KEYCODE_ENTER, + KeyEvent.KEYCODE_CTRL_LEFT, + KeyEvent.KEYCODE_A, + KeyEvent.KEYCODE_S, + KeyEvent.KEYCODE_D, + KeyEvent.KEYCODE_F, + KeyEvent.KEYCODE_G, + KeyEvent.KEYCODE_H, + KeyEvent.KEYCODE_J, + KeyEvent.KEYCODE_K, + KeyEvent.KEYCODE_L, + KeyEvent.KEYCODE_SEMICOLON, + KeyEvent.KEYCODE_APOSTROPHE, + KeyEvent.KEYCODE_GRAVE, + KeyEvent.KEYCODE_SHIFT_LEFT, + KeyEvent.KEYCODE_BACKSLASH, + KeyEvent.KEYCODE_Z, + KeyEvent.KEYCODE_X, + KeyEvent.KEYCODE_C, + KeyEvent.KEYCODE_V, + KeyEvent.KEYCODE_B, + KeyEvent.KEYCODE_N, + KeyEvent.KEYCODE_M, + KeyEvent.KEYCODE_COMMA, + KeyEvent.KEYCODE_PERIOD, + KeyEvent.KEYCODE_SLASH, + KeyEvent.KEYCODE_SHIFT_RIGHT, + KeyEvent.KEYCODE_NUMPAD_MULTIPLY, + KeyEvent.KEYCODE_ALT_LEFT, + KeyEvent.KEYCODE_SPACE, + KeyEvent.KEYCODE_CAPS_LOCK, + KeyEvent.KEYCODE_F1, + KeyEvent.KEYCODE_F2, + KeyEvent.KEYCODE_F3, + KeyEvent.KEYCODE_F4, + KeyEvent.KEYCODE_F5, + KeyEvent.KEYCODE_F6, + KeyEvent.KEYCODE_F7, + KeyEvent.KEYCODE_F8, + KeyEvent.KEYCODE_F9, + KeyEvent.KEYCODE_F10, + KeyEvent.KEYCODE_NUM_LOCK, + KeyEvent.KEYCODE_SCROLL_LOCK, + KeyEvent.KEYCODE_NUMPAD_7, + KeyEvent.KEYCODE_NUMPAD_8, + KeyEvent.KEYCODE_NUMPAD_9, + KeyEvent.KEYCODE_NUMPAD_SUBTRACT, + KeyEvent.KEYCODE_NUMPAD_4, + KeyEvent.KEYCODE_NUMPAD_5, + KeyEvent.KEYCODE_NUMPAD_6, + KeyEvent.KEYCODE_NUMPAD_ADD, + KeyEvent.KEYCODE_NUMPAD_1, + KeyEvent.KEYCODE_NUMPAD_2, + KeyEvent.KEYCODE_NUMPAD_3, + KeyEvent.KEYCODE_NUMPAD_0, + KeyEvent.KEYCODE_NUMPAD_DOT, + 0, + 0, //KeyEvent.VK_ZENKAKUHANKAKU, + 0, //KeyEvent.VK_102ND, + KeyEvent.KEYCODE_F11, + KeyEvent.KEYCODE_F12, + 0, //KeyEvent.VK_RO, + 0, //KeyEvent.VK_KATAKANA, + 0, //KeyEvent.VK_HIRAGANA, + 0, //KeyEvent.VK_HENKAN, + 0, //KeyEvent.VK_KATAKANAHIRAGANA, + 0, //KeyEvent.VK_MUHENKAN, + 0, //KeyEvent.VK_KPJPCOMMA, + KeyEvent.KEYCODE_NUMPAD_ENTER, + KeyEvent.KEYCODE_CTRL_RIGHT, + KeyEvent.KEYCODE_NUMPAD_DIVIDE, + KeyEvent.KEYCODE_SYSRQ, + KeyEvent.KEYCODE_ALT_RIGHT, + 0, //KeyEvent.VK_LINEFEED, + KeyEvent.KEYCODE_HOME, + KeyEvent.KEYCODE_DPAD_UP, + KeyEvent.KEYCODE_PAGE_UP, + KeyEvent.KEYCODE_DPAD_LEFT, + KeyEvent.KEYCODE_DPAD_RIGHT, + KeyEvent.KEYCODE_MOVE_END, + KeyEvent.KEYCODE_DPAD_DOWN, + KeyEvent.KEYCODE_PAGE_DOWN, + KeyEvent.KEYCODE_INSERT, + KeyEvent.KEYCODE_FORWARD_DEL, + 0, //KeyEvent.VK_MACRO, + 0, //KeyEvent.VK_MUTE, + 0, //KeyEvent.VK_VOLUMEDOWN, + 0, //KeyEvent.VK_VOLUMEUP, + 0, //KeyEvent.VK_POWER, /* SC System Power Down */ + KeyEvent.KEYCODE_NUMPAD_EQUALS, + 0, //KeyEvent.VK_KPPLUSMINUS, + KeyEvent.KEYCODE_BREAK, + 0, //KeyEvent.VK_SCALE, /* AL Compiz Scale (Expose) */ + }; + + public static short translateEvdevKeyCode(short evdevKeyCode) { + if (evdevKeyCode < EVDEV_KEY_CODES.length) { + return EVDEV_KEY_CODES[evdevKeyCode]; + } + + return 0; + } + +}