blob: 80063399f4db48e7165c0c3f3e0aa0391f209f4d [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/*
Dees Troy3be70a82013-10-22 14:25:12 +00002 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
Dees_Troy51a0e822012-09-05 15:24:24 -040018
19#include <linux/input.h>
20#include <pthread.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <errno.h>
24#include <stdlib.h>
25#include <string.h>
26#include <fcntl.h>
27#include <sys/reboot.h>
28#include <sys/stat.h>
29#include <sys/time.h>
30#include <sys/mman.h>
31#include <sys/types.h>
32#include <sys/ioctl.h>
33#include <sys/mount.h>
34#include <time.h>
35#include <unistd.h>
36#include <stdlib.h>
37
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050038extern "C"
39{
Dees_Troy2673cec2013-04-02 20:22:16 +000040#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040041#include "../minuitwrp/minui.h"
Dees Troyb7ae0982013-09-10 20:47:35 +000042#ifdef HAVE_SELINUX
Dees_Troy51a0e822012-09-05 15:24:24 -040043#include "../minzip/Zip.h"
Dees Troyb7ae0982013-09-10 20:47:35 +000044#else
45#include "../minzipold/Zip.h"
46#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040047#include <pixelflinger/pixelflinger.h>
48}
49
50#include "rapidxml.hpp"
51#include "objects.hpp"
52#include "../data.hpp"
53#include "../variables.h"
Dees_Troy5bf43922012-09-07 16:07:55 -040054#include "../partitions.hpp"
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050055#include "../twrp-functions.hpp"
Ethan Yonker03a42f62014-08-08 11:03:51 -050056#include "../openrecoveryscript.hpp"
57#include "../orscmd/orscmd.h"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070058#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050059#include "blanktimer.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070060#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040061
Vojtech Boceke5ffcd12014-02-06 21:17:32 +010062// Enable to print render time of each frame to the log file
63//#define PRINT_RENDER_TIME 1
64
Dees_Troy51a0e822012-09-05 15:24:24 -040065const static int CURTAIN_FADE = 32;
66
67using namespace rapidxml;
68
69// Global values
70static gr_surface gCurtain = NULL;
71static int gGuiInitialized = 0;
72static int gGuiConsoleRunning = 0;
73static int gGuiConsoleTerminate = 0;
74static int gForceRender = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050075pthread_mutex_t gForceRendermutex;
Dees_Troyc8b199c2012-09-24 11:55:07 -040076static int gNoAnimation = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +000077static int gGuiInputRunning = 0;
Ethan Yonker03a42f62014-08-08 11:03:51 -050078static int gCmdLineRunning = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070079#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050080blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070081#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040082
83// Needed by pages.cpp too
84int gGuiRunning = 0;
85
86static int gRecorder = -1;
87
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020088extern "C" void gr_write_frame_to_file(int fd);
Dees_Troy51a0e822012-09-05 15:24:24 -040089
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020090void flip(void)
Dees_Troy51a0e822012-09-05 15:24:24 -040091{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020092 if (gRecorder != -1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050093 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020094 timespec time;
95 clock_gettime(CLOCK_MONOTONIC, &time);
96 write(gRecorder, &time, sizeof(timespec));
97 gr_write_frame_to_file(gRecorder);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050098 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020099 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400100}
101
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200102void rapidxml::parse_error_handler(const char *what, void *where)
Dees_Troy51a0e822012-09-05 15:24:24 -0400103{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200104 fprintf(stderr, "Parser error: %s\n", what);
105 fprintf(stderr, " Start of string: %s\n",(char *) where);
106 LOGERR("Error parsing XML file.\n");
107 //abort();
Dees_Troy51a0e822012-09-05 15:24:24 -0400108}
109
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200110static void curtainSet()
Dees_Troy51a0e822012-09-05 15:24:24 -0400111{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200112 gr_color(0, 0, 0, 255);
113 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
114 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
115 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400116}
117
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200118static void curtainRaise(gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400119{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200120 int sy = 0;
121 int h = gr_get_height(gCurtain) - 1;
122 int w = gr_get_width(gCurtain);
123 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400124
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200125 int msw = gr_get_width(surface);
126 int msh = gr_get_height(surface);
127 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400128
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200129 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500130 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200131 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500132 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200133 gr_blit(surface, 0, 0, msw, msh, 0, 0);
134 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
135 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500136 }
137 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200138 gr_blit(surface, 0, 0, msw, msh, 0, 0);
139 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400140}
141
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200142void curtainClose()
Dees_Troy51a0e822012-09-05 15:24:24 -0400143{
144#if 0
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200145 int w = gr_get_width(gCurtain);
146 int h = 1;
147 int sy = gr_get_height(gCurtain) - 1;
148 int fbh = gr_fb_height();
149 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400150
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200151 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500152 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200153 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500154 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200155 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
156 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500157 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200158 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
159 gr_get_height(gCurtain), 0, 0);
160 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400161
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200162 if (gRecorder != -1)
163 close(gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400164
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200165 int fade;
166 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500167 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200168 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
169 gr_get_height(gCurtain), 0, 0);
170 gr_color(0, 0, 0, fade);
171 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
172 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500173 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200174 gr_color(0, 0, 0, 255);
175 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
176 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400177 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500178#else
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200179 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
180 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500181#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400182}
183
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200184static void * input_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400185{
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700186
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200187 int drag = 0;
188 static int touch_and_hold = 0, dontwait = 0;
189 static int touch_repeat = 0, key_repeat = 0;
190 static int x = 0, y = 0;
191 static int lshift = 0, rshift = 0;
192 static struct timeval touchStart;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200193 string seconds;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100194 HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100195 MouseCursor *cursor = PageManager::GetMouseCursor();
Dees_Troy51a0e822012-09-05 15:24:24 -0400196
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700197#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200198 //start screen timeout threads
199 blankTimer.setTimerThread();
200 DataManager::GetValue("tw_screen_timeout_secs", seconds);
201 blankTimer.setTime(atoi(seconds.c_str()));
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700202#else
203 LOGINFO("Skipping screen timeout threads: TW_NO_SCREEN_TIMEOUT is set\n");
204#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400205
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200206 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500207 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200208 // wait for the next event
209 struct input_event ev;
210 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400211
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200212 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400213
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200214 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500215 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 struct timeval curTime;
217 gettimeofday(&curTime, NULL);
218 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400219
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200220 seconds = curTime.tv_sec - touchStart.tv_sec;
221 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500222
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
224 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500225 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200226 touch_and_hold = 0;
227 touch_repeat = 1;
228 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400229#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400231#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200232 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700233#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200234 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700235#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400236 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200237 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500238 {
239#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200240 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500241#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200242 gettimeofday(&touchStart, NULL);
243 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700244#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700246#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500247 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200248 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500249 {
250#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200251 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500252#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200253 gettimeofday(&touchStart, NULL);
254 key_repeat = 2;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100255 kb->KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700256#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700258#endif
259
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500260 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200261 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500262 {
263#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200264 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500265#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200266 gettimeofday(&touchStart, NULL);
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100267 kb->KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700268#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200269 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700270#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500271 }
272 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200273 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500274 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400275
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200276 x = ev.value >> 16;
277 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400278
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200279 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500280 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200281 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500282 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400283#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200284 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400285#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200286 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700287#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200288 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700289#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200290 touch_and_hold = 0;
291 touch_repeat = 0;
292 if (!key_repeat)
293 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400294 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200295 state = 0;
296 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400297 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200298 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500299 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200300 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500301 {
Dees Troy1eba56f2014-04-12 13:09:00 +0000302 if (x != 0 && y != 0) {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500303#ifdef _EVENT_LOGGING
Dees Troy1eba56f2014-04-12 13:09:00 +0000304 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500305#endif
Dees Troy1eba56f2014-04-12 13:09:00 +0000306 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
307 state = 1;
308 drag = 1;
309 touch_and_hold = 1;
310 dontwait = 1;
311 key_repeat = 0;
312 gettimeofday(&touchStart, NULL);
313 }
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700314#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200315 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700316#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500317 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200318 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500319 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200320 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500321 {
322#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200323 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500324#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200325 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
326 state = 1;
327 key_repeat = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700328#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200329 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700330#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500331 }
332 }
333 }
334 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200335 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500336 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200337 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500338#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200339 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500340#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100341 // Left mouse button
342 if(ev.code == BTN_LEFT)
343 {
344 if(ev.value == 1)
345 {
346 cursor->GetPos(x, y);
347
348 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
349 state = 1;
350 drag = 1;
351 touch_and_hold = 1;
352 dontwait = 1;
353 key_repeat = 0;
354 gettimeofday(&touchStart, NULL);
355 }
356 else if(drag == 1)
357 {
358 if (state == 0)
359 {
360 cursor->GetPos(x, y);
361
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100362#ifdef _EVENT_LOGGING
363 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
364#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100365 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
366
367 touch_and_hold = 0;
368 touch_repeat = 0;
369 if (!key_repeat)
370 dontwait = 0;
371 }
372 state = 0;
373 drag = 0;
374 }
375 }
376 // side mouse button, often used for "back" function
377 else if(ev.code == BTN_SIDE)
378 {
379 if(ev.value == 1)
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100380 kb->KeyDown(KEY_BACK);
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100381 else
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100382 kb->KeyUp(KEY_BACK);
383 } else if (ev.value != 0) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200384 // This is a key press
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100385 if (kb->KeyDown(ev.code)) {
386 // Key repeat is enabled for this key
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200387 key_repeat = 1;
388 touch_and_hold = 0;
389 touch_repeat = 0;
390 dontwait = 1;
391 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700392#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200393 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700394#endif
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100395 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200396 key_repeat = 0;
397 touch_and_hold = 0;
398 touch_repeat = 0;
399 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700400#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200401 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700402#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500403 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100404 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200405 // This is a key release
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100406 kb->KeyUp(ev.code);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200407 key_repeat = 0;
408 touch_and_hold = 0;
409 touch_repeat = 0;
410 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700411#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200412 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700413#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500414 }
415 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100416 else if(ev.type == EV_REL)
417 {
418#ifdef _EVENT_LOGGING
419 LOGERR("EV_REL %d %d\n", ev.code, ev.value);
420#endif
421 if(ev.code == REL_X)
422 cursor->Move(ev.value, 0);
423 else if(ev.code == REL_Y)
424 cursor->Move(0, ev.value);
425
426 if(drag == 1) {
427 cursor->GetPos(x, y);
428#ifdef _EVENT_LOGGING
429 LOGERR("TOUCH_DRAG: %d, %d\n", x, y);
430#endif
431 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
432 state = 1;
433 key_repeat = 0;
434 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500435 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500436 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200437 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400438}
439
Ethan Yonker03a42f62014-08-08 11:03:51 -0500440static void * command_thread(void *cookie)
441{
442 int read_fd;
443 FILE* orsout;
444 char command[1024], result[512];
445
446 LOGINFO("Starting command line thread\n");
447
448 unlink(ORS_INPUT_FILE);
449 if (mkfifo(ORS_INPUT_FILE, 06660) != 0) {
450 LOGINFO("Unable to mkfifo %s\n", ORS_INPUT_FILE);
451 return 0;
452 }
453 unlink(ORS_OUTPUT_FILE);
454 if (mkfifo(ORS_OUTPUT_FILE, 06666) != 0) {
455 LOGINFO("Unable to mkfifo %s\n", ORS_OUTPUT_FILE);
456 unlink(ORS_INPUT_FILE);
457 return 0;
458 }
459
460 read_fd = open(ORS_INPUT_FILE, O_RDONLY);
461 if (read_fd < 0) {
462 LOGINFO("Unable to open %s\n", ORS_INPUT_FILE);
463 unlink(ORS_INPUT_FILE);
464 unlink(ORS_OUTPUT_FILE);
465 return 0;
466 }
467
468 while (!gGuiRunning)
469 sleep(1);
470
471 for (;;) {
472 while (read(read_fd, &command, sizeof(command)) > 0) {
473 command[1022] = '\n';
474 command[1023] = '\0';
475 LOGINFO("Command '%s' received\n", command);
476 orsout = fopen(ORS_OUTPUT_FILE, "w");
477 if (!orsout) {
478 close(read_fd);
479 LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE);
480 unlink(ORS_INPUT_FILE);
481 unlink(ORS_OUTPUT_FILE);
482 return 0;
483 }
484 if (DataManager::GetIntValue("tw_busy") != 0) {
485 strcpy(result, "Failed, operation in progress\n");
486 fprintf(orsout, "%s", result);
487 LOGINFO("Command cannot be performed, operation in progress.\n");
488 } else {
489 if (gui_console_only() == 0) {
490 LOGINFO("Console started successfully\n");
491 gui_set_FILE(orsout);
492 if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) {
493 char* filename = command + 11;
494 if (OpenRecoveryScript::copy_script_file(filename) == 0) {
495 LOGERR("Unable to copy script file\n");
496 } else {
497 OpenRecoveryScript::run_script_file();
498 }
499 } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) {
500 char* varname = command + 4;
501 string temp;
502 DataManager::GetValue(varname, temp);
503 gui_print("%s = %s\n", varname, temp.c_str());
504 } else if (OpenRecoveryScript::Insert_ORS_Command(command)) {
505 OpenRecoveryScript::run_script_file();
506 }
507 gui_set_FILE(NULL);
508 gGuiConsoleTerminate = 1;
509 }
510 }
511 fclose(orsout);
512 }
513 }
514 close(read_fd);
515 LOGINFO("Command thread exiting\n");
516 return 0;
517}
518
Dees_Troy51a0e822012-09-05 15:24:24 -0400519// This special function will return immediately the first time, but then
520// always returns 1/30th of a second (or immediately if called later) from
521// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200522static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400523{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200524 static timespec lastCall;
525 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400526
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200527 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400528 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200529 clock_gettime(CLOCK_MONOTONIC, &lastCall);
530 initialized = 1;
531 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400532 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400533
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200534 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500535 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200536 timespec curTime;
537 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400538
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200539 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500540
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200541 // This is really 30 times per second
542 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500543 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200544 lastCall = curTime;
545 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500546 }
547
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200548 // We need to sleep some period time microseconds
549 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
550 usleep(sleepTime);
551 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400552}
553
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200554static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500555{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200556 // Raise the curtain
557 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500558 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200559 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500560
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200561 PageManager::Render();
562 gr_get_surface(&surface);
563 curtainRaise(surface);
564 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500565 }
566
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200567 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500568
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200569 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500570
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100571#ifdef PRINT_RENDER_TIME
572 timespec start, end;
573 int32_t render_t, flip_t;
574#endif
575
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200576 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500577 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200578 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500579
Ethan Yonker03a42f62014-08-08 11:03:51 -0500580 if (gGuiConsoleRunning) {
581 continue;
582 }
583
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200584 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500585 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200586 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500587
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200588 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100589
590#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200591 if (ret > 1)
592 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500593
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200594 if (ret > 0)
595 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100596#else
597 if (ret > 1)
598 {
599 clock_gettime(CLOCK_MONOTONIC, &start);
600 PageManager::Render();
601 clock_gettime(CLOCK_MONOTONIC, &end);
602 render_t = TWFunc::timespec_diff_ms(start, end);
603
604 flip();
605 clock_gettime(CLOCK_MONOTONIC, &start);
606 flip_t = TWFunc::timespec_diff_ms(end, start);
607
608 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
609 }
610 else if(ret == 1)
611 flip();
612#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500613 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200614 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500615 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200616 pthread_mutex_lock(&gForceRendermutex);
617 gForceRender = 0;
618 pthread_mutex_unlock(&gForceRendermutex);
619 PageManager::Render();
620 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500621 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200622
Dees_Troy6ef66352013-02-21 08:26:57 -0600623 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200624 break;
625 }
626
627 gGuiRunning = 0;
628 return 0;
629}
630
631static int runPage(const char *page_name)
632{
633 gui_changePage(page_name);
634
635 // Raise the curtain
636 if (gCurtain != NULL)
637 {
638 gr_surface surface;
639
640 PageManager::Render();
641 gr_get_surface(&surface);
642 curtainRaise(surface);
643 gr_free_surface(surface);
644 }
645
646 gGuiRunning = 1;
647
648 DataManager::SetValue("tw_loaded", 1);
649
650 for (;;)
651 {
652 loopTimer();
653
654 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600655 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200656 int ret;
657
658 ret = PageManager::Update();
659 if (ret > 1)
660 PageManager::Render();
661
662 if (ret > 0)
663 flip();
664 }
665 else
666 {
667 pthread_mutex_lock(&gForceRendermutex);
668 gForceRender = 0;
669 pthread_mutex_unlock(&gForceRendermutex);
670 PageManager::Render();
671 flip();
672 }
673 if (DataManager::GetIntValue("tw_page_done") != 0)
674 {
675 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600676 break;
677 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500678 }
679
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200680 gGuiRunning = 0;
681 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500682}
683
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200684int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500685{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200686 pthread_mutex_lock(&gForceRendermutex);
687 gForceRender = 1;
688 pthread_mutex_unlock(&gForceRendermutex);
689 return 0;
690}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500691
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692int gui_changePage(std::string newPage)
693{
694 LOGINFO("Set page: '%s'\n", newPage.c_str());
695 PageManager::ChangePage(newPage);
696 pthread_mutex_lock(&gForceRendermutex);
697 gForceRender = 1;
698 pthread_mutex_unlock(&gForceRendermutex);
699 return 0;
700}
701
702int gui_changeOverlay(std::string overlay)
703{
704 PageManager::ChangeOverlay(overlay);
705 pthread_mutex_lock(&gForceRendermutex);
706 gForceRender = 1;
707 pthread_mutex_unlock(&gForceRendermutex);
708 return 0;
709}
710
711int gui_changePackage(std::string newPackage)
712{
713 PageManager::SelectPackage(newPackage);
714 pthread_mutex_lock(&gForceRendermutex);
715 gForceRender = 1;
716 pthread_mutex_unlock(&gForceRendermutex);
717 return 0;
718}
719
720std::string gui_parse_text(string inText)
721{
722 // Copied from std::string GUIText::parseText(void)
723 // This function parses text for DataManager values encompassed by %value% in the XML
724 static int counter = 0;
725 std::string str = inText;
726 size_t pos = 0;
727 size_t next = 0, end = 0;
728
729 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500730 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200731 next = str.find('%', pos);
732 if (next == std::string::npos)
733 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500734
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200735 end = str.find('%', next + 1);
736 if (end == std::string::npos)
737 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200739 // We have a block of data
740 std::string var = str.substr(next + 1,(end - next) - 1);
741 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500742
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200743 if (next + 1 == end)
744 str.insert(next, 1, '%');
745 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500746 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200747 std::string value;
748 if (DataManager::GetValue(var, value) == 0)
749 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500750 }
751
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500753 }
754}
755
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200756extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500757{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500759
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200760 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500761
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200762 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500763 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200764 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500765 ("Unable to locate '/res/images/curtain.jpg'\nDid you set a DEVICE_RESOLUTION in your config files?\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200766 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500767 }
768
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200769 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500770
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200771 ev_init();
772 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500773}
774
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200775extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400776{
Ethan Yonker83e82572014-04-04 10:59:28 -0500777#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200778 int check = 0;
779 DataManager::GetValue(TW_IS_ENCRYPTED, check);
780 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500781 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200782 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400783 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200784 LOGERR("Failed to load base packages.\n");
785 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400786 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200787 else
788 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500789 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400790
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200791 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
792 {
793 std::string theme_path;
794
795 theme_path = DataManager::GetSettingsStoragePath();
796 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400797 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200798 int retry_count = 5;
799 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400800 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200801 usleep(500000);
802 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500803 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200804
805 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500806 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200807 LOGERR("Unable to mount %s during GUI startup.\n",
808 theme_path.c_str());
809 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500810 }
811 }
812
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200813 theme_path += "/TWRP/theme/ui.zip";
814 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500815 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500816#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200817 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500818 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200819 LOGERR("Failed to load base packages.\n");
820 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400821 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500822#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400823 }
824 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500825#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200826 // Set the default package
827 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400828
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200829 gGuiInitialized = 1;
830 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400831
832error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500833 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200834 gGuiInitialized = 0;
835 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400836}
837
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200838extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400839{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200840 if (!gGuiInitialized)
841 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400842
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200843 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400844
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200845 while (gGuiConsoleRunning)
846 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400847
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200848 // Set the default package
849 PageManager::SelectPackage("TWRP");
850
851 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500852 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200853 // Start by spinning off an input handler.
854 pthread_t t;
855 pthread_create(&t, NULL, input_thread, NULL);
856 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000857 }
Ethan Yonker03a42f62014-08-08 11:03:51 -0500858#ifndef TW_OEM_BUILD
859 if (!gCmdLineRunning)
860 {
861 // Start by spinning off an input handler.
862 pthread_t t;
863 pthread_create(&t, NULL, command_thread, NULL);
864 gCmdLineRunning = 1;
865 }
866#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200867 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400868}
869
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200870extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000871{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200872 if (!gGuiInitialized)
873 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000874
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200875 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000876
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200877 while (gGuiConsoleRunning)
878 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000879
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200880 // Set the default package
881 PageManager::SelectPackage("TWRP");
882
883 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500884 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200885 // Start by spinning off an input handler.
886 pthread_t t;
887 pthread_create(&t, NULL, input_thread, NULL);
888 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000889 }
890
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200891 DataManager::SetValue("tw_page_done", 0);
892 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000893}
894
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200895static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400896{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200897 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400898
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200899 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500900 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200901 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400902
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200903 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500904 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200905 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400906
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200907 ret = PageManager::Update();
908 if (ret > 1)
909 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400910
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200911 if (ret > 0)
912 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400913
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200914 if (ret < 0)
915 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500916 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200917 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500918 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200919 pthread_mutex_lock(&gForceRendermutex);
920 gForceRender = 0;
921 pthread_mutex_unlock(&gForceRendermutex);
922 PageManager::Render();
923 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500924 }
925 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200926 gGuiConsoleRunning = 0;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500927 gForceRender = 1; // this will kickstart the GUI to render again
928 PageManager::EndConsole();
929 LOGINFO("Console stopping\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200930 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400931}
932
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200933extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400934{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200935 if (!gGuiInitialized)
936 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400937
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200938 gGuiConsoleTerminate = 0;
939 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400940
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200941 // Start by spinning off an input handler.
942 pthread_t t;
943 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400944
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200945 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400946}