Add REL_RX, REL_RY, REL_RZ
[evtest.git] / evtest-capture.c
blob319693025e700fc4c09fa8e4da8bcf5ee03929aa
1 /*
2 * Copyright (c) 2009 Red Hat, Inc.
4 * Event device capture program.
5 */
7 /*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/input.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <signal.h>
31 #include <dirent.h>
32 #include <errno.h>
34 #include <libxml/encoding.h>
35 #include <libxml/xmlwriter.h>
37 #define BITS_PER_LONG (sizeof(long) * 8)
38 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
39 #define OFF(x) ((x)%BITS_PER_LONG)
40 #define BIT(x) (1UL<<OFF(x))
41 #define LONG(x) ((x)/BITS_PER_LONG)
42 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
43 #define MY_ENCODING "ISO-8859-1"
45 /* libxml api is annoying. 'sanitize' it with macros */
46 #define call(func) \
47 rc = (func); \
48 if (rc < 0) \
49 goto error;
50 #define start(...) call(xmlTextWriterStartElement(writer, __VA_ARGS__))
51 #define end(dummy) call(xmlTextWriterEndElement(writer))
52 #define format(...) call(xmlTextWriterWriteFormatElement(writer, __VA_ARGS__))
53 #define attr(...) call(xmlTextWriterWriteAttribute(writer, __VA_ARGS__))
55 static int stop = 0;
57 const char *keys[KEY_MAX + 1] = {
58 [KEY_RESERVED] = "KEY_RESERVED",
59 [KEY_ESC] = "KEY_ESC",
60 [KEY_1] = "KEY_1",
61 [KEY_2] = "KEY_2",
62 [KEY_3] = "KEY_3",
63 [KEY_4] = "KEY_4",
64 [KEY_5] = "KEY_5",
65 [KEY_6] = "KEY_6",
66 [KEY_7] = "KEY_7",
67 [KEY_8] = "KEY_8",
68 [KEY_9] = "KEY_9",
69 [KEY_0] = "KEY_0",
70 [KEY_MINUS] = "KEY_MINUS",
71 [KEY_EQUAL] = "KEY_EQUAL",
72 [KEY_BACKSPACE] = "KEY_BACKSPACE",
73 [KEY_TAB] = "KEY_TAB",
74 [KEY_Q] = "KEY_Q",
75 [KEY_W] = "KEY_W",
76 [KEY_E] = "KEY_E",
77 [KEY_R] = "KEY_R",
78 [KEY_T] = "KEY_T",
79 [KEY_Y] = "KEY_Y",
80 [KEY_U] = "KEY_U",
81 [KEY_I] = "KEY_I",
82 [KEY_O] = "KEY_O",
83 [KEY_P] = "KEY_P",
84 [KEY_LEFTBRACE] = "KEY_LEFTBRACE",
85 [KEY_RIGHTBRACE] = "KEY_RIGHTBRACE",
86 [KEY_ENTER] = "KEY_ENTER",
87 [KEY_LEFTCTRL] = "KEY_LEFTCTRL",
88 [KEY_A] = "KEY_A",
89 [KEY_S] = "KEY_S",
90 [KEY_D] = "KEY_D",
91 [KEY_F] = "KEY_F",
92 [KEY_G] = "KEY_G",
93 [KEY_H] = "KEY_H",
94 [KEY_J] = "KEY_J",
95 [KEY_K] = "KEY_K",
96 [KEY_L] = "KEY_L",
97 [KEY_SEMICOLON] = "KEY_SEMICOLON",
98 [KEY_APOSTROPHE] = "KEY_APOSTROPHE",
99 [KEY_GRAVE] = "KEY_GRAVE",
100 [KEY_LEFTSHIFT] = "KEY_LEFTSHIFT",
101 [KEY_BACKSLASH] = "KEY_BACKSLASH",
102 [KEY_Z] = "KEY_Z",
103 [KEY_X] = "KEY_X",
104 [KEY_C] = "KEY_C",
105 [KEY_V] = "KEY_V",
106 [KEY_B] = "KEY_B",
107 [KEY_N] = "KEY_N",
108 [KEY_M] = "KEY_M",
109 [KEY_COMMA] = "KEY_COMMA",
110 [KEY_DOT] = "KEY_DOT",
111 [KEY_SLASH] = "KEY_SLASH",
112 [KEY_RIGHTSHIFT] = "KEY_RIGHTSHIFT",
113 [KEY_KPASTERISK] = "KEY_KPASTERISK",
114 [KEY_LEFTALT] = "KEY_LEFTALT",
115 [KEY_SPACE] = "KEY_SPACE",
116 [KEY_CAPSLOCK] = "KEY_CAPSLOCK",
117 [KEY_F1] = "KEY_F1",
118 [KEY_F2] = "KEY_F2",
119 [KEY_F3] = "KEY_F3",
120 [KEY_F4] = "KEY_F4",
121 [KEY_F5] = "KEY_F5",
122 [KEY_F6] = "KEY_F6",
123 [KEY_F7] = "KEY_F7",
124 [KEY_F8] = "KEY_F8",
125 [KEY_F9] = "KEY_F9",
126 [KEY_F10] = "KEY_F10",
127 [KEY_NUMLOCK] = "KEY_NUMLOCK",
128 [KEY_SCROLLLOCK] = "KEY_SCROLLLOCK",
129 [KEY_KP7] = "KEY_KP7",
130 [KEY_KP8] = "KEY_KP8",
131 [KEY_KP9] = "KEY_KP9",
132 [KEY_KPMINUS] = "KEY_KPMINUS",
133 [KEY_KP4] = "KEY_KP4",
134 [KEY_KP5] = "KEY_KP5",
135 [KEY_KP6] = "KEY_KP6",
136 [KEY_KPPLUS] = "KEY_KPPLUS",
137 [KEY_KP1] = "KEY_KP1",
138 [KEY_KP2] = "KEY_KP2",
139 [KEY_KP3] = "KEY_KP3",
140 [KEY_KP0] = "KEY_KP0",
141 [KEY_KPDOT] = "KEY_KPDOT",
143 [KEY_ZENKAKUHANKAKU] = "KEY_ZENKAKUHANKAKU",
144 [KEY_102ND] = "KEY_102ND",
145 [KEY_F11] = "KEY_F11",
146 [KEY_F12] = "KEY_F12",
147 [KEY_RO] = "KEY_RO",
148 [KEY_KATAKANA] = "KEY_KATAKANA",
149 [KEY_HIRAGANA] = "KEY_HIRAGANA",
150 [KEY_HENKAN] = "KEY_HENKAN",
151 [KEY_KATAKANAHIRAGANA] = "KEY_KATAKANAHIRAGANA",
152 [KEY_MUHENKAN] = "KEY_MUHENKAN",
153 [KEY_KPJPCOMMA] = "KEY_KPJPCOMMA",
154 [KEY_KPENTER] = "KEY_KPENTER",
155 [KEY_RIGHTCTRL] = "KEY_RIGHTCTRL",
156 [KEY_KPSLASH] = "KEY_KPSLASH",
157 [KEY_SYSRQ] = "KEY_SYSRQ",
158 [KEY_RIGHTALT] = "KEY_RIGHTALT",
159 [KEY_LINEFEED] = "KEY_LINEFEED",
160 [KEY_HOME] = "KEY_HOME",
161 [KEY_UP] = "KEY_UP",
162 [KEY_PAGEUP] = "KEY_PAGEUP",
163 [KEY_LEFT] = "KEY_LEFT",
164 [KEY_RIGHT] = "KEY_RIGHT",
165 [KEY_END] = "KEY_END",
166 [KEY_DOWN] = "KEY_DOWN",
167 [KEY_PAGEDOWN] = "KEY_PAGEDOWN",
168 [KEY_INSERT] = "KEY_INSERT",
169 [KEY_DELETE] = "KEY_DELETE",
170 [KEY_MACRO] = "KEY_MACRO",
171 [KEY_MUTE] = "KEY_MUTE",
172 [KEY_VOLUMEDOWN] = "KEY_VOLUMEDOWN",
173 [KEY_VOLUMEUP] = "KEY_VOLUMEUP",
174 [KEY_POWER] = "KEY_POWER",
175 [KEY_KPEQUAL] = "KEY_KPEQUAL",
176 [KEY_KPPLUSMINUS] = "KEY_KPPLUSMINUS",
177 [KEY_PAUSE] = "KEY_PAUSE",
178 [KEY_SCALE] = "KEY_SCALE",
180 [KEY_KPCOMMA] = "KEY_KPCOMMA",
181 [KEY_HANGEUL] = "KEY_HANGEUL",
182 [KEY_HANGUEL] = "KEY_HANGUEL",
183 [KEY_HANJA] = "KEY_HANJA",
184 [KEY_YEN] = "KEY_YEN",
185 [KEY_LEFTMETA] = "KEY_LEFTMETA",
186 [KEY_RIGHTMETA] = "KEY_RIGHTMETA",
187 [KEY_COMPOSE] = "KEY_COMPOSE",
189 [KEY_STOP] = "KEY_STOP",
190 [KEY_AGAIN] = "KEY_AGAIN",
191 [KEY_PROPS] = "KEY_PROPS",
192 [KEY_UNDO] = "KEY_UNDO",
193 [KEY_FRONT] = "KEY_FRONT",
194 [KEY_COPY] = "KEY_COPY",
195 [KEY_OPEN] = "KEY_OPEN",
196 [KEY_PASTE] = "KEY_PASTE",
197 [KEY_FIND] = "KEY_FIND",
198 [KEY_CUT] = "KEY_CUT",
199 [KEY_HELP] = "KEY_HELP",
200 [KEY_MENU] = "KEY_MENU",
201 [KEY_CALC] = "KEY_CALC",
202 [KEY_SETUP] = "KEY_SETUP",
203 [KEY_SLEEP] = "KEY_SLEEP",
204 [KEY_WAKEUP] = "KEY_WAKEUP",
205 [KEY_FILE] = "KEY_FILE",
206 [KEY_SENDFILE] = "KEY_SENDFILE",
207 [KEY_DELETEFILE] = "KEY_DELETEFILE",
208 [KEY_XFER] = "KEY_XFER",
209 [KEY_PROG1] = "KEY_PROG1",
210 [KEY_PROG2] = "KEY_PROG2",
211 [KEY_WWW] = "KEY_WWW",
212 [KEY_MSDOS] = "KEY_MSDOS",
213 [KEY_COFFEE] = "KEY_COFFEE",
214 [KEY_SCREENLOCK] = "KEY_SCREENLOCK",
215 [KEY_DIRECTION] = "KEY_DIRECTION",
216 [KEY_CYCLEWINDOWS] = "KEY_CYCLEWINDOWS",
217 [KEY_MAIL] = "KEY_MAIL",
218 [KEY_BOOKMARKS] = "KEY_BOOKMARKS",
219 [KEY_COMPUTER] = "KEY_COMPUTER",
220 [KEY_BACK] = "KEY_BACK",
221 [KEY_FORWARD] = "KEY_FORWARD",
222 [KEY_CLOSECD] = "KEY_CLOSECD",
223 [KEY_EJECTCD] = "KEY_EJECTCD",
224 [KEY_EJECTCLOSECD] = "KEY_EJECTCLOSECD",
225 [KEY_NEXTSONG] = "KEY_NEXTSONG",
226 [KEY_PLAYPAUSE] = "KEY_PLAYPAUSE",
227 [KEY_PREVIOUSSONG] = "KEY_PREVIOUSSONG",
228 [KEY_STOPCD] = "KEY_STOPCD",
229 [KEY_RECORD] = "KEY_RECORD",
230 [KEY_REWIND] = "KEY_REWIND",
231 [KEY_PHONE] = "KEY_PHONE",
232 [KEY_ISO] = "KEY_ISO",
233 [KEY_CONFIG] = "KEY_CONFIG",
234 [KEY_HOMEPAGE] = "KEY_HOMEPAGE",
235 [KEY_REFRESH] = "KEY_REFRESH",
236 [KEY_EXIT] = "KEY_EXIT",
237 [KEY_MOVE] = "KEY_MOVE",
238 [KEY_EDIT] = "KEY_EDIT",
239 [KEY_SCROLLUP] = "KEY_SCROLLUP",
240 [KEY_SCROLLDOWN] = "KEY_SCROLLDOWN",
241 [KEY_KPLEFTPAREN] = "KEY_KPLEFTPAREN",
242 [KEY_KPRIGHTPAREN] = "KEY_KPRIGHTPAREN",
243 [KEY_NEW] = "KEY_NEW",
244 [KEY_REDO] = "KEY_REDO",
246 [KEY_F13] = "KEY_F13",
247 [KEY_F14] = "KEY_F14",
248 [KEY_F15] = "KEY_F15",
249 [KEY_F16] = "KEY_F16",
250 [KEY_F17] = "KEY_F17",
251 [KEY_F18] = "KEY_F18",
252 [KEY_F19] = "KEY_F19",
253 [KEY_F20] = "KEY_F20",
254 [KEY_F21] = "KEY_F21",
255 [KEY_F22] = "KEY_F22",
256 [KEY_F23] = "KEY_F23",
257 [KEY_F24] = "KEY_F24",
259 [KEY_PLAYCD] = "KEY_PLAYCD",
260 [KEY_PAUSECD] = "KEY_PAUSECD",
261 [KEY_PROG3] = "KEY_PROG3",
262 [KEY_PROG4] = "KEY_PROG4",
263 [KEY_DASHBOARD] = "KEY_DASHBOARD",
264 [KEY_SUSPEND] = "KEY_SUSPEND",
265 [KEY_CLOSE] = "KEY_CLOSE",
266 [KEY_PLAY] = "KEY_PLAY",
267 [KEY_FASTFORWARD] = "KEY_FASTFORWARD",
268 [KEY_BASSBOOST] = "KEY_BASSBOOST",
269 [KEY_PRINT] = "KEY_PRINT",
270 [KEY_HP] = "KEY_HP",
271 [KEY_CAMERA] = "KEY_CAMERA",
272 [KEY_SOUND] = "KEY_SOUND",
273 [KEY_QUESTION] = "KEY_QUESTION",
274 [KEY_EMAIL] = "KEY_EMAIL",
275 [KEY_CHAT] = "KEY_CHAT",
276 [KEY_SEARCH] = "KEY_SEARCH",
277 [KEY_CONNECT] = "KEY_CONNECT",
278 [KEY_FINANCE] = "KEY_FINANCE",
279 [KEY_SPORT] = "KEY_SPORT",
280 [KEY_SHOP] = "KEY_SHOP",
281 [KEY_ALTERASE] = "KEY_ALTERASE",
282 [KEY_CANCEL] = "KEY_CANCEL",
283 [KEY_BRIGHTNESSDOWN] = "KEY_BRIGHTNESSDOWN",
284 [KEY_BRIGHTNESSUP] = "KEY_BRIGHTNESSUP",
285 [KEY_MEDIA] = "KEY_MEDIA",
287 [KEY_SWITCHVIDEOMODE] = "KEY_SWITCHVIDEOMODE",
288 [KEY_KBDILLUMTOGGLE] = "KEY_KBDILLUMTOGGLE",
289 [KEY_KBDILLUMDOWN] = "KEY_KBDILLUMDOWN",
290 [KEY_KBDILLUMUP] = "KEY_KBDILLUMUP",
292 [KEY_SEND] = "KEY_SEND",
293 [KEY_REPLY] = "KEY_REPLY",
294 [KEY_FORWARDMAIL] = "KEY_FORWARDMAIL",
295 [KEY_SAVE] = "KEY_SAVE",
296 [KEY_DOCUMENTS] = "KEY_DOCUMENTS",
298 [KEY_BATTERY] = "KEY_BATTERY",
300 [KEY_BLUETOOTH] = "KEY_BLUETOOTH",
301 [KEY_WLAN] = "KEY_WLAN",
302 [KEY_UWB] = "KEY_UWB",
304 [KEY_UNKNOWN] = "KEY_UNKNOWN",
306 [KEY_VIDEO_NEXT] = "KEY_VIDEO_NEXT",
307 [KEY_VIDEO_PREV] = "KEY_VIDEO_PREV",
308 [KEY_BRIGHTNESS_CYCLE] = "KEY_BRIGHTNESS_CYCLE",
309 [KEY_BRIGHTNESS_ZERO] = "KEY_BRIGHTNESS_ZERO",
310 [KEY_DISPLAY_OFF] = "KEY_DISPLAY_OFF",
312 [KEY_WIMAX] = "KEY_WIMAX",
314 [BTN_0] = "BTN_0",
315 [BTN_1] = "BTN_1",
317 [BTN_2] = "BTN_2",
318 [BTN_3] = "BTN_3",
320 [BTN_4] = "BTN_4",
321 [BTN_5] = "BTN_5",
323 [BTN_6] = "BTN_6",
324 [BTN_7] = "BTN_7",
326 [BTN_8] = "BTN_8",
327 [BTN_9] = "BTN_9",
329 [BTN_LEFT] = "BTN_LEFT",
330 [BTN_RIGHT] = "BTN_RIGHT",
332 [BTN_MIDDLE] = "BTN_MIDDLE",
333 [BTN_SIDE] = "BTN_SIDE",
335 [BTN_EXTRA] = "BTN_EXTRA",
336 [BTN_FORWARD] = "BTN_FORWARD",
338 [BTN_BACK] = "BTN_BACK",
339 [BTN_TASK] = "BTN_TASK",
341 [BTN_TRIGGER] = "BTN_TRIGGER",
342 [BTN_THUMB] = "BTN_THUMB",
344 [BTN_THUMB2] = "BTN_THUMB2",
345 [BTN_TOP] = "BTN_TOP",
347 [BTN_TOP2] = "BTN_TOP2",
348 [BTN_PINKIE] = "BTN_PINKIE",
350 [BTN_BASE] = "BTN_BASE",
351 [BTN_BASE2] = "BTN_BASE2",
353 [BTN_BASE3] = "BTN_BASE3",
354 [BTN_BASE4] = "BTN_BASE4",
356 [BTN_BASE5] = "BTN_BASE5",
357 [BTN_BASE6] = "BTN_BASE6",
359 [BTN_DEAD] = "BTN_DEAD",
360 [BTN_A] = "BTN_A",
362 [BTN_B] = "BTN_B",
363 [BTN_C] = "BTN_C",
365 [BTN_X] = "BTN_X",
366 [BTN_Y] = "BTN_Y",
368 [BTN_Z] = "BTN_Z",
369 [BTN_TL] = "BTN_TL",
371 [BTN_TR] = "BTN_TR",
372 [BTN_TL2] = "BTN_TL2",
374 [BTN_TR2] = "BTN_TR2",
375 [BTN_SELECT] = "BTN_SELECT",
377 [BTN_START] = "BTN_START",
378 [BTN_MODE] = "BTN_MODE",
380 [BTN_THUMBL] = "BTN_THUMBL",
381 [BTN_THUMBR] = "BTN_THUMBR",
383 [BTN_TOOL_PEN] = "BTN_TOOL_PEN",
384 [BTN_TOOL_RUBBER] = "BTN_TOOL_RUBBER",
386 [BTN_TOOL_BRUSH] = "BTN_TOOL_BRUSH",
387 [BTN_TOOL_PENCIL] = "BTN_TOOL_PENCIL",
389 [BTN_TOOL_AIRBRUSH] = "BTN_TOOL_AIRBRUSH",
390 [BTN_TOOL_FINGER] = "BTN_TOOL_FINGER",
392 [BTN_TOOL_MOUSE] = "BTN_TOOL_MOUSE",
393 [BTN_TOOL_LENS] = "BTN_TOOL_LENS",
395 [BTN_TOUCH] = "BTN_TOUCH",
396 [BTN_STYLUS] = "BTN_STYLUS",
398 [BTN_STYLUS2] = "BTN_STYLUS2",
399 [BTN_TOOL_DOUBLETAP] = "BTN_TOOL_DOUBLETAP",
401 [BTN_TOOL_TRIPLETAP] = "BTN_TOOL_TRIPLETAP",
402 [BTN_GEAR_DOWN] = "BTN_GEAR_DOWN",
404 [BTN_GEAR_UP] = "BTN_GEAR_UP",
405 [KEY_OK] = "KEY_OK",
407 [KEY_SELECT] = "KEY_SELECT",
408 [KEY_GOTO] = "KEY_GOTO",
410 [KEY_CLEAR] = "KEY_CLEAR",
411 [KEY_POWER2] = "KEY_POWER2",
413 [KEY_OPTION] = "KEY_OPTION",
414 [KEY_INFO] = "KEY_INFO",
416 [KEY_TIME] = "KEY_TIME",
417 [KEY_VENDOR] = "KEY_VENDOR",
419 [KEY_ARCHIVE] = "KEY_ARCHIVE",
420 [KEY_PROGRAM] = "KEY_PROGRAM",
422 [KEY_CHANNEL] = "KEY_CHANNEL",
423 [KEY_FAVORITES] = "KEY_FAVORITES",
425 [KEY_EPG] = "KEY_EPG",
426 [KEY_PVR] = "KEY_PVR",
428 [KEY_MHP] = "KEY_MHP",
429 [KEY_LANGUAGE] = "KEY_LANGUAGE",
431 [KEY_TITLE] = "KEY_TITLE",
432 [KEY_SUBTITLE] = "KEY_SUBTITLE",
434 [KEY_ANGLE] = "KEY_ANGLE",
435 [KEY_ZOOM] = "KEY_ZOOM",
437 [KEY_MODE] = "KEY_MODE",
438 [KEY_KEYBOARD] = "KEY_KEYBOARD",
440 [KEY_SCREEN] = "KEY_SCREEN",
441 [KEY_PC] = "KEY_PC",
443 [KEY_TV] = "KEY_TV",
444 [KEY_TV2] = "KEY_TV2",
446 [KEY_VCR] = "KEY_VCR",
447 [KEY_VCR2] = "KEY_VCR2",
449 [KEY_SAT] = "KEY_SAT",
450 [KEY_SAT2] = "KEY_SAT2",
452 [KEY_CD] = "KEY_CD",
453 [KEY_TAPE] = "KEY_TAPE",
455 [KEY_RADIO] = "KEY_RADIO",
456 [KEY_TUNER] = "KEY_TUNER",
458 [KEY_PLAYER] = "KEY_PLAYER",
459 [KEY_TEXT] = "KEY_TEXT",
461 [KEY_DVD] = "KEY_DVD",
462 [KEY_AUX] = "KEY_AUX",
464 [KEY_MP3] = "KEY_MP3",
465 [KEY_AUDIO] = "KEY_AUDIO",
467 [KEY_VIDEO] = "KEY_VIDEO",
468 [KEY_DIRECTORY] = "KEY_DIRECTORY",
470 [KEY_LIST] = "KEY_LIST",
471 [KEY_MEMO] = "KEY_MEMO",
473 [KEY_CALENDAR] = "KEY_CALENDAR",
474 [KEY_RED] = "KEY_RED",
476 [KEY_GREEN] = "KEY_GREEN",
477 [KEY_YELLOW] = "KEY_YELLOW",
479 [KEY_BLUE] = "KEY_BLUE",
480 [KEY_CHANNELUP] = "KEY_CHANNELUP",
482 [KEY_CHANNELDOWN] = "KEY_CHANNELDOWN",
483 [KEY_FIRST] = "KEY_FIRST",
485 [KEY_LAST] = "KEY_LAST",
486 [KEY_AB] = "KEY_AB",
488 [KEY_NEXT] = "KEY_NEXT",
489 [KEY_RESTART] = "KEY_RESTART",
491 [KEY_SLOW] = "KEY_SLOW",
492 [KEY_SHUFFLE] = "KEY_SHUFFLE",
494 [KEY_BREAK] = "KEY_BREAK",
495 [KEY_PREVIOUS] = "KEY_PREVIOUS",
497 [KEY_DIGITS] = "KEY_DIGITS",
498 [KEY_TEEN] = "KEY_TEEN",
500 [KEY_TWEN] = "KEY_TWEN",
501 [KEY_DEL_EOL] = "KEY_DEL_EOL",
503 [KEY_DEL_EOS] = "KEY_DEL_EOS",
504 [KEY_INS_LINE] = "KEY_INS_LINE",
506 [KEY_DEL_LINE] = "KEY_DEL_LINE",
509 const char *events[EV_MAX + 1] = {
510 [0 ... EV_MAX] = NULL,
511 [EV_SYN] = "EV_SYN",
512 [EV_KEY] = "EV_KEY",
513 [EV_REL] = "EV_REL",
514 [EV_ABS] = "EV_ABS",
515 [EV_MSC] = "EV_MSC",
516 [EV_SW] = "EV_SW",
517 [EV_LED] = "EV_LED",
518 [EV_SND] = "EV_SND",
519 [EV_REP] = "EV_REP",
520 [EV_FF] = "EV_FF",
521 [EV_PWR] = "EV_PWR",
522 [EV_FF_STATUS] = "EV_FF_STATUS",
525 const char *relatives[REL_MAX + 1] = {
526 [0 ... REL_MAX] = NULL,
527 [REL_X] = "REL_X",
528 [REL_Y] = "REL_Y",
529 [REL_Z] = "REL_Z",
530 [REL_HWHEEL] = "REL_HWHEEL",
531 [REL_DIAL] = "REL_DIAL",
532 [REL_WHEEL] = "REL_WHEEL",
533 [REL_MISC] = "REL_MISC",
536 const char *absolutes[ABS_MAX + 1] = {
537 [0 ... ABS_MAX] = NULL,
538 [ABS_X] = "ABS_X",
539 [ABS_Y] = "ABS_Y",
540 [ABS_Z] = "ABS_Z",
541 [ABS_RX] = "ABS_RX",
542 [ABS_RY] = "ABS_RY",
543 [ABS_RZ] = "ABS_RZ",
544 [ABS_THROTTLE] = "ABS_THROTTLE",
545 [ABS_RUDDER] = "ABS_RUDDER",
546 [ABS_WHEEL] = "ABS_WHEEL",
547 [ABS_GAS] = "ABS_GAS",
548 [ABS_BRAKE] = "ABS_BRAKE",
549 [ABS_HAT0X] = "ABS_HAT0X",
550 [ABS_HAT0Y] = "ABS_HAT0Y",
551 [ABS_HAT1X] = "ABS_HAT1X",
552 [ABS_HAT1Y] = "ABS_HAT1Y",
553 [ABS_HAT2X] = "ABS_HAT2X",
554 [ABS_HAT2Y] = "ABS_HAT2Y",
555 [ABS_HAT3X] = "ABS_HAT3X",
556 [ABS_HAT3Y] = "ABS_HAT3Y",
557 [ABS_PRESSURE] = "ABS_PRESSURE",
558 [ABS_DISTANCE] = "ABS_DISTANCE",
559 [ABS_TILT_X] = "ABS_TILT_X",
560 [ABS_TILT_Y] = "ABS_TILT_Y",
561 [ABS_TOOL_WIDTH] = "ABS_TOOL_WIDTH",
562 [ABS_VOLUME] = "ABS_VOLUME",
563 [ABS_MISC] = "ABS_MISC",
564 [ABS_MT_TOUCH_MAJOR] = "ABS_MT_TOUCH_MAJOR",
565 [ABS_MT_TOUCH_MINOR] = "ABS_MT_TOUCH_MINOR",
566 [ABS_MT_WIDTH_MAJOR] = "ABS_MT_WIDTH_MAJOR",
567 [ABS_MT_WIDTH_MINOR] = "ABS_MT_WIDTH_MINOR",
568 [ABS_MT_ORIENTATION] = "ABS_MT_ORIENTATION",
569 [ABS_MT_POSITION_X] = "ABS_MT_POSITION_X",
570 [ABS_MT_POSITION_Y] = "ABS_MT_POSITION_Y",
571 [ABS_MT_TOOL_TYPE] = "ABS_MT_TOOL_TYPE",
572 [ABS_MT_BLOB_ID] = "ABS_MT_BLOB_ID",
573 [ABS_MT_TRACKING_ID] = "ABS_MT_TRACKING_ID",
576 const char *misc[MSC_MAX + 1] = {
577 [ 0 ... MSC_MAX] = NULL,
578 [MSC_SERIAL] = "MSC_SERIAL",
579 [MSC_PULSELED] = "MSC_PULSELED",
580 [MSC_GESTURE] = "MSC_GESTURE",
581 [MSC_RAW] = "MSC_RAW",
582 [MSC_SCAN] = "MSC_SCAN",
585 const char *leds[LED_MAX + 1] = {
586 [0 ... LED_MAX] = NULL,
587 [LED_NUML] = "LED_NUML",
588 [LED_CAPSL] = "LED_CAPSL",
589 [LED_SCROLLL] = "LED_SCROLLL",
590 [LED_COMPOSE] = "LED_COMPOSE",
591 [LED_KANA] = "LED_KANA",
592 [LED_SLEEP] = "LED_SLEEP",
593 [LED_SUSPEND] = "LED_SUSPEND",
594 [LED_MUTE] = "LED_MUTE",
595 [LED_MISC] = "LED_MISC",
599 const char *repeats[REP_MAX + 1] = {
600 [0 ... REP_MAX] = NULL,
601 [REP_DELAY] = "REP_DELAY",
602 [REP_PERIOD] = "REP_PERIOD"
605 const char *sounds[SND_MAX + 1] = {
606 [0 ... SND_MAX] = NULL,
607 [SND_CLICK] = "SND_CLICK",
608 [SND_BELL] = "SND_BELL",
609 [SND_TONE] = "SND_TONE"
612 const char **names[EV_MAX + 1] = {
613 [0 ... EV_MAX] = NULL,
614 [EV_SYN] = events,
615 [EV_KEY] = keys,
616 [EV_REL] = relatives,
617 [EV_ABS] = absolutes,
618 [EV_MSC] = misc,
619 [EV_LED] = leds,
620 [EV_SND] = sounds,
621 [EV_REP] = repeats,
624 char *absval[6] = { "abs-value",
625 "abs-min",
626 "abs-max",
627 "abs-fuzz",
628 "abs-flat",
629 "abs-resolution"
632 static int print_capabilities(int fd, xmlTextWriterPtr writer)
635 int rc, i;
636 unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
637 unsigned int abs[6];
638 char buffer[64];
640 memset(bit, 0, sizeof(bit));
641 call(ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]));
643 for (i = 0; i < EV_MAX; i++)
645 if (test_bit(i, bit[0]))
647 int j;
648 start(BAD_CAST "event-type");
649 sprintf(buffer, "%s", events[i]);
650 attr(BAD_CAST "type", BAD_CAST buffer);
651 if (!i)
653 end();
654 continue;
656 ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
657 for (j = 0; j < KEY_MAX; j++)
659 if (test_bit(j, bit[i]))
661 start(BAD_CAST "code");
662 sprintf(buffer, "%s", (names[i] && names[i][j]) ? names[i][j] : "?");
663 attr(BAD_CAST "value", BAD_CAST
664 buffer)
666 if (i == EV_ABS) {
667 int k;
668 ioctl(fd, EVIOCGABS(j), abs);
669 for (k = 0; k < sizeof(abs)/sizeof(abs[0]); k++)
671 sprintf(buffer, "%d", abs[k]);
672 attr(BAD_CAST
673 absval[k],
674 BAD_CAST
675 buffer);
677 /*format(BAD_CAST
678 * absval[k],
679 * "%d",
680 * abs[k]);*/
682 end("code");
685 end("event-type");
689 return 0;
690 error:
691 return -1;
694 static int print_info(int fd, xmlTextWriterPtr writer)
696 unsigned short id[4];
697 char name[256] = "---";
698 char buffer[64];
699 int rc;
701 call(ioctl(fd, EVIOCGID, id));
702 call(ioctl(fd, EVIOCGNAME(sizeof(name)), name));
704 start(BAD_CAST "info");
705 start(BAD_CAST "id");
706 sprintf(buffer, "%#x", id[ID_BUS]);
707 attr(BAD_CAST "bus", BAD_CAST buffer);
708 sprintf(buffer, "%#x", id[ID_VENDOR]);
709 attr(BAD_CAST "vendor", BAD_CAST buffer);
710 sprintf(buffer, "%#x", id[ID_PRODUCT]);
711 attr(BAD_CAST "product", BAD_CAST buffer);
712 sprintf(buffer, "%#x", id[ID_VERSION]);
713 attr(BAD_CAST "version", BAD_CAST buffer);
714 xmlTextWriterWriteFormatString(writer, "%s", name);
715 end("id");
716 call(print_capabilities(fd, writer));
717 end("info");
719 printf("Capturing device '%s'.\n", name);
721 return 0;
722 error:
723 return -1;
726 static int init_xml(xmlTextWriterPtr *writer, const char *outfile)
728 LIBXML_TEST_VERSION
730 *writer = xmlNewTextWriterFilename(outfile, 0);
731 if (!*writer)
732 return -1;
734 xmlTextWriterSetIndent(*writer, 1);
735 xmlTextWriterSetIndentString(*writer, BAD_CAST " ");
736 return xmlTextWriterStartDocument(*writer, NULL, MY_ENCODING, NULL);
739 static void fini_xml(xmlTextWriterPtr writer)
741 xmlTextWriterEndDocument(writer);
742 xmlCleanupParser();
745 static void sig_handler(int signal)
747 stop = 1;
748 printf("Stopping.\n");
749 return;
752 static int print_events(int fd, xmlTextWriterPtr writer)
754 int rc;
755 struct input_event ev;
756 start(BAD_CAST "events");
757 char buffer[64];
759 struct sigaction sigact = {
760 .sa_handler = sig_handler,
763 sigemptyset(&sigact.sa_mask);
764 sigact.sa_flags = 0;
765 sigaction(SIGINT, &sigact, &sigact);
768 printf("Press Ctrl+C to stop.\n");
769 while(!stop)
771 rc = read(fd, &ev, sizeof(struct input_event));
772 if (rc == -1 && errno == EINTR)
773 continue;
775 if (rc < sizeof(ev))
776 goto error;
778 start(BAD_CAST "event");
779 sprintf(buffer, "%ld", ev.time.tv_sec);
780 attr(BAD_CAST "sec", BAD_CAST buffer);
781 sprintf(buffer, "%ld", ev.time.tv_usec);
782 attr(BAD_CAST "usec", BAD_CAST buffer);
783 sprintf(buffer, "%s", (events[ev.type]) ? events[ev.type] : "?");
784 attr(BAD_CAST "type", BAD_CAST buffer);
785 sprintf(buffer, "%s", (names[ev.type] && names[ev.type][ev.code]) ? names[ev.type][ev.code] : "?");
786 attr(BAD_CAST "code", BAD_CAST buffer);
787 sprintf(buffer, "%d", ev.value);
788 attr(BAD_CAST "value", BAD_CAST buffer);
789 end("event");
792 sigaction(SIGINT, &sigact, &sigact);
794 end("events");
795 return 0;
796 error:
797 sigaction(SIGINT, &sigact, &sigact);
798 perror("Read error: \n");
799 return -1;
803 #define DEV_INPUT_EVENT "/dev/input"
804 #define EVENT_DEV_NAME "event"
807 /* filter for the AutoDevProbe scandir on /dev/input */
808 static int EventDevOnly(const struct dirent *dir) {
809 return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
812 /* Scans all /dev/input/event* and returns the number of the one to open */
813 static int scan_devices(void)
815 struct dirent **namelist;
816 int i, ndev, devnum;
818 ndev = scandir(DEV_INPUT_EVENT, &namelist, EventDevOnly, alphasort);
819 if (ndev <= 0)
820 return -1;
822 printf("Available devices:\n");
824 for (i = 0; i < ndev; i++)
826 char fname[64];
827 int fd = -1;
828 char name[256] = "???";
830 sprintf(fname, "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
831 fd = open(fname, O_RDONLY);
832 if (fd < 0)
833 continue;
834 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
836 printf("%s: %s\n", fname, name);
837 close(fd);
838 free(namelist[i]);
841 printf("Select the device event number [0-%d]: ", ndev - 1);
842 scanf("%d", &devnum);
844 if (devnum >= ndev || devnum < 0)
845 return -1;
847 return devnum;
850 static void usage(void)
852 printf("Usage: evtest-capture /dev/input/eventX [evtest-capture.xml]\n");
853 printf("Where X = input device number and\n");
854 printf("outfile.xml is the output file. Default: evtest-capture.xml\n\n");
857 int main(int argc, char **argv)
859 int fd = -1;
860 int rc;
861 char *outfile = "evtest-capture.xml";
862 char infile[64];
864 xmlTextWriterPtr writer = NULL;
866 if (argc < 2) {
867 int dev;
869 if (getuid() != 0)
870 printf("Not running as root, no devices may be available.\n");
872 dev = scan_devices();
873 if (dev == -1)
875 usage();
876 return 1;
879 sprintf(infile, "%s/%s%d", DEV_INPUT_EVENT, EVENT_DEV_NAME, dev);
880 } else
881 strcpy(infile, argv[1]);
883 if ((fd = open(infile, O_RDONLY)) < 0)
884 goto error;
886 if (argc >= 3)
887 outfile = argv[2];
889 printf("Writing to '%s'\n", outfile);
891 init_xml(&writer, outfile);
893 start(BAD_CAST "evtest-capture");
895 call(print_info(fd, writer));
896 call(print_events(fd, writer));
898 end("evtest-capture");
899 fini_xml(writer);
900 return 0;
902 error:
903 if (fd >= 0)
905 if (writer)
906 xmlTextWriterEndDocument(writer);
907 xmlCleanupParser();
909 perror("Failed with error");
910 return 1;
913 /* vim: set noexpandtab shiftwidth=8: */