int get_event(struct input_event* event, int timeout) { int res; int i; int pollres; const char* device_path = "/dev/input"; while (1) { pollres = poll(ufds, nfds, timeout); if (pollres == 0) { return 1; } if (ufds[0].revents & POLLIN) { read_notify(device_path, ufds[0].fd); } for (i = 1; i < nfds; i++) { if (ufds[i].revents) { if (ufds[i].revents & POLLIN) { res = read(ufds[i].fd, event, sizeof(*event)); if (res < static_cast<int>(sizeof(event))) { fprintf(stderr, "could not get event\n"); return -1; } return 0; } } } } return 0; }
int startRecord() { int i; int res; int pollres; struct input_event event; int version; const char *device = NULL; const char *device_path = "/dev/input"; nfds = 1; ufds = (pollfd*)calloc(1, sizeof(ufds[0])); ufds[0].fd = inotify_init(); ufds[0].events = POLLIN; res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); if(res < 0) { fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno)); return 1; } res = scan_dir(device_path); if(res < 0) { fprintf(stderr, "scan dir failed for %s\n", device_path); return 1; } while(1) { pollres = poll(ufds, nfds, -1); if(ufds[0].revents & POLLIN) { read_notify(device_path, ufds[0].fd); } for(i = 1; i < nfds; i++) { if(ufds[i].revents) { if(ufds[i].revents & POLLIN) { res = read(ufds[i].fd, &event, sizeof(event)); if(res < (int)sizeof(event)) { fprintf(stderr, "could not get event\n"); return 1; } RECORD("[%8ld.%06ld] %s: %x %x %x\n", event.time.tv_sec, event.time.tv_usec, device_names[i], event.type, event.code, event.value); } } } } return 0; }
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { *outDeviceId = 0; *outType = 0; *outScancode = 0; *outKeycode = 0; *outFlags = 0; *outValue = 0; *outWhen = 0; status_t err; fd_set readfds; int maxFd = -1; int cc; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; } while(1) { #ifdef HAVE_TSLIB //Checks if we have to send any more events read by input-raw plugin. if(!samp.total_events) { #endif // First, report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_REMOVED; delete device; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_ADDED; return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { #ifdef HAVE_TSLIB LOGV("Inside EventHub.cpp with mFDs[i].fd=%d \n", mFDs[i].fd); if (mTS != NULL) { if (mFDs[i].fd != mTS->fd ) { LOGV("mFDs[%d].fd = %d and mTS->fd = %d", i, mFDs[i].fd, mTS->fd); #endif res = read(mFDs[i].fd, &iev, sizeof(iev)); #ifdef HAVE_TSLIB } else{ LOGV("mTS->fd = %d", mTS->fd); LOGV("tslib: calling ts_read from eventhub\n"); res = ts_read(mTS, &samp, 1); if (res < 0) { LOGE("[EventHub.cpp:: After Poll] Error in ts_read()\n"); } else { numOfEventsSent = 0; samp.tsIndex = i; break; } } } else { LOGE("ERROR in setup of mTS: mTS is NULL!\n"); } #endif if (res == sizeof(iev) #ifdef HAVE_TSLIB || ((iev.code == 0x1d || iev.code == 0x1e) && res >= 0) #endif ) { LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", mDevices[i]->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); *outDeviceId = mDevices[i]->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = iev.type; *outScancode = iev.code; if (iev.type == EV_KEY) { err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags); LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n", iev.code, *outKeycode, *outFlags, err); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = iev.code; } *outValue = iev.value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; } } } } // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } #ifdef HAVE_TSLIB } if(samp.total_events) { *outDeviceId = mDevices[samp.tsIndex]->id; *outType = samp.ev[numOfEventsSent].type; *outScancode = samp.ev[numOfEventsSent].code; if (samp.ev[numOfEventsSent].type == EV_KEY) { err = mDevices[samp.tsIndex]->layoutMap->map(samp.ev[numOfEventsSent].code, outKeycode, outFlags); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = samp.ev[numOfEventsSent].code; } if(*outType == EV_ABS) { if(*outScancode == ABS_X) *outValue = samp.x; if(*outScancode == ABS_Y) *outValue = samp.y; if(*outScancode == ABS_PRESSURE) *outValue = samp.pressure; } else { *outValue = samp.ev[numOfEventsSent].value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); } if(++numOfEventsSent == samp.total_events) samp.total_events = 0; return true; } #endif } }
int getevent_main(int argc, char *argv[]) { int c; int i; int res; int get_time = 0; int print_device = 0; char *newline = "\n"; uint16_t get_switch = 0; struct input_event event; int print_flags = 0; int print_flags_set = 0; int dont_block = -1; int event_count = 0; int sync_rate = 0; int64_t last_sync_time = 0; const char *device = NULL; const char *device_path = "/dev/input"; opterr = 0; do { c = getopt(argc, argv, "tns:Sv::dpilqc:rh"); if (c == EOF) break; switch (c) { case 't': get_time = 1; break; case 'n': newline = ""; break; case 's': get_switch = strtoul(optarg, NULL, 0); if(dont_block == -1) dont_block = 1; break; case 'S': get_switch = ~0; if(dont_block == -1) dont_block = 1; break; case 'v': if(optarg) print_flags |= strtoul(optarg, NULL, 0); else print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION; print_flags_set = 1; break; case 'd': print_flags |= PRINT_HID_DESCRIPTOR; break; case 'p': print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_POSSIBLE_EVENTS | PRINT_INPUT_PROPS; print_flags_set = 1; if(dont_block == -1) dont_block = 1; break; case 'i': print_flags |= PRINT_ALL_INFO; print_flags_set = 1; if(dont_block == -1) dont_block = 1; break; case 'l': print_flags |= PRINT_LABELS; break; case 'q': print_flags_set = 1; break; case 'c': event_count = atoi(optarg); dont_block = 0; break; case 'r': sync_rate = 1; break; case '?': fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt); case 'h': usage(argv[0]); exit(1); } } while (1); if(dont_block == -1) dont_block = 0; if (optind + 1 == argc) { device = argv[optind]; optind++; } if (optind != argc) { usage(argv[0]); exit(1); } nfds = 1; ufds = calloc(1, sizeof(ufds[0])); ufds[0].fd = inotify_init(); ufds[0].events = POLLIN; if(device) { if(!print_flags_set) print_flags |= PRINT_DEVICE_ERRORS; res = open_device(device, print_flags); if(res < 0) { return 1; } } else { if(!print_flags_set) print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME; print_device = 1; res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); if(res < 0) { fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno)); return 1; } res = scan_dir(device_path, print_flags); if(res < 0) { fprintf(stderr, "scan dir failed for %s\n", device_path); return 1; } } if(get_switch) { for(i = 1; i < nfds; i++) { uint16_t sw; res = ioctl(ufds[i].fd, EVIOCGSW(1), &sw); if(res < 0) { fprintf(stderr, "could not get switch state, %s\n", strerror(errno)); return 1; } sw &= get_switch; printf("%04x%s", sw, newline); } } if(dont_block) return 0; while(1) { //int pollres = poll(ufds, nfds, -1); //printf("poll %d, returned %d\n", nfds, pollres); if(ufds[0].revents & POLLIN) { read_notify(device_path, ufds[0].fd, print_flags); } for(i = 1; i < nfds; i++) { if(ufds[i].revents) { if(ufds[i].revents & POLLIN) { res = read(ufds[i].fd, &event, sizeof(event)); if(res < (int)sizeof(event)) { fprintf(stderr, "could not get event\n"); return 1; } if(get_time) { printf("[%8ld.%06ld] ", event.time.tv_sec, event.time.tv_usec); } if(print_device) printf("%s: ", device_names[i]); print_event(event.type, event.code, event.value, print_flags); if(sync_rate && event.type == 0 && event.code == 0) { int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec; if(last_sync_time) printf(" rate %lld", 1000000LL / (now - last_sync_time)); last_sync_time = now; } printf("%s", newline); if(event_count && --event_count == 0) return 0; } } } } return 0; }
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { *outDeviceId = 0; *outType = 0; *outScancode = 0; *outKeycode = 0; *outFlags = 0; *outValue = 0; *outWhen = 0; status_t err; fd_set readfds; int maxFd = -1; int cc; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; } while(1) { // First, report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_REMOVED; delete device; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_ADDED; return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { res = read(mFDs[i].fd, &iev, sizeof(iev)); if (res == sizeof(iev)) { LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", mDevices[i]->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); *outDeviceId = mDevices[i]->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = iev.type; *outScancode = iev.code; if (iev.type == EV_KEY) { err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags); LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n", iev.code, *outKeycode, *outFlags, err); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = iev.code; } *outValue = iev.value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; } } } } // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } } }