|
@@ -0,0 +1,746 @@
|
|
|
+/*
|
|
|
+** Xbox360 USB Gamepad Userspace Driver
|
|
|
+** Copyright (C) 2008 Ingo Ruhnke <grumbel@gmail.com>
|
|
|
+**
|
|
|
+** This program is free software: you can redistribute it and/or modify
|
|
|
+** it under the terms of the GNU General Public License as published by
|
|
|
+** the Free Software Foundation, either version 3 of the License, or
|
|
|
+** (at your option) any later version.
|
|
|
+**
|
|
|
+** This program is distributed in the hope that it will be useful,
|
|
|
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+** GNU General Public License for more details.
|
|
|
+**
|
|
|
+** You should have received a copy of the GNU General Public License
|
|
|
+** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+*/
|
|
|
+
|
|
|
+#include <X11/Xlib.h>
|
|
|
+#include <linux/input.h>
|
|
|
+#include <iostream>
|
|
|
+#include <sstream>
|
|
|
+#include <stdexcept>
|
|
|
+#include <map>
|
|
|
+#include "evdev_helper.hpp"
|
|
|
+
|
|
|
+template <class Enum>
|
|
|
+class EnumBox
|
|
|
+{
|
|
|
+protected:
|
|
|
+ std::string name; // 枚举名称
|
|
|
+ std::map<Enum, std::string> enum2string; // 枚举值到字符串的映射
|
|
|
+ std::map<std::string, Enum> string2enum; // 字符串到枚举值的映射
|
|
|
+
|
|
|
+protected:
|
|
|
+ // 构造函数,初始化枚举名称
|
|
|
+ EnumBox(const std::string &name)
|
|
|
+ : name(name)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加一个枚举值及其对应的字符串表示
|
|
|
+ void add(Enum i, const std::string &name)
|
|
|
+ {
|
|
|
+ enum2string[i] = name;
|
|
|
+ string2enum[name] = i;
|
|
|
+ }
|
|
|
+
|
|
|
+public:
|
|
|
+ // 将字符串转换为对应的枚举值
|
|
|
+ Enum operator[](const std::string &str) const
|
|
|
+ {
|
|
|
+ typename std::map<std::string, Enum>::const_iterator i = string2enum.find(str);
|
|
|
+ if (i == string2enum.end())
|
|
|
+ {
|
|
|
+ std::istringstream in(str);
|
|
|
+ Enum tmp;
|
|
|
+ in >> tmp;
|
|
|
+ if (in.fail())
|
|
|
+ {
|
|
|
+ std::ostringstream out;
|
|
|
+ out << "无法将 '" << str << "' 转换为枚举 " << name << std::endl;
|
|
|
+ throw std::runtime_error(out.str());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return tmp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return i->second;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将枚举值转换为对应的字符串表示
|
|
|
+ std::string operator[](Enum v) const
|
|
|
+ {
|
|
|
+ typename std::map<Enum, std::string>::const_iterator i = enum2string.find(v);
|
|
|
+ if (i == enum2string.end())
|
|
|
+ {
|
|
|
+ // 如果无法进行符号转换,则直接将整数转换为字符串
|
|
|
+ std::ostringstream out;
|
|
|
+ out << v;
|
|
|
+ return out.str();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return i->second;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 定义一个相对事件枚举类,继承自EnumBox<int>
|
|
|
+class EvDevRelEnum : public EnumBox<int>
|
|
|
+{
|
|
|
+public:
|
|
|
+ // 构造函数初始化相对事件枚举类
|
|
|
+ EvDevRelEnum()
|
|
|
+ : EnumBox<int>("EV_REL")
|
|
|
+ {
|
|
|
+ // 下面的注释代码展示了如何从Linux输入头文件中提取REL定义,并自动生成add函数调用
|
|
|
+ // 这段代码是 Ruby 代码,用于生成add函数调用,以保持代码的自文档化特性
|
|
|
+ // File.new("/usr/include/linux/input.h")
|
|
|
+ // .grep(/^#define REL/)
|
|
|
+ // .each{|i| name = i.split[1]; puts "add(%s,%s\"%s\");" % [name, " " * (20-name.length), name] };
|
|
|
+
|
|
|
+ // 添加相对事件枚举值和对应的名称
|
|
|
+ add(REL_X, "REL_X");
|
|
|
+ add(REL_Y, "REL_Y");
|
|
|
+ add(REL_Z, "REL_Z");
|
|
|
+ add(REL_RX, "REL_RX");
|
|
|
+ add(REL_RY, "REL_RY");
|
|
|
+ add(REL_RZ, "REL_RZ");
|
|
|
+ add(REL_HWHEEL, "REL_HWHEEL");
|
|
|
+ add(REL_DIAL, "REL_DIAL");
|
|
|
+ add(REL_WHEEL, "REL_WHEEL");
|
|
|
+ add(REL_MISC, "REL_MISC");
|
|
|
+ }
|
|
|
+} evdev_rel_names;
|
|
|
+
|
|
|
+class EvDevAbsEnum : public EnumBox<int>
|
|
|
+{
|
|
|
+public:
|
|
|
+EvDevAbsEnum()
|
|
|
+ : EnumBox<int>("EV_ABS")
|
|
|
+{
|
|
|
+ // File.new("/usr/include/linux/input.h")
|
|
|
+ // .grep(/^#define ABS/)
|
|
|
+ // .each{|i| name = i.split[1]; puts "add(%s,%s\"%s\");" % [name, " " * (20-name.length), name] };
|
|
|
+
|
|
|
+ add(ABS_X, "ABS_X"); // X轴绝对坐标(常用于鼠标/手柄X轴)
|
|
|
+ add(ABS_Y, "ABS_Y"); // Y轴绝对坐标(常用于鼠标/手柄Y轴)
|
|
|
+ add(ABS_Z, "ABS_Z"); // Z轴绝对坐标(如三维控制器)
|
|
|
+ add(ABS_RX, "ABS_RX"); // 绕X轴旋转角度(摇杆RX轴)
|
|
|
+ add(ABS_RY, "ABS_RY"); // 绕Y轴旋转角度(摇杆RY轴)
|
|
|
+ add(ABS_RZ, "ABS_RZ"); // 绕Z轴旋转角度(摇杆RZ轴)
|
|
|
+ add(ABS_THROTTLE, "ABS_THROTTLE"); // 油门控制轴(飞行模拟器等)
|
|
|
+ add(ABS_RUDDER, "ABS_RUDDER"); // 方向舵轴(飞行模拟器方向控制)
|
|
|
+ add(ABS_WHEEL, "ABS_WHEEL"); // 转向轮角度(方向盘设备使用)
|
|
|
+ add(ABS_GAS, "ABS_GAS"); // 加速踏板(油门)
|
|
|
+ add(ABS_BRAKE, "ABS_BRAKE"); // 制动踏板
|
|
|
+ add(ABS_HAT0X, "ABS_HAT0X"); // 第0方向帽(D-Pad)X轴
|
|
|
+ add(ABS_HAT0Y, "ABS_HAT0Y"); // 第0方向帽(D-Pad)Y轴
|
|
|
+ add(ABS_HAT1X, "ABS_HAT1X"); // 第1方向帽X轴
|
|
|
+ add(ABS_HAT1Y, "ABS_HAT1Y"); // 第1方向帽Y轴
|
|
|
+ add(ABS_HAT2X, "ABS_HAT2X"); // 第2方向帽X轴
|
|
|
+ add(ABS_HAT2Y, "ABS_HAT2Y"); // 第2方向帽Y轴
|
|
|
+ add(ABS_HAT3X, "ABS_HAT3X"); // 第3方向帽X轴
|
|
|
+ add(ABS_HAT3Y, "ABS_HAT3Y"); // 第3方向帽Y轴
|
|
|
+ add(ABS_PRESSURE, "ABS_PRESSURE"); // 压力传感器输入(如触控笔压力)
|
|
|
+ add(ABS_DISTANCE, "ABS_DISTANCE"); // 距离测量轴
|
|
|
+ add(ABS_TILT_X, "ABS_TILT_X"); // X轴倾斜度(如重力感应)
|
|
|
+ add(ABS_TILT_Y, "ABS_TILT_Y"); // Y轴倾斜度
|
|
|
+ add(ABS_TOOL_WIDTH, "ABS_TOOL_WIDTH"); // 工具宽度(绘图软件识别笔尖粗细)
|
|
|
+ add(ABS_VOLUME, "ABS_VOLUME"); // 音量调节轴
|
|
|
+ add(ABS_MISC, "ABS_MISC"); // 杂项轴(保留用于未分类输入)
|
|
|
+}
|
|
|
+} evdev_abs_names;
|
|
|
+
|
|
|
+class EvDevBtnEnum : public EnumBox<int>
|
|
|
+{
|
|
|
+public:
|
|
|
+ EvDevBtnEnum()
|
|
|
+ : EnumBox<int>("EV_KEY")
|
|
|
+ {
|
|
|
+ // File.new("/usr/include/linux/input.h")
|
|
|
+ // .grep(/^#define (BTN|KEY)/)
|
|
|
+ // .each{|i| name = i.split[1]; puts "add(%s,%s\"%s\");" % [name, " " * (20-name.length), name] };
|
|
|
+ add(KEY_RESERVED, "KEY_RESERVED");
|
|
|
+ add(KEY_ESC, "KEY_ESC");
|
|
|
+ add(KEY_1, "KEY_1");
|
|
|
+ add(KEY_2, "KEY_2");
|
|
|
+ add(KEY_3, "KEY_3");
|
|
|
+ add(KEY_4, "KEY_4");
|
|
|
+ add(KEY_5, "KEY_5");
|
|
|
+ add(KEY_6, "KEY_6");
|
|
|
+ add(KEY_7, "KEY_7");
|
|
|
+ add(KEY_8, "KEY_8");
|
|
|
+ add(KEY_9, "KEY_9");
|
|
|
+ add(KEY_0, "KEY_0");
|
|
|
+ add(KEY_MINUS, "KEY_MINUS");
|
|
|
+ add(KEY_EQUAL, "KEY_EQUAL");
|
|
|
+ add(KEY_BACKSPACE, "KEY_BACKSPACE");
|
|
|
+ add(KEY_TAB, "KEY_TAB");
|
|
|
+ add(KEY_Q, "KEY_Q");
|
|
|
+ add(KEY_W, "KEY_W");
|
|
|
+ add(KEY_E, "KEY_E");
|
|
|
+ add(KEY_R, "KEY_R");
|
|
|
+ add(KEY_T, "KEY_T");
|
|
|
+ add(KEY_Y, "KEY_Y");
|
|
|
+ add(KEY_U, "KEY_U");
|
|
|
+ add(KEY_I, "KEY_I");
|
|
|
+ add(KEY_O, "KEY_O");
|
|
|
+ add(KEY_P, "KEY_P");
|
|
|
+ add(KEY_LEFTBRACE, "KEY_LEFTBRACE");
|
|
|
+ add(KEY_RIGHTBRACE, "KEY_RIGHTBRACE");
|
|
|
+ add(KEY_ENTER, "KEY_ENTER");
|
|
|
+ add(KEY_LEFTCTRL, "KEY_LEFTCTRL");
|
|
|
+ add(KEY_A, "KEY_A");
|
|
|
+ add(KEY_S, "KEY_S");
|
|
|
+ add(KEY_D, "KEY_D");
|
|
|
+ add(KEY_F, "KEY_F");
|
|
|
+ add(KEY_G, "KEY_G");
|
|
|
+ add(KEY_H, "KEY_H");
|
|
|
+ add(KEY_J, "KEY_J");
|
|
|
+ add(KEY_K, "KEY_K");
|
|
|
+ add(KEY_L, "KEY_L");
|
|
|
+ add(KEY_SEMICOLON, "KEY_SEMICOLON");
|
|
|
+ add(KEY_APOSTROPHE, "KEY_APOSTROPHE");
|
|
|
+ add(KEY_GRAVE, "KEY_GRAVE");
|
|
|
+ add(KEY_LEFTSHIFT, "KEY_LEFTSHIFT");
|
|
|
+ add(KEY_BACKSLASH, "KEY_BACKSLASH");
|
|
|
+ add(KEY_Z, "KEY_Z");
|
|
|
+ add(KEY_X, "KEY_X");
|
|
|
+ add(KEY_C, "KEY_C");
|
|
|
+ add(KEY_V, "KEY_V");
|
|
|
+ add(KEY_B, "KEY_B");
|
|
|
+ add(KEY_N, "KEY_N");
|
|
|
+ add(KEY_M, "KEY_M");
|
|
|
+ add(KEY_COMMA, "KEY_COMMA");
|
|
|
+ add(KEY_DOT, "KEY_DOT");
|
|
|
+ add(KEY_SLASH, "KEY_SLASH");
|
|
|
+ add(KEY_RIGHTSHIFT, "KEY_RIGHTSHIFT");
|
|
|
+ add(KEY_KPASTERISK, "KEY_KPASTERISK");
|
|
|
+ add(KEY_LEFTALT, "KEY_LEFTALT");
|
|
|
+ add(KEY_SPACE, "KEY_SPACE");
|
|
|
+ add(KEY_CAPSLOCK, "KEY_CAPSLOCK");
|
|
|
+ add(KEY_F1, "KEY_F1");
|
|
|
+ add(KEY_F2, "KEY_F2");
|
|
|
+ add(KEY_F3, "KEY_F3");
|
|
|
+ add(KEY_F4, "KEY_F4");
|
|
|
+ add(KEY_F5, "KEY_F5");
|
|
|
+ add(KEY_F6, "KEY_F6");
|
|
|
+ add(KEY_F7, "KEY_F7");
|
|
|
+ add(KEY_F8, "KEY_F8");
|
|
|
+ add(KEY_F9, "KEY_F9");
|
|
|
+ add(KEY_F10, "KEY_F10");
|
|
|
+ add(KEY_NUMLOCK, "KEY_NUMLOCK");
|
|
|
+ add(KEY_SCROLLLOCK, "KEY_SCROLLLOCK");
|
|
|
+ add(KEY_KP7, "KEY_KP7");
|
|
|
+ add(KEY_KP8, "KEY_KP8");
|
|
|
+ add(KEY_KP9, "KEY_KP9");
|
|
|
+ add(KEY_KPMINUS, "KEY_KPMINUS");
|
|
|
+ add(KEY_KP4, "KEY_KP4");
|
|
|
+ add(KEY_KP5, "KEY_KP5");
|
|
|
+ add(KEY_KP6, "KEY_KP6");
|
|
|
+ add(KEY_KPPLUS, "KEY_KPPLUS");
|
|
|
+ add(KEY_KP1, "KEY_KP1");
|
|
|
+ add(KEY_KP2, "KEY_KP2");
|
|
|
+ add(KEY_KP3, "KEY_KP3");
|
|
|
+ add(KEY_KP0, "KEY_KP0");
|
|
|
+ add(KEY_KPDOT, "KEY_KPDOT");
|
|
|
+ add(KEY_ZENKAKUHANKAKU, "KEY_ZENKAKUHANKAKU");
|
|
|
+ add(KEY_102ND, "KEY_102ND");
|
|
|
+ add(KEY_F11, "KEY_F11");
|
|
|
+ add(KEY_F12, "KEY_F12");
|
|
|
+ add(KEY_RO, "KEY_RO");
|
|
|
+ add(KEY_KATAKANA, "KEY_KATAKANA");
|
|
|
+ add(KEY_HIRAGANA, "KEY_HIRAGANA");
|
|
|
+ add(KEY_HENKAN, "KEY_HENKAN");
|
|
|
+ add(KEY_KATAKANAHIRAGANA, "KEY_KATAKANAHIRAGANA");
|
|
|
+ add(KEY_MUHENKAN, "KEY_MUHENKAN");
|
|
|
+ add(KEY_KPJPCOMMA, "KEY_KPJPCOMMA");
|
|
|
+ add(KEY_KPENTER, "KEY_KPENTER");
|
|
|
+ add(KEY_RIGHTCTRL, "KEY_RIGHTCTRL");
|
|
|
+ add(KEY_KPSLASH, "KEY_KPSLASH");
|
|
|
+ add(KEY_SYSRQ, "KEY_SYSRQ");
|
|
|
+ add(KEY_RIGHTALT, "KEY_RIGHTALT");
|
|
|
+ add(KEY_LINEFEED, "KEY_LINEFEED");
|
|
|
+ add(KEY_HOME, "KEY_HOME");
|
|
|
+ add(KEY_UP, "KEY_UP");
|
|
|
+ add(KEY_PAGEUP, "KEY_PAGEUP");
|
|
|
+ add(KEY_LEFT, "KEY_LEFT");
|
|
|
+ add(KEY_RIGHT, "KEY_RIGHT");
|
|
|
+ add(KEY_END, "KEY_END");
|
|
|
+ add(KEY_DOWN, "KEY_DOWN");
|
|
|
+ add(KEY_PAGEDOWN, "KEY_PAGEDOWN");
|
|
|
+ add(KEY_INSERT, "KEY_INSERT");
|
|
|
+ add(KEY_DELETE, "KEY_DELETE");
|
|
|
+ add(KEY_MACRO, "KEY_MACRO");
|
|
|
+ add(KEY_MUTE, "KEY_MUTE");
|
|
|
+ add(KEY_VOLUMEDOWN, "KEY_VOLUMEDOWN");
|
|
|
+ add(KEY_VOLUMEUP, "KEY_VOLUMEUP");
|
|
|
+ add(KEY_POWER, "KEY_POWER");
|
|
|
+ add(KEY_KPEQUAL, "KEY_KPEQUAL");
|
|
|
+ add(KEY_KPPLUSMINUS, "KEY_KPPLUSMINUS");
|
|
|
+ add(KEY_PAUSE, "KEY_PAUSE");
|
|
|
+ add(KEY_KPCOMMA, "KEY_KPCOMMA");
|
|
|
+ add(KEY_HANGEUL, "KEY_HANGEUL");
|
|
|
+ add(KEY_HANGUEL, "KEY_HANGUEL");
|
|
|
+ add(KEY_HANJA, "KEY_HANJA");
|
|
|
+ add(KEY_YEN, "KEY_YEN");
|
|
|
+ add(KEY_LEFTMETA, "KEY_LEFTMETA");
|
|
|
+ add(KEY_RIGHTMETA, "KEY_RIGHTMETA");
|
|
|
+ add(KEY_COMPOSE, "KEY_COMPOSE");
|
|
|
+ add(KEY_STOP, "KEY_STOP");
|
|
|
+ add(KEY_AGAIN, "KEY_AGAIN");
|
|
|
+ add(KEY_PROPS, "KEY_PROPS");
|
|
|
+ add(KEY_UNDO, "KEY_UNDO");
|
|
|
+ add(KEY_FRONT, "KEY_FRONT");
|
|
|
+ add(KEY_COPY, "KEY_COPY");
|
|
|
+ add(KEY_OPEN, "KEY_OPEN");
|
|
|
+ add(KEY_PASTE, "KEY_PASTE");
|
|
|
+ add(KEY_FIND, "KEY_FIND");
|
|
|
+ add(KEY_CUT, "KEY_CUT");
|
|
|
+ add(KEY_HELP, "KEY_HELP");
|
|
|
+ add(KEY_MENU, "KEY_MENU");
|
|
|
+ add(KEY_CALC, "KEY_CALC");
|
|
|
+ add(KEY_SETUP, "KEY_SETUP");
|
|
|
+ add(KEY_SLEEP, "KEY_SLEEP");
|
|
|
+ add(KEY_WAKEUP, "KEY_WAKEUP");
|
|
|
+ add(KEY_FILE, "KEY_FILE");
|
|
|
+ add(KEY_SENDFILE, "KEY_SENDFILE");
|
|
|
+ add(KEY_DELETEFILE, "KEY_DELETEFILE");
|
|
|
+ add(KEY_XFER, "KEY_XFER");
|
|
|
+ add(KEY_PROG1, "KEY_PROG1");
|
|
|
+ add(KEY_PROG2, "KEY_PROG2");
|
|
|
+ add(KEY_WWW, "KEY_WWW");
|
|
|
+ add(KEY_MSDOS, "KEY_MSDOS");
|
|
|
+ add(KEY_COFFEE, "KEY_COFFEE");
|
|
|
+ add(KEY_SCREENLOCK, "KEY_SCREENLOCK");
|
|
|
+ add(KEY_DIRECTION, "KEY_DIRECTION");
|
|
|
+ add(KEY_CYCLEWINDOWS, "KEY_CYCLEWINDOWS");
|
|
|
+ add(KEY_MAIL, "KEY_MAIL");
|
|
|
+ add(KEY_BOOKMARKS, "KEY_BOOKMARKS");
|
|
|
+ add(KEY_COMPUTER, "KEY_COMPUTER");
|
|
|
+ add(KEY_BACK, "KEY_BACK");
|
|
|
+ add(KEY_FORWARD, "KEY_FORWARD");
|
|
|
+ add(KEY_CLOSECD, "KEY_CLOSECD");
|
|
|
+ add(KEY_EJECTCD, "KEY_EJECTCD");
|
|
|
+ add(KEY_EJECTCLOSECD, "KEY_EJECTCLOSECD");
|
|
|
+ add(KEY_NEXTSONG, "KEY_NEXTSONG");
|
|
|
+ add(KEY_PLAYPAUSE, "KEY_PLAYPAUSE");
|
|
|
+ add(KEY_PREVIOUSSONG, "KEY_PREVIOUSSONG");
|
|
|
+ add(KEY_STOPCD, "KEY_STOPCD");
|
|
|
+ add(KEY_RECORD, "KEY_RECORD");
|
|
|
+ add(KEY_REWIND, "KEY_REWIND");
|
|
|
+ add(KEY_PHONE, "KEY_PHONE");
|
|
|
+ add(KEY_ISO, "KEY_ISO");
|
|
|
+ add(KEY_CONFIG, "KEY_CONFIG");
|
|
|
+ add(KEY_HOMEPAGE, "KEY_HOMEPAGE");
|
|
|
+ add(KEY_REFRESH, "KEY_REFRESH");
|
|
|
+ add(KEY_EXIT, "KEY_EXIT");
|
|
|
+ add(KEY_MOVE, "KEY_MOVE");
|
|
|
+ add(KEY_EDIT, "KEY_EDIT");
|
|
|
+ add(KEY_SCROLLUP, "KEY_SCROLLUP");
|
|
|
+ add(KEY_SCROLLDOWN, "KEY_SCROLLDOWN");
|
|
|
+ add(KEY_KPLEFTPAREN, "KEY_KPLEFTPAREN");
|
|
|
+ add(KEY_KPRIGHTPAREN, "KEY_KPRIGHTPAREN");
|
|
|
+ add(KEY_NEW, "KEY_NEW");
|
|
|
+ add(KEY_REDO, "KEY_REDO");
|
|
|
+ add(KEY_F13, "KEY_F13");
|
|
|
+ add(KEY_F14, "KEY_F14");
|
|
|
+ add(KEY_F15, "KEY_F15");
|
|
|
+ add(KEY_F16, "KEY_F16");
|
|
|
+ add(KEY_F17, "KEY_F17");
|
|
|
+ add(KEY_F18, "KEY_F18");
|
|
|
+ add(KEY_F19, "KEY_F19");
|
|
|
+ add(KEY_F20, "KEY_F20");
|
|
|
+ add(KEY_F21, "KEY_F21");
|
|
|
+ add(KEY_F22, "KEY_F22");
|
|
|
+ add(KEY_F23, "KEY_F23");
|
|
|
+ add(KEY_F24, "KEY_F24");
|
|
|
+ add(KEY_PLAYCD, "KEY_PLAYCD");
|
|
|
+ add(KEY_PAUSECD, "KEY_PAUSECD");
|
|
|
+ add(KEY_PROG3, "KEY_PROG3");
|
|
|
+ add(KEY_PROG4, "KEY_PROG4");
|
|
|
+ add(KEY_SUSPEND, "KEY_SUSPEND");
|
|
|
+ add(KEY_CLOSE, "KEY_CLOSE");
|
|
|
+ add(KEY_PLAY, "KEY_PLAY");
|
|
|
+ add(KEY_FASTFORWARD, "KEY_FASTFORWARD");
|
|
|
+ add(KEY_BASSBOOST, "KEY_BASSBOOST");
|
|
|
+ add(KEY_PRINT, "KEY_PRINT");
|
|
|
+ add(KEY_HP, "KEY_HP");
|
|
|
+ add(KEY_CAMERA, "KEY_CAMERA");
|
|
|
+ add(KEY_SOUND, "KEY_SOUND");
|
|
|
+ add(KEY_QUESTION, "KEY_QUESTION");
|
|
|
+ add(KEY_EMAIL, "KEY_EMAIL");
|
|
|
+ add(KEY_CHAT, "KEY_CHAT");
|
|
|
+ add(KEY_SEARCH, "KEY_SEARCH");
|
|
|
+ add(KEY_CONNECT, "KEY_CONNECT");
|
|
|
+ add(KEY_FINANCE, "KEY_FINANCE");
|
|
|
+ add(KEY_SPORT, "KEY_SPORT");
|
|
|
+ add(KEY_SHOP, "KEY_SHOP");
|
|
|
+ add(KEY_ALTERASE, "KEY_ALTERASE");
|
|
|
+ add(KEY_CANCEL, "KEY_CANCEL");
|
|
|
+ add(KEY_BRIGHTNESSDOWN, "KEY_BRIGHTNESSDOWN");
|
|
|
+ add(KEY_BRIGHTNESSUP, "KEY_BRIGHTNESSUP");
|
|
|
+ add(KEY_MEDIA, "KEY_MEDIA");
|
|
|
+ add(KEY_SWITCHVIDEOMODE, "KEY_SWITCHVIDEOMODE");
|
|
|
+ add(KEY_KBDILLUMTOGGLE, "KEY_KBDILLUMTOGGLE");
|
|
|
+ add(KEY_KBDILLUMDOWN, "KEY_KBDILLUMDOWN");
|
|
|
+ add(KEY_KBDILLUMUP, "KEY_KBDILLUMUP");
|
|
|
+ add(KEY_SEND, "KEY_SEND");
|
|
|
+ add(KEY_REPLY, "KEY_REPLY");
|
|
|
+ add(KEY_FORWARDMAIL, "KEY_FORWARDMAIL");
|
|
|
+ add(KEY_SAVE, "KEY_SAVE");
|
|
|
+ add(KEY_DOCUMENTS, "KEY_DOCUMENTS");
|
|
|
+ add(KEY_BATTERY, "KEY_BATTERY");
|
|
|
+ add(KEY_BLUETOOTH, "KEY_BLUETOOTH");
|
|
|
+ add(KEY_WLAN, "KEY_WLAN");
|
|
|
+ add(KEY_UWB, "KEY_UWB");
|
|
|
+ add(KEY_UNKNOWN, "KEY_UNKNOWN");
|
|
|
+ add(KEY_VIDEO_NEXT, "KEY_VIDEO_NEXT");
|
|
|
+ add(KEY_VIDEO_PREV, "KEY_VIDEO_PREV");
|
|
|
+ add(KEY_BRIGHTNESS_CYCLE, "KEY_BRIGHTNESS_CYCLE");
|
|
|
+ add(KEY_BRIGHTNESS_ZERO, "KEY_BRIGHTNESS_ZERO");
|
|
|
+ add(KEY_DISPLAY_OFF, "KEY_DISPLAY_OFF");
|
|
|
+ add(KEY_WIMAX, "KEY_WIMAX");
|
|
|
+ add(BTN_MISC, "BTN_MISC");
|
|
|
+ add(BTN_0, "BTN_0");
|
|
|
+ add(BTN_1, "BTN_1");
|
|
|
+ add(BTN_2, "BTN_2");
|
|
|
+ add(BTN_3, "BTN_3");
|
|
|
+ add(BTN_4, "BTN_4");
|
|
|
+ add(BTN_5, "BTN_5");
|
|
|
+ add(BTN_6, "BTN_6");
|
|
|
+ add(BTN_7, "BTN_7");
|
|
|
+ add(BTN_8, "BTN_8");
|
|
|
+ add(BTN_9, "BTN_9");
|
|
|
+ add(BTN_MOUSE, "BTN_MOUSE");
|
|
|
+ add(BTN_LEFT, "BTN_LEFT");
|
|
|
+ add(BTN_RIGHT, "BTN_RIGHT");
|
|
|
+ add(BTN_MIDDLE, "BTN_MIDDLE");
|
|
|
+ add(BTN_SIDE, "BTN_SIDE");
|
|
|
+ add(BTN_EXTRA, "BTN_EXTRA");
|
|
|
+ add(BTN_FORWARD, "BTN_FORWARD");
|
|
|
+ add(BTN_BACK, "BTN_BACK");
|
|
|
+ add(BTN_TASK, "BTN_TASK");
|
|
|
+ add(BTN_JOYSTICK, "BTN_JOYSTICK");
|
|
|
+ add(BTN_TRIGGER, "BTN_TRIGGER"); // 0 buttons
|
|
|
+ add(BTN_THUMB, "BTN_THUMB");
|
|
|
+ add(BTN_THUMB2, "BTN_THUMB2");
|
|
|
+ add(BTN_TOP, "BTN_TOP");
|
|
|
+ add(BTN_TOP2, "BTN_TOP2");
|
|
|
+ add(BTN_PINKIE, "BTN_PINKIE");
|
|
|
+ add(BTN_BASE, "BTN_BASE");
|
|
|
+ add(BTN_BASE2, "BTN_BASE2");
|
|
|
+ add(BTN_BASE3, "BTN_BASE3");
|
|
|
+ add(BTN_BASE4, "BTN_BASE4");
|
|
|
+ add(BTN_BASE5, "BTN_BASE5");
|
|
|
+ add(BTN_BASE6, "BTN_BASE6"); // 11 buttons
|
|
|
+ add(BTN_DEAD, "BTN_DEAD");
|
|
|
+ add(BTN_GAMEPAD, "BTN_GAMEPAD");
|
|
|
+ add(BTN_A, "BTN_A");
|
|
|
+ add(BTN_B, "BTN_B");
|
|
|
+ add(BTN_C, "BTN_C");
|
|
|
+ add(BTN_X, "BTN_X");
|
|
|
+ add(BTN_Y, "BTN_Y");
|
|
|
+ add(BTN_Z, "BTN_Z");
|
|
|
+ add(BTN_TL, "BTN_TL");
|
|
|
+ add(BTN_TR, "BTN_TR");
|
|
|
+ add(BTN_TL2, "BTN_TL2");
|
|
|
+ add(BTN_TR2, "BTN_TR2");
|
|
|
+ add(BTN_SELECT, "BTN_SELECT");
|
|
|
+ add(BTN_START, "BTN_START");
|
|
|
+ add(BTN_MODE, "BTN_MODE");
|
|
|
+ add(BTN_THUMBL, "BTN_THUMBL");
|
|
|
+ add(BTN_THUMBR, "BTN_THUMBR");
|
|
|
+ add(BTN_DIGI, "BTN_DIGI");
|
|
|
+ add(BTN_TOOL_PEN, "BTN_TOOL_PEN");
|
|
|
+ add(BTN_TOOL_RUBBER, "BTN_TOOL_RUBBER");
|
|
|
+ add(BTN_TOOL_BRUSH, "BTN_TOOL_BRUSH");
|
|
|
+ add(BTN_TOOL_PENCIL, "BTN_TOOL_PENCIL");
|
|
|
+ add(BTN_TOOL_AIRBRUSH, "BTN_TOOL_AIRBRUSH");
|
|
|
+ add(BTN_TOOL_FINGER, "BTN_TOOL_FINGER");
|
|
|
+ add(BTN_TOOL_MOUSE, "BTN_TOOL_MOUSE");
|
|
|
+ add(BTN_TOOL_LENS, "BTN_TOOL_LENS");
|
|
|
+ add(BTN_TOUCH, "BTN_TOUCH");
|
|
|
+ add(BTN_STYLUS, "BTN_STYLUS");
|
|
|
+ add(BTN_STYLUS2, "BTN_STYLUS2");
|
|
|
+ add(BTN_TOOL_DOUBLETAP, "BTN_TOOL_DOUBLETAP");
|
|
|
+ add(BTN_TOOL_TRIPLETAP, "BTN_TOOL_TRIPLETAP");
|
|
|
+ add(BTN_WHEEL, "BTN_WHEEL");
|
|
|
+ add(BTN_GEAR_DOWN, "BTN_GEAR_DOWN");
|
|
|
+ add(BTN_GEAR_UP, "BTN_GEAR_UP");
|
|
|
+ add(KEY_OK, "KEY_OK");
|
|
|
+ add(KEY_SELECT, "KEY_SELECT");
|
|
|
+ add(KEY_GOTO, "KEY_GOTO");
|
|
|
+ add(KEY_CLEAR, "KEY_CLEAR");
|
|
|
+ add(KEY_POWER2, "KEY_POWER2");
|
|
|
+ add(KEY_OPTION, "KEY_OPTION");
|
|
|
+ add(KEY_INFO, "KEY_INFO");
|
|
|
+ add(KEY_TIME, "KEY_TIME");
|
|
|
+ add(KEY_VENDOR, "KEY_VENDOR");
|
|
|
+ add(KEY_ARCHIVE, "KEY_ARCHIVE");
|
|
|
+ add(KEY_PROGRAM, "KEY_PROGRAM");
|
|
|
+ add(KEY_CHANNEL, "KEY_CHANNEL");
|
|
|
+ add(KEY_FAVORITES, "KEY_FAVORITES");
|
|
|
+ add(KEY_EPG, "KEY_EPG");
|
|
|
+ add(KEY_PVR, "KEY_PVR");
|
|
|
+ add(KEY_MHP, "KEY_MHP");
|
|
|
+ add(KEY_LANGUAGE, "KEY_LANGUAGE");
|
|
|
+ add(KEY_TITLE, "KEY_TITLE");
|
|
|
+ add(KEY_SUBTITLE, "KEY_SUBTITLE");
|
|
|
+ add(KEY_ANGLE, "KEY_ANGLE");
|
|
|
+ add(KEY_ZOOM, "KEY_ZOOM");
|
|
|
+ add(KEY_MODE, "KEY_MODE");
|
|
|
+ add(KEY_KEYBOARD, "KEY_KEYBOARD");
|
|
|
+ add(KEY_SCREEN, "KEY_SCREEN");
|
|
|
+ add(KEY_PC, "KEY_PC");
|
|
|
+ add(KEY_TV, "KEY_TV");
|
|
|
+ add(KEY_TV2, "KEY_TV2");
|
|
|
+ add(KEY_VCR, "KEY_VCR");
|
|
|
+ add(KEY_VCR2, "KEY_VCR2");
|
|
|
+ add(KEY_SAT, "KEY_SAT");
|
|
|
+ add(KEY_SAT2, "KEY_SAT2");
|
|
|
+ add(KEY_CD, "KEY_CD");
|
|
|
+ add(KEY_TAPE, "KEY_TAPE");
|
|
|
+ add(KEY_RADIO, "KEY_RADIO");
|
|
|
+ add(KEY_TUNER, "KEY_TUNER");
|
|
|
+ add(KEY_PLAYER, "KEY_PLAYER");
|
|
|
+ add(KEY_TEXT, "KEY_TEXT");
|
|
|
+ add(KEY_DVD, "KEY_DVD");
|
|
|
+ add(KEY_AUX, "KEY_AUX");
|
|
|
+ add(KEY_MP3, "KEY_MP3");
|
|
|
+ add(KEY_AUDIO, "KEY_AUDIO");
|
|
|
+ add(KEY_VIDEO, "KEY_VIDEO");
|
|
|
+ add(KEY_DIRECTORY, "KEY_DIRECTORY");
|
|
|
+ add(KEY_LIST, "KEY_LIST");
|
|
|
+ add(KEY_MEMO, "KEY_MEMO");
|
|
|
+ add(KEY_CALENDAR, "KEY_CALENDAR");
|
|
|
+ add(KEY_RED, "KEY_RED");
|
|
|
+ add(KEY_GREEN, "KEY_GREEN");
|
|
|
+ add(KEY_YELLOW, "KEY_YELLOW");
|
|
|
+ add(KEY_BLUE, "KEY_BLUE");
|
|
|
+ add(KEY_CHANNELUP, "KEY_CHANNELUP");
|
|
|
+ add(KEY_CHANNELDOWN, "KEY_CHANNELDOWN");
|
|
|
+ add(KEY_FIRST, "KEY_FIRST");
|
|
|
+ add(KEY_LAST, "KEY_LAST");
|
|
|
+ add(KEY_AB, "KEY_AB");
|
|
|
+ add(KEY_NEXT, "KEY_NEXT");
|
|
|
+ add(KEY_RESTART, "KEY_RESTART");
|
|
|
+ add(KEY_SLOW, "KEY_SLOW");
|
|
|
+ add(KEY_SHUFFLE, "KEY_SHUFFLE");
|
|
|
+ add(KEY_BREAK, "KEY_BREAK");
|
|
|
+ add(KEY_PREVIOUS, "KEY_PREVIOUS");
|
|
|
+ add(KEY_DIGITS, "KEY_DIGITS");
|
|
|
+ add(KEY_TEEN, "KEY_TEEN");
|
|
|
+ add(KEY_TWEN, "KEY_TWEN");
|
|
|
+ add(KEY_VIDEOPHONE, "KEY_VIDEOPHONE");
|
|
|
+ add(KEY_GAMES, "KEY_GAMES");
|
|
|
+ add(KEY_ZOOMIN, "KEY_ZOOMIN");
|
|
|
+ add(KEY_ZOOMOUT, "KEY_ZOOMOUT");
|
|
|
+ add(KEY_ZOOMRESET, "KEY_ZOOMRESET");
|
|
|
+ add(KEY_WORDPROCESSOR, "KEY_WORDPROCESSOR");
|
|
|
+ add(KEY_EDITOR, "KEY_EDITOR");
|
|
|
+ add(KEY_SPREADSHEET, "KEY_SPREADSHEET");
|
|
|
+ add(KEY_GRAPHICSEDITOR, "KEY_GRAPHICSEDITOR");
|
|
|
+ add(KEY_PRESENTATION, "KEY_PRESENTATION");
|
|
|
+ add(KEY_DATABASE, "KEY_DATABASE");
|
|
|
+ add(KEY_NEWS, "KEY_NEWS");
|
|
|
+ add(KEY_VOICEMAIL, "KEY_VOICEMAIL");
|
|
|
+ add(KEY_ADDRESSBOOK, "KEY_ADDRESSBOOK");
|
|
|
+ add(KEY_MESSENGER, "KEY_MESSENGER");
|
|
|
+ add(KEY_DISPLAYTOGGLE, "KEY_DISPLAYTOGGLE");
|
|
|
+ add(KEY_SPELLCHECK, "KEY_SPELLCHECK");
|
|
|
+ add(KEY_LOGOFF, "KEY_LOGOFF");
|
|
|
+ add(KEY_DOLLAR, "KEY_DOLLAR");
|
|
|
+ add(KEY_EURO, "KEY_EURO");
|
|
|
+ add(KEY_FRAMEBACK, "KEY_FRAMEBACK");
|
|
|
+ add(KEY_FRAMEFORWARD, "KEY_FRAMEFORWARD");
|
|
|
+ add(KEY_CONTEXT_MENU, "KEY_CONTEXT_MENU");
|
|
|
+#ifdef KEY_MEDIA_REPEAT
|
|
|
+ add(KEY_MEDIA_REPEAT, "KEY_MEDIA_REPEAT");
|
|
|
+#endif
|
|
|
+ add(KEY_DEL_EOL, "KEY_DEL_EOL");
|
|
|
+ add(KEY_DEL_EOS, "KEY_DEL_EOS");
|
|
|
+ add(KEY_INS_LINE, "KEY_INS_LINE");
|
|
|
+ add(KEY_DEL_LINE, "KEY_DEL_LINE");
|
|
|
+ add(KEY_FN, "KEY_FN");
|
|
|
+ add(KEY_FN_ESC, "KEY_FN_ESC");
|
|
|
+ add(KEY_FN_F1, "KEY_FN_F1");
|
|
|
+ add(KEY_FN_F2, "KEY_FN_F2");
|
|
|
+ add(KEY_FN_F3, "KEY_FN_F3");
|
|
|
+ add(KEY_FN_F4, "KEY_FN_F4");
|
|
|
+ add(KEY_FN_F5, "KEY_FN_F5");
|
|
|
+ add(KEY_FN_F6, "KEY_FN_F6");
|
|
|
+ add(KEY_FN_F7, "KEY_FN_F7");
|
|
|
+ add(KEY_FN_F8, "KEY_FN_F8");
|
|
|
+ add(KEY_FN_F9, "KEY_FN_F9");
|
|
|
+ add(KEY_FN_F10, "KEY_FN_F10");
|
|
|
+ add(KEY_FN_F11, "KEY_FN_F11");
|
|
|
+ add(KEY_FN_F12, "KEY_FN_F12");
|
|
|
+ add(KEY_FN_1, "KEY_FN_1");
|
|
|
+ add(KEY_FN_2, "KEY_FN_2");
|
|
|
+ add(KEY_FN_D, "KEY_FN_D");
|
|
|
+ add(KEY_FN_E, "KEY_FN_E");
|
|
|
+ add(KEY_FN_F, "KEY_FN_F");
|
|
|
+ add(KEY_FN_S, "KEY_FN_S");
|
|
|
+ add(KEY_FN_B, "KEY_FN_B");
|
|
|
+ add(KEY_BRL_DOT1, "KEY_BRL_DOT1");
|
|
|
+ add(KEY_BRL_DOT2, "KEY_BRL_DOT2");
|
|
|
+ add(KEY_BRL_DOT3, "KEY_BRL_DOT3");
|
|
|
+ add(KEY_BRL_DOT4, "KEY_BRL_DOT4");
|
|
|
+ add(KEY_BRL_DOT5, "KEY_BRL_DOT5");
|
|
|
+ add(KEY_BRL_DOT6, "KEY_BRL_DOT6");
|
|
|
+ add(KEY_BRL_DOT7, "KEY_BRL_DOT7");
|
|
|
+ add(KEY_BRL_DOT8, "KEY_BRL_DOT8");
|
|
|
+ add(KEY_BRL_DOT9, "KEY_BRL_DOT9");
|
|
|
+ add(KEY_BRL_DOT10, "KEY_BRL_DOT10");
|
|
|
+ add(KEY_MIN_INTERESTING, "KEY_MIN_INTERESTING");
|
|
|
+ }
|
|
|
+} evdev_btn_names;
|
|
|
+
|
|
|
+class Keysym2Keycode
|
|
|
+{
|
|
|
+public:
|
|
|
+ // Map KeySym to kernel keycode
|
|
|
+ std::map<KeySym, int> mapping;
|
|
|
+
|
|
|
+ Keysym2Keycode()
|
|
|
+ {
|
|
|
+ // std::cout << "Initing Keysym2Keycode" << std::endl;
|
|
|
+
|
|
|
+ Display *dpy = XOpenDisplay(NULL);
|
|
|
+ if (!dpy)
|
|
|
+ {
|
|
|
+ throw std::runtime_error("Keysym2Keycode: Couldn't open X11 display");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ process_keymap(dpy);
|
|
|
+ XCloseDisplay(dpy);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void process_keymap(Display *dpy)
|
|
|
+ {
|
|
|
+ int min_keycode, max_keycode;
|
|
|
+ XDisplayKeycodes(dpy, &min_keycode, &max_keycode);
|
|
|
+
|
|
|
+ int num_keycodes = max_keycode - min_keycode + 1;
|
|
|
+ int keysyms_per_keycode;
|
|
|
+ KeySym *keymap = XGetKeyboardMapping(dpy, min_keycode,
|
|
|
+ num_keycodes,
|
|
|
+ &keysyms_per_keycode);
|
|
|
+
|
|
|
+ for (int i = 0; i < num_keycodes; ++i)
|
|
|
+ {
|
|
|
+ if (keymap[i * keysyms_per_keycode] != NoSymbol)
|
|
|
+ {
|
|
|
+ KeySym keysym = keymap[i * keysyms_per_keycode];
|
|
|
+ // FIXME: Duplicate entries confuse the conversion
|
|
|
+ // std::map<KeySym, int>::iterator it = mapping.find(keysym);
|
|
|
+ // if (it != mapping.end())
|
|
|
+ // std::cout << "Duplicate keycode: " << i << std::endl;
|
|
|
+ mapping[keysym] = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ XFree(keymap);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+int xkeysym2keycode(const std::string &name)
|
|
|
+{
|
|
|
+ static Keysym2Keycode sym2code;
|
|
|
+
|
|
|
+ KeySym keysym = XStringToKeysym(name.substr(3).c_str());
|
|
|
+
|
|
|
+ if (keysym == NoSymbol)
|
|
|
+ {
|
|
|
+ throw std::runtime_error("xkeysym2keycode: Couldn't convert name '" + name + "' to xkeysym");
|
|
|
+ }
|
|
|
+
|
|
|
+ std::map<KeySym, int>::iterator i = sym2code.mapping.find(keysym);
|
|
|
+ if (i == sym2code.mapping.end())
|
|
|
+ {
|
|
|
+ throw std::runtime_error("xkeysym2keycode: Couldn't convert xkeysym '" + name + "' to evdev keycode");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (0)
|
|
|
+ std::cout << name << " -> " << keysym << " -> " << XKeysymToString(keysym)
|
|
|
+ << " -> " << btn2str(i->second) << "(" << i->second << ")" << std::endl;
|
|
|
+ return i->second;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool str2event(const std::string &name, int &type, int &code)
|
|
|
+{
|
|
|
+ if (name == "void" || name == "none")
|
|
|
+ {
|
|
|
+ type = -1;
|
|
|
+ code = -1;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (name.compare(0, 3, "REL") == 0)
|
|
|
+ {
|
|
|
+ type = EV_REL;
|
|
|
+ code = evdev_rel_names[name];
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (name.compare(0, 3, "ABS") == 0)
|
|
|
+ {
|
|
|
+ type = EV_ABS;
|
|
|
+ code = evdev_abs_names[name];
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (name.compare(0, 2, "XK") == 0)
|
|
|
+ {
|
|
|
+ type = EV_KEY;
|
|
|
+ code = xkeysym2keycode(name);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (name.compare(0, 2, "JS") == 0)
|
|
|
+ {
|
|
|
+ int int_value = 0;
|
|
|
+ std::istringstream(name.substr(3)) >> int_value;
|
|
|
+
|
|
|
+ type = EV_KEY;
|
|
|
+ code = BTN_JOYSTICK + int_value;
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (name.compare(0, 3, "KEY") == 0 ||
|
|
|
+ name.compare(0, 3, "BTN") == 0)
|
|
|
+ {
|
|
|
+ type = EV_KEY;
|
|
|
+ code = evdev_btn_names[name];
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+std::string btn2str(int i)
|
|
|
+{
|
|
|
+ return evdev_btn_names[i];
|
|
|
+}
|
|
|
+
|
|
|
+std::string abs2str(int i)
|
|
|
+{
|
|
|
+ return evdev_abs_names[i];
|
|
|
+}
|
|
|
+
|
|
|
+std::string rel2str(int i)
|
|
|
+{
|
|
|
+ return evdev_rel_names[i];
|
|
|
+}
|
|
|
+
|
|
|
+/* EOF */
|