blob: 589c935dcdaa9121968eb20779dabc2a2acb8ec8 [file] [log] [blame]
Doug Zongker211aebc2011-10-28 15:13:10 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <fcntl.h>
19#include <linux/input.h>
20#include <pthread.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/stat.h>
26#include <sys/time.h>
27#include <sys/types.h>
28#include <time.h>
29#include <unistd.h>
30
31#include "common.h"
Doug Zongkerdaefc1d2011-10-31 09:34:15 -070032#include "device.h"
Doug Zongker32a0a472011-11-01 11:00:20 -070033#include "minui/minui.h"
34#include "screen_ui.h"
35#include "ui.h"
Doug Zongker211aebc2011-10-28 15:13:10 -070036
Doug Zongker55a36ac2013-03-04 15:49:02 -080037static int char_width;
38static int char_height;
Doug Zongker211aebc2011-10-28 15:13:10 -070039
Doug Zongker211aebc2011-10-28 15:13:10 -070040// There's only (at most) one of these objects, and global callbacks
41// (for pthread_create, and the input event system) need to find it,
42// so use a global variable.
43static ScreenRecoveryUI* self = NULL;
44
45// Return the current time as a double (including fractions of a second).
46static double now() {
47 struct timeval tv;
48 gettimeofday(&tv, NULL);
49 return tv.tv_sec + tv.tv_usec / 1000000.0;
50}
51
52ScreenRecoveryUI::ScreenRecoveryUI() :
53 currentIcon(NONE),
54 installingFrame(0),
Doug Zongker5fa8c232012-09-18 12:37:02 -070055 rtl_locale(false),
Doug Zongker211aebc2011-10-28 15:13:10 -070056 progressBarType(EMPTY),
57 progressScopeStart(0),
58 progressScopeSize(0),
59 progress(0),
60 pagesIdentical(false),
61 text_cols(0),
62 text_rows(0),
63 text_col(0),
64 text_row(0),
65 text_top(0),
66 show_text(false),
67 show_text_ever(false),
68 show_menu(false),
69 menu_top(0),
70 menu_items(0),
71 menu_sel(0),
Doug Zongker32a0a472011-11-01 11:00:20 -070072 animation_fps(20),
Doug Zongker469954f2014-03-07 09:21:25 -080073 installing_frames(-1) {
yetta_wu5b468fc2013-06-25 15:03:11 +080074 for (int i = 0; i < 5; i++)
75 backgroundIcon[i] = NULL;
76
Doug Zongker211aebc2011-10-28 15:13:10 -070077 pthread_mutex_init(&updateMutex, NULL);
Doug Zongker211aebc2011-10-28 15:13:10 -070078 self = this;
79}
80
Doug Zongker211aebc2011-10-28 15:13:10 -070081// Clear the screen and draw the currently selected background icon (if any).
82// Should only be called with updateMutex locked.
83void ScreenRecoveryUI::draw_background_locked(Icon icon)
84{
85 pagesIdentical = false;
86 gr_color(0, 0, 0, 255);
Doug Zongker16f97c32014-03-06 16:16:05 -080087 gr_clear();
Doug Zongker211aebc2011-10-28 15:13:10 -070088
89 if (icon) {
90 gr_surface surface = backgroundIcon[icon];
Doug Zongker469954f2014-03-07 09:21:25 -080091 if (icon == INSTALLING_UPDATE || icon == ERASING) {
92 surface = installation[installingFrame];
93 }
Doug Zongker02ec6b82012-08-22 17:26:40 -070094 gr_surface text_surface = backgroundText[icon];
95
Doug Zongker211aebc2011-10-28 15:13:10 -070096 int iconWidth = gr_get_width(surface);
97 int iconHeight = gr_get_height(surface);
Doug Zongker02ec6b82012-08-22 17:26:40 -070098 int textWidth = gr_get_width(text_surface);
99 int textHeight = gr_get_height(text_surface);
100
Doug Zongker469954f2014-03-07 09:21:25 -0800101 iconX = (gr_fb_width() - iconWidth) / 2;
102 iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700103
104 int textX = (gr_fb_width() - textWidth) / 2;
105 int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40;
106
Doug Zongker211aebc2011-10-28 15:13:10 -0700107 gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700108
109 gr_color(255, 255, 255, 255);
110 gr_texticon(textX, textY, text_surface);
Doug Zongker211aebc2011-10-28 15:13:10 -0700111 }
112}
113
114// Draw the progress bar (if any) on the screen. Does not flip pages.
115// Should only be called with updateMutex locked.
116void ScreenRecoveryUI::draw_progress_locked()
117{
Doug Zongker69f4b672012-04-26 14:37:53 -0700118 if (currentIcon == ERROR) return;
119
Doug Zongker02ec6b82012-08-22 17:26:40 -0700120 if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
Doug Zongker469954f2014-03-07 09:21:25 -0800121 gr_surface icon = installation[installingFrame];
122 gr_blit(icon, 0, 0, gr_get_width(icon), gr_get_height(icon), iconX, iconY);
Doug Zongker211aebc2011-10-28 15:13:10 -0700123 }
124
125 if (progressBarType != EMPTY) {
Doug Zongker02ec6b82012-08-22 17:26:40 -0700126 int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]);
Doug Zongker211aebc2011-10-28 15:13:10 -0700127 int width = gr_get_width(progressBarEmpty);
128 int height = gr_get_height(progressBarEmpty);
129
130 int dx = (gr_fb_width() - width)/2;
131 int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
132
133 // Erase behind the progress bar (in case this was a progress-only update)
134 gr_color(0, 0, 0, 255);
135 gr_fill(dx, dy, width, height);
136
137 if (progressBarType == DETERMINATE) {
138 float p = progressScopeStart + progress * progressScopeSize;
139 int pos = (int) (p * width);
140
Doug Zongker5fa8c232012-09-18 12:37:02 -0700141 if (rtl_locale) {
142 // Fill the progress bar from right to left.
143 if (pos > 0) {
144 gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy);
145 }
146 if (pos < width-1) {
147 gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy);
148 }
149 } else {
150 // Fill the progress bar from left to right.
151 if (pos > 0) {
152 gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
153 }
154 if (pos < width-1) {
155 gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
156 }
Doug Zongker211aebc2011-10-28 15:13:10 -0700157 }
158 }
Doug Zongker211aebc2011-10-28 15:13:10 -0700159 }
160}
161
Doug Zongkerc0441d12013-07-31 11:28:24 -0700162void ScreenRecoveryUI::SetColor(UIElement e) {
163 switch (e) {
164 case HEADER:
165 gr_color(247, 0, 6, 255);
166 break;
167 case MENU:
168 case MENU_SEL_BG:
169 gr_color(0, 106, 157, 255);
170 break;
171 case MENU_SEL_FG:
172 gr_color(255, 255, 255, 255);
173 break;
174 case LOG:
175 gr_color(249, 194, 0, 255);
176 break;
177 case TEXT_FILL:
178 gr_color(0, 0, 0, 160);
179 break;
180 default:
181 gr_color(255, 255, 255, 255);
182 break;
183 }
184}
Doug Zongker211aebc2011-10-28 15:13:10 -0700185
186// Redraw everything on the screen. Does not flip pages.
187// Should only be called with updateMutex locked.
188void ScreenRecoveryUI::draw_screen_locked()
189{
Doug Zongker16f97c32014-03-06 16:16:05 -0800190 if (!show_text) {
191 draw_background_locked(currentIcon);
192 draw_progress_locked();
193 } else {
194 gr_color(0, 0, 0, 255);
195 gr_clear();
Doug Zongker211aebc2011-10-28 15:13:10 -0700196
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800197 int y = 0;
Doug Zongker211aebc2011-10-28 15:13:10 -0700198 int i = 0;
199 if (show_menu) {
Doug Zongkerc0441d12013-07-31 11:28:24 -0700200 SetColor(HEADER);
Doug Zongker211aebc2011-10-28 15:13:10 -0700201
202 for (; i < menu_top + menu_items; ++i) {
Doug Zongkerc0441d12013-07-31 11:28:24 -0700203 if (i == menu_top) SetColor(MENU);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800204
Doug Zongker211aebc2011-10-28 15:13:10 -0700205 if (i == menu_top + menu_sel) {
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800206 // draw the highlight bar
Doug Zongkerc0441d12013-07-31 11:28:24 -0700207 SetColor(MENU_SEL_BG);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800208 gr_fill(0, y-2, gr_fb_width(), y+char_height+2);
209 // white text of selected item
Doug Zongkerc0441d12013-07-31 11:28:24 -0700210 SetColor(MENU_SEL_FG);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800211 if (menu[i][0]) gr_text(4, y, menu[i], 1);
Doug Zongkerc0441d12013-07-31 11:28:24 -0700212 SetColor(MENU);
Doug Zongker211aebc2011-10-28 15:13:10 -0700213 } else {
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800214 if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top);
Doug Zongker211aebc2011-10-28 15:13:10 -0700215 }
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800216 y += char_height+4;
Doug Zongker211aebc2011-10-28 15:13:10 -0700217 }
Doug Zongkerc0441d12013-07-31 11:28:24 -0700218 SetColor(MENU);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800219 y += 4;
220 gr_fill(0, y, gr_fb_width(), y+2);
221 y += 4;
Doug Zongker211aebc2011-10-28 15:13:10 -0700222 ++i;
223 }
224
Doug Zongkerc0441d12013-07-31 11:28:24 -0700225 SetColor(LOG);
Doug Zongker211aebc2011-10-28 15:13:10 -0700226
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800227 // display from the bottom up, until we hit the top of the
228 // screen, the bottom of the menu, or we've displayed the
229 // entire text buffer.
230 int ty;
231 int row = (text_top+text_rows-1) % text_rows;
232 for (int ty = gr_fb_height() - char_height, count = 0;
233 ty > y+2 && count < text_rows;
234 ty -= char_height, ++count) {
235 gr_text(4, ty, text[row], 0);
236 --row;
237 if (row < 0) row = text_rows-1;
Doug Zongker211aebc2011-10-28 15:13:10 -0700238 }
239 }
240}
241
242// Redraw everything on the screen and flip the screen (make it visible).
243// Should only be called with updateMutex locked.
244void ScreenRecoveryUI::update_screen_locked()
245{
246 draw_screen_locked();
247 gr_flip();
248}
249
250// Updates only the progress bar, if possible, otherwise redraws the screen.
251// Should only be called with updateMutex locked.
252void ScreenRecoveryUI::update_progress_locked()
253{
254 if (show_text || !pagesIdentical) {
255 draw_screen_locked(); // Must redraw the whole screen
256 pagesIdentical = true;
257 } else {
258 draw_progress_locked(); // Draw only the progress bar and overlays
259 }
260 gr_flip();
261}
262
263// Keeps the progress bar updated, even when the process is otherwise busy.
Doug Zongker32a0a472011-11-01 11:00:20 -0700264void* ScreenRecoveryUI::progress_thread(void *cookie) {
265 self->progress_loop();
266 return NULL;
267}
268
269void ScreenRecoveryUI::progress_loop() {
270 double interval = 1.0 / animation_fps;
Doug Zongker211aebc2011-10-28 15:13:10 -0700271 for (;;) {
272 double start = now();
Doug Zongker32a0a472011-11-01 11:00:20 -0700273 pthread_mutex_lock(&updateMutex);
Doug Zongker211aebc2011-10-28 15:13:10 -0700274
275 int redraw = 0;
276
277 // update the installation animation, if active
278 // skip this if we have a text overlay (too expensive to update)
Doug Zongker02ec6b82012-08-22 17:26:40 -0700279 if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) &&
280 installing_frames > 0 && !show_text) {
Doug Zongker32a0a472011-11-01 11:00:20 -0700281 installingFrame = (installingFrame + 1) % installing_frames;
Doug Zongker211aebc2011-10-28 15:13:10 -0700282 redraw = 1;
283 }
284
Doug Zongker211aebc2011-10-28 15:13:10 -0700285 // move the progress bar forward on timed intervals, if configured
Doug Zongker32a0a472011-11-01 11:00:20 -0700286 int duration = progressScopeDuration;
287 if (progressBarType == DETERMINATE && duration > 0) {
288 double elapsed = now() - progressScopeTime;
Doug Zongker69f4b672012-04-26 14:37:53 -0700289 float p = 1.0 * elapsed / duration;
290 if (p > 1.0) p = 1.0;
291 if (p > progress) {
292 progress = p;
Doug Zongker211aebc2011-10-28 15:13:10 -0700293 redraw = 1;
294 }
295 }
296
Doug Zongker32a0a472011-11-01 11:00:20 -0700297 if (redraw) update_progress_locked();
Doug Zongker211aebc2011-10-28 15:13:10 -0700298
Doug Zongker32a0a472011-11-01 11:00:20 -0700299 pthread_mutex_unlock(&updateMutex);
Doug Zongker211aebc2011-10-28 15:13:10 -0700300 double end = now();
301 // minimum of 20ms delay between frames
302 double delay = interval - (end-start);
303 if (delay < 0.02) delay = 0.02;
304 usleep((long)(delay * 1000000));
305 }
Doug Zongker211aebc2011-10-28 15:13:10 -0700306}
307
308void ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) {
309 int result = res_create_surface(filename, surface);
310 if (result < 0) {
311 LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
312 }
313}
314
Doug Zongker469954f2014-03-07 09:21:25 -0800315void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, gr_surface** surface) {
316 int result = res_create_multi_surface(filename, frames, surface);
317 if (result < 0) {
318 LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
319 }
320}
321
Doug Zongker02ec6b82012-08-22 17:26:40 -0700322void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) {
323 int result = res_create_localized_surface(filename, surface);
324 if (result < 0) {
325 LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
326 }
327}
328
Doug Zongker211aebc2011-10-28 15:13:10 -0700329void ScreenRecoveryUI::Init()
330{
331 gr_init();
Doug Zongker211aebc2011-10-28 15:13:10 -0700332
Doug Zongker55a36ac2013-03-04 15:49:02 -0800333 gr_font_size(&char_width, &char_height);
334
Doug Zongker211aebc2011-10-28 15:13:10 -0700335 text_col = text_row = 0;
Doug Zongker55a36ac2013-03-04 15:49:02 -0800336 text_rows = gr_fb_height() / char_height;
Doug Zongker211aebc2011-10-28 15:13:10 -0700337 if (text_rows > kMaxRows) text_rows = kMaxRows;
338 text_top = 1;
339
Doug Zongker55a36ac2013-03-04 15:49:02 -0800340 text_cols = gr_fb_width() / char_width;
Doug Zongker211aebc2011-10-28 15:13:10 -0700341 if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
342
Doug Zongker469954f2014-03-07 09:21:25 -0800343 backgroundIcon[NONE] = NULL;
344 LoadBitmapArray("icon_installing", &installing_frames, &installation);
345 backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : NULL;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700346 backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
Doug Zongker211aebc2011-10-28 15:13:10 -0700347 LoadBitmap("icon_error", &backgroundIcon[ERROR]);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700348 backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
349
Doug Zongker211aebc2011-10-28 15:13:10 -0700350 LoadBitmap("progress_empty", &progressBarEmpty);
351 LoadBitmap("progress_fill", &progressBarFill);
352
Doug Zongker02ec6b82012-08-22 17:26:40 -0700353 LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]);
354 LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]);
355 LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]);
356 LoadLocalizedBitmap("error_text", &backgroundText[ERROR]);
357
Doug Zongker211aebc2011-10-28 15:13:10 -0700358 pthread_create(&progress_t, NULL, progress_thread, NULL);
Doug Zongker32a0a472011-11-01 11:00:20 -0700359
360 RecoveryUI::Init();
Doug Zongker211aebc2011-10-28 15:13:10 -0700361}
362
Doug Zongker5fa8c232012-09-18 12:37:02 -0700363void ScreenRecoveryUI::SetLocale(const char* locale) {
364 if (locale) {
365 char* lang = strdup(locale);
366 for (char* p = lang; *p; ++p) {
367 if (*p == '_') {
368 *p = '\0';
369 break;
370 }
371 }
372
373 // A bit cheesy: keep an explicit list of supported languages
374 // that are RTL.
375 if (strcmp(lang, "ar") == 0 || // Arabic
376 strcmp(lang, "fa") == 0 || // Persian (Farsi)
377 strcmp(lang, "he") == 0 || // Hebrew (new language code)
Doug Zongkerb66cb692012-09-18 14:52:18 -0700378 strcmp(lang, "iw") == 0 || // Hebrew (old language code)
379 strcmp(lang, "ur") == 0) { // Urdu
Doug Zongker5fa8c232012-09-18 12:37:02 -0700380 rtl_locale = true;
381 }
382 free(lang);
383 }
384}
385
Doug Zongker211aebc2011-10-28 15:13:10 -0700386void ScreenRecoveryUI::SetBackground(Icon icon)
387{
388 pthread_mutex_lock(&updateMutex);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700389
Doug Zongker52eeea4f2012-09-04 14:28:25 -0700390 currentIcon = icon;
391 update_screen_locked();
392
Doug Zongker211aebc2011-10-28 15:13:10 -0700393 pthread_mutex_unlock(&updateMutex);
394}
395
396void ScreenRecoveryUI::SetProgressType(ProgressType type)
397{
398 pthread_mutex_lock(&updateMutex);
399 if (progressBarType != type) {
400 progressBarType = type;
Doug Zongker211aebc2011-10-28 15:13:10 -0700401 }
Doug Zongker69f4b672012-04-26 14:37:53 -0700402 progressScopeStart = 0;
Doug Zongker239ac6a2013-08-20 16:03:25 -0700403 progressScopeSize = 0;
Doug Zongker69f4b672012-04-26 14:37:53 -0700404 progress = 0;
Doug Zongker239ac6a2013-08-20 16:03:25 -0700405 update_progress_locked();
Doug Zongker211aebc2011-10-28 15:13:10 -0700406 pthread_mutex_unlock(&updateMutex);
407}
408
409void ScreenRecoveryUI::ShowProgress(float portion, float seconds)
410{
411 pthread_mutex_lock(&updateMutex);
412 progressBarType = DETERMINATE;
413 progressScopeStart += progressScopeSize;
414 progressScopeSize = portion;
415 progressScopeTime = now();
416 progressScopeDuration = seconds;
417 progress = 0;
418 update_progress_locked();
419 pthread_mutex_unlock(&updateMutex);
420}
421
422void ScreenRecoveryUI::SetProgress(float fraction)
423{
424 pthread_mutex_lock(&updateMutex);
425 if (fraction < 0.0) fraction = 0.0;
426 if (fraction > 1.0) fraction = 1.0;
427 if (progressBarType == DETERMINATE && fraction > progress) {
428 // Skip updates that aren't visibly different.
Doug Zongker469954f2014-03-07 09:21:25 -0800429 int width = gr_get_width(progressBarEmpty);
Doug Zongker211aebc2011-10-28 15:13:10 -0700430 float scale = width * progressScopeSize;
431 if ((int) (progress * scale) != (int) (fraction * scale)) {
432 progress = fraction;
433 update_progress_locked();
434 }
435 }
436 pthread_mutex_unlock(&updateMutex);
437}
438
439void ScreenRecoveryUI::Print(const char *fmt, ...)
440{
441 char buf[256];
442 va_list ap;
443 va_start(ap, fmt);
444 vsnprintf(buf, 256, fmt, ap);
445 va_end(ap);
446
447 fputs(buf, stdout);
448
449 // This can get called before ui_init(), so be careful.
450 pthread_mutex_lock(&updateMutex);
451 if (text_rows > 0 && text_cols > 0) {
452 char *ptr;
453 for (ptr = buf; *ptr != '\0'; ++ptr) {
454 if (*ptr == '\n' || text_col >= text_cols) {
455 text[text_row][text_col] = '\0';
456 text_col = 0;
457 text_row = (text_row + 1) % text_rows;
458 if (text_row == text_top) text_top = (text_top + 1) % text_rows;
459 }
460 if (*ptr != '\n') text[text_row][text_col++] = *ptr;
461 }
462 text[text_row][text_col] = '\0';
463 update_screen_locked();
464 }
465 pthread_mutex_unlock(&updateMutex);
466}
467
468void ScreenRecoveryUI::StartMenu(const char* const * headers, const char* const * items,
469 int initial_selection) {
470 int i;
471 pthread_mutex_lock(&updateMutex);
472 if (text_rows > 0 && text_cols > 0) {
473 for (i = 0; i < text_rows; ++i) {
474 if (headers[i] == NULL) break;
475 strncpy(menu[i], headers[i], text_cols-1);
476 menu[i][text_cols-1] = '\0';
477 }
478 menu_top = i;
479 for (; i < text_rows; ++i) {
480 if (items[i-menu_top] == NULL) break;
481 strncpy(menu[i], items[i-menu_top], text_cols-1);
482 menu[i][text_cols-1] = '\0';
483 }
484 menu_items = i - menu_top;
485 show_menu = 1;
486 menu_sel = initial_selection;
487 update_screen_locked();
488 }
489 pthread_mutex_unlock(&updateMutex);
490}
491
492int ScreenRecoveryUI::SelectMenu(int sel) {
493 int old_sel;
494 pthread_mutex_lock(&updateMutex);
495 if (show_menu > 0) {
496 old_sel = menu_sel;
497 menu_sel = sel;
498 if (menu_sel < 0) menu_sel = 0;
499 if (menu_sel >= menu_items) menu_sel = menu_items-1;
500 sel = menu_sel;
501 if (menu_sel != old_sel) update_screen_locked();
502 }
503 pthread_mutex_unlock(&updateMutex);
504 return sel;
505}
506
507void ScreenRecoveryUI::EndMenu() {
508 int i;
509 pthread_mutex_lock(&updateMutex);
510 if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
511 show_menu = 0;
512 update_screen_locked();
513 }
514 pthread_mutex_unlock(&updateMutex);
515}
516
517bool ScreenRecoveryUI::IsTextVisible()
518{
519 pthread_mutex_lock(&updateMutex);
520 int visible = show_text;
521 pthread_mutex_unlock(&updateMutex);
522 return visible;
523}
524
525bool ScreenRecoveryUI::WasTextEverVisible()
526{
527 pthread_mutex_lock(&updateMutex);
528 int ever_visible = show_text_ever;
529 pthread_mutex_unlock(&updateMutex);
530 return ever_visible;
531}
532
533void ScreenRecoveryUI::ShowText(bool visible)
534{
535 pthread_mutex_lock(&updateMutex);
536 show_text = visible;
537 if (show_text) show_text_ever = 1;
538 update_screen_locked();
539 pthread_mutex_unlock(&updateMutex);
540}
Doug Zongkerc0441d12013-07-31 11:28:24 -0700541
542void ScreenRecoveryUI::Redraw()
543{
544 pthread_mutex_lock(&updateMutex);
545 update_screen_locked();
546 pthread_mutex_unlock(&updateMutex);
547}