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