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