void *bootmgr_input_thread(void *cookie) { ev_init(); struct input_event ev; uint16_t x, y; pthread_mutex_init(bootmgr_input_mutex, NULL); struct timeval tv; struct timeval tv_last; gettimeofday(&tv_last, NULL); while(bootmgr_input_run) { ev_get(&ev, 0); if(ev.type == EV_KEY && (!ev.value || ev.code == KEY_POWER) && ev.code <= KEY_MAX) { pthread_mutex_lock(bootmgr_input_mutex); if(bootmgr_key_itr > 0 && ev.code != -1) bootmgr_key_queue[--bootmgr_key_itr] = ev.code; pthread_mutex_unlock(bootmgr_input_mutex); } else if(!sleep_mode && ev.type == EV_ABS && ev.code == 0x30 && ev.value) //#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ { gettimeofday(&tv, NULL); int32_t ms = (tv.tv_sec - tv_last.tv_sec)*1000+(tv.tv_usec-tv_last.tv_usec)/1000; if(ms >= 200) { do { ev_get(&ev, 0); } while(ev.type != EV_ABS); x = ev.value; do { ev_get(&ev, 0); } while(ev.type != EV_ABS); y = ev.value; do { ev_get(&ev, 0); } while(ev.type != EV_SYN && ev.code != SYN_REPORT); // Wait for touch seq end pthread_mutex_lock(bootmgr_input_mutex); if(bootmgr_touch_itr > 0) { bootmgr_touch_queue[--bootmgr_touch_itr][0] = x; bootmgr_touch_queue[ bootmgr_touch_itr][1] = y; } pthread_mutex_unlock(bootmgr_input_mutex); tv_last.tv_sec = tv.tv_sec; tv_last.tv_usec = tv.tv_usec; } else do { ev_get(&ev, 0); } while(ev.type != EV_SYN && ev.code != SYN_REPORT); // Wait for touch seq end } } ev_exit(); pthread_mutex_destroy(bootmgr_input_mutex); return NULL; }
static void *input_thread_work(void *cookie) { ev_init(); struct input_event ev; memset(mt_events, 0, sizeof(mt_events)); key_itr = 10; mt_slot = 0; int res; while(input_run) { while(ev_get(&ev, 1) == 0) { switch(ev.type) { case EV_KEY: handle_key_event(&ev); break; case EV_ABS: handle_abs_event(&ev); break; case EV_SYN: handle_syn_event(&ev); break; } } usleep(10000); } ev_exit(); pthread_exit(NULL); return NULL; }
bool InputHandler::processInput(int timeout_ms) { input_event ev; int ret = ev_get(&ev, timeout_ms); if (ret < 0) { // This path means that we did not get any new touch data, but // we do not get new touch data if you press and hold on either // the screen or on a keyboard key or mouse button if (touch_status || key_status) { processHoldAndRepeat(); } return (ret != -2); // -2 means no more events in the queue } switch (ev.type) { case EV_ABS: process_EV_ABS(ev); break; case EV_REL: process_EV_REL(ev); break; case EV_KEY: process_EV_KEY(ev); break; } blankTimer.resetTimerAndUnblank(); return true; // we got an event, so there might be more in the queue }
// Reads input events, handles special hot keys, and adds to the key queue. static void *input_thread(void *cookie) { int rel_sum = 0; int fake_key = 0; for (;;) { // wait for the next key event struct input_event ev; do { ev_get(&ev, 0); if (ev.type == EV_SYN) { continue; } else if (ev.type == EV_REL) { if (ev.code == REL_Y) { // accumulate the up or down motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an up/down // key event. rel_sum += ev.value; if (rel_sum > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_DOWN; ev.value = 1; rel_sum = 0; } else if (rel_sum < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_UP; ev.value = 1; rel_sum = 0; } } } else { rel_sum = 0; } } while (ev.type != EV_KEY || ev.code > KEY_MAX); pthread_mutex_lock(&key_queue_mutex); if (!fake_key) { // our "fake" keys only report a key-down event (no // key-up), so don't record them in the key_pressed // table. key_pressed[ev.code] = ev.value; } fake_key = 0; const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) { pthread_mutex_lock(&gUpdateMutex); show_text = !show_text; update_screen_locked(); pthread_mutex_unlock(&gUpdateMutex); } if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) { reboot(RB_AUTOBOOT); } } return NULL; }
// Reads input events, handles special hot keys, and adds to the key queue. static void *input_thread(void *cookie) { int rel_sum = 0; int fake_key = 0; for (;;) { // wait for the next key event struct input_event ev; do { ev_get(&ev, 0); if (ev.value == 1) {/* <[email protected]> */ ev.value = 0; } else if (ev.value == 0) { ev.value = 1; } if(ev.type == EV_KEY || ev.type == EV_SW) { if (ev.value == 0 && ev.code == 115) { //item up ev.code = KEY_VOLUMEUP; ev.value = 1; break; } else if (ev.value == 0 && ev.code == 114 ) { //item down ev.code = KEY_VOLUMEDOWN; ev.value = 1; break; } else if (ev.value == 0 && ev.code == 116 ) { //item select ev.code = KEY_ENTER; ev.value = 1; break; } else if (ev.value == 1 && ev.code == 8 ) { //usb in ev.code = USB_IN; ev.value = 1; break; } else if (ev.value == 0 && ev.code == 8 ) { //usb out ev.code = USB_OUT; ev.value = 1; break; } } else { continue; } } while (ev.value != 0); // key up pthread_mutex_lock(&key_queue_mutex); key_pressed[ev.code] = ev.value; const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) { pthread_mutex_lock(&gUpdateMutex); show_text = !show_text; update_screen_locked(); pthread_mutex_unlock(&gUpdateMutex); } if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) { reboot(RB_AUTOBOOT); } } return NULL; }
// Reads input events, handles special hot keys, and adds to the key queue. static void *input_thread(void *cookie) { int rel_sum_x = 0; int rel_sum_y = 0; int fake_key = 0; int got_data = 0; while (pt_input_thread_active) { // wait for the next key event struct input_event ev; do { do { got_data = ev_get(&ev, 1000/PROGRESSBAR_INDETERMINATE_FPS); if (!pt_input_thread_active) { pthread_exit(NULL); return NULL; } } while (got_data==-1); if (ev.type == EV_SYN) { // end of a multitouch point if (ev.code == SYN_MT_REPORT) { if (actPos.num>=0 && actPos.num<MAX_MT_POINTS) { // create a fake keyboard event. We will use BTN_WHEEL, BTN_GEAR_DOWN and BTN_GEAR_UP key events to fake // TOUCH_MOVE, TOUCH_DOWN and TOUCH_UP in this order int type = BTN_WHEEL; // new and old pressure state are not consistent --> we have touch down or up event if ((mousePos[actPos.num].pressure!=0) != (actPos.pressure!=0)) { if (actPos.pressure == 0) { type = BTN_GEAR_UP; if (actPos.num==0) { if (mousePos[0].length<15) { // consider this a mouse click type = BTN_MOUSE; } memset(&grabPos,0,sizeof(grabPos)); } } else if (actPos.pressure != 0) { type == BTN_GEAR_DOWN; if (actPos.num==0) { grabPos = actPos; } } } fake_key = 1; ev.type = EV_KEY; ev.code = type; ev.value = actPos.num+1; // this should be locked, but that causes ui events to get dropped, as the screen drawing takes too much time // this should be solved by making the critical section inside the drawing much much smaller if (actPos.pressure) { if (mousePos[actPos.num].pressure) { actPos.length = mousePos[actPos.num].length + abs(mousePos[actPos.num].x-actPos.x) + abs(mousePos[actPos.num].y-actPos.y); } else { actPos.length = 0; } } else { actPos.length = 0; } oldMousePos[actPos.num] = mousePos[actPos.num]; mousePos[actPos.num] = actPos; int curPos[] = {actPos.pressure, actPos.x, actPos.y}; ui_handle_mouse_input(curPos); } memset(&actPos,0,sizeof(actPos)); } else { continue; } } else if (ev.type == EV_ABS) { // multitouch records are sent as ABS events. Well at least on the SGS-i9000 if (ev.code == ABS_MT_POSITION_X) { actPos.x = MT_X(ev.value); } else if (ev.code == ABS_MT_POSITION_Y) { actPos.y = MT_Y(ev.value); } else if (ev.code == ABS_MT_TOUCH_MAJOR) { actPos.pressure = ev.value; // on SGS-i9000 this is 0 for not-pressed and 40 for pressed } else if (ev.code == ABS_MT_WIDTH_MAJOR) { // num is stored inside the high byte of width. Well at least on SGS-i9000 if (actPos.num==0) { // only update if it was not already set. On a normal device MT_TRACKING_ID is sent actPos.num = ev.value >> 8; } actPos.size = ev.value & 0xFF; } else if (ev.code == ABS_MT_TRACKING_ID) { // on a normal device, the num is got from this value actPos.num = ev.value; } } else if (ev.type == EV_REL) {
int main() { struct device_state old_state; get_device_state(&old_state); if (screen_init() < 0) goto err1; ev_init(); led_init(); sleep(3); /* Set battery LED, initialize image, screen brightness */ power_event(1); screen_brightness_animation_start(); while (!quit) { int r, delay = alarm_get_time_until_next(); if (delay < 1) { alarm_process(); continue; } r = ev_get(delay); /* Press below keys will wake the display and repeat the display cycle: Power key, Volume up/down key, Camera key. Long press Power key will reboot the device. */ switch (r) { /* Power key */ case EVENT_POWER_KEY_DOWN: if (powerup) alarm_set_relative(power_key_alarm, NULL, 1000); break; case EVENT_POWER_KEY_UP: alarm_cancel(power_key_alarm); update_screen_on_wakeup_key(); break; /* Other keys */ case EVENT_VOLUMEDOWN_KEY_DOWN: update_screen_on_wakeup_key2(); break; case EVENT_VOLUMEUP_KEY_DOWN: update_screen_on_wakeup_key2(); break; case EVENT_CAMERA_KEY_DOWN: update_screen_on_wakeup_key2(); break; /* Battery events */ case EVENT_BATTERY: power_event(1); break; /* Others */ case EVENT_QUIT: quit = 1; break; default: break; } } led_uninit(); ev_exit(); screen_uninit(); return 0; err1: return -1; }
// Reads input events, handles special hot keys, and adds to the key queue. static void *input_thread(void *cookie) { int rel_sum = 0; int fake_key = 0; for (;;) { // wait for the next key event struct input_event ev; do { ev_get(&ev, 0); if (ev.type == EV_SYN) { continue; } else if (ev.type == EV_REL) { if (ev.code == REL_Y) { // accumulate the up or down motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an up/down // key event. rel_sum += ev.value; if (rel_sum > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_DOWN; ev.value = 1; rel_sum = 0; } else if (rel_sum < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_UP; ev.value = 1; rel_sum = 0; } } } else { rel_sum = 0; } } while (ev.type != EV_KEY || ev.code > KEY_MAX); pthread_mutex_lock(&key_queue_mutex); if (!fake_key) { // our "fake" keys only report a key-down event (no // key-up), so don't record them in the key_pressed // table. key_pressed[ev.code] = ev.value; } fake_key = 0; const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); // Alt+L or Home+End: toggle log display int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT]; if ((alt && ev.code == KEY_L && ev.value > 0) || (key_pressed[KEY_HOME] && ev.code == KEY_END && ev.value > 0)) { pthread_mutex_lock(&gUpdateMutex); show_text = !show_text; update_screen_locked(); pthread_mutex_unlock(&gUpdateMutex); } // Green+Menu+Red: reboot immediately if (ev.code == KEY_DREAM_RED && key_pressed[KEY_DREAM_MENU] && key_pressed[KEY_DREAM_GREEN]) { reboot(RB_AUTOBOOT); } } return NULL; }
// Reads input events, handles special hot keys, and adds to the key queue. static void *input_thread(void *cookie) { int rel_sum_y = 0, rel_sum_x = 0; int fake_key = 0; for (;;) { // wait for the next key event struct input_event ev; do { ev_get(&ev, 0); if (ev.type == EV_SYN) { continue; } else if (ev.type == EV_REL) { if (ev.code == REL_Y) { // accumulate the up or down motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an up/down // key event. rel_sum_y += ev.value; if (rel_sum_y > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_DOWN; ev.value = 1; rel_sum_y = 0; } else if (rel_sum_y < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_UP; ev.value = 1; rel_sum_y = 0; } } if (ev.code == REL_X) { // accumulate the left or right motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an left/right // key event. rel_sum_x += ev.value; if (rel_sum_x > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_RIGHT; ev.value = 1; rel_sum_x = 0; } else if (rel_sum_x < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_LEFT; ev.value = 1; rel_sum_x = 0; } } } else { rel_sum_x = 0; rel_sum_y = 0; } } while (ev.type != EV_KEY || ev.code > KEY_MAX); pthread_mutex_lock(&key_queue_mutex); if (!fake_key) { // our "fake" keys only report a key-down event (no // key-up), so don't record them in the key_pressed // table. key_pressed[ev.code] = ev.value; } fake_key = 0; const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); } return NULL; }