screen_ui.cpp revision 80a7a4642be31db7ecd5eaa9e62b78deaa461146
1c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project/* 2211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker * Copyright (C) 2011 The Android Open Source Project 3c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 4c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * you may not use this file except in compliance with the License. 6c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * You may obtain a copy of the License at 7c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 8c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * 10c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * See the License for the specific language governing permissions and 14c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project * limitations under the License. 15c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project */ 16c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 176ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <errno.h> 186ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <fcntl.h> 19c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <linux/input.h> 20c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <pthread.h> 21c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdarg.h> 22c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdio.h> 23c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <stdlib.h> 24c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <string.h> 256ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <sys/stat.h> 26c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <sys/time.h> 276ce4a326efae4abb108e19899f4d7776abc362daDoug Zongker#include <sys/types.h> 28c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <time.h> 29c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include <unistd.h> 30c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 31c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include "common.h" 3232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker#include "device.h" 33c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project#include "minui/minui.h" 34211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker#include "screen_ui.h" 3532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker#include "ui.h" 36c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 3755a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongkerstatic int char_width; 3855a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongkerstatic int char_height; 39c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 40211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// There's only (at most) one of these objects, and global callbacks 41211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// (for pthread_create, and the input event system) need to find it, 42211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// so use a global variable. 43211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerstatic ScreenRecoveryUI* self = NULL; 44c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 456809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// Return the current time as a double (including fractions of a second). 466809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongkerstatic double now() { 476809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker struct timeval tv; 486809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gettimeofday(&tv, NULL); 496809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker return tv.tv_sec + tv.tv_usec / 1000000.0; 506809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker} 516809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 52211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug ZongkerScreenRecoveryUI::ScreenRecoveryUI() : 53211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker currentIcon(NONE), 54211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker installingFrame(0), 555fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker rtl_locale(false), 56211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType(EMPTY), 57211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeStart(0), 58211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeSize(0), 59211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress(0), 60211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical(false), 61211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_cols(0), 62211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_rows(0), 63211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_col(0), 64211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_row(0), 65211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker text_top(0), 66211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_text(false), 67211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_text_ever(false), 68211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker show_menu(false), 69211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_top(0), 70211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_items(0), 71211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker menu_sel(0), 7232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 7332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker // These values are correct for the default image resources 7432a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker // provided with the android platform. Devices which use 7532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker // different resources should have a subclass of ScreenRecoveryUI 7632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker // that overrides Init() to set these values appropriately and 7732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker // then call the superclass Init(). 7832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker animation_fps(20), 798347cb2d813b9a8b7c9165aadaea0b699eb5082fDoug Zongker indeterminate_frames(6), 808347cb2d813b9a8b7c9165aadaea0b699eb5082fDoug Zongker installing_frames(7), 818347cb2d813b9a8b7c9165aadaea0b699eb5082fDoug Zongker install_overlay_offset_x(13), 828347cb2d813b9a8b7c9165aadaea0b699eb5082fDoug Zongker install_overlay_offset_y(190), 8352eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker overlay_offset_x(-1), 8452eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker overlay_offset_y(-1) { 852f6877a0220475303907203308c018d789ea1a53yetta_wu 862f6877a0220475303907203308c018d789ea1a53yetta_wu for (int i = 0; i < 5; i++) 872f6877a0220475303907203308c018d789ea1a53yetta_wu backgroundIcon[i] = NULL; 882f6877a0220475303907203308c018d789ea1a53yetta_wu 8980a7a4642be31db7ecd5eaa9e62b78deaa461146Bjorn Andersson memset(text, 0, sizeof(text)); 9080a7a4642be31db7ecd5eaa9e62b78deaa461146Bjorn Andersson 91211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_init(&updateMutex, NULL); 92211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker self = this; 93211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 94211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 956809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// Draw the given frame over the installation overlay animation. The 966809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// background is not cleared or draw with the base icon first; we 976809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// assume that the frame already contains some other frame of the 986809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// animation. Does nothing if no overlay animation is defined. 99211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 100211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_install_overlay_locked(int frame) { 10152eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker if (installationOverlay == NULL || overlay_offset_x < 0) return; 102211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_surface surface = installationOverlay[frame]; 1036809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconWidth = gr_get_width(surface); 1046809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconHeight = gr_get_height(surface); 1056809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_blit(surface, 0, 0, iconWidth, iconHeight, 10602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_x, overlay_offset_y); 1076809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker} 1086809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 109c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Clear the screen and draw the currently selected background icon (if any). 110211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 111211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_background_locked(Icon icon) 112c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 113211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = false; 114c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(0, 0, 0, 255); 115c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_fill(0, 0, gr_fb_width(), gr_fb_height()); 116c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 117c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (icon) { 118211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_surface surface = backgroundIcon[icon]; 11902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface text_surface = backgroundText[icon]; 12002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1216809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconWidth = gr_get_width(surface); 1226809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconHeight = gr_get_height(surface); 12302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textWidth = gr_get_width(text_surface); 12402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textHeight = gr_get_height(text_surface); 12502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 126c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int iconX = (gr_fb_width() - iconWidth) / 2; 12702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; 12802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 12902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textX = (gr_fb_width() - textWidth) / 2; 13002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40; 13102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1326809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); 13302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (icon == INSTALLING_UPDATE || icon == ERASING) { 134211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_install_overlay_locked(installingFrame); 1356809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 13602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 13702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_color(255, 255, 255, 255); 13802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_texticon(textX, textY, text_surface); 139c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 140c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 141c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 142c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Draw the progress bar (if any) on the screen. Does not flip pages. 143211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 144211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_progress_locked() 145c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 14669f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (currentIcon == ERROR) return; 14769f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker 14802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { 149211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_install_overlay_locked(installingFrame); 1506809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 151c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 152211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != EMPTY) { 15302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); 154211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int width = gr_get_width(progressBarEmpty); 155211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int height = gr_get_height(progressBarEmpty); 156c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1576809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dx = (gr_fb_width() - width)/2; 1586809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dy = (3*gr_fb_height() + iconHeight - 2*height)/4; 159c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1606809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // Erase behind the progress bar (in case this was a progress-only update) 1616809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_color(0, 0, 0, 255); 1626809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_fill(dx, dy, width, height); 163c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 164211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE) { 165211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float p = progressScopeStart + progress * progressScopeSize; 166211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int pos = (int) (p * width); 167c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1685fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (rtl_locale) { 1695fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from right to left. 1705fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1715fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); 1725fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1735fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1745fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); 1755fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1765fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } else { 1775fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from left to right. 1785fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1795fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); 1805fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1815fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1825fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); 1835fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1846809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 185c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 186c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 187211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == INDETERMINATE) { 1886809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker static int frame = 0; 189211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); 1905fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // in RTL locales, we run the animation backwards, which 1915fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // makes the spinner spin the other way. 1925fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (rtl_locale) { 1935fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker frame = (frame + indeterminate_frames - 1) % indeterminate_frames; 1945fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } else { 1955fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker frame = (frame + 1) % indeterminate_frames; 1965fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1976809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 198c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 199c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 200c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2016fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_HEADER 247,0,6 2026fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_MENU 0,106,157 2036fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_LOG 249,194,0 204c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 205c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen. Does not flip pages. 206211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 207211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_screen_locked() 208c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 209211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_background_locked(currentIcon); 210c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_progress_locked(); 211c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 212c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_text) { 213c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(0, 0, 0, 160); 214c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_fill(0, 0, gr_fb_width(), gr_fb_height()); 215c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2166fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int y = 0; 217c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i = 0; 218c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu) { 2196fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_HEADER, 255); 220c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 221c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < menu_top + menu_items; ++i) { 2226fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (i == menu_top) gr_color(C_MENU, 255); 2236fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 224c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (i == menu_top + menu_sel) { 2256fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // draw the highlight bar 2266fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_fill(0, y-2, gr_fb_width(), y+char_height+2); 2276fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // white text of selected item 228c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(255, 255, 255, 255); 2296fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], 1); 2306fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_MENU, 255); 231c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2326fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top); 233c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 2346fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += char_height+4; 235c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 2366fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_MENU, 255); 2376fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 2386fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_fill(0, y, gr_fb_width(), y+2); 2396fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 240c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project ++i; 241c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 242c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2436fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_LOG, 255); 2446fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 2456fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // display from the bottom up, until we hit the top of the 2466fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // screen, the bottom of the menu, or we've displayed the 2476fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // entire text buffer. 2486fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int ty; 2496fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int row = (text_top+text_rows-1) % text_rows; 2506fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker for (int ty = gr_fb_height() - char_height, count = 0; 2516fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty > y+2 && count < text_rows; 2526fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty -= char_height, ++count) { 2536fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_text(4, ty, text[row], 0); 2546fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker --row; 2556fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (row < 0) row = text_rows-1; 256c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 257c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 258c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 259c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 260c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen and flip the screen (make it visible). 261211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 262211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_screen_locked() 263c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 264c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); 265c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 266c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 267c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 268c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Updates only the progress bar, if possible, otherwise redraws the screen. 269211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 270211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_progress_locked() 271c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 272211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (show_text || !pagesIdentical) { 273c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); // Must redraw the whole screen 274211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = true; 275c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2766809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker draw_progress_locked(); // Draw only the progress bar and overlays 277c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 278c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 279c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 280c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 281c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Keeps the progress bar updated, even when the process is otherwise busy. 28232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid* ScreenRecoveryUI::progress_thread(void *cookie) { 28332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker self->progress_loop(); 28432a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker return NULL; 28532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker} 28632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 28732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid ScreenRecoveryUI::progress_loop() { 28832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double interval = 1.0 / animation_fps; 289c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (;;) { 2906809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double start = now(); 29132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_lock(&updateMutex); 292c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2936809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int redraw = 0; 2946809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 2956809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // update the installation animation, if active 2966809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // skip this if we have a text overlay (too expensive to update) 29702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && 29802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker installing_frames > 0 && !show_text) { 29932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker installingFrame = (installingFrame + 1) % installing_frames; 3006809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 3016809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 3026809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 303c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // update the progress bar animation, if active 304c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // skip this if we have a text overlay (too expensive to update) 30532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (progressBarType == INDETERMINATE && !show_text) { 3066809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 307c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 308c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 309c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // move the progress bar forward on timed intervals, if configured 31032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker int duration = progressScopeDuration; 31132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (progressBarType == DETERMINATE && duration > 0) { 31232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double elapsed = now() - progressScopeTime; 31369f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker float p = 1.0 * elapsed / duration; 31469f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > 1.0) p = 1.0; 31569f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > progress) { 31669f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = p; 3176809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 318c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 319c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 320c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 32132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (redraw) update_progress_locked(); 3226809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 32332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_unlock(&updateMutex); 3246809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double end = now(); 3256809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // minimum of 20ms delay between frames 3266809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double delay = interval - (end-start); 3276809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker if (delay < 0.02) delay = 0.02; 3286809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker usleep((long)(delay * 1000000)); 329c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 330c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 331c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 332211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) { 333211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int result = res_create_surface(filename, surface); 334211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (result < 0) { 335211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 336211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker } 337211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 338211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 33902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongkervoid ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) { 34002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int result = res_create_localized_surface(filename, surface); 34102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (result < 0) { 34202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 34302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker } 34402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker} 34502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 346211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Init() 347c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 348c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_init(); 349c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 35055a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker gr_font_size(&char_width, &char_height); 35155a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker 352c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = text_row = 0; 35355a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker text_rows = gr_fb_height() / char_height; 354211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_rows > kMaxRows) text_rows = kMaxRows; 355c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_top = 1; 356c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 35755a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker text_cols = gr_fb_width() / char_width; 358211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; 359211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 36002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); 36102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; 362211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("icon_error", &backgroundIcon[ERROR]); 36302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; 36402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 365211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_empty", &progressBarEmpty); 366211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_fill", &progressBarFill); 367c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 36802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); 36902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); 37002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); 37102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); 37202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 373c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 3746809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 37532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames * 37628ce47cfa6919518a8c298088bf08b03bb374c0fDoug Zongker sizeof(gr_surface)); 37732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker for (i = 0; i < indeterminate_frames; ++i) { 3786809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker char filename[40]; 379be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "indeterminate01.png", "indeterminate02.png", ... 380be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker sprintf(filename, "indeterminate%02d", i+1); 381211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap(filename, progressBarIndeterminate+i); 3826809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 3836809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 38432a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (installing_frames > 0) { 38532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker installationOverlay = (gr_surface*)malloc(installing_frames * 38628ce47cfa6919518a8c298088bf08b03bb374c0fDoug Zongker sizeof(gr_surface)); 38732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker for (i = 0; i < installing_frames; ++i) { 3886809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker char filename[40]; 389be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "icon_installing_overlay01.png", 390be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "icon_installing_overlay02.png", ... 391be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker sprintf(filename, "icon_installing_overlay%02d", i+1); 392211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap(filename, installationOverlay+i); 393c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 3946809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } else { 395211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker installationOverlay = NULL; 396c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 397c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 398211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_create(&progress_t, NULL, progress_thread, NULL); 39932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 40032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker RecoveryUI::Init(); 401c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 402c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 4035fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongkervoid ScreenRecoveryUI::SetLocale(const char* locale) { 4045fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (locale) { 4055fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker char* lang = strdup(locale); 4065fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker for (char* p = lang; *p; ++p) { 4075fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (*p == '_') { 4085fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker *p = '\0'; 4095fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker break; 4105fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4115fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4125fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 4135fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // A bit cheesy: keep an explicit list of supported languages 4145fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // that are RTL. 4155fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (strcmp(lang, "ar") == 0 || // Arabic 4165fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "fa") == 0 || // Persian (Farsi) 4175fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "he") == 0 || // Hebrew (new language code) 418b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "iw") == 0 || // Hebrew (old language code) 419b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "ur") == 0) { // Urdu 4205fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker rtl_locale = true; 4215fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4225fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker free(lang); 4235fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4245fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker} 4255fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 426211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetBackground(Icon icon) 427c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 428211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 42902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 43002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker // Adjust the offset to account for the positioning of the 43102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker // base image on the screen. 43202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (backgroundIcon[icon] != NULL) { 43302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface bg = backgroundIcon[icon]; 43402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface text = backgroundText[icon]; 43502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_x = install_overlay_offset_x + (gr_fb_width() - gr_get_width(bg)) / 2; 43602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_y = install_overlay_offset_y + 43702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker (gr_fb_height() - (gr_get_height(bg) + gr_get_height(text) + 40)) / 2; 43802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker } 43902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 44052eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker currentIcon = icon; 44152eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker update_screen_locked(); 44252eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker 443211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 444c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 445c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 446211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgressType(ProgressType type) 447c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 448211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 449211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != type) { 450211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = type; 451c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 452c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 45369f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progressScopeStart = 0; 45469f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = 0; 455211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 456c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 457c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 458211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowProgress(float portion, float seconds) 459c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 460211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 461211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = DETERMINATE; 462211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeStart += progressScopeSize; 463211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeSize = portion; 464211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeTime = now(); 465211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeDuration = seconds; 466211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = 0; 467c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 468211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 469c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 470c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 471211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgress(float fraction) 472c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 473211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 474c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction < 0.0) fraction = 0.0; 475c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction > 1.0) fraction = 1.0; 476211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE && fraction > progress) { 477c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // Skip updates that aren't visibly different. 478211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int width = gr_get_width(progressBarIndeterminate[0]); 479211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float scale = width * progressScopeSize; 480211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if ((int) (progress * scale) != (int) (fraction * scale)) { 481211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = fraction; 482c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 483c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 484c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 485211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 486c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 487c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 488211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Print(const char *fmt, ...) 489c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 490c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char buf[256]; 491c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_list ap; 492c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_start(ap, fmt); 493c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project vsnprintf(buf, 256, fmt, ap); 494c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_end(ap); 495c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 4963d177d055c9cf3571e4b7c098818b454d1dbf9d7Doug Zongker fputs(buf, stdout); 497c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 498c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // This can get called before ui_init(), so be careful. 499211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 500c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 501c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char *ptr; 502c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (ptr = buf; *ptr != '\0'; ++ptr) { 503c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr == '\n' || text_col >= text_cols) { 504c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 505c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = 0; 506c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_row = (text_row + 1) % text_rows; 507c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_row == text_top) text_top = (text_top + 1) % text_rows; 508c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 509c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr != '\n') text[text_row][text_col++] = *ptr; 510c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 511c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 512c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 513c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 514211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 515c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 516c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 517211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::StartMenu(const char* const * headers, const char* const * items, 518211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int initial_selection) { 519c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 520211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 521c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 522c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (i = 0; i < text_rows; ++i) { 523c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (headers[i] == NULL) break; 524c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], headers[i], text_cols-1); 525c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 526c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 527c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_top = i; 528c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < text_rows; ++i) { 529c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (items[i-menu_top] == NULL) break; 530c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], items[i-menu_top], text_cols-1); 531c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 532c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 533c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_items = i - menu_top; 534c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 1; 535be598881d079511385a88b12b7a14b97e63dc85eDoug Zongker menu_sel = initial_selection; 536c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 537c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 538211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 539c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 540c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 541211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerint ScreenRecoveryUI::SelectMenu(int sel) { 542c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int old_sel; 543211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 544c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0) { 545c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project old_sel = menu_sel; 546c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_sel = sel; 547c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel < 0) menu_sel = 0; 548c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel >= menu_items) menu_sel = menu_items-1; 549c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project sel = menu_sel; 550c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel != old_sel) update_screen_locked(); 551c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 552211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 553c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return sel; 554c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 555c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 556211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::EndMenu() { 557c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 558211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 559c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0 && text_rows > 0 && text_cols > 0) { 560c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 0; 561c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 562c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 563211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 564c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 565c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 566211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::IsTextVisible() 567c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 568211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 569c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int visible = show_text; 570211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 571c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return visible; 572c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 573c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 574211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::WasTextEverVisible() 5755cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker{ 576211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5775cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker int ever_visible = show_text_ever; 578211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5795cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker return ever_visible; 5805cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker} 5815cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker 582211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowText(bool visible) 5834bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker{ 584211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5854bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker show_text = visible; 5865cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker if (show_text) show_text_ever = 1; 5874bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker update_screen_locked(); 588211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5894bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker} 590