staticbool should_add_input_device(int fd, bool allow_touch_inputs) { // Use unsigned long to match ioctl's parameter type. unsignedlong ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
// Read the evbits of the input device. if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { returnfalse;
}
// We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also // allowed if allow_touch_inputs is set. if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) { if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) { returnfalse;
}
}
// The inotify will put one or several complete events. // Should not read part of one event. int event_len_int; int ret = ioctl(fd, FIONREAD, &event_len_int); if (ret != 0) return -1; if (event_len_int < 0) return -1;
size_t event_len = event_len_int;
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(INPUT_DEV_DIR), closedir); if (!dir) { return -1;
}
std::vector<int8_t> buf(event_len);
ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf.data(), event_len)); if (r != event_len) { return -1;
}
size_t offset = 0; while (offset < event_len) { struct inotify_event* pevent = reinterpret_cast<struct inotify_event*>(buf.data() + offset); if (offset + sizeof(inotify_event) + pevent->len > event_len) { // The pevent->len is too large and buffer will over flow. // In general, should not happen, just make more stable. return -1;
}
offset += sizeof(inotify_event) + pevent->len;
std::string event_name(pevent->name, pevent->len); if (!android::base::StartsWith(event_name, "event")) { continue;
}
int ev_wait(int timeout) {
g_polled_events_count = epoll_wait(g_epoll_fd, g_polled_events, g_ev_count, timeout); if (g_polled_events_count <= 0) { return -1;
} return0;
}
void ev_dispatch(void) { for (int n = 0; n < g_polled_events_count; n++) {
FdInfo* fdi = static_cast<FdInfo*>(g_polled_events[n].data.ptr); const ev_callback& cb = fdi->cb; if (cb) {
cb(fdi->fd, g_polled_events[n].events);
}
}
}
int ev_get_input(int fd, uint32_t epevents, input_event* ev) { if (epevents & EPOLLIN) {
ssize_t r = TEMP_FAILURE_RETRY(read(fd, ev, sizeof(*ev))); if (r == sizeof(*ev)) { return0;
}
} if (epevents & EPOLLHUP) { // Delete this watch
epoll_ctl(g_epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
} return -1;
}
int ev_sync_sw_state(const ev_set_sw_callback& set_sw_cb) { // Use unsigned long to match ioctl's parameter type. unsignedlong ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT unsignedlong sw_bits[BITS_TO_LONGS(SW_MAX)]; // NOLINT
for (size_t i = 0; i < g_ev_dev_count; ++i) {
memset(ev_bits, 0, sizeof(ev_bits));
memset(sw_bits, 0, sizeof(sw_bits));
if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { continue;
} if (!test_bit(EV_SW, ev_bits)) { continue;
} if (ioctl(ev_fdinfo[i].fd, EVIOCGSW(sizeof(sw_bits)), sw_bits) == -1) { continue;
}
for (int code = 0; code <= SW_MAX; code++) { if (test_bit(code, sw_bits)) {
set_sw_cb(code, 1);
}
}
}
return0;
}
int ev_sync_key_state(const ev_set_key_callback& set_key_cb) { // Use unsigned long to match ioctl's parameter type. unsignedlong ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT unsignedlong key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
for (size_t i = 0; i < g_ev_dev_count; ++i) {
memset(ev_bits, 0, sizeof(ev_bits));
memset(key_bits, 0, sizeof(key_bits));
if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { continue;
} if (!test_bit(EV_KEY, ev_bits)) { continue;
} if (ioctl(ev_fdinfo[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits) == -1) { continue;
}
for (int code = 0; code <= KEY_MAX; code++) { if (test_bit(code, key_bits)) {
set_key_cb(code, 1);
}
}
}
return0;
}
void ev_iterate_available_keys(const std::function<void(int)>& f) { // Use unsigned long to match ioctl's parameter type. unsignedlong ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT unsignedlong key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
for (size_t i = 0; i < g_ev_dev_count; ++i) {
memset(ev_bits, 0, sizeof(ev_bits));
memset(key_bits, 0, sizeof(key_bits));
// Does this device even have keys? if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { continue;
} if (!test_bit(EV_KEY, ev_bits)) { continue;
}
if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits) == -1) { continue;
}
for (int key_code = 0; key_code <= KEY_MAX; ++key_code) { if (test_bit(key_code, key_bits)) {
f(key_code);
}
}
}
}
void ev_iterate_touch_inputs(const std::function<void(int)>& action) { for (size_t i = 0; i < g_ev_dev_count; ++i) { // Use unsigned long to match ioctl's parameter type. unsignedlong ev_bits[BITS_TO_LONGS(EV_MAX)] = {}; // NOLINT if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) { continue;
} if (!test_bit(EV_ABS, ev_bits)) { continue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.