2个分析input event事件的开源工具evtest,getevent

来源:互联网 发布:500价位入耳耳机 知乎 编辑:程序博客网 时间:2024/05/12 18:56
linux 的/etc/input/eventxx 设备可以用来方便地调试 鼠标、键盘、触摸板等输入设备
有两个开源可用来读取input event事件的值,evtest与getevent(这个是从android中提取的)

evtest
Evtest.c

点击(此处)折叠或打开

  1. /*
  2.  * $Id: evtest.c,v 1.23 2005/02/06 13:51:42 vojtech Exp $
  3.  *
  4.  * Copyright (c) 1999-2000 Vojtech Pavlik
  5.  *
  6.  * Event device test program
  7.  */

  8. /*
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or 
  12.  * (at your option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17.  * GNU General Public License for more details.
  18.  * 
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22.  * 
  23.  * Should you need to contact me, the author, you can do so either by
  24.  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  25.  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  26.  */

  27. #include <stdint.h>

  28. #include <linux/input.h>

  29. #include <string.h>
  30. #include <fcntl.h>
  31. #include <unistd.h>
  32. #include <stdio.h>

  33. #ifndef EV_SYN
  34. #define EV_SYN 0
  35. #endif

  36. char *events[EV_MAX + 1] = {
  37.     [... EV_MAX] = NULL,
  38.     [EV_SYN] = "Sync",            [EV_KEY] = "Key",
  39.     [EV_REL] = "Relative",            [EV_ABS] = "Absolute",
  40.     [EV_MSC] = "Misc",            [EV_LED] = "LED",
  41.     [EV_SND] = "Sound",            [EV_REP] = "Repeat",
  42.     [EV_FF] = "ForceFeedback",        [EV_PWR] = "Power",
  43.     [EV_FF_STATUS] = "ForceFeedbackStatus",
  44. };

  45. char *keys[KEY_MAX + 1] = {
  46.     [... KEY_MAX] = NULL,
  47.     [KEY_RESERVED] = "Reserved",        [KEY_ESC] = "Esc",
  48.     [KEY_1] = "1",                [KEY_2] = "2",
  49.     [KEY_3] = "3",                [KEY_4] = "4",
  50.     [KEY_5] = "5",                [KEY_6] = "6",
  51.     [KEY_7] = "7",                [KEY_8] = "8",
  52.     [KEY_9] = "9",                [KEY_0] = "0",
  53.     [KEY_MINUS] = "Minus",            [KEY_EQUAL] = "Equal",
  54.     [KEY_BACKSPACE] = "Backspace",        [KEY_TAB] = "Tab",
  55.     [KEY_Q] = "Q",                [KEY_W] = "W",
  56.     [KEY_E] = "E",                [KEY_R] = "R",
  57.     [KEY_T] = "T",                [KEY_Y] = "Y",
  58.     [KEY_U] = "U",                [KEY_I] = "I",
  59.     [KEY_O] = "O",                [KEY_P] = "P",
  60.     [KEY_LEFTBRACE] = "LeftBrace",        [KEY_RIGHTBRACE] = "RightBrace",
  61.     [KEY_ENTER] = "Enter",            [KEY_LEFTCTRL] = "LeftControl",
  62.     [KEY_A] = "A",                [KEY_S] = "S",
  63.     [KEY_D] = "D",                [KEY_F] = "F",
  64.     [KEY_G] = "G",                [KEY_H] = "H",
  65.     [KEY_J] = "J",                [KEY_K] = "K",
  66.     [KEY_L] = "L",                [KEY_SEMICOLON] = "Semicolon",
  67.     [KEY_APOSTROPHE] = "Apostrophe",    [KEY_GRAVE] = "Grave",
  68.     [KEY_LEFTSHIFT] = "LeftShift",        [KEY_BACKSLASH] = "BackSlash",
  69.     [KEY_Z] = "Z",                [KEY_X] = "X",
  70.     [KEY_C] = "C",                [KEY_V] = "V",
  71.     [KEY_B] = "B",                [KEY_N] = "N",
  72.     [KEY_M] = "M",                [KEY_COMMA] = "Comma",
  73.     [KEY_DOT] = "Dot",            [KEY_SLASH] = "Slash",
  74.     [KEY_RIGHTSHIFT] = "RightShift",    [KEY_KPASTERISK] = "KPAsterisk",
  75.     [KEY_LEFTALT] = "LeftAlt",        [KEY_SPACE] = "Space",
  76.     [KEY_CAPSLOCK] = "CapsLock",        [KEY_F1] = "F1",
  77.     [KEY_F2] = "F2",            [KEY_F3] = "F3",
  78.     [KEY_F4] = "F4",            [KEY_F5] = "F5",
  79.     [KEY_F6] = "F6",            [KEY_F7] = "F7",
  80.     [KEY_F8] = "F8",            [KEY_F9] = "F9",
  81.     [KEY_F10] = "F10",            [KEY_NUMLOCK] = "NumLock",
  82.     [KEY_SCROLLLOCK] = "ScrollLock",    [KEY_KP7] = "KP7",
  83.     [KEY_KP8] = "KP8",            [KEY_KP9] = "KP9",
  84.     [KEY_KPMINUS] = "KPMinus",        [KEY_KP4] = "KP4",
  85.     [KEY_KP5] = "KP5",            [KEY_KP6] = "KP6",
  86.     [KEY_KPPLUS] = "KPPlus",        [KEY_KP1] = "KP1",
  87.     [KEY_KP2] = "KP2",            [KEY_KP3] = "KP3",
  88.     [KEY_KP0] = "KP0",            [KEY_KPDOT] = "KPDot",
  89.     [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
  90.     [KEY_F11] = "F11",            [KEY_F12] = "F12",
  91.     [KEY_RO] = "RO",            [KEY_KATAKANA] = "Katakana",
  92.     [KEY_HIRAGANA] = "HIRAGANA",        [KEY_HENKAN] = "Henkan",
  93.     [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
  94.     [KEY_KPJPCOMMA] = "KPJpComma",        [KEY_KPENTER] = "KPEnter",
  95.     [KEY_RIGHTCTRL] = "RightCtrl",        [KEY_KPSLASH] = "KPSlash",
  96.     [KEY_SYSRQ] = "SysRq",            [KEY_RIGHTALT] = "RightAlt",
  97.     [KEY_LINEFEED] = "LineFeed",        [KEY_HOME] = "Home",
  98.     [KEY_UP] = "Up",            [KEY_PAGEUP] = "PageUp",
  99.     [KEY_LEFT] = "Left",            [KEY_RIGHT] = "Right",
  100.     [KEY_END] = "End",            [KEY_DOWN] = "Down",
  101.     [KEY_PAGEDOWN] = "PageDown",        [KEY_INSERT] = "Insert",
  102.     [KEY_DELETE] = "Delete",        [KEY_MACRO] = "Macro",
  103.     [KEY_MUTE] = "Mute",            [KEY_VOLUMEDOWN] = "VolumeDown",
  104.     [KEY_VOLUMEUP] = "VolumeUp",        [KEY_POWER] = "Power",
  105.     [KEY_KPEQUAL] = "KPEqual",        [KEY_KPPLUSMINUS] = "KPPlusMinus",
  106.     [KEY_PAUSE] = "Pause",            [KEY_KPCOMMA] = "KPComma",
  107.     [KEY_HANGUEL] = "Hanguel",        [KEY_HANJA] = "Hanja",
  108.     [KEY_YEN] = "Yen",            [KEY_LEFTMETA] = "LeftMeta",
  109.     [KEY_RIGHTMETA] = "RightMeta",        [KEY_COMPOSE] = "Compose",
  110.     [KEY_STOP] = "Stop",            [KEY_AGAIN] = "Again",
  111.     [KEY_PROPS] = "Props",            [KEY_UNDO] = "Undo",
  112.     [KEY_FRONT] = "Front",            [KEY_COPY] = "Copy",
  113.     [KEY_OPEN] = "Open",            [KEY_PASTE] = "Paste",
  114.     [KEY_FIND] = "Find",            [KEY_CUT] = "Cut",
  115.     [KEY_HELP] = "Help",            [KEY_MENU] = "Menu",
  116.     [KEY_CALC] = "Calc",            [KEY_SETUP] = "Setup",
  117.     [KEY_SLEEP] = "Sleep",            [KEY_WAKEUP] = "WakeUp",
  118.     [KEY_FILE] = "File",            [KEY_SENDFILE] = "SendFile",
  119.     [KEY_DELETEFILE] = "DeleteFile",    [KEY_XFER] = "X-fer",
  120.     [KEY_PROG1] = "Prog1",            [KEY_PROG2] = "Prog2",
  121.     [KEY_WWW] = "WWW",            [KEY_MSDOS] = "MSDOS",
  122.     [KEY_COFFEE] = "Coffee",        [KEY_DIRECTION] = "Direction",
  123.     [KEY_CYCLEWINDOWS] = "CycleWindows",    [KEY_MAIL] = "Mail",
  124.     [KEY_BOOKMARKS] = "Bookmarks",        [KEY_COMPUTER] = "Computer",
  125.     [KEY_BACK] = "Back",            [KEY_FORWARD] = "Forward",
  126.     [KEY_CLOSECD] = "CloseCD",        [KEY_EJECTCD] = "EjectCD",
  127.     [KEY_EJECTCLOSECD] = "EjectCloseCD",    [KEY_NEXTSONG] = "NextSong",
  128.     [KEY_PLAYPAUSE] = "PlayPause",        [KEY_PREVIOUSSONG] = "PreviousSong",
  129.     [KEY_STOPCD] = "StopCD",        [KEY_RECORD] = "Record",
  130.     [KEY_REWIND] = "Rewind",        [KEY_PHONE] = "Phone",
  131.     [KEY_ISO] = "ISOKey",            [KEY_CONFIG] = "Config",
  132.     [KEY_HOMEPAGE] = "HomePage",        [KEY_REFRESH] = "Refresh",
  133.     [KEY_EXIT] = "Exit",            [KEY_MOVE] = "Move",
  134.     [KEY_EDIT] = "Edit",            [KEY_SCROLLUP] = "ScrollUp",
  135.     [KEY_SCROLLDOWN] = "ScrollDown",    [KEY_KPLEFTPAREN] = "KPLeftParenthesis",
  136.     [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13",
  137.     [KEY_F14] = "F14",            [KEY_F15] = "F15",
  138.     [KEY_F16] = "F16",            [KEY_F17] = "F17",
  139.     [KEY_F18] = "F18",            [KEY_F19] = "F19",
  140.     [KEY_F20] = "F20",            [KEY_F21] = "F21",
  141.     [KEY_F22] = "F22",            [KEY_F23] = "F23",
  142.     [KEY_F24] = "F24",            [KEY_PLAYCD] = "PlayCD",
  143.     [KEY_PAUSECD] = "PauseCD",        [KEY_PROG3] = "Prog3",
  144.     [KEY_PROG4] = "Prog4",            [KEY_SUSPEND] = "Suspend",
  145.     [KEY_CLOSE] = "Close",            [KEY_PLAY] = "Play",
  146.     [KEY_FASTFORWARD] = "Fast Forward",    [KEY_BASSBOOST] = "Bass Boost",
  147.     [KEY_PRINT] = "Print",            [KEY_HP] = "HP",
  148.     [KEY_CAMERA] = "Camera",        [KEY_SOUND] = "Sound",
  149.     [KEY_QUESTION] = "Question",        [KEY_EMAIL] = "Email",
  150.     [KEY_CHAT] = "Chat",            [KEY_SEARCH] = "Search",
  151.     [KEY_CONNECT] = "Connect",        [KEY_FINANCE] = "Finance",
  152.     [KEY_SPORT] = "Sport",            [KEY_SHOP] = "Shop",
  153.     [KEY_ALTERASE] = "Alternate Erase",    [KEY_CANCEL] = "Cancel",
  154.     [KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = "Brightness up",
  155.     [KEY_MEDIA] = "Media",            [KEY_UNKNOWN] = "Unknown",
  156.     [BTN_0] = "Btn0",            [BTN_1] = "Btn1",
  157.     [BTN_2] = "Btn2",            [BTN_3] = "Btn3",
  158.     [BTN_4] = "Btn4",            [BTN_5] = "Btn5",
  159.     [BTN_6] = "Btn6",            [BTN_7] = "Btn7",
  160.     [BTN_8] = "Btn8",            [BTN_9] = "Btn9",
  161.     [BTN_LEFT] = "LeftBtn",            [BTN_RIGHT] = "RightBtn",
  162.     [BTN_MIDDLE] = "MiddleBtn",        [BTN_SIDE] = "SideBtn",
  163.     [BTN_EXTRA] = "ExtraBtn",        [BTN_FORWARD] = "ForwardBtn",
  164.     [BTN_BACK] = "BackBtn",            [BTN_TASK] = "TaskBtn",
  165.     [BTN_TRIGGER] = "Trigger",        [BTN_THUMB] = "ThumbBtn",
  166.     [BTN_THUMB2] = "ThumbBtn2",        [BTN_TOP] = "TopBtn",
  167.     [BTN_TOP2] = "TopBtn2",            [BTN_PINKIE] = "PinkieBtn",
  168.     [BTN_BASE] = "BaseBtn",            [BTN_BASE2] = "BaseBtn2",
  169.     [BTN_BASE3] = "BaseBtn3",        [BTN_BASE4] = "BaseBtn4",
  170.     [BTN_BASE5] = "BaseBtn5",        [BTN_BASE6] = "BaseBtn6",
  171.     [BTN_DEAD] = "BtnDead",            [BTN_A] = "BtnA",
  172.     [BTN_B] = "BtnB",            [BTN_C] = "BtnC",
  173.     [BTN_X] = "BtnX",            [BTN_Y] = "BtnY",
  174.     [BTN_Z] = "BtnZ",            [BTN_TL] = "BtnTL",
  175.     [BTN_TR] = "BtnTR",            [BTN_TL2] = "BtnTL2",
  176.     [BTN_TR2] = "BtnTR2",            [BTN_SELECT] = "BtnSelect",
  177.     [BTN_START] = "BtnStart",        [BTN_MODE] = "BtnMode",
  178.     [BTN_THUMBL] = "BtnThumbL",        [BTN_THUMBR] = "BtnThumbR",
  179.     [BTN_TOOL_PEN] = "ToolPen",        [BTN_TOOL_RUBBER] = "ToolRubber",
  180.     [BTN_TOOL_BRUSH] = "ToolBrush",        [BTN_TOOL_PENCIL] = "ToolPencil",
  181.     [BTN_TOOL_AIRBRUSH] = "ToolAirbrush",    [BTN_TOOL_FINGER] = "ToolFinger",
  182.     [BTN_TOOL_MOUSE] = "ToolMouse",        [BTN_TOOL_LENS] = "ToolLens",
  183.     [BTN_TOUCH] = "Touch",            [BTN_STYLUS] = "Stylus",
  184.     [BTN_STYLUS2] = "Stylus2",        [BTN_TOOL_DOUBLETAP] = "Tool Doubletap",
  185.     [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn",
  186.     [BTN_GEAR_UP] = "Gear up",        [KEY_OK] = "Ok",
  187.     [KEY_SELECT] = "Select",        [KEY_GOTO] = "Goto",
  188.     [KEY_CLEAR] = "Clear",            [KEY_POWER2] = "Power2",
  189.     [KEY_OPTION] = "Option",        [KEY_INFO] = "Info",
  190.     [KEY_TIME] = "Time",            [KEY_VENDOR] = "Vendor",
  191.     [KEY_ARCHIVE] = "Archive",        [KEY_PROGRAM] = "Program",
  192.     [KEY_CHANNEL] = "Channel",        [KEY_FAVORITES] = "Favorites",
  193.     [KEY_EPG] = "EPG",            [KEY_PVR] = "PVR",
  194.     [KEY_MHP] = "MHP",            [KEY_LANGUAGE] = "Language",
  195.     [KEY_TITLE] = "Title",            [KEY_SUBTITLE] = "Subtitle",
  196.     [KEY_ANGLE] = "Angle",            [KEY_ZOOM] = "Zoom",
  197.     [KEY_MODE] = "Mode",            [KEY_KEYBOARD] = "Keyboard",
  198.     [KEY_SCREEN] = "Screen",        [KEY_PC] = "PC",
  199.     [KEY_TV] = "TV",            [KEY_TV2] = "TV2",
  200.     [KEY_VCR] = "VCR",            [KEY_VCR2] = "VCR2",
  201.     [KEY_SAT] = "Sat",            [KEY_SAT2] = "Sat2",
  202.     [KEY_CD] = "CD",            [KEY_TAPE] = "Tape",
  203.     [KEY_RADIO] = "Radio",            [KEY_TUNER] = "Tuner",
  204.     [KEY_PLAYER] = "Player",        [KEY_TEXT] = "Text",
  205.     [KEY_DVD] = "DVD",            [KEY_AUX] = "Aux",
  206.     [KEY_MP3] = "MP3",            [KEY_AUDIO] = "Audio",
  207.     [KEY_VIDEO] = "Video",            [KEY_DIRECTORY] = "Directory",
  208.     [KEY_LIST] = "List",            [KEY_MEMO] = "Memo",
  209.     [KEY_CALENDAR] = "Calendar",        [KEY_RED] = "Red",
  210.     [KEY_GREEN] = "Green",            [KEY_YELLOW] = "Yellow",
  211.     [KEY_BLUE] = "Blue",            [KEY_CHANNELUP] = "ChannelUp",
  212.     [KEY_CHANNELDOWN] = "ChannelDown",    [KEY_FIRST] = "First",
  213.     [KEY_LAST] = "Last",            [KEY_AB] = "AB",
  214.     [KEY_NEXT] = "Next",            [KEY_RESTART] = "Restart",
  215.     [KEY_SLOW] = "Slow",            [KEY_SHUFFLE] = "Shuffle",
  216.     [KEY_BREAK] = "Break",            [KEY_PREVIOUS] = "Previous",
  217.     [KEY_DIGITS] = "Digits",        [KEY_TEEN] = "TEEN",
  218.     [KEY_TWEN] = "TWEN",            [KEY_DEL_EOL] = "Delete EOL",
  219.     [KEY_DEL_EOS] = "Delete EOS",        [KEY_INS_LINE] = "Insert line",
  220.     [KEY_DEL_LINE] = "Delete line",
  221. };

  222. char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };

  223. char *relatives[REL_MAX + 1] = {
  224.     [... REL_MAX] = NULL,
  225.     [REL_X] = "X",            [REL_Y] = "Y",
  226.     [REL_Z] = "Z",            [REL_HWHEEL] = "HWheel",
  227.     [REL_DIAL] = "Dial",        [REL_WHEEL] = "Wheel", 
  228.     [REL_MISC] = "Misc",    
  229. };

  230. char *absolutes[ABS_MAX + 1] = {
  231.     [... ABS_MAX] = NULL,
  232.     [ABS_X] = "X",            [ABS_Y] = "Y",
  233.     [ABS_Z] = "Z",            [ABS_RX] = "Rx",
  234.     [ABS_RY] = "Ry",        [ABS_RZ] = "Rz",
  235.     [ABS_THROTTLE] = "Throttle",    [ABS_RUDDER] = "Rudder",
  236.     [ABS_WHEEL] = "Wheel",        [ABS_GAS] = "Gas",
  237.     [ABS_BRAKE] = "Brake",        [ABS_HAT0X] = "Hat0X",
  238.     [ABS_HAT0Y] = "Hat0Y",        [ABS_HAT1X] = "Hat1X",
  239.     [ABS_HAT1Y] = "Hat1Y",        [ABS_HAT2X] = "Hat2X",
  240.     [ABS_HAT2Y] = "Hat2Y",        [ABS_HAT3X] = "Hat3X",
  241.     [ABS_HAT3Y] = "Hat 3Y",        [ABS_PRESSURE] = "Pressure",
  242.     [ABS_DISTANCE] = "Distance",    [ABS_TILT_X] = "XTilt",
  243.     [ABS_TILT_Y] = "YTilt",        [ABS_TOOL_WIDTH] = "Tool Width",
  244.     [ABS_VOLUME] = "Volume",    [ABS_MISC] = "Misc",
  245. };

  246. char *misc[MSC_MAX + 1] = {
  247.     [ 0 ... MSC_MAX] = NULL,
  248.     [MSC_SERIAL] = "Serial",    [MSC_PULSELED] = "Pulseled",
  249.     [MSC_GESTURE] = "Gesture",    [MSC_RAW] = "RawData",
  250.     [MSC_SCAN] = "ScanCode",
  251. };

  252. char *leds[LED_MAX + 1] = {
  253.     [... LED_MAX] = NULL,
  254.     [LED_NUML] = "NumLock",        [LED_CAPSL] = "CapsLock", 
  255.     [LED_SCROLLL] = "ScrollLock",    [LED_COMPOSE] = "Compose",
  256.     [LED_KANA] = "Kana",        [LED_SLEEP] = "Sleep", 
  257.     [LED_SUSPEND] = "Suspend",    [LED_MUTE] = "Mute",
  258.     [LED_MISC] = "Misc",
  259. };

  260. char *repeats[REP_MAX + 1] = {
  261.     [... REP_MAX] = NULL,
  262.     [REP_DELAY] = "Delay",        [REP_PERIOD] = "Period"
  263. };

  264. char *sounds[SND_MAX + 1] = {
  265.     [... SND_MAX] = NULL,
  266.     [SND_CLICK] = "Click",        [SND_BELL] = "Bell",
  267.     [SND_TONE] = "Tone"
  268. };

  269. char **names[EV_MAX + 1] = {
  270.     [... EV_MAX] = NULL,
  271.     [EV_SYN] = events,            [EV_KEY] = keys,
  272.     [EV_REL] = relatives,            [EV_ABS] = absolutes,
  273.     [EV_MSC] = misc,            [EV_LED] = leds,
  274.     [EV_SND] = sounds,            [EV_REP] = repeats,
  275. };

  276. #define BITS_PER_LONG (sizeof(long) * 8)
  277. #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
  278. #define OFF(x) ((x)%BITS_PER_LONG)
  279. #define BIT(x) (1UL<<OFF(x))
  280. #define LONG(x) ((x)/BITS_PER_LONG)
  281. #define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)

  282. int main (int argc, char **argv)
  283. {
  284.     int fd, rd, i, j, k;
  285.     struct input_event ev[64];
  286.     int version;
  287.     unsigned short id[4];
  288.     unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
  289.     char name[256] = "Unknown";
  290.     int abs[5];

  291.     if (argc < 2) {
  292.         printf("Usage: evtest /dev/input/eventX\n");
  293.         printf("Where X = input device number\n");
  294.         return 1;
  295.     }

  296.     if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
  297.         perror("evtest");
  298.         return 1;
  299.     }

  300.     if (ioctl(fd, EVIOCGVERSION, &version)) {
  301.         perror("evtest: can't get version");
  302.         return 1;
  303.     }

  304.     printf("Input driver version is %d.%d.%d\n",
  305.         version >> 16, (version >> 8) & 0xff, version & 0xff);

  306.     ioctl(fd, EVIOCGID, id);
  307.     printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
  308.         id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

  309.     ioctl(fd, EVIOCGNAME(sizeof(name)), name);
  310.     printf("Input device name: \"%s\"\n", name);

  311.     memset(bit, 0, sizeof(bit));
  312.     ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
  313.     printf("Supported events:\n");

  314.     for (= 0; i < EV_MAX; i++)
  315.         if (test_bit(i, bit[0])) {
  316.             printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
  317.             if (!i) continue;
  318.             ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
  319.             for (= 0; j < KEY_MAX; j++) 
  320.                 if (test_bit(j, bit[i])) {
  321.                     printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
  322.                     if (== EV_ABS) {
  323.                         ioctl(fd, EVIOCGABS(j), abs);
  324.                         for (= 0; k < 5; k++)
  325.                             if ((< 3) || abs[k])
  326.                                 printf(" %s %6d\n", absval[k], abs[k]);
  327.                     }
  328.                 }
  329.         }
  330.         

  331.     printf("Testing ... (interrupt to exit)\n");

  332.     while (1) {
  333.         rd = read(fd, ev, sizeof(struct input_event) * 64);

  334.         if (rd < (int) sizeof(struct input_event)) {
  335.             printf("yyy\n");
  336.             perror("\nevtest: error reading");
  337.             return 1;
  338.         }

  339.         for (= 0; i < rd / sizeof(struct input_event); i++)

  340.             if (ev[i].type == EV_SYN) {
  341.                 printf("Event: time %ld.%06ld, -------------- %s ------------\n",
  342.                     ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
  343.             } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
  344.                 printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
  345.                     ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  346.                     events[ev[i].type] ? events[ev[i].type] : "?",
  347.                     ev[i].code,
  348.                     names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  349.                     ev[i].value);
  350.             } else {
  351.                 printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
  352.                     ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  353.                     events[ev[i].type] ? events[ev[i].type] : "?",
  354.                     ev[i].code,
  355.                     names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  356.                     ev[i].value);
  357.             }    

  358.     }
  359. }
gcc  Evtest.c -o evtest

getevent单独提取出来在linux下编译做了些修改

getevent.h

点击(此处)折叠或打开

  1. #include <linux/input.h>
  2. #include <stdio.h>

  3. struct label {
  4.     const char *name;
  5.     int value;
  6. };

  7. #define LABEL(constant) { #constant, constant }
  8. #define LABEL_END { NULL, -1 }

  9. static struct label input_prop_labels[] = {
  10.         LABEL(INPUT_PROP_POINTER),
  11.         LABEL(INPUT_PROP_DIRECT),
  12.         LABEL(INPUT_PROP_BUTTONPAD),
  13.         LABEL(INPUT_PROP_SEMI_MT),
  14.         LABEL_END,
  15. };

  16. static struct label ev_labels[] = {
  17.         LABEL(EV_SYN),
  18.         LABEL(EV_KEY),
  19.         LABEL(EV_REL),
  20.         LABEL(EV_ABS),
  21.         LABEL(EV_MSC),
  22.         LABEL(EV_SW),
  23.         LABEL(EV_LED),
  24.         LABEL(EV_SND),
  25.         LABEL(EV_REP),
  26.         LABEL(EV_FF),
  27.         LABEL(EV_PWR),
  28.         LABEL(EV_FF_STATUS),
  29.         LABEL_END,
  30. };

  31. static struct label syn_labels[] = {
  32.         LABEL(SYN_REPORT),
  33.         LABEL(SYN_CONFIG),
  34.         LABEL(SYN_MT_REPORT),
  35.         LABEL(SYN_DROPPED),
  36.         LABEL_END,
  37. };

  38. static struct label key_labels[] = {
  39.         LABEL(KEY_RESERVED),
  40.         LABEL(KEY_ESC),
  41.         LABEL(KEY_1),
  42.         LABEL(KEY_2),
  43.         LABEL(KEY_3),
  44.         LABEL(KEY_4),
  45.         LABEL(KEY_5),
  46.         LABEL(KEY_6),
  47.         LABEL(KEY_7),
  48.         LABEL(KEY_8),
  49.         LABEL(KEY_9),
  50.         LABEL(KEY_0),
  51.         LABEL(KEY_MINUS),
  52.         LABEL(KEY_EQUAL),
  53.         LABEL(KEY_BACKSPACE),
  54.         LABEL(KEY_TAB),
  55.         LABEL(KEY_Q),
  56.         LABEL(KEY_W),
  57.         LABEL(KEY_E),
  58.         LABEL(KEY_R),
  59.         LABEL(KEY_T),
  60.         LABEL(KEY_Y),
  61.         LABEL(KEY_U),
  62.         LABEL(KEY_I),
  63.         LABEL(KEY_O),
  64.         LABEL(KEY_P),
  65.         LABEL(KEY_LEFTBRACE),
  66.         LABEL(KEY_RIGHTBRACE),
  67.         LABEL(KEY_ENTER),
  68.         LABEL(KEY_LEFTCTRL),
  69.         LABEL(KEY_A),
  70.         LABEL(KEY_S),
  71.         LABEL(KEY_D),
  72.         LABEL(KEY_F),
  73.         LABEL(KEY_G),
  74.         LABEL(KEY_H),
  75.         LABEL(KEY_J),
  76.         LABEL(KEY_K),
  77.         LABEL(KEY_L),
  78.         LABEL(KEY_SEMICOLON),
  79.         LABEL(KEY_APOSTROPHE),
  80.         LABEL(KEY_GRAVE),
  81.         LABEL(KEY_LEFTSHIFT),
  82.         LABEL(KEY_BACKSLASH),
  83.         LABEL(KEY_Z),
  84.         LABEL(KEY_X),
  85.         LABEL(KEY_C),
  86.         LABEL(KEY_V),
  87.         LABEL(KEY_B),
  88.         LABEL(KEY_N),
  89.         LABEL(KEY_M),
  90.         LABEL(KEY_COMMA),
  91.         LABEL(KEY_DOT),
  92.         LABEL(KEY_SLASH),
  93.         LABEL(KEY_RIGHTSHIFT),
  94.         LABEL(KEY_KPASTERISK),
  95.         LABEL(KEY_LEFTALT),
  96.         LABEL(KEY_SPACE),
  97.         LABEL(KEY_CAPSLOCK),
  98.         LABEL(KEY_F1),
  99.         LABEL(KEY_F2),
  100.         LABEL(KEY_F3),
  101.         LABEL(KEY_F4),
  102.         LABEL(KEY_F5),
  103.         LABEL(KEY_F6),
  104.         LABEL(KEY_F7),
  105.         LABEL(KEY_F8),
  106.         LABEL(KEY_F9),
  107.         LABEL(KEY_F10),
  108.         LABEL(KEY_NUMLOCK),
  109.         LABEL(KEY_SCROLLLOCK),
  110.         LABEL(KEY_KP7),
  111.         LABEL(KEY_KP8),
  112.         LABEL(KEY_KP9),
  113.         LABEL(KEY_KPMINUS),
  114.         LABEL(KEY_KP4),
  115.         LABEL(KEY_KP5),
  116.         LABEL(KEY_KP6),
  117.         LABEL(KEY_KPPLUS),
  118.         LABEL(KEY_KP1),
  119.         LABEL(KEY_KP2),
  120.         LABEL(KEY_KP3),
  121.         LABEL(KEY_KP0),
  122.         LABEL(KEY_KPDOT),
  123.         LABEL(KEY_ZENKAKUHANKAKU),
  124.         LABEL(KEY_102ND),
  125.         LABEL(KEY_F11),
  126.         LABEL(KEY_F12),
  127.         LABEL(KEY_RO),
  128.         LABEL(KEY_KATAKANA),
  129.         LABEL(KEY_HIRAGANA),
  130.         LABEL(KEY_HENKAN),
  131.         LABEL(KEY_KATAKANAHIRAGANA),
  132.         LABEL(KEY_MUHENKAN),
  133.         LABEL(KEY_KPJPCOMMA),
  134.         LABEL(KEY_KPENTER),
  135.         LABEL(KEY_RIGHTCTRL),
  136.         LABEL(KEY_KPSLASH),
  137.         LABEL(KEY_SYSRQ),
  138.         LABEL(KEY_RIGHTALT),
  139.         LABEL(KEY_LINEFEED),
  140.         LABEL(KEY_HOME),
  141.         LABEL(KEY_UP),
  142.         LABEL(KEY_PAGEUP),
  143.         LABEL(KEY_LEFT),
  144.         LABEL(KEY_RIGHT),
  145.         LABEL(KEY_END),
  146.         LABEL(KEY_DOWN),
  147.         LABEL(KEY_PAGEDOWN),
  148.         LABEL(KEY_INSERT),
  149.         LABEL(KEY_DELETE),
  150.         LABEL(KEY_MACRO),
  151.         LABEL(KEY_MUTE),
  152.         LABEL(KEY_VOLUMEDOWN),
  153.         LABEL(KEY_VOLUMEUP),
  154.         LABEL(KEY_POWER),
  155.         LABEL(KEY_KPEQUAL),
  156.         LABEL(KEY_KPPLUSMINUS),
  157.         LABEL(KEY_PAUSE),
  158.         LABEL(KEY_SCALE),
  159.         LABEL(KEY_KPCOMMA),
  160.         LABEL(KEY_HANGEUL),
  161.         LABEL(KEY_HANGUEL),
  162.         LABEL(KEY_HANJA),
  163.         LABEL(KEY_YEN),
  164.         LABEL(KEY_LEFTMETA),
  165.         LABEL(KEY_RIGHTMETA),
  166.         LABEL(KEY_COMPOSE),
  167.         LABEL(KEY_STOP),
  168.         LABEL(KEY_AGAIN),
  169.         LABEL(KEY_PROPS),
  170.         LABEL(KEY_UNDO),
  171.         LABEL(KEY_FRONT),
  172.         LABEL(KEY_COPY),
  173.         LABEL(KEY_OPEN),
  174.         LABEL(KEY_PASTE),
  175.         LABEL(KEY_FIND),
  176.         LABEL(KEY_CUT),
  177.         LABEL(KEY_HELP),
  178.         LABEL(KEY_MENU),
  179.         LABEL(KEY_CALC),
  180.         LABEL(KEY_SETUP),
  181.         LABEL(KEY_SLEEP),
  182.         LABEL(KEY_WAKEUP),
  183.         LABEL(KEY_FILE),
  184.         LABEL(KEY_SENDFILE),
  185.         LABEL(KEY_DELETEFILE),
  186.         LABEL(KEY_XFER),
  187.         LABEL(KEY_PROG1),
  188.         LABEL(KEY_PROG2),
  189.         LABEL(KEY_WWW),
  190.         LABEL(KEY_MSDOS),
  191.         LABEL(KEY_COFFEE),
  192.         LABEL(KEY_SCREENLOCK),
  193.         LABEL(KEY_DIRECTION),
  194.         LABEL(KEY_CYCLEWINDOWS),
  195.         LABEL(KEY_MAIL),
  196.         LABEL(KEY_BOOKMARKS),
  197.         LABEL(KEY_COMPUTER),
  198.         LABEL(KEY_BACK),
  199.         LABEL(KEY_FORWARD),
  200.         LABEL(KEY_CLOSECD),
  201.         LABEL(KEY_EJECTCD),
  202.         LABEL(KEY_EJECTCLOSECD),
  203.         LABEL(KEY_NEXTSONG),
  204.         LABEL(KEY_PLAYPAUSE),
  205.         LABEL(KEY_PREVIOUSSONG),
  206.         LABEL(KEY_STOPCD),
  207.         LABEL(KEY_RECORD),
  208.         LABEL(KEY_REWIND),
  209.         LABEL(KEY_PHONE),
  210.         LABEL(KEY_ISO),
  211.         LABEL(KEY_CONFIG),
  212.         LABEL(KEY_HOMEPAGE),
  213.         LABEL(KEY_REFRESH),
  214.         LABEL(KEY_EXIT),
  215.         LABEL(KEY_MOVE),
  216.         LABEL(KEY_EDIT),
  217.         LABEL(KEY_SCROLLUP),
  218.         LABEL(KEY_SCROLLDOWN),
  219.         LABEL(KEY_KPLEFTPAREN),
  220.         LABEL(KEY_KPRIGHTPAREN),
  221.         LABEL(KEY_NEW),
  222.         LABEL(KEY_REDO),
  223.         LABEL(KEY_F13),
  224.         LABEL(KEY_F14),
  225.         LABEL(KEY_F15),
  226.         LABEL(KEY_F16),
  227.         LABEL(KEY_F17),
  228.         LABEL(KEY_F18),
  229.         LABEL(KEY_F19),
  230.         LABEL(KEY_F20),
  231.         LABEL(KEY_F21),
  232.         LABEL(KEY_F22),
  233.         LABEL(KEY_F23),
  234.         LABEL(KEY_F24),
  235.         LABEL(KEY_PLAYCD),
  236.         LABEL(KEY_PAUSECD),
  237.         LABEL(KEY_PROG3),
  238.         LABEL(KEY_PROG4),
  239.         LABEL(KEY_DASHBOARD),
  240.         LABEL(KEY_SUSPEND),
  241.         LABEL(KEY_CLOSE),
  242.         LABEL(KEY_PLAY),
  243.         LABEL(KEY_FASTFORWARD),
  244.         LABEL(KEY_BASSBOOST),
  245.         LABEL(KEY_PRINT),
  246.         LABEL(KEY_HP),
  247.         LABEL(KEY_CAMERA),
  248.         LABEL(KEY_SOUND),
  249.         LABEL(KEY_QUESTION),
  250.         LABEL(KEY_EMAIL),
  251.         LABEL(KEY_CHAT),
  252.         LABEL(KEY_SEARCH),
  253.         LABEL(KEY_CONNECT),
  254.         LABEL(KEY_FINANCE),
  255.         LABEL(KEY_SPORT),
  256.         LABEL(KEY_SHOP),
  257.         LABEL(KEY_ALTERASE),
  258.         LABEL(KEY_CANCEL),
  259.         LABEL(KEY_BRIGHTNESSDOWN),
  260.         LABEL(KEY_BRIGHTNESSUP),
  261.         LABEL(KEY_MEDIA),
  262.         LABEL(KEY_SWITCHVIDEOMODE),
  263.         LABEL(KEY_KBDILLUMTOGGLE),
  264.         LABEL(KEY_KBDILLUMDOWN),
  265.         LABEL(KEY_KBDILLUMUP),
  266.         LABEL(KEY_SEND),
  267.         LABEL(KEY_REPLY),
  268.         LABEL(KEY_FORWARDMAIL),
  269.         LABEL(KEY_SAVE),
  270.         LABEL(KEY_DOCUMENTS),
  271.         LABEL(KEY_BATTERY),
  272.         LABEL(KEY_BLUETOOTH),
  273.         LABEL(KEY_WLAN),
  274.         LABEL(KEY_UWB),
  275.         LABEL(KEY_UNKNOWN),
  276.         LABEL(KEY_VIDEO_NEXT),
  277.         LABEL(KEY_VIDEO_PREV),
  278.         LABEL(KEY_BRIGHTNESS_CYCLE),
  279.         LABEL(KEY_BRIGHTNESS_ZERO),
  280.         LABEL(KEY_DISPLAY_OFF),
  281.         LABEL(KEY_WIMAX),
  282.         LABEL(KEY_RFKILL),
  283.         LABEL(BTN_0),
  284.         LABEL(BTN_1),
  285.         LABEL(BTN_2),
  286.         LABEL(BTN_3),
  287.         LABEL(BTN_4),
  288.         LABEL(BTN_5),
  289.         LABEL(BTN_6),
  290.         LABEL(BTN_7),
  291.         LABEL(BTN_8),
  292.         LABEL(BTN_9),
  293.         LABEL(BTN_LEFT),
  294.         LABEL(BTN_RIGHT),
  295.         LABEL(BTN_MIDDLE),
  296.         LABEL(BTN_SIDE),
  297.         LABEL(BTN_EXTRA),
  298.         LABEL(BTN_FORWARD),
  299.         LABEL(BTN_BACK),
  300.         LABEL(BTN_TASK),
  301.         LABEL(BTN_JOYSTICK),
  302.         LABEL(BTN_TRIGGER),
  303.         LABEL(BTN_THUMB),
  304.         LABEL(BTN_THUMB2),
  305.         LABEL(BTN_TOP),
  306.         LABEL(BTN_TOP2),
  307.         LABEL(BTN_PINKIE),
  308.         LABEL(BTN_BASE),
  309.         LABEL(BTN_BASE2),
  310.         LABEL(BTN_BASE3),
  311.         LABEL(BTN_BASE4),
  312.         LABEL(BTN_BASE5),
  313.         LABEL(BTN_BASE6),
  314.         LABEL(BTN_DEAD),
  315.         LABEL(BTN_A),
  316.         LABEL(BTN_B),
  317.         LABEL(BTN_C),
  318.         LABEL(BTN_X),
  319.         LABEL(BTN_Y),
  320.         LABEL(BTN_Z),
  321.         LABEL(BTN_TL),
  322.         LABEL(BTN_TR),
  323.         LABEL(BTN_TL2),
  324.         LABEL(BTN_TR2),
  325.         LABEL(BTN_SELECT),
  326.         LABEL(BTN_START),
  327.         LABEL(BTN_MODE),
  328.         LABEL(BTN_THUMBL),
  329.         LABEL(BTN_THUMBR),
  330.         LABEL(BTN_TOOL_PEN),
  331.         LABEL(BTN_TOOL_RUBBER),
  332.         LABEL(BTN_TOOL_BRUSH),
  333.         LABEL(BTN_TOOL_PENCIL),
  334.         LABEL(BTN_TOOL_AIRBRUSH),
  335.         LABEL(BTN_TOOL_FINGER),
  336.         LABEL(BTN_TOOL_MOUSE),
  337.         LABEL(BTN_TOOL_LENS),
  338.         LABEL(BTN_TOUCH),
  339.         LABEL(BTN_STYLUS),
  340.         LABEL(BTN_STYLUS2),
  341.         LABEL(BTN_TOOL_DOUBLETAP),
  342.         LABEL(BTN_TOOL_TRIPLETAP),
  343.         LABEL(BTN_TOOL_QUADTAP),
  344.         LABEL(BTN_GEAR_DOWN),
  345.         LABEL(BTN_GEAR_UP),
  346.         LABEL(KEY_OK),
  347.         LABEL(KEY_SELECT),
  348.         LABEL(KEY_GOTO),
  349.         LABEL(KEY_CLEAR),
  350.         LABEL(KEY_POWER2),
  351.         LABEL(KEY_OPTION),
  352.         LABEL(KEY_INFO),
  353.         LABEL(KEY_TIME),
  354.         LABEL(KEY_VENDOR),
  355.         LABEL(KEY_ARCHIVE),
  356.         LABEL(KEY_PROGRAM),
  357.         LABEL(KEY_CHANNEL),
  358.         LABEL(KEY_FAVORITES),
  359.         LABEL(KEY_EPG),
  360.         LABEL(KEY_PVR),
  361.         LABEL(KEY_MHP),
  362.         LABEL(KEY_LANGUAGE),
  363.         LABEL(KEY_TITLE),
  364.         LABEL(KEY_SUBTITLE),
  365.         LABEL(KEY_ANGLE),
  366.         LABEL(KEY_ZOOM),
  367.         LABEL(KEY_MODE),
  368.         LABEL(KEY_KEYBOARD),
  369.         LABEL(KEY_SCREEN),
  370.         LABEL(KEY_PC),
  371.         LABEL(KEY_TV),
  372.         LABEL(KEY_TV2),
  373.         LABEL(KEY_VCR),
  374.         LABEL(KEY_VCR2),
  375.         LABEL(KEY_SAT),
  376.         LABEL(KEY_SAT2),
  377.         LABEL(KEY_CD),
  378.         LABEL(KEY_TAPE),
  379.         LABEL(KEY_RADIO),
  380.         LABEL(KEY_TUNER),
  381.         LABEL(KEY_PLAYER),
  382.         LABEL(KEY_TEXT),
  383.         LABEL(KEY_DVD),
  384.         LABEL(KEY_AUX),
  385.         LABEL(KEY_MP3),
  386.         LABEL(KEY_AUDIO),
  387.         LABEL(KEY_VIDEO),
  388.         LABEL(KEY_DIRECTORY),
  389.         LABEL(KEY_LIST),
  390.         LABEL(KEY_MEMO),
  391.         LABEL(KEY_CALENDAR),
  392.         LABEL(KEY_RED),
  393.         LABEL(KEY_GREEN),
  394.         LABEL(KEY_YELLOW),
  395.         LABEL(KEY_BLUE),
  396.         LABEL(KEY_CHANNELUP),
  397.         LABEL(KEY_CHANNELDOWN),
  398.         LABEL(KEY_FIRST),
  399.         LABEL(KEY_LAST),
  400.         LABEL(KEY_AB),
  401.         LABEL(KEY_NEXT),
  402.         LABEL(KEY_RESTART),
  403.         LABEL(KEY_SLOW),
  404.         LABEL(KEY_SHUFFLE),
  405.         LABEL(KEY_BREAK),
  406.         LABEL(KEY_PREVIOUS),
  407.         LABEL(KEY_DIGITS),
  408.         LABEL(KEY_TEEN),
  409.         LABEL(KEY_TWEN),
  410.         LABEL(KEY_VIDEOPHONE),
  411.         LABEL(KEY_GAMES),
  412.         LABEL(KEY_ZOOMIN),
  413.         LABEL(KEY_ZOOMOUT),
  414.         LABEL(KEY_ZOOMRESET),
  415.         LABEL(KEY_WORDPROCESSOR),
  416.         LABEL(KEY_EDITOR),
  417.         LABEL(KEY_SPREADSHEET),
  418.         LABEL(KEY_GRAPHICSEDITOR),
  419.         LABEL(KEY_PRESENTATION),
  420.         LABEL(KEY_DATABASE),
  421.         LABEL(KEY_NEWS),
  422.         LABEL(KEY_VOICEMAIL),
  423.         LABEL(KEY_ADDRESSBOOK),
  424.         LABEL(KEY_MESSENGER),
  425.         LABEL(KEY_DISPLAYTOGGLE),
  426.         LABEL(KEY_SPELLCHECK),
  427.         LABEL(KEY_LOGOFF),
  428.         LABEL(KEY_DOLLAR),
  429.         LABEL(KEY_EURO),
  430.         LABEL(KEY_FRAMEBACK),
  431.         LABEL(KEY_FRAMEFORWARD),
  432.         LABEL(KEY_CONTEXT_MENU),
  433.         LABEL(KEY_MEDIA_REPEAT),
  434.         LABEL(KEY_10CHANNELSUP),
  435.         LABEL(KEY_10CHANNELSDOWN),
  436.         LABEL(KEY_IMAGES),
  437.         LABEL(KEY_DEL_EOL),
  438.         LABEL(KEY_DEL_EOS),
  439.         LABEL(KEY_INS_LINE),
  440.         LABEL(KEY_DEL_LINE),
  441.         LABEL(KEY_FN),
  442.         LABEL(KEY_FN_ESC),
  443.         LABEL(KEY_FN_F1),
  444.         LABEL(KEY_FN_F2),
  445.         LABEL(KEY_FN_F3),
  446.         LABEL(KEY_FN_F4),
  447.         LABEL(KEY_FN_F5),
  448.         LABEL(KEY_FN_F6),
  449.         LABEL(KEY_FN_F7),
  450.         LABEL(KEY_FN_F8),
  451.         LABEL(KEY_FN_F9),
  452.         LABEL(KEY_FN_F10),
  453.         LABEL(KEY_FN_F11),
  454.         LABEL(KEY_FN_F12),
  455.         LABEL(KEY_FN_1),
  456.         LABEL(KEY_FN_2),
  457.         LABEL(KEY_FN_D),
  458.         LABEL(KEY_FN_E),
  459.         LABEL(KEY_FN_F),
  460.         LABEL(KEY_FN_S),
  461.         LABEL(KEY_FN_B),
  462.         LABEL(KEY_BRL_DOT1),
  463.         LABEL(KEY_BRL_DOT2),
  464.         LABEL(KEY_BRL_DOT3),
  465.         LABEL(KEY_BRL_DOT4),
  466.         LABEL(KEY_BRL_DOT5),
  467.         LABEL(KEY_BRL_DOT6),
  468.         LABEL(KEY_BRL_DOT7),
  469.         LABEL(KEY_BRL_DOT8),
  470.         LABEL(KEY_BRL_DOT9),
  471.         LABEL(KEY_BRL_DOT10),
  472.         LABEL(KEY_NUMERIC_0),
  473.         LABEL(KEY_NUMERIC_1),
  474.         LABEL(KEY_NUMERIC_2),
  475.         LABEL(KEY_NUMERIC_3),
  476.         LABEL(KEY_NUMERIC_4),
  477.         LABEL(KEY_NUMERIC_5),
  478.         LABEL(KEY_NUMERIC_6),
  479.         LABEL(KEY_NUMERIC_7),
  480.         LABEL(KEY_NUMERIC_8),
  481.         LABEL(KEY_NUMERIC_9),
  482.         LABEL(KEY_NUMERIC_STAR),
  483.         LABEL(KEY_NUMERIC_POUND),
  484.         LABEL(KEY_CAMERA_FOCUS),
  485.         LABEL(KEY_WPS_BUTTON),
  486.         LABEL(KEY_TOUCHPAD_TOGGLE),
  487.         LABEL(KEY_TOUCHPAD_ON),
  488.         LABEL(KEY_TOUCHPAD_OFF),
  489.         LABEL(KEY_CAMERA_ZOOMIN),
  490.         LABEL(KEY_CAMERA_ZOOMOUT),
  491.         LABEL(KEY_CAMERA_UP),
  492.         LABEL(KEY_CAMERA_DOWN),
  493.         LABEL(KEY_CAMERA_LEFT),
  494.         LABEL(KEY_CAMERA_RIGHT),
  495.         LABEL(BTN_TRIGGER_HAPPY1),
  496.         LABEL(BTN_TRIGGER_HAPPY2),
  497.         LABEL(BTN_TRIGGER_HAPPY3),
  498.         LABEL(BTN_TRIGGER_HAPPY4),
  499.         LABEL(BTN_TRIGGER_HAPPY5),
  500.         LABEL(BTN_TRIGGER_HAPPY6),
  501.         LABEL(BTN_TRIGGER_HAPPY7),
  502.         LABEL(BTN_TRIGGER_HAPPY8),
  503.         LABEL(BTN_TRIGGER_HAPPY9),
  504.         LABEL(BTN_TRIGGER_HAPPY10),
  505.         LABEL(BTN_TRIGGER_HAPPY11),
  506.         LABEL(BTN_TRIGGER_HAPPY12),
  507.         LABEL(BTN_TRIGGER_HAPPY13),
  508.         LABEL(BTN_TRIGGER_HAPPY14),
  509.         LABEL(BTN_TRIGGER_HAPPY15),
  510.         LABEL(BTN_TRIGGER_HAPPY16),
  511.         LABEL(BTN_TRIGGER_HAPPY17),
  512.         LABEL(BTN_TRIGGER_HAPPY18),
  513.         LABEL(BTN_TRIGGER_HAPPY19),
  514.         LABEL(BTN_TRIGGER_HAPPY20),
  515.         LABEL(BTN_TRIGGER_HAPPY21),
  516.         LABEL(BTN_TRIGGER_HAPPY22),
  517.         LABEL(BTN_TRIGGER_HAPPY23),
  518.         LABEL(BTN_TRIGGER_HAPPY24),
  519.         LABEL(BTN_TRIGGER_HAPPY25),
  520.         LABEL(BTN_TRIGGER_HAPPY26),
  521.         LABEL(BTN_TRIGGER_HAPPY27),
  522.         LABEL(BTN_TRIGGER_HAPPY28),
  523.         LABEL(BTN_TRIGGER_HAPPY29),
  524.         LABEL(BTN_TRIGGER_HAPPY30),
  525.         LABEL(BTN_TRIGGER_HAPPY31),
  526.         LABEL(BTN_TRIGGER_HAPPY32),
  527.         LABEL(BTN_TRIGGER_HAPPY33),
  528.         LABEL(BTN_TRIGGER_HAPPY34),
  529.         LABEL(BTN_TRIGGER_HAPPY35),
  530.         LABEL(BTN_TRIGGER_HAPPY36),
  531.         LABEL(BTN_TRIGGER_HAPPY37),
  532.         LABEL(BTN_TRIGGER_HAPPY38),
  533.         LABEL(BTN_TRIGGER_HAPPY39),
  534.         LABEL(BTN_TRIGGER_HAPPY40),
  535.         LABEL_END,
  536. };

  537. static struct label rel_labels[] = {
  538.         LABEL(REL_X),
  539.         LABEL(REL_Y),
  540.         LABEL(REL_Z),
  541.         LABEL(REL_RX),
  542.         LABEL(REL_RY),
  543.         LABEL(REL_RZ),
  544.         LABEL(REL_HWHEEL),
  545.         LABEL(REL_DIAL),
  546.         LABEL(REL_WHEEL),
  547.         LABEL(REL_MISC),
  548.         LABEL_END,
  549. };

  550. static struct label abs_labels[] = {
  551.         LABEL(ABS_X),
  552.         LABEL(ABS_Y),
  553.         LABEL(ABS_Z),
  554.         LABEL(ABS_RX),
  555.         LABEL(ABS_RY),
  556.         LABEL(ABS_RZ),
  557.         LABEL(ABS_THROTTLE),
  558.         LABEL(ABS_RUDDER),
  559.         LABEL(ABS_WHEEL),
  560.         LABEL(ABS_GAS),
  561.         LABEL(ABS_BRAKE),
  562.         LABEL(ABS_HAT0X),
  563.         LABEL(ABS_HAT0Y),
  564.         LABEL(ABS_HAT1X),
  565.         LABEL(ABS_HAT1Y),
  566.         LABEL(ABS_HAT2X),
  567.         LABEL(ABS_HAT2Y),
  568.         LABEL(ABS_HAT3X),
  569.         LABEL(ABS_HAT3Y),
  570.         LABEL(ABS_PRESSURE),
  571.         LABEL(ABS_DISTANCE),
  572.         LABEL(ABS_TILT_X),
  573.         LABEL(ABS_TILT_Y),
  574.         LABEL(ABS_TOOL_WIDTH),
  575.         LABEL(ABS_VOLUME),
  576.         LABEL(ABS_MISC),
  577.         LABEL(ABS_MT_SLOT),
  578.         LABEL(ABS_MT_TOUCH_MAJOR),
  579.         LABEL(ABS_MT_TOUCH_MINOR),
  580.         LABEL(ABS_MT_WIDTH_MAJOR),
  581.         LABEL(ABS_MT_WIDTH_MINOR),
  582.         LABEL(ABS_MT_ORIENTATION),
  583.         LABEL(ABS_MT_POSITION_X),
  584.         LABEL(ABS_MT_POSITION_Y),
  585.         LABEL(ABS_MT_TOOL_TYPE),
  586.         LABEL(ABS_MT_BLOB_ID),
  587.         LABEL(ABS_MT_TRACKING_ID),
  588.         LABEL(ABS_MT_PRESSURE),
  589.         LABEL(ABS_MT_DISTANCE),
  590.         LABEL_END,
  591. };

  592. static struct label sw_labels[] = {
  593.         LABEL(SW_LID),
  594.         LABEL(SW_TABLET_MODE),
  595.         LABEL(SW_HEADPHONE_INSERT),
  596.         LABEL(SW_RFKILL_ALL),
  597.         LABEL(SW_RADIO),
  598.         LABEL(SW_MICROPHONE_INSERT),
  599.         LABEL(SW_DOCK),
  600.         LABEL(SW_LINEOUT_INSERT),
  601.         LABEL(SW_JACK_PHYSICAL_INSERT),
  602.         LABEL(SW_VIDEOOUT_INSERT),
  603.         LABEL(SW_CAMERA_LENS_COVER),
  604.         LABEL(SW_KEYPAD_SLIDE),
  605.         LABEL(SW_FRONT_PROXIMITY),
  606.         LABEL(SW_ROTATE_LOCK),
  607.         LABEL_END,
  608. };

  609. static struct label msc_labels[] = {
  610.         LABEL(MSC_SERIAL),
  611.         LABEL(MSC_PULSELED),
  612.         LABEL(MSC_GESTURE),
  613.         LABEL(MSC_RAW),
  614.         LABEL(MSC_SCAN),
  615.         LABEL_END,
  616. };

  617. static struct label led_labels[] = {
  618.         LABEL(LED_NUML),
  619.         LABEL(LED_CAPSL),
  620.         LABEL(LED_SCROLLL),
  621.         LABEL(LED_COMPOSE),
  622.         LABEL(LED_KANA),
  623.         LABEL(LED_SLEEP),
  624.         LABEL(LED_SUSPEND),
  625.         LABEL(LED_MUTE),
  626.         LABEL(LED_MISC),
  627.         LABEL(LED_MAIL),
  628.         LABEL(LED_CHARGING),
  629.         LABEL_END,
  630. };

  631. static struct label rep_labels[] = {
  632.         LABEL(REP_DELAY),
  633.         LABEL(REP_PERIOD),
  634.         LABEL_END,
  635. };

  636. static struct label snd_labels[] = {
  637.         LABEL(SND_CLICK),
  638.         LABEL(SND_BELL),
  639.         LABEL(SND_TONE),
  640.         LABEL_END,
  641. };

  642. #if 0
  643. static struct label id_labels[] = {
  644.         LABEL(ID_BUS),
  645.         LABEL(ID_VENDOR),
  646.         LABEL(ID_PRODUCT),
  647.         LABEL(ID_VERSION),
  648.         LABEL_END,
  649. };
  650. static struct label bus_labels[] = {
  651.         LABEL(BUS_PCI),
  652.         LABEL(BUS_ISAPNP),
  653.         LABEL(BUS_USB),
  654.         LABEL(BUS_HIL),
  655.         LABEL(BUS_BLUETOOTH),
  656.         LABEL(BUS_VIRTUAL),
  657.         LABEL(BUS_ISA),
  658.         LABEL(BUS_I8042),
  659.         LABEL(BUS_XTKBD),
  660.         LABEL(BUS_RS232),
  661.         LABEL(BUS_GAMEPORT),
  662.         LABEL(BUS_PARPORT),
  663.         LABEL(BUS_AMIGA),
  664.         LABEL(BUS_ADB),
  665.         LABEL(BUS_I2C),
  666.         LABEL(BUS_HOST),
  667.         LABEL(BUS_GSC),
  668.         LABEL(BUS_ATARI),
  669.         LABEL(BUS_SPI),
  670.         LABEL_END,
  671. };
  672. #endif

  673. static struct label mt_tool_labels[] = {
  674.         LABEL(MT_TOOL_FINGER),
  675.         LABEL(MT_TOOL_PEN),
  676.         LABEL(MT_TOOL_MAX),
  677.         LABEL_END,
  678. };

  679. static struct label ff_status_labels[] = {
  680.         LABEL(FF_STATUS_STOPPED),
  681.         LABEL(FF_STATUS_PLAYING),
  682.         LABEL(FF_STATUS_MAX),
  683.         LABEL_END,
  684. };

  685. static struct label ff_labels[] = {
  686.         LABEL(FF_RUMBLE),
  687.         LABEL(FF_PERIODIC),
  688.         LABEL(FF_CONSTANT),
  689.         LABEL(FF_SPRING),
  690.         LABEL(FF_FRICTION),
  691.         LABEL(FF_DAMPER),
  692.         LABEL(FF_INERTIA),
  693.         LABEL(FF_RAMP),
  694.         LABEL(FF_SQUARE),
  695.         LABEL(FF_TRIANGLE),
  696.         LABEL(FF_SINE),
  697.         LABEL(FF_SAW_UP),
  698.         LABEL(FF_SAW_DOWN),
  699.         LABEL(FF_CUSTOM),
  700.         LABEL(FF_GAIN),
  701.         LABEL(FF_AUTOCENTER),
  702.         LABEL_END,
  703. };

  704. static struct label key_value_labels[] = {
  705.         { "UP", 0 },
  706.         { "DOWN", 1 },
  707.         { "REPEAT", 2 },
  708.         LABEL_END,
  709. }

getevent.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <dirent.h>
  6. #include <fcntl.h>
  7. #include <sys/ioctl.h>
  8. #include <sys/inotify.h>
  9. #include <linux/limits.h>
  10. #include <sys/poll.h>
  11. #include <linux/input.h>
  12. #include <errno.h>
  13. #include <unistd.h>
  14. #include <time.h>

  15. #include "getevent.h"

  16. static struct pollfd *ufds;
  17. static char **device_names;
  18. static int nfds;

  19. enum {
  20.     PRINT_DEVICE_ERRORS = 1U << 0,
  21.     PRINT_DEVICE = 1U << 1,
  22.     PRINT_DEVICE_NAME = 1U << 2,
  23.     PRINT_DEVICE_INFO = 1U << 3,
  24.     PRINT_VERSION = 1U << 4,
  25.     PRINT_POSSIBLE_EVENTS = 1U << 5,
  26.     PRINT_INPUT_PROPS = 1U << 6,
  27.     PRINT_HID_DESCRIPTOR = 1U << 7,

  28.     PRINT_ALL_INFO = (1U << 8) - 1,

  29.     PRINT_LABELS = 1U << 16,
  30. };

  31. static const char *get_label(const struct label *labels, int value)
  32. {
  33.     while(labels->name && value != labels->value) {
  34.         labels++;
  35.     }
  36.     return labels->name;
  37. }

  38. static int print_input_props(int fd)
  39. {
  40.     uint8_t bits[INPUT_PROP_CNT / 8];
  41.     int i, j;
  42.     int res;
  43.     int count;
  44.     const char *bit_label;

  45.     printf(" input props:\n");
  46.     res = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits);
  47.     if(res < 0) {
  48.         printf(" <not available\n"<="" span="" style="word-wrap: break-word;">);
  49.         return 1;
  50.     }
  51.     count = 0;
  52.     for(= 0; i < res; i++) {
  53.         for(= 0; j < 8; j++) {
  54.             if (bits[i] & 1 << j) {
  55.                 bit_label = get_label(input_prop_labels, i * 8 + j);
  56.                 if(bit_label)
  57.                     printf(" %s\n", bit_label);
  58.                 else
  59.                     printf(" %04x\n", i * 8 + j);
  60.                 count++;
  61.             }
  62.         }
  63.     }
  64.     if (!count)
  65.         printf(" \n");
  66.     return 0;
  67. }

  68. static int print_possible_events(int fd, int print_flags)
  69. {
  70.     uint8_t *bits = NULL;
  71.     ssize_t bits_size = 0;
  72.     const char* label;
  73.     int i, j, k;
  74.     int res, res2;
  75.     struct label* bit_labels;
  76.     const char *bit_label;

  77.     printf(" events:\n");
  78.     for(= EV_KEY; i <= EV_MAX; i++) { // skip EV_SYN since we cannot query its available codes
  79.         int count = 0;
  80.         while(1) {
  81.             res = ioctl(fd, EVIOCGBIT(i, bits_size), bits);
  82.             if(res < bits_size)
  83.                 break;
  84.             bits_size = res + 16;
  85.             bits = realloc(bits, bits_size * 2);
  86.             if(bits == NULL) {
  87.                 fprintf(stderr, "failed to allocate buffer of size %d\n", (int)bits_size);
  88.                 return 1;
  89.             }
  90.         }
  91.         res2 = 0;
  92.         switch(i) {
  93.             case EV_KEY:
  94.                 res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
  95.                 label = "KEY";
  96.                 bit_labels = key_labels;
  97.                 break;
  98.             case EV_REL:
  99.                 label = "REL";
  100.                 bit_labels = rel_labels;
  101.                 break;
  102.             case EV_ABS:
  103.                 label = "ABS";
  104.                 bit_labels = abs_labels;
  105.                 break;
  106.             case EV_MSC:
  107.                 label = "MSC";
  108.                 bit_labels = msc_labels;
  109.                 break;
  110.             case EV_LED:
  111.                 res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
  112.                 label = "LED";
  113.                 bit_labels = led_labels;
  114.                 break;
  115.             case EV_SND:
  116.                 res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
  117.                 label = "SND";
  118.                 bit_labels = snd_labels;
  119.                 break;
  120.             case EV_SW:
  121.                 res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
  122.                 label = "SW ";
  123.                 bit_labels = sw_labels;
  124.                 break;
  125.             case EV_REP:
  126.                 label = "REP";
  127.                 bit_labels = rep_labels;
  128.                 break;
  129.             case EV_FF:
  130.                 label = "FF ";
  131.                 bit_labels = ff_labels;
  132.                 break;
  133.             case EV_PWR:
  134.                 label = "PWR";
  135.                 bit_labels = NULL;
  136.                 break;
  137.             case EV_FF_STATUS:
  138.                 label = "FFS";
  139.                 bit_labels = ff_status_labels;
  140.                 break;
  141.             default:
  142.                 res2 = 0;
  143.                 label = "???";
  144.                 bit_labels = NULL;
  145.         }
  146.         for(= 0; j < res; j++) {
  147.             for(= 0; k < 8; k++)
  148.                 if(bits[j] & 1 << k) {
  149.                     char down;
  150.                     if(< res2 && (bits[+ bits_size] & 1 << k))
  151.                         down = '*';
  152.                     else
  153.                         down = ' ';
  154.                     if(count == 0)
  155.                         printf(" %s (%04x):", label, i);
  156.                     else if((count & (print_flags & PRINT_LABELS ? 0x3 : 0x7)) == 0 || i == EV_ABS)
  157.                         printf("\n ");
  158.                     if(bit_labels && (print_flags & PRINT_LABELS)) {
  159.                         bit_label = get_label(bit_labels, j * 8 + k);
  160.                         if(bit_label)
  161.                             printf(" %.20s%c%*s", bit_label, down, (int) (20 - strlen(bit_label)), "");
  162.                         else
  163.                             printf(" %04x%c ", j * 8 + k, down);
  164.                     } else {
  165.                         printf(" %04x%c", j * 8 + k, down);
  166.                     }
  167.                     if(== EV_ABS) {
  168.                         struct input_absinfo abs;
  169.                         if(ioctl(fd, EVIOCGABS(* 8 + k), &abs) == 0) {
  170.                             printf(" : value %d, min %d, max %d, fuzz %d, flat %d, resolution %d",
  171.                                 abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat,
  172.                                 abs.resolution);
  173.                         }
  174.                     }
  175.                     count++;
  176.                 }
  177.         }
  178.         if(count)
  179.             printf("\n");
  180.     }
  181.     free(bits);
  182.     return 0;
  183. }

  184. static void print_event(int type, int code, int value, int print_flags)
  185. {
  186.     const char *type_label, *code_label, *value_label;

  187.     if (print_flags & PRINT_LABELS) {
  188.         type_label = get_label(ev_labels, type);
  189.         code_label = NULL;
  190.         value_label = NULL;

  191.         switch(type) {
  192.             case EV_SYN:
  193.                 code_label = get_label(syn_labels, code);
  194.                 break;
  195.             case EV_KEY:
  196.                 code_label = get_label(key_labels, code);
  197.                 value_label = get_label(key_value_labels, value);
  198.                 break;
  199.             case EV_REL:
  200.                 code_label = get_label(rel_labels, code);
  201.                 break;
  202.             case EV_ABS:
  203.                 code_label = get_label(abs_labels, code);
  204.                 switch(code) {
  205.                     case ABS_MT_TOOL_TYPE:
  206.                         value_label = get_label(mt_tool_labels, value);
  207.                 }
  208.                 break;
  209.             case EV_MSC:
  210.                 code_label = get_label(msc_labels, code);
  211.                 break;
  212.             case EV_LED:
  213.                 code_label = get_label(led_labels, code);
  214.                 break;
  215.             case EV_SND:
  216.                 code_label = get_label(snd_labels, code);
  217.                 break;
  218.             case EV_SW:
  219.                 code_label = get_label(sw_labels, code);
  220.                 break;
  221.             case EV_REP:
  222.                 code_label = get_label(rep_labels, code);
  223.                 break;
  224.             case EV_FF:
  225.                 code_label = get_label(ff_labels, code);
  226.                 break;
  227.             case EV_FF_STATUS:
  228.                 code_label = get_label(ff_status_labels, code);
  229.                 break;
  230.         }

  231.         if (type_label)
  232.             printf("%-12.12s", type_label);
  233.         else
  234.             printf("%04x ", type);
  235.         if (code_label)
  236.             printf(" %-20.20s", code_label);
  237.         else
  238.             printf(" %04x ", code);
  239.         if (value_label)
  240.             printf(" %-20.20s", value_label);
  241.         else
  242.             printf(" %08x ", value);
  243.     } else {
  244.         printf("%04x %04x %08x", type, code, value);
  245.     }
  246. }

  247. static void print_hid_descriptor(int bus, int vendor, int product)
  248. {
  249.     const char *dirname = "/sys/kernel/debug/hid";
  250.     char prefix[16];
  251.     DIR *dir;
  252.     struct dirent *de;
  253.     char filename[PATH_MAX];
  254.     FILE *file;
  255.     char line[2048];

  256.     snprintf(prefix, sizeof(prefix), "%04X:%04X:%04X.", bus, vendor, product);

  257.     dir = opendir(dirname);
  258.     if(dir == NULL)
  259.         return;
  260.     while((de = readdir(dir))) {
  261.         if (strstr(de->d_name, prefix) == de->d_name) {
  262.             snprintf(filename, sizeof(filename), "%s/%s/rdesc", dirname, de->d_name);

  263.             file = fopen(filename, "r");
  264.             if (file) {
  265.                 printf(" HID descriptor: %s\n\n", de->d_name);
  266.                 while (fgets(line, sizeof(line), file)) {
  267.                     fputs(" ", stdout);
  268.                     fputs(line, stdout);
  269.                 }
  270.                 fclose(file);
  271.                 puts("");
  272.             }
  273.         }
  274.     }
  275.     closedir(dir);
  276. }

  277. static int open_device(const char *device, int print_flags)
  278. {
  279.     int version;
  280.     int fd;
  281.     int clkid = CLOCK_MONOTONIC;
  282.     struct pollfd *new_ufds;
  283.     char **new_device_names;
  284.     char name[80];
  285.     char location[80];
  286.     char idstr[80];
  287.     struct input_id id;

  288.     fd = open(device, O_RDWR);
  289.     if(fd < 0) {
  290.         if(print_flags & PRINT_DEVICE_ERRORS)
  291.             fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
  292.         return -1;
  293.     }
  294.     
  295.     if(ioctl(fd, EVIOCGVERSION, &version)) {
  296.         if(print_flags & PRINT_DEVICE_ERRORS)
  297.             fprintf(stderr, "could not get driver version for %s, %s\n", device, strerror(errno));
  298.         return -1;
  299.     }
  300.     if(ioctl(fd, EVIOCGID, &id)) {
  301.         if(print_flags & PRINT_DEVICE_ERRORS)
  302.             fprintf(stderr, "could not get driver id for %s, %s\n", device, strerror(errno));
  303.         return -1;
  304.     }
  305.     name[sizeof(name) - 1] = '\0';
  306.     location[sizeof(location) - 1] = '\0';
  307.     idstr[sizeof(idstr) - 1] = '\0';
  308.     if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
  309.         //fprintf(stderr, "could not get device name for %s, %s\n", device, strerror(errno));
  310.         name[0] = '\0';
  311.     }
  312.     if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
  313.         //fprintf(stderr, "could not get location for %s, %s\n", device, strerror(errno));
  314.         location[0] = '\0';
  315.     }
  316.     if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
  317.         //fprintf(stderr, "could not get idstring for %s, %s\n", device, strerror(errno));
  318.         idstr[0] = '\0';
  319.     }

  320.     if (ioctl(fd, EVIOCSCLOCKID, &clkid) != 0) {
  321.         fprintf(stderr, "Can't enable monotonic clock reporting: %s\n", strerror(errno));
  322.         // a non-fatal error
  323.     }

  324.     new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
  325.     if(new_ufds == NULL) {
  326.         fprintf(stderr, "out of memory\n");
  327.         return -1;
  328.     }
  329.     ufds = new_ufds;
  330.     new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
  331.     if(new_device_names == NULL) {
  332.         fprintf(stderr, "out of memory\n");
  333.         return -1;
  334.     }
  335.     device_names = new_device_names;

  336.     if(print_flags & PRINT_DEVICE)
  337.         printf("add device %d: %s\n", nfds, device);
  338.     if(print_flags & PRINT_DEVICE_INFO)
  339.         printf(" bus: %04x\n"
  340.                " vendor %04x\n"
  341.                " product %04x\n"
  342.                " version %04x\n",
  343.                id.bustype, id.vendor, id.product, id.version);
  344.     if(print_flags & PRINT_DEVICE_NAME)
  345.         printf(" name: \"%s\"\n", name);
  346.     if(print_flags & PRINT_DEVICE_INFO)
  347.         printf(" location: \"%s\"\n"
  348.                " id: \"%s\"\n", location, idstr);
  349.     if(print_flags & PRINT_VERSION)
  350.         printf(" version: %d.%d.%d\n",
  351.                version >> 16, (version >> 8) & 0xff, version & 0xff);

  352.     if(print_flags & PRINT_POSSIBLE_EVENTS) {
  353.         print_possible_events(fd, print_flags);
  354.     }

  355.     if(print_flags & PRINT_INPUT_PROPS) {
  356.         print_input_props(fd);
  357.     }
  358.     if(print_flags & PRINT_HID_DESCRIPTOR) {
  359.         print_hid_descriptor(id.bustype, id.vendor, id.product);
  360.     }

  361.     ufds[nfds].fd = fd;
  362.     ufds[nfds].events = POLLIN;
  363.     device_names[nfds] = strdup(device);
  364.     nfds++;

  365.     return 0;
  366. }

  367. int close_device(const char *device, int print_flags)
  368. {
  369.     int i;
  370.     for(= 1; i < nfds; i++) {
  371.         if(strcmp(device_names[i], device) == 0) {
  372.             int count = nfds - i - 1;
  373.             if(print_flags & PRINT_DEVICE)
  374.                 printf("remove device %d: %s\n", i, device);
  375.             free(device_names[i]);
  376.             memmove(device_names + i, device_names + i + 1, sizeof(device_names[0]) * count);
  377.             memmove(ufds + i, ufds + i + 1, sizeof(ufds[0]) * count);
  378.             nfds--;
  379.             return 0;
  380.         }
  381.     }
  382.     if(print_flags & PRINT_DEVICE_ERRORS)
  383.         fprintf(stderr, "remote device: %s not found\n", device);
  384.     return -1;
  385. }

  386. static int read_notify(const char *dirname, int nfd, int print_flags)
  387. {
  388.     int res;
  389.     char devname[PATH_MAX];
  390.     char *filename;
  391.     char event_buf[512];
  392.     int event_size;
  393.     int event_pos = 0;
  394.     struct inotify_event *event;

  395.     res = read(nfd, event_buf, sizeof(event_buf));
  396.     if(res < (int)sizeof(*event)) {
  397.         if(errno == EINTR)
  398.             return 0;
  399.         fprintf(stderr, "could not get event, %s\n", strerror(errno));
  400.         return 1;
  401.     }
  402.     //printf("got %d bytes of event information\n", res);

  403.     strcpy(devname, dirname);
  404.     filename = devname + strlen(devname);
  405.     *filename++ = '/';

  406.     while(res >= (int)sizeof(*event)) {
  407.         event = (struct inotify_event *)(event_buf + event_pos);
  408.         //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
  409.         if(event->len) {
  410.             strcpy(filename, event->name);
  411.             if(event->mask & IN_CREATE) {
  412.                 open_device(devname, print_flags);
  413.             }
  414.             else {
  415.                 close_device(devname, print_flags);
  416.             }
  417.         }
  418.         event_size = sizeof(*event) + event->len;
  419.         res -= event_size;
  420.         event_pos += event_size;
  421.     }
  422.     return 0;
  423. }

  424. static int scan_dir(const char *dirname, int print_flags)
  425. {
  426.     char devname[PATH_MAX];
  427.     char *filename;
  428.     DIR *dir;
  429.     struct dirent *de;
  430.     dir = opendir(dirname);
  431.     if(dir == NULL)
  432.         return -1;
  433.     strcpy(devname, dirname);
  434.     filename = devname + strlen(devname);
  435.     *filename++ = '/';
  436.     while((de = readdir(dir))) {
  437.         if(de->d_name[0] == '.' &&
  438.            (de->d_name[1] == '\0' ||
  439.             (de->d_name[1] == '.' && de->d_name[2] == '\0')))
  440.             continue;
  441.         strcpy(filename, de->d_name);
  442.         open_device(devname, print_flags);
  443.     }
  444.     closedir(dir);
  445.     return 0;
  446. }

  447. static void usage(char *name)
  448. {
  449.     fprintf(stderr, "Usage: %s [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]\n", name);
  450.     fprintf(stderr, " -t: show time stamps\n");
  451.     fprintf(stderr, " -n: don't print newlines\n");
  452.     fprintf(stderr, " -s: print switch states for given bits\n");
  453.     fprintf(stderr, " -S: print all switch states\n");
  454.     fprintf(stderr, " -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)\n");
  455.     fprintf(stderr, " -d: show HID descriptor, if available\n");
  456.     fprintf(stderr, " -p: show possible events (errs, dev, name, pos. events)\n");
  457.     fprintf(stderr, " -i: show all device info and possible events\n");
  458.     fprintf(stderr, " -l: label event types and names in plain text\n");
  459.     fprintf(stderr, " -q: quiet (clear verbosity mask)\n");
  460.     fprintf(stderr, " -c: print given number of events then exit\n");
  461.     fprintf(stderr, " -r: print rate events are received\n");
  462. }

  463. int main(int argc, char *argv[])
  464. {
  465.     int c;
  466.     int i;
  467.     int res;
  468.     int get_time = 0;
  469.     int print_device = 0;
  470.     char *newline = "\n";
  471.     uint16_t get_switch = 0;
  472.     struct input_event event;
  473.     int print_flags = 0;
  474.     int print_flags_set = 0;
  475.     int dont_block = -1;
  476.     int event_count = 0;
  477.     int sync_rate = 0;
  478.     int64_t last_sync_time = 0;
  479.     const char *device = NULL;
  480.     const char *device_path = "/dev/input";

  481.     opterr = 0;
  482.     do {
  483.         c = getopt(argc, argv, "tns:Sv::dpilqc:rh");
  484.         if (== EOF)
  485.             break;
  486.         switch (c) {
  487.         case 't':
  488.             get_time = 1;
  489.             break;
  490.         case 'n':
  491.             newline = "";
  492.             break;
  493.         case 's':
  494.             get_switch = strtoul(optarg, NULL, 0);
  495.             if(dont_block == -1)
  496.                 dont_block = 1;
  497.             break;
  498.         case 'S':
  499.             get_switch = ~0;
  500.             if(dont_block == -1)
  501.                 dont_block = 1;
  502.             break;
  503.         case 'v':
  504.             if(optarg)
  505.                 print_flags |= strtoul(optarg, NULL, 0);
  506.             else
  507.                 print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION;
  508.             print_flags_set = 1;
  509.             break;
  510.         case 'd':
  511.             print_flags |= PRINT_HID_DESCRIPTOR;
  512.             break;
  513.         case 'p':
  514.             print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE
  515.                     | PRINT_DEVICE_NAME | PRINT_POSSIBLE_EVENTS | PRINT_INPUT_PROPS;
  516.             print_flags_set = 1;
  517.             if(dont_block == -1)
  518.                 dont_block = 1;
  519.             break;
  520.         case 'i':
  521.             print_flags |= PRINT_ALL_INFO;
  522.             print_flags_set = 1;
  523.             if(dont_block == -1)
  524.                 dont_block = 1;
  525.             break;
  526.         case 'l':
  527.             print_flags |= PRINT_LABELS;
  528.             break;
  529.         case 'q':
  530.             print_flags_set = 1;
  531.             break;
  532.         case 'c':
  533.             event_count = atoi(optarg);
  534.             dont_block = 0;
  535.             break;
  536.         case 'r':
  537.             sync_rate = 1;
  538.             break;
  539.         case '?':
  540.             fprintf(stderr, "%s: invalid option -%c\n",
  541.                 argv[0], optopt);
  542.         case 'h':
  543.             usage(argv[0]);
  544.             exit(1);
  545.         }
  546.     } while (1);
  547.     if(dont_block == -1)
  548.         dont_block = 0;

  549.     if (optind + 1 == argc) {
  550.         device = argv[optind];
  551.         optind++;
  552.     }
  553.     if (optind != argc) {
  554.         usage(argv[0]);
  555.         exit(1);
  556.     }
  557.     nfds = 1;
  558.     ufds = calloc(1, sizeof(ufds[0]));
  559.     ufds[0].fd = inotify_init();
  560.     ufds[0].events = POLLIN;
  561.     if(device) {
  562.         if(!print_flags_set)
  563.             print_flags |= PRINT_DEVICE_ERRORS;
  564.         res = open_device(device, print_flags);
  565.         if(res < 0) {
  566.             return 1;
  567.         }
  568.     } else {
  569.         if(!print_flags_set)
  570.             print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME;
  571.         print_device = 1;
  572.         res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
  573.         if(res < 0) {
  574.             fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
  575.             return 1;
  576.         }
  577.         res = scan_dir(device_path, print_flags);
  578.         if(res < 0) {
  579.             fprintf(stderr, "scan dir failed for %s\n", device_path);
  580.             return 1;
  581.         }
  582.     }

  583.     if(get_switch) {
  584.         for(= 1; i < nfds; i++) {
  585.             uint16_t sw;
  586.             res = ioctl(ufds[i].fd, EVIOCGSW(1), &sw);
  587.             if(res < 0) {
  588.                 fprintf(stderr, "could not get switch state, %s\n", strerror(errno));
  589.                 return 1;
  590.             }
  591.             sw &= get_switch;
  592.             printf("%04x%s", sw, newline);
  593.         }
  594.     }

  595.     if(dont_block)
  596.         return 0;

  597.     while(1) {
  598.         //int pollres =
  599.         poll(ufds, nfds, -1);
  600.         //printf("poll %d, returned %d\n", nfds, pollres);
  601.         if(ufds[0].revents & POLLIN) {
  602.             read_notify(device_path, ufds[0].fd, print_flags);
  603.         }
  604.         for(= 1; i < nfds; i++) {
  605.             if(ufds[i].revents) {
  606.                 if(ufds[i].revents & POLLIN) {
  607.                     res = read(ufds[i].fd, &event, sizeof(event));
  608.                     if(res < (int)sizeof(event)) {
  609.                         fprintf(stderr, "could not get event\n");
  610.                         return 1;
  611.                     }
  612.                     if(get_time) {
  613.                         printf("[%8ld.%06ld] ", event.time.tv_sec, event.time.tv_usec);
  614.                     }
  615.                     if(print_device)
  616.                         printf("%s: ", device_names[i]);
  617.                     print_event(event.type, event.code, event.value, print_flags);
  618.                     if(sync_rate && event.type == 0 && event.code == 0) {
  619.                         int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec;
  620.                         if(last_sync_time)
  621.                             printf(" rate %lld", 1000000LL / (now - last_sync_time));
  622.                         last_sync_time = now;
  623.                     }
  624.                     printf("%s", newline);
  625.                     if(event_count && --event_count == 0)
  626.                         return 0;
  627.                 }
  628.             }
  629.         }
  630.     }

  631.     return 0;
  632. }
gcc getevent.c getevent.h -I ./ -o getevent
0 0