4 * Copyright (c) 1999-2000 Vojtech Pavlik
6 * As modified by Rene van Paassen, May 19, 2005
7 * Event device test program
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Should you need to contact me, the author, you can do so either by
26 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
27 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
30 #include <linux/input.h>
31 #include <linux/version.h>
38 char *events[EV_MAX + 1] = { "Reset", "Key", "Relative", "Absolute", "MSC", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
39 NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", "Power", "ForceFeedbackStatus"};
41 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
43 /* Keys updated with version 2.6.11, am assuming this is 2.6 style */
44 char *keys[KEY_MAX + 1] =
45 { "Reserved", "Esc", /* 0, 1 */
46 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", /* 2 - 11 */
47 "Minus", "Equal", "Backspace", "Tab", /* 12 - 15 */
48 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", /* 16 - 25 */
49 "LeftBrace", "RightBrace", "Enter", "LeftControl", /* 26 - 29 */
50 "A", "S", "D", "F", "G", "H", "J", "K", "L", /* 30 - 38 */
51 "Semicolon", "Apostrophe", "Grave", "LeftShift", "BackSlash", /* 39 - 43 */
52 "Z", "X", "C", "V", "B", "N", "M", /* 44 - 50 */
53 "Comma", "Dot", "Slash", "RightShift", "KPAsterisk",
54 "LeftAlt", "Space", "CapsLock", /* 51 - 58 */
55 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", /* 59 - 68 */
56 "NumLock", "ScrollLock", /* 69, 70 */
57 "KP7", "KP8", "KP9", "KPMinus", /* 71 - 74 */
58 "KP4", "KP5", "KP6", "KPPlus", /* 75 - 78 */
59 "KP1", "KP2", "KP3", "KP0", "KPDot", /* 79 - 83 */
61 "ZENKAKUHANKAKU", /* 85 */
62 "102nd", "F11", "F12", /* 86 - 88 */
63 "R0", "KATAKANA", "HIRAGANA", "HENKAN", /* 89 - 92 */
64 "KATAKANAHIRAGANA", "MUHENKAN", "KPJPCOMMA", /* 93 - 95 */
65 "KPEnter", "RightCtrl", "KPSlash", "SysRq", /* 96 - 99 */
66 "RightAlt", "LineFeed", /*100 - 101 */
67 "Home", "Up", "PageUp", "Left", "Right", "End", "Down",
68 "PageDown", "Insert", "Delete", /* 102 - 111 */
69 "Macro", "Mute", "VolumeDown", "VolumeUp", "Power", /* 112 - 116 */
70 "KPEqual", "KPPlusMinus", "Pause", /* 117 - 119 */
73 "Hanguel", "Hanja", "Yen", /* 122 - 124 */
74 "LeftMeta", "RightMeta", "Compose", /* 125 - 127 */
75 "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open",
76 "Paste", "Find", "Cut", "Help", "Menu", "Calc", "Setup",
77 "Sleep", "WakeUp", "File", "SendFile", "DeleteFile", "X-fer",
78 "Prog1", "Prog2", "WWW", "MSDOS", "Coffee", "Direction",
79 "CycleWindows", "Mail", "Bookmarks", "Computer",
80 "Back", "Forward", "CloseCD", "EjectCD", "EjectCloseCD",
81 "NextSong", "PlayPause", "PreviousSong", "StopCD",
82 "Record", "Rewind", "Phone", /* 128 - 169 */
83 "ISOKey", "Config", "HomePage", "Refresh", "Exit",
84 "Move", "Edit", "ScrollUp", "ScrollDown", /* 170 - 178 */
85 "KPLeftParenthesis", "KPRightParenthesis", /* 179 - 180 */
87 "F13", "F14", "F15", "F16", "F17", "F18",
88 "F19", "F20", "F21", "F22", "F23", "F24", /* 183 - 194 */
89 NULL, NULL, NULL, NULL, NULL,
90 "PlayCD", "PauseCD", "Prog3", "Prog4", NULL,
91 "Suspend", "Close", /* 200 - 206 */
92 "Play", "FastForward", "BassBoost", "Print", "HP", "Camera",
93 "Sound", "Question", "Email", "Chat", "Search",
94 "Connect", "Finance", "Sport", "Shop", "AltErase",
95 "Cancel", "BrightnessDown", "BrightnessUp", "Media", /* 207 - 226 */
97 "KBDIllumToggle", "KBDIllumDown", "KBDIllumUp", /* 227 - 230 */
98 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
100 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
101 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
102 "Btn0", "Btn1", "Btn2", "Btn3", "Btn4",
103 "Btn5", "Btn6", "Btn7", "Btn8", "Btn9", /* 256 - 265 */
104 NULL, NULL, NULL, NULL, NULL, NULL,
105 "LeftBtn", "RightBtn", "MiddleBtn", "SideBtn",
106 "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn", /* 0x110 - 0x117 */
107 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
108 "Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn",
109 "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2",
110 "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6",
111 NULL, NULL, NULL, "BtnDead", /* 0x120 - 0x12f */
112 "BtnA", "BtnB", "BtnC", "BtnX",
113 "BtnY", "BtnZ", "BtnTL", "BtnTR",
114 "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart",
115 "BtnMode", "BtnThumbL", "BtnThumbR", /* 0x130 - 0x13e */ NULL,
116 "ToolPen", "ToolRubber", "ToolBrush", "ToolPencil",
117 "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens", /* 0x140-0x147 */
118 NULL, NULL, "Touch", "Stylus",
119 "Stylus2", "DoubleTap", "TripleTap", /* 0x14a - 0x14e */ NULL,
120 "GearUp", "GearDown", /* 0x150, 0x151 */
121 NULL, NULL, NULL, NULL, NULL, NULL,
122 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
123 "Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time",
124 "Vendor", "Archive", "Program", "Channel",
125 "Favorites", "Epg", "Pvr", "Mhp",
126 "Language", "Title", "Subtitle", "Angle",
127 "Zoom", "Mode", "Keyboard", "Screen",
128 "Pc", "Tv", "Tv2", "Vcr", "Vcr2", "Sat", "Sat2", "Cd",
129 "Tape", "Radio", "Tuner", "Player", "Text", "Dvd", "Aux", "Mp3",
130 "Audio", "Video", "Directory", "List",
131 "Memo", "Calendar", "Red", "Green",
132 "Yellow", "Blue", "Channelup", "Channeldown",
133 "First", "Last", "Ab", "Next",
134 "Restart", "Slow", "Shuffle", "Break",
135 "Previous", "Digits", "Teen", "Twen", /* 160 - 19f */
136 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
137 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
138 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
140 "DelEol", "DelEos", "InsLine", "DelLine", /* 1c0 - 1c3 */
141 NULL, NULL, NULL, NULL,
142 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
144 "FN_F1", "FN_F2", "FN_F3", "FN_F4", "FN_F5",
145 "FN_F6", "FN_F7", "FN_F8", "FN_F9", "FN_F10",
147 "FN_1", "FN_2", "FN_D", "FN_E", "FN_F", "FN_S", "FN_B" /* 0x1d0 - 0x1e4 */
152 /* Keys I used with 2.4 kernels. */
153 char *keys[KEY_MAX + 1] = { "Reserved", "Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equal", "Backspace",
154 "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S", "D", "F", "G",
155 "H", "J", "K", "L", "Semicolon", "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V", "B", "N", "M", "Comma", "Dot",
156 "Slash", "RightShift", "KPAsterisk", "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
157 "NumLock", "ScrollLock", "KP7", "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1", "KP2", "KP3", "KP0", "KPDot", "103rd",
158 "F13", "102nd", "F11", "F12", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "KPEnter", "RightCtrl", "KPSlash", "SysRq",
159 "RightAlt", "LineFeed", "Home", "Up", "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete", "Macro", "Mute",
160 "VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause", "F21", "F22", "F23", "F24", "KPComma", "LeftMeta", "RightMeta",
161 "Compose", "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste", "Find", "Cut", "Help", "Menu", "Calc", "Setup",
162 "Sleep", "WakeUp", "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS", "Coffee", "Direction",
163 "CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward", "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause",
164 "PreviousSong", "StopCD", "Record", "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move", "Edit", "ScrollUp",
165 "ScrollDown", "KPLeftParenthesis", "KPRightParenthesis",
166 "International1", "International2", "International3", "International4", "International5",
167 "International6", "International7", "International8", "International9",
168 "Language1", "Language2", "Language3", "Language4", "Language5", "Language6", "Language7", "Language8", "Language9",
170 "PlayCD", "PauseCD", "Prog3", "Prog4", "Suspend", "Close",
171 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
172 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
173 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
174 "Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9",
175 NULL, NULL, NULL, NULL, NULL, NULL,
176 "LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn",
177 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
178 "Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn",
179 "BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6",
180 NULL, NULL, NULL, "BtnDead",
181 "BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode",
182 "BtnThumbL", "BtnThumbR", NULL,
183 "ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens", NULL, NULL,
184 "Touch", "Stylus", "Stylus2" };
187 char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " };
188 char *relatives[REL_MAX + 1] =
189 { "X", "Y", "Z", NULL,
190 NULL, NULL, "HWheel", "Dial",
191 /* 0x08: */ "Wheel", "MISC" };
192 char *absolutes[ABS_MAX + 1] =
193 { "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
194 "Wheel", "Gas", "Brake", NULL, NULL, NULL, NULL, NULL,
195 /* 0x10: */ "Hat0X", "Hat0Y", "Hat1X", "Hat1Y",
196 "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y",
197 "Pressure", "Distance", "XTilt", "YTilt",
198 "ToolWidth", NULL, NULL, NULL,
199 /* 0x20: */ "Volume", NULL, NULL, NULL,
200 NULL, NULL, NULL, NULL,
201 /* 0x28: */ "Misc" };
202 char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" };
203 char *repeats[REP_MAX + 1] = { "Delay", "Period" };
204 char *sounds[SND_MAX + 1] = { "Bell", "Click" };
206 char **names[EV_MAX + 1] = { events, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
207 NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL };
209 #define BITS_PER_LONG (sizeof(long) * 8)
210 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
211 #define OFF(x) ((x)%BITS_PER_LONG)
212 #define BIT(x) (1UL<<OFF(x))
213 #define LONG(x) ((x)/BITS_PER_LONG)
214 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
216 int main (int argc, char **argv)
219 struct input_event ev[64];
221 unsigned short id[4];
222 unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
223 char name[256] = "Unknown";
227 for (i = 0; i < KEY_MAX; i++) {
228 printf("Key %d, name \"%s\"\n", i, keys[i] ? keys[i]: "?");
233 printf ("Usage: evtest /dev/inputX\n");
234 printf ("Where X = input device number\n");
238 if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
243 ioctl(fd, EVIOCGVERSION, &version);
244 printf("Input driver version is %d.%d.%d\n",
245 version >> 16, (version >> 8) & 0xff, version & 0xff);
247 ioctl(fd, EVIOCGID, id);
248 printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
249 id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
251 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
252 printf("Input device name: \"%s\"\n", name);
254 memset(bit, 0, sizeof(bit));
255 ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
256 printf("Supported events:\n");
258 for (i = 0; i < EV_MAX; i++)
260 if (test_bit(i, bit[0]))
262 printf(" Event type %d (%s)\n", i, events[i] ? events[i] : "?");
263 ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
264 for (j = 0; j < KEY_MAX; j++)
266 if (test_bit(j, bit[i]))
268 printf(" Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
271 ioctl(fd, EVIOCGABS(j), abs);
272 for (k = 0; k < 5; k++)
274 if ((k < 3) || abs[k])
276 printf(" %s %6d\n", absval[k], abs[k]);
285 printf("Testing ... (interrupt to exit)\n");
289 rd = read(fd, ev, sizeof(struct input_event) * 64);
291 if (rd < (int) sizeof(struct input_event))
294 perror("\nevtest: error reading");
298 for (i = 0; i < rd / sizeof(struct input_event); i++)
300 printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
304 events[ev[i].type] ? events[ev[i].type] : "?",
306 names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",