Download Address: http://download.csdn.net/detail/luckydarcy/9679701
getevent.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include < dirent.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/inotify.h>//#include <sys/ limits.h> #include <sys/poll.h> #include <linux/input.h> #include <errno.h> #include <time.h
> #include "getevent.h" static struct POLLFD *ufds;
static char **device_names;
static int Nfds; enum {print_device_errors = 1U << 0, Print_device = 1U << 1, Print_device_name = 1U << 2, Print_device_info = 1U << 3, print_version = 1U << 4, Print_po
ssible_events = 1U << 5, print_input_props = 1U << 6, print_hid_descriptor = 1U << 7,
Print_all_info = (1U << 8)-1, print_labels = 1U << 16,}; static const char *get_label (const struct label *labels, int value) {WhilE (labels->name && value!= labels->value) {labels++;
Return labels->name;
static int print_input_props (int fd) {uint8_t BITS[INPUT_PROP_CNT/8];
int I, J;
int res;
int count;
const char *bit_label;
printf ("Input props:\n");
res = IOCTL (FD, Eviocgprop (sizeof (BITS)), bits);
if (Res < 0) {printf ("<not available\n");
return 1;
Count = 0;
for (i = 0; i < res; i++) {for (j = 0; J < 8; J +) {if (Bits[i] & 1 << j) {
Bit_label = Get_label (Input_prop_labels, I * 8 + j);
if (Bit_label) printf ("%s\n", Bit_label);
else printf ("%04x\n", I * 8 + j);
count++;
}} if (!count) printf ("<none>\n");
return 0;
The static int print_possible_events (int fd, int print_flags) {uint8_t *bits = NULL; ssize_t bits_size = 0;
const char* label;
int I, j, K;
int res, res2;
struct label* bit_labels;
const char *bit_label;
printf ("events:\n");
for (i = Ev_key i <= Ev_max, i++) {//Skip Ev_syn Since we cannot query its available codes int count = 0;
while (1) {res = IOCTL (FD, Eviocgbit (i, bits_size), bits);
if (res < bits_size) break;
Bits_size = res + 16;
bits = realloc (Bits, bits_size * 2);
if (bits = NULL) {fprintf (stderr, "failed to allocate buffer of size%d\n", (int) bits_size);
return 1;
} res2 = 0;
switch (i) {case ev_key:res2 = IOCTL (FD, Eviocgkey (res), bits + bits_size);
label = "KEY";
Bit_labels = Key_labels;
Break
Case Ev_rel:label = "REL"; Bit_labels = rel_labels;
Break
Case Ev_abs:label = "ABS";
Bit_labels = Abs_labels;
Break
Case Ev_msc:label = "MSC";
Bit_labels = Msc_labels;
Break
Case ev_led:res2 = IOCTL (FD, eviocgled (res), bits + bits_size);
label = "LED";
Bit_labels = Led_labels;
Break
Case ev_snd:res2 = IOCTL (FD, EVIOCGSND (res), bits + bits_size);
label = "SND";
Bit_labels = Snd_labels;
Break
Case ev_sw:res2 = IOCTL (FD, EVIOCGSW (bits_size), bits + bits_size);
label = "SW";
Bit_labels = Sw_labels;
Break
Case Ev_rep:label = "REP";
Bit_labels = Rep_labels;
Break Case Ev_ff:lAbel = "FF";
Bit_labels = Ff_labels;
Break
Case Ev_pwr:label = "PWR";
Bit_labels = NULL;
Break
Case Ev_ff_status:label = "FFS";
Bit_labels = Ff_status_labels;
Break
Default:res2 = 0;
label = "???";
Bit_labels = NULL; for (j = 0; J < Res; J +) {for (k = 0; k < 8; k++) if (Bits[j] & 1 <<
k) {char down;
if (J < Res2 && (Bits[j + bits_size] & 1 << k)) down = ' * ';
else down = ';
if (count = = 0) printf ("%s (%04x):", label, I);
else if ((Count & print_flags & print_labels 0x3:0x7)) = = 0 | | i = = ev_abs) printf ("\ n"); if (Bit_labels && (Print_flags & Print_labels)) {Bit_label = Get_label (Bit_labels, J *
8 + k);
if (Bit_label) printf ("%.20s%c%*s", Bit_label, Down, (int) (20-strlen (Bit_label)), "");
else printf ("%04x%c", J * 8 + K, down);
else {printf ("%04x%c", J * 8 + K, down);
} if (i = = ev_abs) {struct Input_absinfo ABS; if (IOCTL (FD, Eviocgabs (J * 8 + K), &abs) = = 0) {printf (": Value%d, min%d, max%d, fuzz
%d, flat%d, resolution%d ", Abs.value, Abs.minimum, Abs.maximum, Abs.fuzz, Abs.flat,
Abs.resolution);
} } count++;
} if (count) printf ("\ n");
Free (BITS);
return 0; static void print_event (int type, int code, int value, int print_flags) {const char *type_label, *code_label, *val
Ue_label;
if (Print_flags & print_labels) {Type_label = Get_label (ev_labels, type);
Code_label = NULL;
Value_label = NULL;
Switch (type) {Case Ev_syn:code_label = Get_label (syn_labels, code);
Break
Case Ev_key:code_label = Get_label (key_labels, code);
Value_label = Get_label (key_value_labels, value);
Break
Case Ev_rel:code_label = Get_label (rel_labels, code);
Break
Case Ev_abs:code_label = Get_label (abs_labels, code);
Switch (code) {Case Abs_mt_tool_type: Value_label = Get_label (mt_tool_labels, value);
} break;
Case Ev_msc:code_label = Get_label (msc_labels, code);
Break
Case Ev_led:code_label = Get_label (led_labels, code);
Break
Case Ev_snd:code_label = Get_label (snd_labels, code);
Break
Case Ev_sw:code_label = Get_label (sw_labels, code);
Break
Case Ev_rep:code_label = Get_label (rep_labels, code);
Break
Case Ev_ff:code_label = Get_label (ff_labels, code);
Break
Case Ev_ff_status:code_label = Get_label (ff_status_labels, code);
Break
} if (Type_label) printf ("%-12.12s", Type_label);
else printf ("%04x", type); if (code_label) printf ("%-20.20s", Code_label);
else printf ("%04x", code);
if (Value_label) printf ("%-20.20s", Value_label);
else printf ("%08x", value);
else {printf ("%04x%04x%08x", type, code, value); } static void Print_hid_descriptor (int bus, int vendor, int product) {const char *dirname = "/sys/kernel/debug/hid
";
Char prefix[16];
DIR *dir;
struct Dirent *de;
Char Filename[path_max];
FILE *file;
Char line[2048];
snprintf (prefix, sizeof (prefix), "%04x:%04x:%04x.", bus, vendor, product);
dir = Opendir (dirname);
if (dir = NULL) return; while (de = Readdir (dir)) {if (strstr (de->d_name, prefix) = = de->d_name) {snprintf (filename,
sizeof (filename), "%s/%s/rdesc", DirName, De->d_name);
FILE = fopen (filename, "R"); if (file) {printf ("HID descripTor:%s\n\n ", de->d_name);
while (fgets (line, sizeof (line), file)) {fputs ("", stdout);
Fputs (line, stdout);
} fclose (file);
Puts ("");
}} closedir (dir);
static int Open_device (const char *device, int print_flags) {int version;
int FD;
int clkid = Clock_monotonic;
struct POLLFD *new_ufds;
Char **new_device_names;
Char name[80];
Char location[80];
Char idstr[80];
struct INPUT_ID ID;
FD = open (device, O_RDWR); if (FD < 0) {if (Print_flags & print_device_errors) fprintf (stderr, "Could not open%s,%s\n", D
Evice, Strerror (errno));
return-1; } if (IOCTL (FD, Eviocgversion, &version)) {if (Print_flags & Print_device_errors) fprintf (s
Tderr, "Could not get driver version for%s,%s\n", Device, Strerror (errno));
return-1;
} if (IOCTL (FD, Eviocgid, &id)) {if (Print_flags & print_device_errors) fprintf (stderr, "could n
OT get driver IDs for%s,%s\n ", Device, Strerror (errno));
return-1;
} name[sizeof (name)-1] = ' I ';
Location[sizeof (location)-1] = ';
Idstr[sizeof (IDSTR)-1] = '; if (IOCTL (FD, Eviocgname (sizeof (name)-1), &name) < 1) {//fprintf (stderr, "could not get device name for%
S,%s\n ", Device, Strerror (errno));
Name[0] = ' the '; } if (IOCTL fd, Eviocgphys (sizeof (location)-1), &location) < 1) {//fprintf (stderr, "could not get Loc
ation for%s,%s\n ", Device, Strerror (errno));
Location[0] = ' the '; } if (IOCTL fd, Eviocguniq (sizeof (IDSTR)-1), &IDSTR) < 1) {//fprintf (stderr, "could not get idstring
For%s,%s\n ", Device, Strerror (errno));
Idstr[0] = ' the '; } if (IOCTL (FD, Eviocsclockid, &clkid)!= 0) {fprintf (stderr, "Can" t enable MonOtonic Clock reporting:%s\n ", Strerror (errno));
A non-fatal error} New_ufds = ReAlloc (UFDs, sizeof (UFDS[0)) * (Nfds + 1));
if (New_ufds = = NULL) {fprintf (stderr, "Out of memory\n");
return-1;
} UFDs = New_ufds;
New_device_names = realloc (device_names, sizeof (DEVICE_NAMES[0)) * (Nfds + 1));
if (new_device_names = = NULL) {fprintf (stderr, "Out of memory\n");
return-1;
} device_names = New_device_names;
if (Print_flags & Print_device) printf ("Add DEVICE%d:%s\n", Nfds, DEVICE);
if (Print_flags & print_device_info) printf ("Bus:%04x\n" "Vendor%04x\n" "Product%04x\n" "Version%04x\n", Id.bustype, Id.vendor, Id.product, Id.versio
n);
if (Print_flags & print_device_name) printf ("Name: \"%s\ "\ n", NAME); if (Print_flags & print_device_info) printf ("Location: \%s\"\ n "" "ID: \"%s\ "\ n", location, IDSTR); if (Print_flags & print_version) printf ("Version:%d.%d.%d\n", version >>, version
>> 8) & 0xFF, version & 0xFF);
if (Print_flags & print_possible_events) {print_possible_events (fd, print_flags);
} if (Print_flags & Print_input_props) {print_input_props (FD);
} if (Print_flags & Print_hid_descriptor) {print_hid_descriptor (Id.bustype, Id.vendor, id.product);
} UFDS[NFDS].FD = FD;
Ufds[nfds].events = Pollin;
Device_names[nfds] = StrDup (device);
nfds++;
return 0;
int Close_device (const char *device, int print_flags) {int i;
for (i = 1; i < Nfds; i++) {if (strcmp (device_names[i), device) = = 0) {int count = nfds-i-1;
if (Print_flags & Print_device) printf ("Remove DEVICE%d:%s\n", I, DEVICE); Free (device_names[i));
Memmove (Device_names + i, device_names + i + 1, sizeof (DEVICE_NAMES[0)) * count);
Memmove (UFDs + i, UFDs + i + 1, sizeof (UFDS[0)) * count);
nfds--;
return 0;
} if (Print_flags & print_device_errors) fprintf (stderr, "remote DEVICE:%s not found\n", DEVICE);
return-1;
static int read_notify (const char *dirname, int nfd, int print_flags) {int res;
Char Devname[path_max];
Char *filename;
Char event_buf[512];
int event_size;
int event_pos = 0;
struct Inotify_event *event;
res = read (NFD, event_buf, sizeof (EVENT_BUF));
if (res < (int) sizeof (*event) {if (errno = = Eintr) return 0;
fprintf (stderr, "Could not get event,%s\n", Strerror (errno));
return 1;
}//printf ("Got%d bytes of event information\n", RES);
strcpy (Devname, dirname);
filename = devname + strlen (devname);
*filename++ = '/'; while (Res >= (int) sizeof (*event)) {event = (struct inotify_event *) (event_buf + event_pos);
printf ("%d:%08x \"%s\ "\ n", Event->wd, Event->mask, Event->len? Event->name: "");
if (Event->len) {strcpy (filename, event->name);
if (Event->mask & in_create) {Open_device (devname, print_flags);
else {close_device (devname, print_flags);
} event_size = sizeof (*event) + event->len;
Res-= event_size;
Event_pos + = Event_size;
return 0; static int Scan_dir (