2 * Copyright (c) 2009 Red Hat, Inc.
4 * Event device capture program.
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>
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 */
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__))
57 const char *keys
[KEY_MAX
+ 1] = {
58 [KEY_RESERVED
] = "KEY_RESERVED",
59 [KEY_ESC
] = "KEY_ESC",
70 [KEY_MINUS
] = "KEY_MINUS",
71 [KEY_EQUAL
] = "KEY_EQUAL",
72 [KEY_BACKSPACE
] = "KEY_BACKSPACE",
73 [KEY_TAB
] = "KEY_TAB",
84 [KEY_LEFTBRACE
] = "KEY_LEFTBRACE",
85 [KEY_RIGHTBRACE
] = "KEY_RIGHTBRACE",
86 [KEY_ENTER
] = "KEY_ENTER",
87 [KEY_LEFTCTRL
] = "KEY_LEFTCTRL",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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
,
522 [EV_FF_STATUS
] = "EV_FF_STATUS",
525 const char *relatives
[REL_MAX
+ 1] = {
526 [0 ... REL_MAX
] = NULL
,
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
,
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
,
616 [EV_REL
] = relatives
,
617 [EV_ABS
] = absolutes
,
624 char *absval
[6] = { "abs-value",
632 static int print_capabilities(int fd
, xmlTextWriterPtr writer
)
636 unsigned long bit
[EV_MAX
][NBITS(KEY_MAX
)];
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]))
648 start(BAD_CAST
"event-type");
649 sprintf(buffer
, "%s", events
[i
]);
650 attr(BAD_CAST
"type", BAD_CAST buffer
);
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
668 ioctl(fd
, EVIOCGABS(j
), abs
);
669 for (k
= 0; k
< sizeof(abs
)/sizeof(abs
[0]); k
++)
671 sprintf(buffer
, "%d", abs
[k
]);
694 static int print_info(int fd
, xmlTextWriterPtr writer
)
696 unsigned short id
[4];
697 char name
[256] = "---";
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
);
716 call(print_capabilities(fd
, writer
));
719 printf("Capturing device '%s'.\n", name
);
726 static int init_xml(xmlTextWriterPtr
*writer
, const char *outfile
)
730 *writer
= xmlNewTextWriterFilename(outfile
, 0);
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
);
745 static void sig_handler(int signal
)
748 printf("Stopping.\n");
752 static int print_events(int fd
, xmlTextWriterPtr writer
)
755 struct input_event ev
;
756 start(BAD_CAST
"events");
759 struct sigaction sigact
= {
760 .sa_handler
= sig_handler
,
763 sigemptyset(&sigact
.sa_mask
);
765 sigaction(SIGINT
, &sigact
, &sigact
);
768 printf("Press Ctrl+C to stop.\n");
771 rc
= read(fd
, &ev
, sizeof(struct input_event
));
772 if (rc
== -1 && errno
== EINTR
)
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
);
792 sigaction(SIGINT
, &sigact
, &sigact
);
797 sigaction(SIGINT
, &sigact
, &sigact
);
798 perror("Read error: \n");
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
;
818 ndev
= scandir(DEV_INPUT_EVENT
, &namelist
, EventDevOnly
, alphasort
);
822 printf("Available devices:\n");
824 for (i
= 0; i
< ndev
; i
++)
828 char name
[256] = "???";
830 sprintf(fname
, "%s/%s", DEV_INPUT_EVENT
, namelist
[i
]->d_name
);
831 fd
= open(fname
, O_RDONLY
);
834 ioctl(fd
, EVIOCGNAME(sizeof(name
)), name
);
836 printf("%s: %s\n", fname
, name
);
841 printf("Select the device event number [0-%d]: ", ndev
- 1);
842 scanf("%d", &devnum
);
844 if (devnum
>= ndev
|| devnum
< 0)
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
)
861 char *outfile
= "evtest-capture.xml";
864 xmlTextWriterPtr writer
= NULL
;
870 printf("Not running as root, no devices may be available.\n");
872 dev
= scan_devices();
879 sprintf(infile
, "%s/%s%d", DEV_INPUT_EVENT
, EVENT_DEV_NAME
, dev
);
881 strcpy(infile
, argv
[1]);
883 if ((fd
= open(infile
, O_RDONLY
)) < 0)
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");
906 xmlTextWriterEndDocument(writer
);
909 perror("Failed with error");
913 /* vim: set noexpandtab shiftwidth=8: */