summaryrefslogtreecommitdiffstats
path: root/screen_ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'screen_ui.cpp')
-rw-r--r--screen_ui.cpp105
1 files changed, 67 insertions, 38 deletions
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 <cutils/android_reboot.h>
#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;
+}