75978eb4ff6309320541b562d2f677a0c8cd72f1
[packages.git] / utils / event_test / src / evtest.c
1 /*
2  * $Id$
3  *
4  *  Copyright (c) 1999-2000 Vojtech Pavlik
5  *
6  *  As modified by Rene van Paassen, May 19, 2005
7  *  Event device test program
8  */
9
10 /*
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.
15  * 
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.
20  * 
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
24  * 
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
28  */
29
30 #include <linux/input.h>
31 #include <linux/version.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37
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"};
40
41 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
42
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 */
60     NULL, 
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 */
71     NULL, 
72     "KPComma", /* 121 */
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 */
86     NULL, NULL,
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 */
96     "SwitchVideoMode", 
97     "KBDIllumToggle", "KBDIllumDown", "KBDIllumUp", /* 227 - 230 */
98     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
99     "Unknown", /* 240 */ 
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,
143     "FN", "FN_ESC", 
144     "FN_F1", "FN_F2", "FN_F3", "FN_F4", "FN_F5", 
145     "FN_F6", "FN_F7", "FN_F8", "FN_F9", "FN_F10", 
146     "FN_F11", "FN_F12", 
147     "FN_1", "FN_2", "FN_D", "FN_E", "FN_F", "FN_S", "FN_B" /* 0x1d0 - 0x1e4 */
148   };
149
150 #else
151
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",
169 NULL, 
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" };
185 #endif
186
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" };
205
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 };
208
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)
215
216 int main (int argc, char **argv)
217 {
218         int fd, rd, i, j, k;
219         struct input_event ev[64];
220         int version;
221         unsigned short id[4];
222         unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
223         char name[256] = "Unknown";
224         int abs[5];
225
226 #if 0
227         for (i = 0; i < KEY_MAX; i++) {
228           printf("Key %d, name \"%s\"\n", i, keys[i] ? keys[i]: "?");
229         }
230 #endif
231             
232         if (argc < 2) {
233                 printf ("Usage: evtest /dev/inputX\n");
234                 printf ("Where X = input device number\n");
235                 exit (1);
236         }
237
238         if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
239                 perror("evtest");
240                 exit(1);
241         }
242
243         ioctl(fd, EVIOCGVERSION, &version);
244         printf("Input driver version is %d.%d.%d\n",
245                 version >> 16, (version >> 8) & 0xff, version & 0xff);
246
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]);
250
251         ioctl(fd, EVIOCGNAME(sizeof(name)), name);
252         printf("Input device name: \"%s\"\n", name);
253
254         memset(bit, 0, sizeof(bit));
255         ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
256         printf("Supported events:\n");
257
258         for (i = 0; i < EV_MAX; i++)
259     {
260                 if (test_bit(i, bit[0])) 
261         {
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++) 
265             {
266                                 if (test_bit(j, bit[i])) 
267                 {
268                                         printf("    Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
269                                         if (i == EV_ABS) 
270                     {
271                                                 ioctl(fd, EVIOCGABS(j), abs);
272                                                 for (k = 0; k < 5; k++)
273                         {
274                                                         if ((k < 3) || abs[k])
275                             {
276                                                                 printf("      %s %6d\n", absval[k], abs[k]);
277                             }
278                         }
279                                         }
280                                 }
281             }
282                 }
283     }   
284
285         printf("Testing ... (interrupt to exit)\n");
286
287         while (1) 
288     {
289                 rd = read(fd, ev, sizeof(struct input_event) * 64);
290
291                 if (rd < (int) sizeof(struct input_event)) 
292         {
293                         printf("yyy\n");
294                         perror("\nevtest: error reading");
295                         exit (1);
296                 }
297
298                 for (i = 0; i < rd / sizeof(struct input_event); i++)
299         {
300                         printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
301                                 ev[i].time.tv_sec, 
302                 ev[i].time.tv_usec, 
303                 ev[i].type,
304                                 events[ev[i].type] ? events[ev[i].type] : "?",
305                                 ev[i].code,
306                                 names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
307                                 ev[i].value);
308         }
309         }
310 }