screen_ui.cpp revision 2f6877a0220475303907203308c018d789ea1a53
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 89211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_init(&updateMutex, NULL); 90211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker self = this; 91211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 92211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 936809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// Draw the given frame over the installation overlay animation. The 946809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// background is not cleared or draw with the base icon first; we 956809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// assume that the frame already contains some other frame of the 966809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker// animation. Does nothing if no overlay animation is defined. 97211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 98211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_install_overlay_locked(int frame) { 9952eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker if (installationOverlay == NULL || overlay_offset_x < 0) return; 100211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_surface surface = installationOverlay[frame]; 1016809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconWidth = gr_get_width(surface); 1026809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconHeight = gr_get_height(surface); 1036809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_blit(surface, 0, 0, iconWidth, iconHeight, 10402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_x, overlay_offset_y); 1056809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker} 1066809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 107c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Clear the screen and draw the currently selected background icon (if any). 108211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 109211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_background_locked(Icon icon) 110c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 111211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = false; 112c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(0, 0, 0, 255); 113c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_fill(0, 0, gr_fb_width(), gr_fb_height()); 114c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 115c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (icon) { 116211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_surface surface = backgroundIcon[icon]; 11702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface text_surface = backgroundText[icon]; 11802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1196809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconWidth = gr_get_width(surface); 1206809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int iconHeight = gr_get_height(surface); 12102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textWidth = gr_get_width(text_surface); 12202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textHeight = gr_get_height(text_surface); 12302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 124c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int iconX = (gr_fb_width() - iconWidth) / 2; 12502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; 12602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 12702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textX = (gr_fb_width() - textWidth) / 2; 12802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40; 12902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 1306809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); 13102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (icon == INSTALLING_UPDATE || icon == ERASING) { 132211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_install_overlay_locked(installingFrame); 1336809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 13402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 13502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_color(255, 255, 255, 255); 13602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_texticon(textX, textY, text_surface); 137c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 138c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 139c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 140c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Draw the progress bar (if any) on the screen. Does not flip pages. 141211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 142211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_progress_locked() 143c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 14469f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (currentIcon == ERROR) return; 14569f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker 14602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { 147211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_install_overlay_locked(installingFrame); 1486809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 149c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 150211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != EMPTY) { 15102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); 152211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int width = gr_get_width(progressBarEmpty); 153211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int height = gr_get_height(progressBarEmpty); 154c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1556809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dx = (gr_fb_width() - width)/2; 1566809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int dy = (3*gr_fb_height() + iconHeight - 2*height)/4; 157c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1586809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // Erase behind the progress bar (in case this was a progress-only update) 1596809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_color(0, 0, 0, 255); 1606809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker gr_fill(dx, dy, width, height); 161c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 162211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE) { 163211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float p = progressScopeStart + progress * progressScopeSize; 164211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int pos = (int) (p * width); 165c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1665fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (rtl_locale) { 1675fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from right to left. 1685fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1695fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); 1705fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1715fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1725fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); 1735fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1745fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } else { 1755fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // Fill the progress bar from left to right. 1765fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos > 0) { 1775fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); 1785fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1795fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (pos < width-1) { 1805fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); 1815fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1826809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 183c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 184c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 185211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == INDETERMINATE) { 1866809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker static int frame = 0; 187211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); 1885fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // in RTL locales, we run the animation backwards, which 1895fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // makes the spinner spin the other way. 1905fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (rtl_locale) { 1915fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker frame = (frame + indeterminate_frames - 1) % indeterminate_frames; 1925fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } else { 1935fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker frame = (frame + 1) % indeterminate_frames; 1945fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 1956809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 196c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 197c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 198c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 1996fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_HEADER 247,0,6 2006fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_MENU 0,106,157 2016fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker#define C_LOG 249,194,0 202c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 203c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen. Does not flip pages. 204211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 205211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::draw_screen_locked() 206c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 207211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker draw_background_locked(currentIcon); 208c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_progress_locked(); 209c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 210c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_text) { 211c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(0, 0, 0, 160); 212c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_fill(0, 0, gr_fb_width(), gr_fb_height()); 213c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2146fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int y = 0; 215c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i = 0; 216c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu) { 2176fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_HEADER, 255); 218c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 219c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < menu_top + menu_items; ++i) { 2206fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (i == menu_top) gr_color(C_MENU, 255); 2216fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 222c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (i == menu_top + menu_sel) { 2236fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // draw the highlight bar 2246fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_fill(0, y-2, gr_fb_width(), y+char_height+2); 2256fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // white text of selected item 226c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_color(255, 255, 255, 255); 2276fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], 1); 2286fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_MENU, 255); 229c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2306fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top); 231c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 2326fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += char_height+4; 233c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 2346fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_MENU, 255); 2356fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 2366fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_fill(0, y, gr_fb_width(), y+2); 2376fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker y += 4; 238c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project ++i; 239c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 240c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2416fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_color(C_LOG, 255); 2426fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker 2436fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // display from the bottom up, until we hit the top of the 2446fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // screen, the bottom of the menu, or we've displayed the 2456fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker // entire text buffer. 2466fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int ty; 2476fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker int row = (text_top+text_rows-1) % text_rows; 2486fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker for (int ty = gr_fb_height() - char_height, count = 0; 2496fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty > y+2 && count < text_rows; 2506fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker ty -= char_height, ++count) { 2516fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker gr_text(4, ty, text[row], 0); 2526fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker --row; 2536fd59ac07d91eb373f4269a40e688aa82a6ccc6eDoug Zongker if (row < 0) row = text_rows-1; 254c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 255c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 256c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 257c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 258c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Redraw everything on the screen and flip the screen (make it visible). 259211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 260211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_screen_locked() 261c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 262c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); 263c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 264c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 265c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 266c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Updates only the progress bar, if possible, otherwise redraws the screen. 267211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker// Should only be called with updateMutex locked. 268211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::update_progress_locked() 269c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 270211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (show_text || !pagesIdentical) { 271c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project draw_screen_locked(); // Must redraw the whole screen 272211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pagesIdentical = true; 273c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } else { 2746809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker draw_progress_locked(); // Draw only the progress bar and overlays 275c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 276c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_flip(); 277c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 278c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 279c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project// Keeps the progress bar updated, even when the process is otherwise busy. 28032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid* ScreenRecoveryUI::progress_thread(void *cookie) { 28132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker self->progress_loop(); 28232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker return NULL; 28332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker} 28432a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 28532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongkervoid ScreenRecoveryUI::progress_loop() { 28632a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double interval = 1.0 / animation_fps; 287c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (;;) { 2886809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double start = now(); 28932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_lock(&updateMutex); 290c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 2916809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker int redraw = 0; 2926809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 2936809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // update the installation animation, if active 2946809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // skip this if we have a text overlay (too expensive to update) 29502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && 29602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker installing_frames > 0 && !show_text) { 29732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker installingFrame = (installingFrame + 1) % installing_frames; 2986809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 2996809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 3006809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 301c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // update the progress bar animation, if active 302c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // skip this if we have a text overlay (too expensive to update) 30332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (progressBarType == INDETERMINATE && !show_text) { 3046809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 305c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 306c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 307c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // move the progress bar forward on timed intervals, if configured 30832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker int duration = progressScopeDuration; 30932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (progressBarType == DETERMINATE && duration > 0) { 31032a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker double elapsed = now() - progressScopeTime; 31169f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker float p = 1.0 * elapsed / duration; 31269f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > 1.0) p = 1.0; 31369f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker if (p > progress) { 31469f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = p; 3156809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker redraw = 1; 316c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 317c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 318c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 31932a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (redraw) update_progress_locked(); 3206809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 32132a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker pthread_mutex_unlock(&updateMutex); 3226809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double end = now(); 3236809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker // minimum of 20ms delay between frames 3246809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker double delay = interval - (end-start); 3256809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker if (delay < 0.02) delay = 0.02; 3266809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker usleep((long)(delay * 1000000)); 327c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 328c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 329c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 330211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) { 331211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int result = res_create_surface(filename, surface); 332211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (result < 0) { 333211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 334211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker } 335211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker} 336211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 33702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongkervoid ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) { 33802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker int result = res_create_localized_surface(filename, surface); 33902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (result < 0) { 34002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LOGE("missing bitmap %s\n(Code %d)\n", filename, result); 34102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker } 34202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker} 34302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 344211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Init() 345c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 346c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project gr_init(); 347c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 34855a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker gr_font_size(&char_width, &char_height); 34955a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker 350c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = text_row = 0; 35155a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker text_rows = gr_fb_height() / char_height; 352211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_rows > kMaxRows) text_rows = kMaxRows; 353c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_top = 1; 354c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 35555a36ac1e01205f2cd461cd2f89d92e3b64cddd2Doug Zongker text_cols = gr_fb_width() / char_width; 356211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; 357211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker 35802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); 35902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; 360211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("icon_error", &backgroundIcon[ERROR]); 36102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; 36202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 363211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_empty", &progressBarEmpty); 364211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap("progress_fill", &progressBarFill); 365c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 36602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); 36702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); 36802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); 36902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); 37002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 371c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 3726809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 37332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames * 37428ce47cfa6919518a8c298088bf08b03bb374c0fDoug Zongker sizeof(gr_surface)); 37532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker for (i = 0; i < indeterminate_frames; ++i) { 3766809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker char filename[40]; 377be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "indeterminate01.png", "indeterminate02.png", ... 378be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker sprintf(filename, "indeterminate%02d", i+1); 379211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap(filename, progressBarIndeterminate+i); 3806809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } 3816809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker 38232a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker if (installing_frames > 0) { 38332a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker installationOverlay = (gr_surface*)malloc(installing_frames * 38428ce47cfa6919518a8c298088bf08b03bb374c0fDoug Zongker sizeof(gr_surface)); 38532a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker for (i = 0; i < installing_frames; ++i) { 3866809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker char filename[40]; 387be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "icon_installing_overlay01.png", 388be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker // "icon_installing_overlay02.png", ... 389be6d4d10529860037c165e4441a2d23f539e7b00Doug Zongker sprintf(filename, "icon_installing_overlay%02d", i+1); 390211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker LoadBitmap(filename, installationOverlay+i); 391c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 3926809c51f8db86f1ab00a076cf570439d11920d3aDoug Zongker } else { 393211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker installationOverlay = NULL; 394c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 395c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 396211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_create(&progress_t, NULL, progress_thread, NULL); 39732a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker 39832a0a47a596509792fde8cdbf8b4b0705708b2beDoug Zongker RecoveryUI::Init(); 399c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 400c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 4015fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongkervoid ScreenRecoveryUI::SetLocale(const char* locale) { 4025fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (locale) { 4035fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker char* lang = strdup(locale); 4045fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker for (char* p = lang; *p; ++p) { 4055fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (*p == '_') { 4065fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker *p = '\0'; 4075fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker break; 4085fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4095fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4105fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 4115fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // A bit cheesy: keep an explicit list of supported languages 4125fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker // that are RTL. 4135fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker if (strcmp(lang, "ar") == 0 || // Arabic 4145fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "fa") == 0 || // Persian (Farsi) 4155fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker strcmp(lang, "he") == 0 || // Hebrew (new language code) 416b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "iw") == 0 || // Hebrew (old language code) 417b66cb69e3933d5f56f06d88cd31817f49d87df5fDoug Zongker strcmp(lang, "ur") == 0) { // Urdu 4185fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker rtl_locale = true; 4195fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4205fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker free(lang); 4215fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker } 4225fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker} 4235fa8c23911759a9e81af0e7fb5eb431277b8e9a6Doug Zongker 424211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetBackground(Icon icon) 425c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 426211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 42702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 42802ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker // Adjust the offset to account for the positioning of the 42902ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker // base image on the screen. 43002ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker if (backgroundIcon[icon] != NULL) { 43102ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface bg = backgroundIcon[icon]; 43202ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker gr_surface text = backgroundText[icon]; 43302ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_x = install_overlay_offset_x + (gr_fb_width() - gr_get_width(bg)) / 2; 43402ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker overlay_offset_y = install_overlay_offset_y + 43502ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker (gr_fb_height() - (gr_get_height(bg) + gr_get_height(text) + 40)) / 2; 43602ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker } 43702ec6b88ed4e6cf40cc257572b07c7277b7b6341Doug Zongker 43852eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker currentIcon = icon; 43952eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker update_screen_locked(); 44052eeea4fa59c15ecb09c32b8e05653f4e55f5188Doug Zongker 441211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 442c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 443c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 444211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgressType(ProgressType type) 445c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 446211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 447211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType != type) { 448211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = type; 449c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 450c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 45169f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progressScopeStart = 0; 45269f4b6732ce13f248b0da0c7eeda56207fdeaba2Doug Zongker progress = 0; 453211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 454c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 455c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 456211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowProgress(float portion, float seconds) 457c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 458211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 459211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressBarType = DETERMINATE; 460211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeStart += progressScopeSize; 461211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeSize = portion; 462211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeTime = now(); 463211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progressScopeDuration = seconds; 464211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = 0; 465c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 466211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 467c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 468c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 469211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::SetProgress(float fraction) 470c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 471211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 472c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction < 0.0) fraction = 0.0; 473c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (fraction > 1.0) fraction = 1.0; 474211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if (progressBarType == DETERMINATE && fraction > progress) { 475c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // Skip updates that aren't visibly different. 476211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int width = gr_get_width(progressBarIndeterminate[0]); 477211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker float scale = width * progressScopeSize; 478211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker if ((int) (progress * scale) != (int) (fraction * scale)) { 479211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker progress = fraction; 480c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_progress_locked(); 481c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 482c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 483211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 484c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 485c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 486211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::Print(const char *fmt, ...) 487c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 488c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char buf[256]; 489c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_list ap; 490c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_start(ap, fmt); 491c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project vsnprintf(buf, 256, fmt, ap); 492c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project va_end(ap); 493c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 4943d177d055c9cf3571e4b7c098818b454d1dbf9d7Doug Zongker fputs(buf, stdout); 495c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 496c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project // This can get called before ui_init(), so be careful. 497211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 498c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 499c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project char *ptr; 500c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (ptr = buf; *ptr != '\0'; ++ptr) { 501c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr == '\n' || text_col >= text_cols) { 502c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 503c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_col = 0; 504c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text_row = (text_row + 1) % text_rows; 505c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_row == text_top) text_top = (text_top + 1) % text_rows; 506c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 507c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (*ptr != '\n') text[text_row][text_col++] = *ptr; 508c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 509c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project text[text_row][text_col] = '\0'; 510c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 511c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 512211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 513c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 514c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 515211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::StartMenu(const char* const * headers, const char* const * items, 516211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker int initial_selection) { 517c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 518211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 519c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (text_rows > 0 && text_cols > 0) { 520c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (i = 0; i < text_rows; ++i) { 521c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (headers[i] == NULL) break; 522c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], headers[i], text_cols-1); 523c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 524c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 525c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_top = i; 526c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project for (; i < text_rows; ++i) { 527c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (items[i-menu_top] == NULL) break; 528c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project strncpy(menu[i], items[i-menu_top], text_cols-1); 529c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu[i][text_cols-1] = '\0'; 530c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 531c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_items = i - menu_top; 532c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 1; 533be598881d079511385a88b12b7a14b97e63dc85eDoug Zongker menu_sel = initial_selection; 534c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 535c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 536211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 537c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 538c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 539211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerint ScreenRecoveryUI::SelectMenu(int sel) { 540c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int old_sel; 541211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 542c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0) { 543c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project old_sel = menu_sel; 544c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project menu_sel = sel; 545c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel < 0) menu_sel = 0; 546c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel >= menu_items) menu_sel = menu_items-1; 547c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project sel = menu_sel; 548c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (menu_sel != old_sel) update_screen_locked(); 549c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 550211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 551c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return sel; 552c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 553c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 554211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::EndMenu() { 555c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int i; 556211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 557c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project if (show_menu > 0 && text_rows > 0 && text_cols > 0) { 558c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project show_menu = 0; 559c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project update_screen_locked(); 560c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project } 561211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 562c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 563c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 564211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::IsTextVisible() 565c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project{ 566211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 567c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project int visible = show_text; 568211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 569c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project return visible; 570c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project} 571c24a8e688a6312764254beac2b2520bb0c5e998dThe Android Open Source Project 572211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkerbool ScreenRecoveryUI::WasTextEverVisible() 5735cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker{ 574211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5755cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker int ever_visible = show_text_ever; 576211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5775cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker return ever_visible; 5785cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker} 5795cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker 580211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongkervoid ScreenRecoveryUI::ShowText(bool visible) 5814bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker{ 582211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_lock(&updateMutex); 5834bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker show_text = visible; 5845cae445e43c5928daba0a76745b0dd2657274edaDoug Zongker if (show_text) show_text_ever = 1; 5854bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker update_screen_locked(); 586211aebc4e09ce7ca37003be4f01c83111cf0bb49Doug Zongker pthread_mutex_unlock(&updateMutex); 5874bc980626c1cf6f1ea7d36e4b54e0023c896c9deDoug Zongker} 588