?
?
直接上代码。后续再补充分析。
这个是android源码中 getevent 命令的源码。
位于源码的目录:system/core/toolbox/
?
?? >>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 "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_POSSIBLE_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;
}
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 +