From daefc1d442fb421606680feb9aeb59c133f4c427 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Mon, 31 Oct 2011 09:34:15 -0700 Subject: C++ class for device-specific code Replace the device-specific functions with a class. Move some of the key handling (for log visibility toggling and rebooting) into the UI class. Fix up the key handling so there is less crosstalk between the immediate keys and the queued keys (an increasing annoyance on button-limited devices). Change-Id: I698f6fd21c67a1e55429312a0484b6c393cad46f --- screen_ui.cpp | 105 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 38 deletions(-) (limited to 'screen_ui.cpp') diff --git a/screen_ui.cpp b/screen_ui.cpp index e6a31db28..a60b04682 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -31,9 +31,9 @@ #include "common.h" #include #include "minui/minui.h" -#include "recovery_ui.h" #include "ui.h" #include "screen_ui.h" +#include "device.h" #define CHAR_WIDTH 10 #define CHAR_HEIGHT 18 @@ -78,7 +78,8 @@ ScreenRecoveryUI::ScreenRecoveryUI() : menu_top(0), menu_items(0), menu_sel(0), - key_queue_len(0) { + key_queue_len(0), + key_last_down(-1) { pthread_mutex_init(&updateMutex, NULL); pthread_mutex_init(&key_queue_mutex, NULL); pthread_cond_init(&key_queue_cond, NULL); @@ -281,7 +282,6 @@ int ScreenRecoveryUI::input_callback(int fd, short revents, void* data) { struct input_event ev; int ret; - int fake_key = 0; ret = ev_get_input(fd, revents, &ev); if (ret) @@ -297,16 +297,12 @@ int ScreenRecoveryUI::input_callback(int fd, short revents, void* data) // key event. self->rel_sum += ev.value; if (self->rel_sum > 3) { - fake_key = 1; - ev.type = EV_KEY; - ev.code = KEY_DOWN; - ev.value = 1; + self->process_key(KEY_DOWN, 1); // press down key + self->process_key(KEY_DOWN, 0); // and release it self->rel_sum = 0; } else if (self->rel_sum < -3) { - fake_key = 1; - ev.type = EV_KEY; - ev.code = KEY_UP; - ev.value = 1; + self->process_key(KEY_UP, 1); // press up key + self->process_key(KEY_UP, 0); // and release it self->rel_sum = 0; } } @@ -314,36 +310,63 @@ int ScreenRecoveryUI::input_callback(int fd, short revents, void* data) self->rel_sum = 0; } - if (ev.type != EV_KEY || ev.code > KEY_MAX) - return 0; + if (ev.type == EV_KEY && ev.code <= KEY_MAX) + self->process_key(ev.code, ev.value); - pthread_mutex_lock(&self->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. - self->key_pressed[ev.code] = ev.value; - } - const int queue_max = sizeof(self->key_queue) / sizeof(self->key_queue[0]); - if (ev.value > 0 && self->key_queue_len < queue_max) { - self->key_queue[self->key_queue_len++] = ev.code; - pthread_cond_signal(&self->key_queue_cond); - } - pthread_mutex_unlock(&self->key_queue_mutex); + return 0; +} - if (ev.value > 0 && device_toggle_display(self->key_pressed, ev.code)) { - pthread_mutex_lock(&self->updateMutex); - self->show_text = !self->show_text; - if (self->show_text) self->show_text_ever = true; - self->update_screen_locked(); - pthread_mutex_unlock(&self->updateMutex); - } +// Process a key-up or -down event. A key is "registered" when it is +// pressed and then released, with no other keypresses or releases in +// between. Registered keys are passed to CheckKey() to see if it +// should trigger a visibility toggle, an immediate reboot, or be +// queued to be processed next time the foreground thread wants a key +// (eg, for the menu). +// +// We also keep track of which keys are currently down so that +// CheckKey can call IsKeyPressed to see what other keys are held when +// a key is registered. +// +// updown == 1 for key down events; 0 for key up events +void ScreenRecoveryUI::process_key(int key_code, int updown) { + bool register_key = false; - if (ev.value > 0 && device_reboot_now(self->key_pressed, ev.code)) { - android_reboot(ANDROID_RB_RESTART, 0, 0); + pthread_mutex_lock(&key_queue_mutex); + key_pressed[key_code] = updown; + if (updown) { + key_last_down = key_code; + } else { + if (key_last_down == key_code) + register_key = true; + key_last_down = -1; } + pthread_mutex_unlock(&key_queue_mutex); - return 0; + if (register_key) { + switch (CheckKey(key_code)) { + case RecoveryUI::TOGGLE: + pthread_mutex_lock(&updateMutex); + show_text = !show_text; + if (show_text) show_text_ever = true; + update_screen_locked(); + pthread_mutex_unlock(&updateMutex); + break; + + case RecoveryUI::REBOOT: + android_reboot(ANDROID_RB_RESTART, 0, 0); + break; + + case RecoveryUI::ENQUEUE: + pthread_mutex_lock(&key_queue_mutex); + const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); + if (key_queue_len < queue_max) { + key_queue[key_queue_len++] = key_code; + pthread_cond_signal(&key_queue_cond); + } + pthread_mutex_unlock(&key_queue_mutex); + break; + } + } } // Reads input events, handles special hot keys, and adds to the key queue. @@ -622,8 +645,10 @@ int ScreenRecoveryUI::WaitKey() bool ScreenRecoveryUI::IsKeyPressed(int key) { - // This is a volatile static array, don't bother locking - return key_pressed[key]; + pthread_mutex_lock(&key_queue_mutex); + int pressed = key_pressed[key]; + pthread_mutex_unlock(&key_queue_mutex); + return pressed; } void ScreenRecoveryUI::FlushKeys() { @@ -631,3 +656,7 @@ void ScreenRecoveryUI::FlushKeys() { key_queue_len = 0; pthread_mutex_unlock(&key_queue_mutex); } + +RecoveryUI::KeyAction ScreenRecoveryUI::CheckKey(int key) { + return RecoveryUI::ENQUEUE; +} -- cgit v1.2.3