add KEY_MACRO 1-30 and other keys
[evtest.git] / evtest.c
blob6d5ce29040a9607c9c730c9eefcf9d95f939987b
1 /*
2 * Copyright (c) 1999-2000 Vojtech Pavlik
3 * Copyright (c) 2009-2011 Red Hat, Inc
4 */
6 /**
7 * @file
8 * Event device test program
10 * evtest prints the capabilities on the kernel devices in /dev/input/eventX
11 * and their events. Its primary purpose is for kernel or X driver
12 * debugging.
14 * See INSTALL for installation details or manually compile with
15 * gcc -o evtest evtest.c
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 * Should you need to contact me, the author, you can do so either by
34 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
35 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
38 #define _GNU_SOURCE /* for asprintf */
39 #include <stdio.h>
40 #include <stdint.h>
42 #if HAVE_CONFIG_H
43 #include <config.h>
44 #endif
46 #include <linux/input.h>
48 #include <string.h>
49 #include <fcntl.h>
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <dirent.h>
53 #include <errno.h>
54 #include <getopt.h>
55 #include <ctype.h>
56 #include <signal.h>
57 #include <limits.h>
58 #include <sys/time.h>
59 #include <sys/types.h>
61 #ifndef input_event_sec
62 #define input_event_sec time.tv_sec
63 #define input_event_usec time.tv_usec
64 #endif
66 #define BITS_PER_LONG (sizeof(long) * 8)
67 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
68 #define OFF(x) ((x)%BITS_PER_LONG)
69 #define BIT(x) (1UL<<OFF(x))
70 #define LONG(x) ((x)/BITS_PER_LONG)
71 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
73 #define DEV_INPUT_EVENT "/dev/input"
74 #define EVENT_DEV_NAME "event"
76 #ifndef EV_SYN
77 #define EV_SYN 0
78 #endif
79 #ifndef SYN_MAX
80 #define SYN_MAX 3
81 #define SYN_CNT (SYN_MAX + 1)
82 #endif
83 #ifndef SYN_MT_REPORT
84 #define SYN_MT_REPORT 2
85 #endif
86 #ifndef SYN_DROPPED
87 #define SYN_DROPPED 3
88 #endif
90 #define NAME_ELEMENT(element) [element] = #element
92 enum evtest_mode {
93 MODE_CAPTURE,
94 MODE_QUERY,
95 MODE_VERSION,
98 static const struct query_mode {
99 const char *name;
100 int event_type;
101 int max;
102 int rq;
103 } query_modes[] = {
104 { "EV_KEY", EV_KEY, KEY_MAX, EVIOCGKEY(KEY_MAX) },
105 { "EV_LED", EV_LED, LED_MAX, EVIOCGLED(LED_MAX) },
106 { "EV_SND", EV_SND, SND_MAX, EVIOCGSND(SND_MAX) },
107 { "EV_SW", EV_SW, SW_MAX, EVIOCGSW(SW_MAX) },
110 static int grab_flag = 0;
111 static char* progname;
112 static volatile sig_atomic_t stop = 0;
114 static void interrupt_handler(int sig)
116 stop = 1;
120 * Look up an entry in the query_modes table by its textual name.
122 * @param mode The name of the entry to be found.
124 * @return The requested query_mode, or NULL if it could not be found.
126 static const struct query_mode *find_query_mode_by_name(const char *name)
128 int i;
129 for (i = 0; i < sizeof(query_modes) / sizeof(*query_modes); i++) {
130 const struct query_mode *mode = &query_modes[i];
131 if (strcmp(mode->name, name) == 0)
132 return mode;
134 return NULL;
138 * Look up an entry in the query_modes table by value.
140 * @param event_type The value of the entry to be found.
142 * @return The requested query_mode, or NULL if it could not be found.
144 static const struct query_mode *find_query_mode_by_value(int event_type)
146 int i;
147 for (i = 0; i < sizeof(query_modes) / sizeof(*query_modes); i++) {
148 const struct query_mode *mode = &query_modes[i];
149 if (mode->event_type == event_type)
150 return mode;
152 return NULL;
156 * Find a query_mode based on a string identifier. The string can either
157 * be a numerical value (e.g. "5") or the name of the event type in question
158 * (e.g. "EV_SW").
160 * @param query_mode The mode to search for
162 * @return The requested code's numerical value, or negative on error.
164 static const struct query_mode *find_query_mode(const char *query_mode)
166 if (isdigit(query_mode[0])) {
167 unsigned long val;
168 errno = 0;
169 val = strtoul(query_mode, NULL, 0);
170 if (errno)
171 return NULL;
172 return find_query_mode_by_value(val);
173 } else {
174 return find_query_mode_by_name(query_mode);
178 static const char * const events[EV_MAX + 1] = {
179 [0 ... EV_MAX] = NULL,
180 NAME_ELEMENT(EV_SYN), NAME_ELEMENT(EV_KEY),
181 NAME_ELEMENT(EV_REL), NAME_ELEMENT(EV_ABS),
182 NAME_ELEMENT(EV_MSC), NAME_ELEMENT(EV_LED),
183 NAME_ELEMENT(EV_SND), NAME_ELEMENT(EV_REP),
184 NAME_ELEMENT(EV_FF), NAME_ELEMENT(EV_PWR),
185 NAME_ELEMENT(EV_FF_STATUS), NAME_ELEMENT(EV_SW),
188 static const int maxval[EV_MAX + 1] = {
189 [0 ... EV_MAX] = -1,
190 [EV_SYN] = SYN_MAX,
191 [EV_KEY] = KEY_MAX,
192 [EV_REL] = REL_MAX,
193 [EV_ABS] = ABS_MAX,
194 [EV_MSC] = MSC_MAX,
195 [EV_SW] = SW_MAX,
196 [EV_LED] = LED_MAX,
197 [EV_SND] = SND_MAX,
198 [EV_REP] = REP_MAX,
199 [EV_FF] = FF_MAX,
200 [EV_FF_STATUS] = FF_STATUS_MAX,
204 #ifdef INPUT_PROP_SEMI_MT
205 static const char * const props[INPUT_PROP_MAX + 1] = {
206 [0 ... INPUT_PROP_MAX] = NULL,
207 NAME_ELEMENT(INPUT_PROP_POINTER),
208 NAME_ELEMENT(INPUT_PROP_DIRECT),
209 NAME_ELEMENT(INPUT_PROP_BUTTONPAD),
210 NAME_ELEMENT(INPUT_PROP_SEMI_MT),
211 #ifdef INPUT_PROP_TOPBUTTONPAD
212 NAME_ELEMENT(INPUT_PROP_TOPBUTTONPAD),
213 #endif
214 #ifdef INPUT_PROP_POINTING_STICK
215 NAME_ELEMENT(INPUT_PROP_POINTING_STICK),
216 #endif
217 #ifdef INPUT_PROP_ACCELEROMETER
218 NAME_ELEMENT(INPUT_PROP_ACCELEROMETER),
219 #endif
221 #endif
223 static const char * const keys[KEY_MAX + 1] = {
224 [0 ... KEY_MAX] = NULL,
225 NAME_ELEMENT(KEY_RESERVED), NAME_ELEMENT(KEY_ESC),
226 NAME_ELEMENT(KEY_1), NAME_ELEMENT(KEY_2),
227 NAME_ELEMENT(KEY_3), NAME_ELEMENT(KEY_4),
228 NAME_ELEMENT(KEY_5), NAME_ELEMENT(KEY_6),
229 NAME_ELEMENT(KEY_7), NAME_ELEMENT(KEY_8),
230 NAME_ELEMENT(KEY_9), NAME_ELEMENT(KEY_0),
231 NAME_ELEMENT(KEY_MINUS), NAME_ELEMENT(KEY_EQUAL),
232 NAME_ELEMENT(KEY_BACKSPACE), NAME_ELEMENT(KEY_TAB),
233 NAME_ELEMENT(KEY_Q), NAME_ELEMENT(KEY_W),
234 NAME_ELEMENT(KEY_E), NAME_ELEMENT(KEY_R),
235 NAME_ELEMENT(KEY_T), NAME_ELEMENT(KEY_Y),
236 NAME_ELEMENT(KEY_U), NAME_ELEMENT(KEY_I),
237 NAME_ELEMENT(KEY_O), NAME_ELEMENT(KEY_P),
238 NAME_ELEMENT(KEY_LEFTBRACE), NAME_ELEMENT(KEY_RIGHTBRACE),
239 NAME_ELEMENT(KEY_ENTER), NAME_ELEMENT(KEY_LEFTCTRL),
240 NAME_ELEMENT(KEY_A), NAME_ELEMENT(KEY_S),
241 NAME_ELEMENT(KEY_D), NAME_ELEMENT(KEY_F),
242 NAME_ELEMENT(KEY_G), NAME_ELEMENT(KEY_H),
243 NAME_ELEMENT(KEY_J), NAME_ELEMENT(KEY_K),
244 NAME_ELEMENT(KEY_L), NAME_ELEMENT(KEY_SEMICOLON),
245 NAME_ELEMENT(KEY_APOSTROPHE), NAME_ELEMENT(KEY_GRAVE),
246 NAME_ELEMENT(KEY_LEFTSHIFT), NAME_ELEMENT(KEY_BACKSLASH),
247 NAME_ELEMENT(KEY_Z), NAME_ELEMENT(KEY_X),
248 NAME_ELEMENT(KEY_C), NAME_ELEMENT(KEY_V),
249 NAME_ELEMENT(KEY_B), NAME_ELEMENT(KEY_N),
250 NAME_ELEMENT(KEY_M), NAME_ELEMENT(KEY_COMMA),
251 NAME_ELEMENT(KEY_DOT), NAME_ELEMENT(KEY_SLASH),
252 NAME_ELEMENT(KEY_RIGHTSHIFT), NAME_ELEMENT(KEY_KPASTERISK),
253 NAME_ELEMENT(KEY_LEFTALT), NAME_ELEMENT(KEY_SPACE),
254 NAME_ELEMENT(KEY_CAPSLOCK), NAME_ELEMENT(KEY_F1),
255 NAME_ELEMENT(KEY_F2), NAME_ELEMENT(KEY_F3),
256 NAME_ELEMENT(KEY_F4), NAME_ELEMENT(KEY_F5),
257 NAME_ELEMENT(KEY_F6), NAME_ELEMENT(KEY_F7),
258 NAME_ELEMENT(KEY_F8), NAME_ELEMENT(KEY_F9),
259 NAME_ELEMENT(KEY_F10), NAME_ELEMENT(KEY_NUMLOCK),
260 NAME_ELEMENT(KEY_SCROLLLOCK), NAME_ELEMENT(KEY_KP7),
261 NAME_ELEMENT(KEY_KP8), NAME_ELEMENT(KEY_KP9),
262 NAME_ELEMENT(KEY_KPMINUS), NAME_ELEMENT(KEY_KP4),
263 NAME_ELEMENT(KEY_KP5), NAME_ELEMENT(KEY_KP6),
264 NAME_ELEMENT(KEY_KPPLUS), NAME_ELEMENT(KEY_KP1),
265 NAME_ELEMENT(KEY_KP2), NAME_ELEMENT(KEY_KP3),
266 NAME_ELEMENT(KEY_KP0), NAME_ELEMENT(KEY_KPDOT),
267 NAME_ELEMENT(KEY_ZENKAKUHANKAKU), NAME_ELEMENT(KEY_102ND),
268 NAME_ELEMENT(KEY_F11), NAME_ELEMENT(KEY_F12),
269 NAME_ELEMENT(KEY_RO), NAME_ELEMENT(KEY_KATAKANA),
270 NAME_ELEMENT(KEY_HIRAGANA), NAME_ELEMENT(KEY_HENKAN),
271 NAME_ELEMENT(KEY_KATAKANAHIRAGANA), NAME_ELEMENT(KEY_MUHENKAN),
272 NAME_ELEMENT(KEY_KPJPCOMMA), NAME_ELEMENT(KEY_KPENTER),
273 NAME_ELEMENT(KEY_RIGHTCTRL), NAME_ELEMENT(KEY_KPSLASH),
274 NAME_ELEMENT(KEY_SYSRQ), NAME_ELEMENT(KEY_RIGHTALT),
275 NAME_ELEMENT(KEY_LINEFEED), NAME_ELEMENT(KEY_HOME),
276 NAME_ELEMENT(KEY_UP), NAME_ELEMENT(KEY_PAGEUP),
277 NAME_ELEMENT(KEY_LEFT), NAME_ELEMENT(KEY_RIGHT),
278 NAME_ELEMENT(KEY_END), NAME_ELEMENT(KEY_DOWN),
279 NAME_ELEMENT(KEY_PAGEDOWN), NAME_ELEMENT(KEY_INSERT),
280 NAME_ELEMENT(KEY_DELETE), NAME_ELEMENT(KEY_MACRO),
281 NAME_ELEMENT(KEY_MUTE), NAME_ELEMENT(KEY_VOLUMEDOWN),
282 NAME_ELEMENT(KEY_VOLUMEUP), NAME_ELEMENT(KEY_POWER),
283 NAME_ELEMENT(KEY_KPEQUAL), NAME_ELEMENT(KEY_KPPLUSMINUS),
284 NAME_ELEMENT(KEY_PAUSE), NAME_ELEMENT(KEY_KPCOMMA),
285 NAME_ELEMENT(KEY_HANGUEL), NAME_ELEMENT(KEY_HANJA),
286 NAME_ELEMENT(KEY_YEN), NAME_ELEMENT(KEY_LEFTMETA),
287 NAME_ELEMENT(KEY_RIGHTMETA), NAME_ELEMENT(KEY_COMPOSE),
288 NAME_ELEMENT(KEY_STOP), NAME_ELEMENT(KEY_AGAIN),
289 NAME_ELEMENT(KEY_PROPS), NAME_ELEMENT(KEY_UNDO),
290 NAME_ELEMENT(KEY_FRONT), NAME_ELEMENT(KEY_COPY),
291 NAME_ELEMENT(KEY_OPEN), NAME_ELEMENT(KEY_PASTE),
292 NAME_ELEMENT(KEY_FIND), NAME_ELEMENT(KEY_CUT),
293 NAME_ELEMENT(KEY_HELP), NAME_ELEMENT(KEY_MENU),
294 NAME_ELEMENT(KEY_CALC), NAME_ELEMENT(KEY_SETUP),
295 NAME_ELEMENT(KEY_SLEEP), NAME_ELEMENT(KEY_WAKEUP),
296 NAME_ELEMENT(KEY_FILE), NAME_ELEMENT(KEY_SENDFILE),
297 NAME_ELEMENT(KEY_DELETEFILE), NAME_ELEMENT(KEY_XFER),
298 NAME_ELEMENT(KEY_PROG1), NAME_ELEMENT(KEY_PROG2),
299 NAME_ELEMENT(KEY_WWW), NAME_ELEMENT(KEY_MSDOS),
300 NAME_ELEMENT(KEY_COFFEE), NAME_ELEMENT(KEY_DIRECTION),
301 NAME_ELEMENT(KEY_CYCLEWINDOWS), NAME_ELEMENT(KEY_MAIL),
302 NAME_ELEMENT(KEY_BOOKMARKS), NAME_ELEMENT(KEY_COMPUTER),
303 NAME_ELEMENT(KEY_BACK), NAME_ELEMENT(KEY_FORWARD),
304 NAME_ELEMENT(KEY_CLOSECD), NAME_ELEMENT(KEY_EJECTCD),
305 NAME_ELEMENT(KEY_EJECTCLOSECD), NAME_ELEMENT(KEY_NEXTSONG),
306 NAME_ELEMENT(KEY_PLAYPAUSE), NAME_ELEMENT(KEY_PREVIOUSSONG),
307 NAME_ELEMENT(KEY_STOPCD), NAME_ELEMENT(KEY_RECORD),
308 NAME_ELEMENT(KEY_REWIND), NAME_ELEMENT(KEY_PHONE),
309 NAME_ELEMENT(KEY_ISO), NAME_ELEMENT(KEY_CONFIG),
310 NAME_ELEMENT(KEY_HOMEPAGE), NAME_ELEMENT(KEY_REFRESH),
311 NAME_ELEMENT(KEY_EXIT), NAME_ELEMENT(KEY_MOVE),
312 NAME_ELEMENT(KEY_EDIT), NAME_ELEMENT(KEY_SCROLLUP),
313 NAME_ELEMENT(KEY_SCROLLDOWN), NAME_ELEMENT(KEY_KPLEFTPAREN),
314 NAME_ELEMENT(KEY_KPRIGHTPAREN), NAME_ELEMENT(KEY_F13),
315 NAME_ELEMENT(KEY_F14), NAME_ELEMENT(KEY_F15),
316 NAME_ELEMENT(KEY_F16), NAME_ELEMENT(KEY_F17),
317 NAME_ELEMENT(KEY_F18), NAME_ELEMENT(KEY_F19),
318 NAME_ELEMENT(KEY_F20), NAME_ELEMENT(KEY_F21),
319 NAME_ELEMENT(KEY_F22), NAME_ELEMENT(KEY_F23),
320 NAME_ELEMENT(KEY_F24), NAME_ELEMENT(KEY_PLAYCD),
321 NAME_ELEMENT(KEY_PAUSECD), NAME_ELEMENT(KEY_PROG3),
322 NAME_ELEMENT(KEY_PROG4), NAME_ELEMENT(KEY_SUSPEND),
323 NAME_ELEMENT(KEY_CLOSE), NAME_ELEMENT(KEY_PLAY),
324 NAME_ELEMENT(KEY_FASTFORWARD), NAME_ELEMENT(KEY_BASSBOOST),
325 NAME_ELEMENT(KEY_PRINT), NAME_ELEMENT(KEY_HP),
326 NAME_ELEMENT(KEY_CAMERA), NAME_ELEMENT(KEY_SOUND),
327 NAME_ELEMENT(KEY_QUESTION), NAME_ELEMENT(KEY_EMAIL),
328 NAME_ELEMENT(KEY_CHAT), NAME_ELEMENT(KEY_SEARCH),
329 NAME_ELEMENT(KEY_CONNECT), NAME_ELEMENT(KEY_FINANCE),
330 NAME_ELEMENT(KEY_SPORT), NAME_ELEMENT(KEY_SHOP),
331 NAME_ELEMENT(KEY_ALTERASE), NAME_ELEMENT(KEY_CANCEL),
332 NAME_ELEMENT(KEY_BRIGHTNESSDOWN), NAME_ELEMENT(KEY_BRIGHTNESSUP),
333 NAME_ELEMENT(KEY_MEDIA), NAME_ELEMENT(KEY_UNKNOWN),
334 NAME_ELEMENT(KEY_OK),
335 NAME_ELEMENT(KEY_SELECT), NAME_ELEMENT(KEY_GOTO),
336 NAME_ELEMENT(KEY_CLEAR), NAME_ELEMENT(KEY_POWER2),
337 NAME_ELEMENT(KEY_OPTION), NAME_ELEMENT(KEY_INFO),
338 NAME_ELEMENT(KEY_TIME), NAME_ELEMENT(KEY_VENDOR),
339 NAME_ELEMENT(KEY_ARCHIVE), NAME_ELEMENT(KEY_PROGRAM),
340 NAME_ELEMENT(KEY_CHANNEL), NAME_ELEMENT(KEY_FAVORITES),
341 NAME_ELEMENT(KEY_EPG), NAME_ELEMENT(KEY_PVR),
342 NAME_ELEMENT(KEY_MHP), NAME_ELEMENT(KEY_LANGUAGE),
343 NAME_ELEMENT(KEY_TITLE), NAME_ELEMENT(KEY_SUBTITLE),
344 NAME_ELEMENT(KEY_ANGLE), NAME_ELEMENT(KEY_ZOOM),
345 NAME_ELEMENT(KEY_MODE), NAME_ELEMENT(KEY_KEYBOARD),
346 NAME_ELEMENT(KEY_SCREEN), NAME_ELEMENT(KEY_PC),
347 NAME_ELEMENT(KEY_TV), NAME_ELEMENT(KEY_TV2),
348 NAME_ELEMENT(KEY_VCR), NAME_ELEMENT(KEY_VCR2),
349 NAME_ELEMENT(KEY_SAT), NAME_ELEMENT(KEY_SAT2),
350 NAME_ELEMENT(KEY_CD), NAME_ELEMENT(KEY_TAPE),
351 NAME_ELEMENT(KEY_RADIO), NAME_ELEMENT(KEY_TUNER),
352 NAME_ELEMENT(KEY_PLAYER), NAME_ELEMENT(KEY_TEXT),
353 NAME_ELEMENT(KEY_DVD), NAME_ELEMENT(KEY_AUX),
354 NAME_ELEMENT(KEY_MP3), NAME_ELEMENT(KEY_AUDIO),
355 NAME_ELEMENT(KEY_VIDEO), NAME_ELEMENT(KEY_DIRECTORY),
356 NAME_ELEMENT(KEY_LIST), NAME_ELEMENT(KEY_MEMO),
357 NAME_ELEMENT(KEY_CALENDAR), NAME_ELEMENT(KEY_RED),
358 NAME_ELEMENT(KEY_GREEN), NAME_ELEMENT(KEY_YELLOW),
359 NAME_ELEMENT(KEY_BLUE), NAME_ELEMENT(KEY_CHANNELUP),
360 NAME_ELEMENT(KEY_CHANNELDOWN), NAME_ELEMENT(KEY_FIRST),
361 NAME_ELEMENT(KEY_LAST), NAME_ELEMENT(KEY_AB),
362 NAME_ELEMENT(KEY_NEXT), NAME_ELEMENT(KEY_RESTART),
363 NAME_ELEMENT(KEY_SLOW), NAME_ELEMENT(KEY_SHUFFLE),
364 NAME_ELEMENT(KEY_BREAK), NAME_ELEMENT(KEY_PREVIOUS),
365 NAME_ELEMENT(KEY_DIGITS), NAME_ELEMENT(KEY_TEEN),
366 NAME_ELEMENT(KEY_TWEN), NAME_ELEMENT(KEY_DEL_EOL),
367 NAME_ELEMENT(KEY_DEL_EOS), NAME_ELEMENT(KEY_INS_LINE),
368 NAME_ELEMENT(KEY_DEL_LINE),
369 NAME_ELEMENT(KEY_VIDEOPHONE), NAME_ELEMENT(KEY_GAMES),
370 NAME_ELEMENT(KEY_ZOOMIN), NAME_ELEMENT(KEY_ZOOMOUT),
371 NAME_ELEMENT(KEY_ZOOMRESET), NAME_ELEMENT(KEY_WORDPROCESSOR),
372 NAME_ELEMENT(KEY_EDITOR), NAME_ELEMENT(KEY_SPREADSHEET),
373 NAME_ELEMENT(KEY_GRAPHICSEDITOR), NAME_ELEMENT(KEY_PRESENTATION),
374 NAME_ELEMENT(KEY_DATABASE), NAME_ELEMENT(KEY_NEWS),
375 NAME_ELEMENT(KEY_VOICEMAIL), NAME_ELEMENT(KEY_ADDRESSBOOK),
376 NAME_ELEMENT(KEY_MESSENGER), NAME_ELEMENT(KEY_DISPLAYTOGGLE),
377 #ifdef KEY_SPELLCHECK
378 NAME_ELEMENT(KEY_SPELLCHECK),
379 #endif
380 #ifdef KEY_LOGOFF
381 NAME_ELEMENT(KEY_LOGOFF),
382 #endif
383 #ifdef KEY_DOLLAR
384 NAME_ELEMENT(KEY_DOLLAR),
385 #endif
386 #ifdef KEY_EURO
387 NAME_ELEMENT(KEY_EURO),
388 #endif
389 #ifdef KEY_FRAMEBACK
390 NAME_ELEMENT(KEY_FRAMEBACK),
391 #endif
392 #ifdef KEY_FRAMEFORWARD
393 NAME_ELEMENT(KEY_FRAMEFORWARD),
394 #endif
395 #ifdef KEY_CONTEXT_MENU
396 NAME_ELEMENT(KEY_CONTEXT_MENU),
397 #endif
398 #ifdef KEY_MEDIA_REPEAT
399 NAME_ELEMENT(KEY_MEDIA_REPEAT),
400 #endif
401 #ifdef KEY_10CHANNELSUP
402 NAME_ELEMENT(KEY_10CHANNELSUP),
403 #endif
404 #ifdef KEY_10CHANNELSDOWN
405 NAME_ELEMENT(KEY_10CHANNELSDOWN),
406 #endif
407 #ifdef KEY_IMAGES
408 NAME_ELEMENT(KEY_IMAGES),
409 #endif
410 #ifdef KEY_NOTIFICATION_CENTER
411 NAME_ELEMENT(KEY_NOTIFICATION_CENTER),
412 NAME_ELEMENT(KEY_PICKUP_PHONE),
413 NAME_ELEMENT(KEY_HANGUP_PHONE),
414 #endif
415 NAME_ELEMENT(KEY_DEL_EOL), NAME_ELEMENT(KEY_DEL_EOS),
416 NAME_ELEMENT(KEY_INS_LINE), NAME_ELEMENT(KEY_DEL_LINE),
417 NAME_ELEMENT(KEY_FN), NAME_ELEMENT(KEY_FN_ESC),
418 NAME_ELEMENT(KEY_FN_F1), NAME_ELEMENT(KEY_FN_F2),
419 NAME_ELEMENT(KEY_FN_F3), NAME_ELEMENT(KEY_FN_F4),
420 NAME_ELEMENT(KEY_FN_F5), NAME_ELEMENT(KEY_FN_F6),
421 NAME_ELEMENT(KEY_FN_F7), NAME_ELEMENT(KEY_FN_F8),
422 NAME_ELEMENT(KEY_FN_F9), NAME_ELEMENT(KEY_FN_F10),
423 NAME_ELEMENT(KEY_FN_F11), NAME_ELEMENT(KEY_FN_F12),
424 NAME_ELEMENT(KEY_FN_1), NAME_ELEMENT(KEY_FN_2),
425 NAME_ELEMENT(KEY_FN_D), NAME_ELEMENT(KEY_FN_E),
426 NAME_ELEMENT(KEY_FN_F), NAME_ELEMENT(KEY_FN_S),
427 NAME_ELEMENT(KEY_FN_B),
428 #ifdef KEY_FN_RIGHT_SHIFT
429 NAME_ELEMENT(KEY_FN_RIGHT_SHIFT),
430 #endif
431 NAME_ELEMENT(KEY_BRL_DOT1), NAME_ELEMENT(KEY_BRL_DOT2),
432 NAME_ELEMENT(KEY_BRL_DOT3), NAME_ELEMENT(KEY_BRL_DOT4),
433 NAME_ELEMENT(KEY_BRL_DOT5), NAME_ELEMENT(KEY_BRL_DOT6),
434 NAME_ELEMENT(KEY_BRL_DOT7), NAME_ELEMENT(KEY_BRL_DOT8),
435 NAME_ELEMENT(KEY_BRL_DOT9), NAME_ELEMENT(KEY_BRL_DOT10),
436 #ifdef KEY_NUMERIC_0
437 NAME_ELEMENT(KEY_NUMERIC_0), NAME_ELEMENT(KEY_NUMERIC_1),
438 NAME_ELEMENT(KEY_NUMERIC_2), NAME_ELEMENT(KEY_NUMERIC_3),
439 NAME_ELEMENT(KEY_NUMERIC_4), NAME_ELEMENT(KEY_NUMERIC_5),
440 NAME_ELEMENT(KEY_NUMERIC_6), NAME_ELEMENT(KEY_NUMERIC_7),
441 NAME_ELEMENT(KEY_NUMERIC_8), NAME_ELEMENT(KEY_NUMERIC_9),
442 NAME_ELEMENT(KEY_NUMERIC_STAR), NAME_ELEMENT(KEY_NUMERIC_POUND),
443 #endif
444 #ifdef KEY_NUMERIC_A
445 NAME_ELEMENT(KEY_NUMERIC_A), NAME_ELEMENT(KEY_NUMERIC_B),
446 NAME_ELEMENT(KEY_NUMERIC_C), NAME_ELEMENT(KEY_NUMERIC_D),
447 #endif
448 #ifdef KEY_NUMERIC_11
449 NAME_ELEMENT(KEY_NUMERIC_11), NAME_ELEMENT(KEY_NUMERIC_12),
450 #endif
451 NAME_ELEMENT(KEY_BATTERY),
452 NAME_ELEMENT(KEY_BLUETOOTH), NAME_ELEMENT(KEY_BRIGHTNESS_CYCLE),
453 NAME_ELEMENT(KEY_BRIGHTNESS_ZERO),
454 #ifdef KEY_DASHBOARD
455 NAME_ELEMENT(KEY_DASHBOARD),
456 #endif
457 NAME_ELEMENT(KEY_DISPLAY_OFF), NAME_ELEMENT(KEY_DOCUMENTS),
458 NAME_ELEMENT(KEY_FORWARDMAIL), NAME_ELEMENT(KEY_NEW),
459 NAME_ELEMENT(KEY_KBDILLUMDOWN), NAME_ELEMENT(KEY_KBDILLUMUP),
460 NAME_ELEMENT(KEY_KBDILLUMTOGGLE), NAME_ELEMENT(KEY_REDO),
461 NAME_ELEMENT(KEY_REPLY), NAME_ELEMENT(KEY_SAVE),
462 #ifdef KEY_SCALE
463 NAME_ELEMENT(KEY_SCALE),
464 #endif
465 NAME_ELEMENT(KEY_SEND),
466 NAME_ELEMENT(KEY_SCREENLOCK), NAME_ELEMENT(KEY_SWITCHVIDEOMODE),
467 #ifdef KEY_UWB
468 NAME_ELEMENT(KEY_UWB),
469 #endif
470 #ifdef KEY_VIDEO_NEXT
471 NAME_ELEMENT(KEY_VIDEO_NEXT),
472 #endif
473 #ifdef KEY_VIDEO_PREV
474 NAME_ELEMENT(KEY_VIDEO_PREV),
475 #endif
476 #ifdef KEY_WIMAX
477 NAME_ELEMENT(KEY_WIMAX),
478 #endif
479 #ifdef KEY_WLAN
480 NAME_ELEMENT(KEY_WLAN),
481 #endif
482 #ifdef KEY_RFKILL
483 NAME_ELEMENT(KEY_RFKILL),
484 #endif
485 #ifdef KEY_MICMUTE
486 NAME_ELEMENT(KEY_MICMUTE),
487 #endif
488 #ifdef KEY_CAMERA_FOCUS
489 NAME_ELEMENT(KEY_CAMERA_FOCUS),
490 #endif
491 #ifdef KEY_WPS_BUTTON
492 NAME_ELEMENT(KEY_WPS_BUTTON),
493 #endif
494 #ifdef KEY_TOUCHPAD_TOGGLE
495 NAME_ELEMENT(KEY_TOUCHPAD_TOGGLE),
496 NAME_ELEMENT(KEY_TOUCHPAD_ON),
497 NAME_ELEMENT(KEY_TOUCHPAD_OFF),
498 #endif
499 #ifdef KEY_CAMERA_ZOOMIN
500 NAME_ELEMENT(KEY_CAMERA_ZOOMIN), NAME_ELEMENT(KEY_CAMERA_ZOOMOUT),
501 NAME_ELEMENT(KEY_CAMERA_UP), NAME_ELEMENT(KEY_CAMERA_DOWN),
502 NAME_ELEMENT(KEY_CAMERA_LEFT), NAME_ELEMENT(KEY_CAMERA_RIGHT),
503 #endif
504 #ifdef KEY_ATTENDANT_ON
505 NAME_ELEMENT(KEY_ATTENDANT_ON), NAME_ELEMENT(KEY_ATTENDANT_OFF),
506 NAME_ELEMENT(KEY_ATTENDANT_TOGGLE), NAME_ELEMENT(KEY_LIGHTS_TOGGLE),
507 #endif
509 NAME_ELEMENT(BTN_0), NAME_ELEMENT(BTN_1),
510 NAME_ELEMENT(BTN_2), NAME_ELEMENT(BTN_3),
511 NAME_ELEMENT(BTN_4), NAME_ELEMENT(BTN_5),
512 NAME_ELEMENT(BTN_6), NAME_ELEMENT(BTN_7),
513 NAME_ELEMENT(BTN_8), NAME_ELEMENT(BTN_9),
514 NAME_ELEMENT(BTN_LEFT), NAME_ELEMENT(BTN_RIGHT),
515 NAME_ELEMENT(BTN_MIDDLE), NAME_ELEMENT(BTN_SIDE),
516 NAME_ELEMENT(BTN_EXTRA), NAME_ELEMENT(BTN_FORWARD),
517 NAME_ELEMENT(BTN_BACK), NAME_ELEMENT(BTN_TASK),
518 NAME_ELEMENT(BTN_TRIGGER), NAME_ELEMENT(BTN_THUMB),
519 NAME_ELEMENT(BTN_THUMB2), NAME_ELEMENT(BTN_TOP),
520 NAME_ELEMENT(BTN_TOP2), NAME_ELEMENT(BTN_PINKIE),
521 NAME_ELEMENT(BTN_BASE), NAME_ELEMENT(BTN_BASE2),
522 NAME_ELEMENT(BTN_BASE3), NAME_ELEMENT(BTN_BASE4),
523 NAME_ELEMENT(BTN_BASE5), NAME_ELEMENT(BTN_BASE6),
524 NAME_ELEMENT(BTN_DEAD), NAME_ELEMENT(BTN_C),
525 #ifdef BTN_SOUTH
526 NAME_ELEMENT(BTN_SOUTH), NAME_ELEMENT(BTN_EAST),
527 NAME_ELEMENT(BTN_NORTH), NAME_ELEMENT(BTN_WEST),
528 #else
529 NAME_ELEMENT(BTN_A), NAME_ELEMENT(BTN_B),
530 NAME_ELEMENT(BTN_X), NAME_ELEMENT(BTN_Y),
531 #endif
532 NAME_ELEMENT(BTN_Z), NAME_ELEMENT(BTN_TL),
533 NAME_ELEMENT(BTN_TR), NAME_ELEMENT(BTN_TL2),
534 NAME_ELEMENT(BTN_TR2), NAME_ELEMENT(BTN_SELECT),
535 NAME_ELEMENT(BTN_START), NAME_ELEMENT(BTN_MODE),
536 NAME_ELEMENT(BTN_THUMBL), NAME_ELEMENT(BTN_THUMBR),
537 NAME_ELEMENT(BTN_TOOL_PEN), NAME_ELEMENT(BTN_TOOL_RUBBER),
538 NAME_ELEMENT(BTN_TOOL_BRUSH), NAME_ELEMENT(BTN_TOOL_PENCIL),
539 NAME_ELEMENT(BTN_TOOL_AIRBRUSH), NAME_ELEMENT(BTN_TOOL_FINGER),
540 NAME_ELEMENT(BTN_TOOL_MOUSE), NAME_ELEMENT(BTN_TOOL_LENS),
541 #ifdef BTN_STYLUS3
542 NAME_ELEMENT(BTN_STYLUS3),
543 #endif
544 NAME_ELEMENT(BTN_TOUCH), NAME_ELEMENT(BTN_STYLUS),
545 NAME_ELEMENT(BTN_STYLUS2), NAME_ELEMENT(BTN_TOOL_DOUBLETAP),
546 NAME_ELEMENT(BTN_TOOL_TRIPLETAP),
547 #ifdef BTN_TOOL_QUADTAP
548 NAME_ELEMENT(BTN_TOOL_QUADTAP),
549 #endif
550 NAME_ELEMENT(BTN_GEAR_DOWN),
551 NAME_ELEMENT(BTN_GEAR_UP),
553 #ifdef BTN_DPAD_UP
554 NAME_ELEMENT(BTN_DPAD_UP), NAME_ELEMENT(BTN_DPAD_DOWN),
555 NAME_ELEMENT(BTN_DPAD_LEFT), NAME_ELEMENT(BTN_DPAD_RIGHT),
556 #endif
557 #ifdef KEY_ALS_TOGGLE
558 NAME_ELEMENT(KEY_ALS_TOGGLE),
559 #endif
560 #ifdef KEY_ROTATE_LOCK_TOGGLE
561 NAME_ELEMENT(KEY_ROTATE_LOCK_TOGGLE),
562 #endif
563 #ifdef KEY_REFRESH_RATE_TOGGLE
564 NAME_ELEMENT(KEY_REFRESH_RATE_TOGGLE),
565 #endif
566 #ifdef KEY_BUTTONCONFIG
567 NAME_ELEMENT(KEY_BUTTONCONFIG),
568 #endif
569 #ifdef KEY_TASKMANAGER
570 NAME_ELEMENT(KEY_TASKMANAGER),
571 #endif
572 #ifdef KEY_JOURNAL
573 NAME_ELEMENT(KEY_JOURNAL),
574 #endif
575 #ifdef KEY_CONTROLPANEL
576 NAME_ELEMENT(KEY_CONTROLPANEL),
577 #endif
578 #ifdef KEY_APPSELECT
579 NAME_ELEMENT(KEY_APPSELECT),
580 #endif
581 #ifdef KEY_SCREENSAVER
582 NAME_ELEMENT(KEY_SCREENSAVER),
583 #endif
584 #ifdef KEY_VOICECOMMAND
585 NAME_ELEMENT(KEY_VOICECOMMAND),
586 #endif
587 #ifdef KEY_ASSISTANT
588 NAME_ELEMENT(KEY_ASSISTANT),
589 #endif
590 #ifdef KEY_EMOJI_PICKER
591 NAME_ELEMENT(KEY_EMOJI_PICKER),
592 #endif
593 #ifdef KEY_KBD_LAYOUT_NEXT
594 NAME_ELEMENT(KEY_KBD_LAYOUT_NEXT),
595 #endif
596 #ifdef KEY_DICTATE
597 NAME_ELEMENT(KEY_DICTATE),
598 #endif
599 #ifdef KEY_CAMERA_ACCESS_ENABLE
600 NAME_ELEMENT(KEY_CAMERA_ACCESS_ENABLE),
601 NAME_ELEMENT(KEY_CAMERA_ACCESS_DISABLE),
602 NAME_ELEMENT(KEY_CAMERA_ACCESS_TOGGLE),
603 #endif
604 #ifdef KEY_BRIGHTNESS_MIN
605 NAME_ELEMENT(KEY_BRIGHTNESS_MIN),
606 #endif
607 #ifdef KEY_BRIGHTNESS_MAX
608 NAME_ELEMENT(KEY_BRIGHTNESS_MAX),
609 #endif
610 #ifdef KEY_KBDINPUTASSIST_PREV
611 NAME_ELEMENT(KEY_KBDINPUTASSIST_PREV),
612 #endif
613 #ifdef KEY_KBDINPUTASSIST_NEXT
614 NAME_ELEMENT(KEY_KBDINPUTASSIST_NEXT),
615 #endif
616 #ifdef KEY_KBDINPUTASSIST_PREVGROUP
617 NAME_ELEMENT(KEY_KBDINPUTASSIST_PREVGROUP),
618 #endif
619 #ifdef KEY_KBDINPUTASSIST_NEXTGROUP
620 NAME_ELEMENT(KEY_KBDINPUTASSIST_NEXTGROUP),
621 #endif
622 #ifdef KEY_KBDINPUTASSIST_ACCEPT
623 NAME_ELEMENT(KEY_KBDINPUTASSIST_ACCEPT),
624 #endif
625 #ifdef KEY_KBDINPUTASSIST_CANCEL
626 NAME_ELEMENT(KEY_KBDINPUTASSIST_CANCEL),
627 #endif
629 #ifdef KEY_RIGHT_UP
630 NAME_ELEMENT(KEY_RIGHT_UP), NAME_ELEMENT(KEY_RIGHT_DOWN),
631 NAME_ELEMENT(KEY_LEFT_UP), NAME_ELEMENT(KEY_LEFT_DOWN),
632 #endif
634 #ifdef KEY_ROOT_MENU
635 NAME_ELEMENT(KEY_ROOT_MENU),
636 NAME_ELEMENT(KEY_MEDIA_TOP_MENU),
637 NAME_ELEMENT(KEY_AUDIO_DESC),
638 NAME_ELEMENT(KEY_3D_MODE),
639 NAME_ELEMENT(KEY_NEXT_FAVORITE),
640 NAME_ELEMENT(KEY_STOP_RECORD),
641 NAME_ELEMENT(KEY_PAUSE_RECORD),
642 NAME_ELEMENT(KEY_VOD),
643 NAME_ELEMENT(KEY_UNMUTE),
644 NAME_ELEMENT(KEY_FASTREVERSE),
645 NAME_ELEMENT(KEY_SLOWREVERSE),
646 #endif
648 #ifdef KEY_DATA
649 NAME_ELEMENT(KEY_DATA),
650 #endif
652 #ifdef KEY_ONSCREEN_KEYBOARD
653 NAME_ELEMENT(KEY_ONSCREEN_KEYBOARD),
654 #endif
656 #ifdef KEY_PRIVACY_SCREEN_TOGGLE
657 NAME_ELEMENT(KEY_PRIVACY_SCREEN_TOGGLE),
658 #endif
660 #ifdef KEY_SELECTIVE_SCREENSHOT
661 NAME_ELEMENT(KEY_SELECTIVE_SCREENSHOT),
662 #endif
664 #ifdef KEY_NEXT_ELEMENT
665 NAME_ELEMENT(KEY_NEXT_ELEMENT),
666 NAME_ELEMENT(KEY_PREVIOUS_ELEMENT),
667 NAME_ELEMENT(KEY_AUTOPILOT_ENGAGE_TOGGLE),
668 NAME_ELEMENT(KEY_MARK_WAYPOINT),
669 NAME_ELEMENT(KEY_SOS),
670 NAME_ELEMENT(KEY_NAV_CHART),
671 NAME_ELEMENT(KEY_FISHING_CHART),
672 NAME_ELEMENT(KEY_SINGLE_RANGE_RADAR),
673 NAME_ELEMENT(KEY_DUAL_RANGE_RADAR),
674 NAME_ELEMENT(KEY_RADAR_OVERLAY),
675 NAME_ELEMENT(KEY_TRADITIONAL_SONAR),
676 NAME_ELEMENT(KEY_CLEARVU_SONAR),
677 NAME_ELEMENT(KEY_SIDEVU_SONAR),
678 NAME_ELEMENT(KEY_NAV_INFO),
679 NAME_ELEMENT(KEY_BRIGHTNESS_MENU),
680 #endif
682 #ifdef KEY_MACRO1
683 NAME_ELEMENT(KEY_MACRO1), NAME_ELEMENT(KEY_MACRO2),
684 NAME_ELEMENT(KEY_MACRO3), NAME_ELEMENT(KEY_MACRO4),
685 NAME_ELEMENT(KEY_MACRO5), NAME_ELEMENT(KEY_MACRO6),
686 NAME_ELEMENT(KEY_MACRO7), NAME_ELEMENT(KEY_MACRO8),
687 NAME_ELEMENT(KEY_MACRO9), NAME_ELEMENT(KEY_MACRO10),
688 NAME_ELEMENT(KEY_MACRO11), NAME_ELEMENT(KEY_MACRO12),
689 NAME_ELEMENT(KEY_MACRO13), NAME_ELEMENT(KEY_MACRO14),
690 NAME_ELEMENT(KEY_MACRO15), NAME_ELEMENT(KEY_MACRO16),
691 NAME_ELEMENT(KEY_MACRO17), NAME_ELEMENT(KEY_MACRO18),
692 NAME_ELEMENT(KEY_MACRO19), NAME_ELEMENT(KEY_MACRO20),
693 NAME_ELEMENT(KEY_MACRO21), NAME_ELEMENT(KEY_MACRO22),
694 NAME_ELEMENT(KEY_MACRO23), NAME_ELEMENT(KEY_MACRO24),
695 NAME_ELEMENT(KEY_MACRO25), NAME_ELEMENT(KEY_MACRO26),
696 NAME_ELEMENT(KEY_MACRO27), NAME_ELEMENT(KEY_MACRO28),
697 NAME_ELEMENT(KEY_MACRO29), NAME_ELEMENT(KEY_MACRO30),
698 #endif
700 #ifdef KEY_MACRO_RECORD_START
701 NAME_ELEMENT(KEY_MACRO_RECORD_START),
702 NAME_ELEMENT(KEY_MACRO_RECORD_STOP),
703 NAME_ELEMENT(KEY_MACRO_PRESET_CYCLE),
704 NAME_ELEMENT(KEY_MACRO_PRESET1),
705 NAME_ELEMENT(KEY_MACRO_PRESET2),
706 NAME_ELEMENT(KEY_MACRO_PRESET3),
707 #endif
709 #ifdef KEY_KBD_LCD_MENU1
710 NAME_ELEMENT(KEY_KBD_LCD_MENU1), NAME_ELEMENT(KEY_KBD_LCD_MENU2),
711 NAME_ELEMENT(KEY_KBD_LCD_MENU2), NAME_ELEMENT(KEY_KBD_LCD_MENU3),
712 NAME_ELEMENT(KEY_KBD_LCD_MENU4), NAME_ELEMENT(KEY_KBD_LCD_MENU5),
713 #endif
715 #ifdef BTN_TRIGGER_HAPPY
716 NAME_ELEMENT(BTN_TRIGGER_HAPPY1), NAME_ELEMENT(BTN_TRIGGER_HAPPY11),
717 NAME_ELEMENT(BTN_TRIGGER_HAPPY2), NAME_ELEMENT(BTN_TRIGGER_HAPPY12),
718 NAME_ELEMENT(BTN_TRIGGER_HAPPY3), NAME_ELEMENT(BTN_TRIGGER_HAPPY13),
719 NAME_ELEMENT(BTN_TRIGGER_HAPPY4), NAME_ELEMENT(BTN_TRIGGER_HAPPY14),
720 NAME_ELEMENT(BTN_TRIGGER_HAPPY5), NAME_ELEMENT(BTN_TRIGGER_HAPPY15),
721 NAME_ELEMENT(BTN_TRIGGER_HAPPY6), NAME_ELEMENT(BTN_TRIGGER_HAPPY16),
722 NAME_ELEMENT(BTN_TRIGGER_HAPPY7), NAME_ELEMENT(BTN_TRIGGER_HAPPY17),
723 NAME_ELEMENT(BTN_TRIGGER_HAPPY8), NAME_ELEMENT(BTN_TRIGGER_HAPPY18),
724 NAME_ELEMENT(BTN_TRIGGER_HAPPY9), NAME_ELEMENT(BTN_TRIGGER_HAPPY19),
725 NAME_ELEMENT(BTN_TRIGGER_HAPPY10), NAME_ELEMENT(BTN_TRIGGER_HAPPY20),
727 NAME_ELEMENT(BTN_TRIGGER_HAPPY21), NAME_ELEMENT(BTN_TRIGGER_HAPPY31),
728 NAME_ELEMENT(BTN_TRIGGER_HAPPY22), NAME_ELEMENT(BTN_TRIGGER_HAPPY32),
729 NAME_ELEMENT(BTN_TRIGGER_HAPPY23), NAME_ELEMENT(BTN_TRIGGER_HAPPY33),
730 NAME_ELEMENT(BTN_TRIGGER_HAPPY24), NAME_ELEMENT(BTN_TRIGGER_HAPPY34),
731 NAME_ELEMENT(BTN_TRIGGER_HAPPY25), NAME_ELEMENT(BTN_TRIGGER_HAPPY35),
732 NAME_ELEMENT(BTN_TRIGGER_HAPPY26), NAME_ELEMENT(BTN_TRIGGER_HAPPY36),
733 NAME_ELEMENT(BTN_TRIGGER_HAPPY27), NAME_ELEMENT(BTN_TRIGGER_HAPPY37),
734 NAME_ELEMENT(BTN_TRIGGER_HAPPY28), NAME_ELEMENT(BTN_TRIGGER_HAPPY38),
735 NAME_ELEMENT(BTN_TRIGGER_HAPPY29), NAME_ELEMENT(BTN_TRIGGER_HAPPY39),
736 NAME_ELEMENT(BTN_TRIGGER_HAPPY30), NAME_ELEMENT(BTN_TRIGGER_HAPPY40),
737 #endif
738 #ifdef BTN_TOOL_QUINTTAP
739 NAME_ELEMENT(BTN_TOOL_QUINTTAP),
740 #endif
743 static const char * const absval[6] = { "Value", "Min ", "Max ", "Fuzz ", "Flat ", "Resolution "};
745 static const char * const relatives[REL_MAX + 1] = {
746 [0 ... REL_MAX] = NULL,
747 NAME_ELEMENT(REL_X), NAME_ELEMENT(REL_Y),
748 NAME_ELEMENT(REL_Z), NAME_ELEMENT(REL_RX),
749 NAME_ELEMENT(REL_RY), NAME_ELEMENT(REL_RZ),
750 NAME_ELEMENT(REL_HWHEEL),
751 NAME_ELEMENT(REL_DIAL), NAME_ELEMENT(REL_WHEEL),
752 NAME_ELEMENT(REL_MISC),
753 #ifdef REL_WHEEL_HI_RES
754 NAME_ELEMENT(REL_WHEEL_HI_RES),
755 NAME_ELEMENT(REL_HWHEEL_HI_RES),
756 #endif
759 static const char * const absolutes[ABS_MAX + 1] = {
760 [0 ... ABS_MAX] = NULL,
761 NAME_ELEMENT(ABS_X), NAME_ELEMENT(ABS_Y),
762 NAME_ELEMENT(ABS_Z), NAME_ELEMENT(ABS_RX),
763 NAME_ELEMENT(ABS_RY), NAME_ELEMENT(ABS_RZ),
764 NAME_ELEMENT(ABS_THROTTLE), NAME_ELEMENT(ABS_RUDDER),
765 NAME_ELEMENT(ABS_WHEEL), NAME_ELEMENT(ABS_GAS),
766 NAME_ELEMENT(ABS_BRAKE), NAME_ELEMENT(ABS_HAT0X),
767 NAME_ELEMENT(ABS_HAT0Y), NAME_ELEMENT(ABS_HAT1X),
768 NAME_ELEMENT(ABS_HAT1Y), NAME_ELEMENT(ABS_HAT2X),
769 NAME_ELEMENT(ABS_HAT2Y), NAME_ELEMENT(ABS_HAT3X),
770 NAME_ELEMENT(ABS_HAT3Y), NAME_ELEMENT(ABS_PRESSURE),
771 NAME_ELEMENT(ABS_DISTANCE), NAME_ELEMENT(ABS_TILT_X),
772 NAME_ELEMENT(ABS_TILT_Y), NAME_ELEMENT(ABS_TOOL_WIDTH),
773 NAME_ELEMENT(ABS_VOLUME), NAME_ELEMENT(ABS_MISC),
774 #ifdef ABS_MT_BLOB_ID
775 NAME_ELEMENT(ABS_MT_TOUCH_MAJOR),
776 NAME_ELEMENT(ABS_MT_TOUCH_MINOR),
777 NAME_ELEMENT(ABS_MT_WIDTH_MAJOR),
778 NAME_ELEMENT(ABS_MT_WIDTH_MINOR),
779 NAME_ELEMENT(ABS_MT_ORIENTATION),
780 NAME_ELEMENT(ABS_MT_POSITION_X),
781 NAME_ELEMENT(ABS_MT_POSITION_Y),
782 NAME_ELEMENT(ABS_MT_TOOL_TYPE),
783 NAME_ELEMENT(ABS_MT_BLOB_ID),
784 #endif
785 #ifdef ABS_MT_TRACKING_ID
786 NAME_ELEMENT(ABS_MT_TRACKING_ID),
787 #endif
788 #ifdef ABS_MT_PRESSURE
789 NAME_ELEMENT(ABS_MT_PRESSURE),
790 #endif
791 #ifdef ABS_MT_SLOT
792 NAME_ELEMENT(ABS_MT_SLOT),
793 #endif
794 #ifdef ABS_MT_TOOL_X
795 NAME_ELEMENT(ABS_MT_TOOL_X),
796 NAME_ELEMENT(ABS_MT_TOOL_Y),
797 NAME_ELEMENT(ABS_MT_DISTANCE),
798 #endif
802 static const char * const misc[MSC_MAX + 1] = {
803 [ 0 ... MSC_MAX] = NULL,
804 NAME_ELEMENT(MSC_SERIAL), NAME_ELEMENT(MSC_PULSELED),
805 NAME_ELEMENT(MSC_GESTURE), NAME_ELEMENT(MSC_RAW),
806 NAME_ELEMENT(MSC_SCAN),
807 #ifdef MSC_TIMESTAMP
808 NAME_ELEMENT(MSC_TIMESTAMP),
809 #endif
812 static const char * const leds[LED_MAX + 1] = {
813 [0 ... LED_MAX] = NULL,
814 NAME_ELEMENT(LED_NUML), NAME_ELEMENT(LED_CAPSL),
815 NAME_ELEMENT(LED_SCROLLL), NAME_ELEMENT(LED_COMPOSE),
816 NAME_ELEMENT(LED_KANA), NAME_ELEMENT(LED_SLEEP),
817 NAME_ELEMENT(LED_SUSPEND), NAME_ELEMENT(LED_MUTE),
818 NAME_ELEMENT(LED_MISC),
819 #ifdef LED_MAIL
820 NAME_ELEMENT(LED_MAIL),
821 #endif
822 #ifdef LED_CHARGING
823 NAME_ELEMENT(LED_CHARGING),
824 #endif
827 static const char * const repeats[REP_MAX + 1] = {
828 [0 ... REP_MAX] = NULL,
829 NAME_ELEMENT(REP_DELAY), NAME_ELEMENT(REP_PERIOD)
832 static const char * const sounds[SND_MAX + 1] = {
833 [0 ... SND_MAX] = NULL,
834 NAME_ELEMENT(SND_CLICK), NAME_ELEMENT(SND_BELL),
835 NAME_ELEMENT(SND_TONE)
838 static const char * const syns[SYN_MAX + 1] = {
839 [0 ... SYN_MAX] = NULL,
840 NAME_ELEMENT(SYN_REPORT),
841 NAME_ELEMENT(SYN_CONFIG),
842 NAME_ELEMENT(SYN_MT_REPORT),
843 NAME_ELEMENT(SYN_DROPPED)
846 static const char * const switches[SW_MAX + 1] = {
847 [0 ... SW_MAX] = NULL,
848 NAME_ELEMENT(SW_LID),
849 NAME_ELEMENT(SW_TABLET_MODE),
850 NAME_ELEMENT(SW_HEADPHONE_INSERT),
851 #ifdef SW_RFKILL_ALL
852 NAME_ELEMENT(SW_RFKILL_ALL),
853 #endif
854 #ifdef SW_MICROPHONE_INSERT
855 NAME_ELEMENT(SW_MICROPHONE_INSERT),
856 #endif
857 #ifdef SW_DOCK
858 NAME_ELEMENT(SW_DOCK),
859 #endif
860 #ifdef SW_LINEOUT_INSERT
861 NAME_ELEMENT(SW_LINEOUT_INSERT),
862 #endif
863 #ifdef SW_JACK_PHYSICAL_INSERT
864 NAME_ELEMENT(SW_JACK_PHYSICAL_INSERT),
865 #endif
866 #ifdef SW_VIDEOOUT_INSERT
867 NAME_ELEMENT(SW_VIDEOOUT_INSERT),
868 #endif
869 #ifdef SW_CAMERA_LENS_COVER
870 NAME_ELEMENT(SW_CAMERA_LENS_COVER),
871 NAME_ELEMENT(SW_KEYPAD_SLIDE),
872 NAME_ELEMENT(SW_FRONT_PROXIMITY),
873 #endif
874 #ifdef SW_ROTATE_LOCK
875 NAME_ELEMENT(SW_ROTATE_LOCK),
876 #endif
877 #ifdef SW_LINEIN_INSERT
878 NAME_ELEMENT(SW_LINEIN_INSERT),
879 #endif
880 #ifdef SW_MUTE_DEVICE
881 NAME_ELEMENT(SW_MUTE_DEVICE),
882 #endif
883 #ifdef SW_PEN_INSERTED
884 NAME_ELEMENT(SW_PEN_INSERTED),
885 #endif
886 #ifdef SW_MACHINE_COVER
887 NAME_ELEMENT(SW_MACHINE_COVER),
888 #endif
891 static const char * const force[FF_MAX + 1] = {
892 [0 ... FF_MAX] = NULL,
893 NAME_ELEMENT(FF_RUMBLE), NAME_ELEMENT(FF_PERIODIC),
894 NAME_ELEMENT(FF_CONSTANT), NAME_ELEMENT(FF_SPRING),
895 NAME_ELEMENT(FF_FRICTION), NAME_ELEMENT(FF_DAMPER),
896 NAME_ELEMENT(FF_INERTIA), NAME_ELEMENT(FF_RAMP),
897 NAME_ELEMENT(FF_SQUARE), NAME_ELEMENT(FF_TRIANGLE),
898 NAME_ELEMENT(FF_SINE), NAME_ELEMENT(FF_SAW_UP),
899 NAME_ELEMENT(FF_SAW_DOWN), NAME_ELEMENT(FF_CUSTOM),
900 NAME_ELEMENT(FF_GAIN), NAME_ELEMENT(FF_AUTOCENTER),
903 static const char * const forcestatus[FF_STATUS_MAX + 1] = {
904 [0 ... FF_STATUS_MAX] = NULL,
905 NAME_ELEMENT(FF_STATUS_STOPPED), NAME_ELEMENT(FF_STATUS_PLAYING),
908 static const char * const * const names[EV_MAX + 1] = {
909 [0 ... EV_MAX] = NULL,
910 [EV_SYN] = syns, [EV_KEY] = keys,
911 [EV_REL] = relatives, [EV_ABS] = absolutes,
912 [EV_MSC] = misc, [EV_LED] = leds,
913 [EV_SND] = sounds, [EV_REP] = repeats,
914 [EV_SW] = switches,
915 [EV_FF] = force, [EV_FF_STATUS] = forcestatus,
919 * Convert a string to a specific key/snd/led/sw code. The string can either
920 * be the name of the key in question (e.g. "SW_DOCK") or the numerical
921 * value, either as decimal (e.g. "5") or as hex (e.g. "0x5").
923 * @param mode The mode being queried (key, snd, led, sw)
924 * @param kstr The string to parse and convert
926 * @return The requested code's numerical value, or negative on error.
928 static int get_keycode(const struct query_mode *query_mode, const char *kstr)
930 if (isdigit(kstr[0])) {
931 unsigned long val;
932 errno = 0;
933 val = strtoul(kstr, NULL, 0);
934 if (errno) {
935 fprintf(stderr, "Could not interpret value %s\n", kstr);
936 return -1;
938 return (int) val;
939 } else {
940 const char * const *keynames = names[query_mode->event_type];
941 int i;
943 for (i = 0; i < query_mode->max; i++) {
944 const char *name = keynames[i];
945 if (name && strcmp(name, kstr) == 0)
946 return i;
949 return -1;
954 * Filter for the AutoDevProbe scandir on /dev/input.
956 * @param dir The current directory entry provided by scandir.
958 * @return Non-zero if the given directory entry starts with "event", or zero
959 * otherwise.
961 static int is_event_device(const struct dirent *dir) {
962 return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
966 * Scans all /dev/input/event*, display them and ask the user which one to
967 * open.
969 * @return The event device file name of the device file selected. This
970 * string is allocated and must be freed by the caller.
972 static char* scan_devices(void)
974 struct dirent **namelist;
975 int i, ndev, devnum, match;
976 char *filename;
977 int max_device = 0;
979 ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, alphasort);
980 if (ndev <= 0)
981 return NULL;
983 fprintf(stderr, "Available devices:\n");
985 for (i = 0; i < ndev; i++)
987 char fname[4096];
988 int fd = -1;
989 char name[256] = "???";
991 snprintf(fname, sizeof(fname),
992 "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
993 fd = open(fname, O_RDONLY);
994 if (fd < 0)
995 continue;
996 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
998 fprintf(stderr, "%s: %s\n", fname, name);
999 close(fd);
1001 match = sscanf(namelist[i]->d_name, "event%d", &devnum);
1002 if (match >= 1 && devnum > max_device)
1003 max_device = devnum;
1005 free(namelist[i]);
1008 fprintf(stderr, "Select the device event number [0-%d]: ", max_device);
1010 match = scanf("%d", &devnum);
1011 if (match < 1 || devnum > max_device || devnum < 0)
1012 return NULL;
1014 if (asprintf(&filename, "%s/%s%d",
1015 DEV_INPUT_EVENT, EVENT_DEV_NAME,
1016 devnum) < 0)
1017 return NULL;
1019 return filename;
1022 static int version(void)
1024 #ifndef PACKAGE_VERSION
1025 #define PACKAGE_VERSION "<version undefined>"
1026 #endif
1027 printf("%s %s\n", progname, PACKAGE_VERSION);
1028 return EXIT_SUCCESS;
1033 * Print usage information.
1035 static int usage(void)
1037 printf("USAGE:\n");
1038 printf(" Capture mode:\n");
1039 printf(" %s [--grab] /dev/input/eventX\n", progname);
1040 printf(" --grab grab the device for exclusive access\n");
1041 printf("\n");
1042 printf(" Query mode: (check exit code)\n");
1043 printf(" %s --query /dev/input/eventX <type> <value>\n", progname);
1045 printf("\n");
1046 printf("<type> is one of: EV_KEY, EV_SW, EV_LED, EV_SND\n");
1047 printf("<value> can either be a numerical value, or the textual name of the\n");
1048 printf("key/switch/LED/sound being queried (e.g. SW_DOCK).\n");
1050 return EXIT_FAILURE;
1054 * Print additional information for absolute axes (min/max, current value,
1055 * etc.).
1057 * @param fd The file descriptor to the device.
1058 * @param axis The axis identifier (e.g. ABS_X).
1060 static void print_absdata(int fd, int axis)
1062 int abs[6] = {0};
1063 int k;
1065 ioctl(fd, EVIOCGABS(axis), abs);
1066 for (k = 0; k < 6; k++)
1067 if ((k < 3) || abs[k])
1068 printf(" %s %6d\n", absval[k], abs[k]);
1071 static void print_repdata(int fd)
1073 int i;
1074 unsigned int rep[2];
1076 ioctl(fd, EVIOCGREP, rep);
1078 for (i = 0; i <= REP_MAX; i++) {
1079 printf(" Repeat code %d (%s)\n", i, names[EV_REP] ? (names[EV_REP][i] ? names[EV_REP][i] : "?") : "?");
1080 printf(" Value %6d\n", rep[i]);
1085 static inline const char* typename(unsigned int type)
1087 return (type <= EV_MAX && events[type]) ? events[type] : "?";
1090 static inline const char* codename(unsigned int type, unsigned int code)
1092 return (type <= EV_MAX && code <= maxval[type] && names[type] && names[type][code]) ? names[type][code] : "?";
1095 #ifdef INPUT_PROP_SEMI_MT
1096 static inline const char* propname(unsigned int prop)
1098 return (prop <= INPUT_PROP_MAX && props[prop]) ? props[prop] : "?";
1100 #endif
1102 static int get_state(int fd, unsigned int type, unsigned long *array, size_t size)
1104 int rc;
1106 switch(type) {
1107 case EV_LED:
1108 rc = ioctl(fd, EVIOCGLED(size), array);
1109 break;
1110 case EV_SND:
1111 rc = ioctl(fd, EVIOCGSND(size), array);
1112 break;
1113 case EV_SW:
1114 rc = ioctl(fd, EVIOCGSW(size), array);
1115 break;
1116 case EV_KEY:
1117 /* intentionally not printing the value for EV_KEY, let the
1118 * repeat handle this */
1119 default:
1120 return 1;
1122 if (rc == -1)
1123 return 1;
1125 return 0;
1129 * Print static device information (no events). This information includes
1130 * version numbers, device name and all bits supported by this device.
1132 * @param fd The file descriptor to the device.
1133 * @return 0 on success or 1 otherwise.
1135 static int print_device_info(int fd)
1137 unsigned int type, code;
1138 int version;
1139 unsigned short id[4];
1140 char name[256] = "Unknown";
1141 unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
1142 unsigned long state[KEY_CNT] = {0};
1143 #ifdef INPUT_PROP_SEMI_MT
1144 unsigned int prop;
1145 unsigned long propbits[INPUT_PROP_MAX];
1146 #endif
1147 int stateval;
1148 int have_state;
1150 if (ioctl(fd, EVIOCGVERSION, &version)) {
1151 perror("evtest: can't get version");
1152 return 1;
1155 printf("Input driver version is %d.%d.%d\n",
1156 version >> 16, (version >> 8) & 0xff, version & 0xff);
1158 ioctl(fd, EVIOCGID, id);
1159 printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
1160 id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
1162 ioctl(fd, EVIOCGNAME(sizeof(name)), name);
1163 printf("Input device name: \"%s\"\n", name);
1165 memset(bit, 0, sizeof(bit));
1166 ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
1167 printf("Supported events:\n");
1169 for (type = 0; type < EV_MAX; type++) {
1170 if (test_bit(type, bit[0]) && type != EV_REP) {
1171 have_state = (get_state(fd, type, state, sizeof(state)) == 0);
1173 printf(" Event type %d (%s)\n", type, typename(type));
1174 if (type == EV_SYN) continue;
1175 ioctl(fd, EVIOCGBIT(type, KEY_MAX), bit[type]);
1176 for (code = 0; code < KEY_MAX; code++)
1177 if (test_bit(code, bit[type])) {
1178 if (have_state) {
1179 stateval = test_bit(code, state);
1180 printf(" Event code %d (%s) state %d\n",
1181 code, codename(type, code), stateval);
1182 } else {
1183 printf(" Event code %d (%s)\n", code, codename(type, code));
1185 if (type == EV_ABS)
1186 print_absdata(fd, code);
1191 if (test_bit(EV_REP, bit[0])) {
1192 printf("Key repeat handling:\n");
1193 printf(" Repeat type %d (%s)\n", EV_REP, events[EV_REP] ? events[EV_REP] : "?");
1194 print_repdata(fd);
1196 #ifdef INPUT_PROP_SEMI_MT
1197 memset(propbits, 0, sizeof(propbits));
1198 ioctl(fd, EVIOCGPROP(sizeof(propbits)), propbits);
1199 printf("Properties:\n");
1200 for (prop = 0; prop < INPUT_PROP_MAX; prop++) {
1201 if (test_bit(prop, propbits))
1202 printf(" Property type %d (%s)\n", prop, propname(prop));
1204 #endif
1206 return 0;
1210 * Print device events as they come in.
1212 * @param fd The file descriptor to the device.
1213 * @return 0 on success or 1 otherwise.
1215 static int print_events(int fd)
1217 struct input_event ev[64];
1218 int i, rd;
1219 fd_set rdfs;
1221 FD_ZERO(&rdfs);
1222 FD_SET(fd, &rdfs);
1224 while (!stop) {
1225 select(fd + 1, &rdfs, NULL, NULL, NULL);
1226 if (stop)
1227 break;
1228 rd = read(fd, ev, sizeof(ev));
1230 if (rd < (int) sizeof(struct input_event)) {
1231 printf("expected %d bytes, got %d\n", (int) sizeof(struct input_event), rd);
1232 perror("\nevtest: error reading");
1233 return 1;
1236 for (i = 0; i < rd / sizeof(struct input_event); i++) {
1237 unsigned int type, code;
1239 type = ev[i].type;
1240 code = ev[i].code;
1242 printf("Event: time %ld.%06ld, ", ev[i].input_event_sec, ev[i].input_event_usec);
1244 if (type == EV_SYN) {
1245 if (code == SYN_MT_REPORT)
1246 printf("++++++++++++++ %s ++++++++++++\n", codename(type, code));
1247 else if (code == SYN_DROPPED)
1248 printf(">>>>>>>>>>>>>> %s <<<<<<<<<<<<\n", codename(type, code));
1249 else
1250 printf("-------------- %s ------------\n", codename(type, code));
1251 } else {
1252 printf("type %d (%s), code %d (%s), ",
1253 type, typename(type),
1254 code, codename(type, code));
1255 if (type == EV_MSC && (code == MSC_RAW || code == MSC_SCAN))
1256 printf("value %02x\n", ev[i].value);
1257 else
1258 printf("value %d\n", ev[i].value);
1264 ioctl(fd, EVIOCGRAB, (void*)0);
1265 return EXIT_SUCCESS;
1269 * Grab and immediately ungrab the device.
1271 * @param fd The file descriptor to the device.
1272 * @return 0 if the grab was successful, or 1 otherwise.
1274 static int test_grab(int fd, int grab_flag)
1276 int rc;
1278 rc = ioctl(fd, EVIOCGRAB, (void*)1);
1280 if (rc == 0 && !grab_flag)
1281 ioctl(fd, EVIOCGRAB, (void*)0);
1283 return rc;
1287 * Enter capture mode. The requested event device will be monitored, and any
1288 * captured events will be decoded and printed on the console.
1290 * @param device The device to monitor, or NULL if the user should be prompted.
1291 * @return 0 on success, non-zero on error.
1293 static int do_capture(const char *device, int grab_flag)
1295 int fd;
1296 char *filename = NULL;
1298 if (!device) {
1299 fprintf(stderr, "No device specified, trying to scan all of %s/%s*\n",
1300 DEV_INPUT_EVENT, EVENT_DEV_NAME);
1302 if (getuid() != 0)
1303 fprintf(stderr, "Not running as root, no devices may be available.\n");
1305 filename = scan_devices();
1306 if (!filename)
1307 return usage();
1308 } else
1309 filename = strdup(device);
1311 if (!filename)
1312 return EXIT_FAILURE;
1314 if ((fd = open(filename, O_RDONLY)) < 0) {
1315 perror("evtest");
1316 if (errno == EACCES && getuid() != 0)
1317 fprintf(stderr, "You do not have access to %s. Try "
1318 "running as root instead.\n",
1319 filename);
1320 goto error;
1323 if (!isatty(fileno(stdout)))
1324 setbuf(stdout, NULL);
1326 if (print_device_info(fd))
1327 goto error;
1329 printf("Testing ... (interrupt to exit)\n");
1331 if (test_grab(fd, grab_flag))
1333 printf("***********************************************\n");
1334 printf(" This device is grabbed by another process.\n");
1335 printf(" No events are available to evtest while the\n"
1336 " other grab is active.\n");
1337 printf(" In most cases, this is caused by an X driver,\n"
1338 " try VT-switching and re-run evtest again.\n");
1339 printf(" Run the following command to see processes with\n"
1340 " an open fd on this device\n"
1341 " \"fuser -v %s\"\n", filename);
1342 printf("***********************************************\n");
1345 if (grab_flag) {
1346 signal(SIGINT, interrupt_handler);
1347 signal(SIGTERM, interrupt_handler);
1350 free(filename);
1352 return print_events(fd);
1354 error:
1355 free(filename);
1356 return EXIT_FAILURE;
1360 * Perform a one-shot state query on a specific device. The query can be of
1361 * any known mode, on any valid keycode.
1363 * @param device Path to the evdev device node that should be queried.
1364 * @param query_mode The event type that is being queried (e.g. key, switch)
1365 * @param keycode The code of the key/switch/sound/LED to be queried
1366 * @return 0 if the state bit is unset, 10 if the state bit is set, 1 on error.
1368 static int query_device(const char *device, const struct query_mode *query_mode, int keycode)
1370 int fd;
1371 int r;
1372 unsigned long state[NBITS(query_mode->max)];
1374 fd = open(device, O_RDONLY);
1375 if (fd < 0) {
1376 perror("open");
1377 return EXIT_FAILURE;
1379 memset(state, 0, sizeof(state));
1380 r = ioctl(fd, query_mode->rq, state);
1381 close(fd);
1383 if (r == -1) {
1384 perror("ioctl");
1385 return EXIT_FAILURE;
1388 if (test_bit(keycode, state))
1389 return 10; /* different from EXIT_FAILURE */
1390 else
1391 return 0;
1395 * Enter query mode. The requested event device will be queried for the state
1396 * of a particular switch/key/sound/LED.
1398 * @param device The device to query.
1399 * @param mode The mode (event type) that is to be queried (snd, sw, key, led)
1400 * @param keycode The key code to query the state of.
1401 * @return 0 if the state bit is unset, 10 if the state bit is set.
1403 static int do_query(const char *device, const char *event_type, const char *keyname)
1405 const struct query_mode *query_mode;
1406 int keycode;
1408 if (!device) {
1409 fprintf(stderr, "Device argument is required for query.\n");
1410 return usage();
1413 query_mode = find_query_mode(event_type);
1414 if (!query_mode) {
1415 fprintf(stderr, "Unrecognised event type: %s\n", event_type);
1416 return usage();
1419 keycode = get_keycode(query_mode, keyname);
1420 if (keycode < 0) {
1421 fprintf(stderr, "Unrecognised key name: %s\n", keyname);
1422 return usage();
1423 } else if (keycode > query_mode->max) {
1424 fprintf(stderr, "Key %d is out of bounds.\n", keycode);
1425 return EXIT_FAILURE;
1428 return query_device(device, query_mode, keycode);
1431 static const struct option long_options[] = {
1432 { "grab", no_argument, &grab_flag, 1 },
1433 { "query", no_argument, NULL, MODE_QUERY },
1434 { "version", no_argument, NULL, MODE_VERSION },
1435 { 0, },
1438 int main (int argc, char **argv)
1440 const char *device = NULL;
1441 const char *keyname;
1442 const char *event_type;
1443 enum evtest_mode mode = MODE_CAPTURE;
1445 progname = argv[0];
1447 while (1) {
1448 int option_index = 0;
1449 int c = getopt_long(argc, argv, "", long_options, &option_index);
1450 if (c == -1)
1451 break;
1452 switch (c) {
1453 case 0:
1454 break;
1455 case MODE_QUERY:
1456 mode = c;
1457 break;
1458 case MODE_VERSION:
1459 return version();
1460 default:
1461 return usage();
1465 if (optind < argc)
1466 device = argv[optind++];
1468 if (mode == MODE_CAPTURE)
1469 return do_capture(device, grab_flag);
1471 if ((argc - optind) < 2) {
1472 fprintf(stderr, "Query mode requires device, type and key parameters\n");
1473 return usage();
1476 event_type = argv[optind++];
1477 keyname = argv[optind++];
1478 return do_query(device, event_type, keyname);
1481 /* vim: set noexpandtab tabstop=8 shiftwidth=8: */