From 8b0b861f7cbf804f9c9bd4e71ea72a82747d3ab2 Mon Sep 17 00:00:00 2001 From: Joseph Hwang Date: Fri, 23 Jan 2015 16:22:16 +0800 Subject: [PATCH] add grab flag If the --grab flag is given in capture mode, evtest keeps an EVIOCGRAB on the device. While this grab is active, other processes will not receive events from the kernel devices. The grab is released again when evtest quits. TEST=Check that the cursor is frozen when --grab option is specified. $ evtest --grab --- evtest.c | 45 +++++++++++++++++++++++++++++++++++++-------- evtest.txt | 6 +++++- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/evtest.c b/evtest.c index 74230ea..c1980cf 100644 --- a/evtest.c +++ b/evtest.c @@ -55,6 +55,10 @@ #include #include #include +#include +#include +#include +#include #define BITS_PER_LONG (sizeof(long) * 8) #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) @@ -93,6 +97,14 @@ static const struct query_mode { { "EV_SW", EV_SW, SW_MAX, EVIOCGSW(SW_MAX) }, }; +static int grab_flag = 0; +static volatile int stop = 0; + +static void interrupt_handler(void) +{ + stop = 1; +} + /** * Look up an entry in the query_modes table by its textual name. * @@ -675,8 +687,9 @@ static int version(void) static int usage(void) { printf("USAGE:\n"); - printf(" Grab mode:\n"); - printf(" %s /dev/input/eventX\n", program_invocation_short_name); + printf(" Capture mode:\n"); + printf(" %s [--grab] /dev/input/eventX\n", program_invocation_short_name); + printf(" --grab grab the device for exclusive access\n"); printf("\n"); printf(" Query mode: (check exit code)\n"); printf(" %s --query /dev/input/eventX \n", @@ -768,8 +781,15 @@ static int print_events(int fd) { struct input_event ev[64]; int i, rd; + fd_set rdfs; - while (1) { + FD_ZERO(&rdfs); + FD_SET(fd, &rdfs); + + while (!stop) { + select(fd + 1, &rdfs, NULL, NULL, NULL); + if (stop) + break; rd = read(fd, ev, sizeof(struct input_event) * 64); if (rd < (int) sizeof(struct input_event)) { @@ -800,6 +820,9 @@ static int print_events(int fd) } } + + ioctl(fd, EVIOCGRAB, (void*)0); + return EXIT_SUCCESS; } /** @@ -808,13 +831,13 @@ static int print_events(int fd) * @param fd The file descriptor to the device. * @return 0 if the grab was successful, or 1 otherwise. */ -static int test_grab(int fd) +static int test_grab(int fd, int grab_flag) { int rc; rc = ioctl(fd, EVIOCGRAB, (void*)1); - if (!rc) + if (rc == 0 && grab_flag == 0) ioctl(fd, EVIOCGRAB, (void*)0); return rc; @@ -827,7 +850,7 @@ static int test_grab(int fd) * @param device The device to monitor, or NULL if the user should be prompted. * @return 0 on success, non-zero on error. */ -static int do_capture(const char *device) +static int do_capture(const char *device, int grab_flag) { int fd; char *filename; @@ -867,7 +890,7 @@ static int do_capture(const char *device) printf("Testing ... (interrupt to exit)\n"); - if (test_grab(fd)) + if (test_grab(fd, grab_flag)) { printf("***********************************************\n"); printf(" This device is grabbed by another process.\n"); @@ -878,6 +901,9 @@ static int do_capture(const char *device) printf("***********************************************\n"); } + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + return print_events(fd); } @@ -954,6 +980,7 @@ static int do_query(const char *device, const char *event_type, const char *keyn } static const struct option long_options[] = { + { "grab", no_argument, &grab_flag, 1 }, { "query", no_argument, NULL, MODE_QUERY }, { "version", no_argument, NULL, MODE_VERSION }, { 0, }, @@ -972,6 +999,8 @@ int main (int argc, char **argv) if (c == -1) break; switch (c) { + case 0: + break; case MODE_QUERY: mode = c; break; @@ -986,7 +1015,7 @@ int main (int argc, char **argv) device = argv[optind++]; if (mode == MODE_CAPTURE) - return do_capture(device); + return do_capture(device, grab_flag); if ((argc - optind) < 2) { fprintf(stderr, "Query mode requires device, type and key parameters\n"); diff --git a/evtest.txt b/evtest.txt index b614482..f64b44b 100644 --- a/evtest.txt +++ b/evtest.txt @@ -8,7 +8,7 @@ NAME SYNOPSIS -------- - evtest /dev/input/eventX + evtest [--grab] /dev/input/eventX evtest --query /dev/input/eventX @@ -19,6 +19,10 @@ display information about the specified input device, including all the events supported by the device. It then monitors the device and displays all the events layer events generated. +If the --grab flag is given in capture mode, evtest keeps an EVIOCGRAB on the +device. While this grab is active, other processes will not receive events +from the kernel devices. The grab is released again when evtest quits. + In the second invocation type ("query mode"), evtest performs a one-shot query of the state of a specific key *value* of an event *type*. -- 2.2.0.rc0.207.ga3a616c