blob: 9b918f0e70b5aa41e2af26458ab89611e1ff6485 [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_Troy51a0e822012-09-05 15:24:24 -040042#include <pixelflinger/pixelflinger.h>
43}
44
45#include "rapidxml.hpp"
46#include "objects.hpp"
47#include "../data.hpp"
48#include "../variables.h"
Dees_Troy5bf43922012-09-07 16:07:55 -040049#include "../partitions.hpp"
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050050#include "../twrp-functions.hpp"
Ethan Yonker03a42f62014-08-08 11:03:51 -050051#include "../openrecoveryscript.hpp"
52#include "../orscmd/orscmd.h"
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050053#include "blanktimer.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040054
Vojtech Boceke5ffcd12014-02-06 21:17:32 +010055// Enable to print render time of each frame to the log file
56//#define PRINT_RENDER_TIME 1
57
Dees_Troy51a0e822012-09-05 15:24:24 -040058const static int CURTAIN_FADE = 32;
59
60using namespace rapidxml;
61
62// Global values
63static gr_surface gCurtain = NULL;
64static int gGuiInitialized = 0;
65static int gGuiConsoleRunning = 0;
66static int gGuiConsoleTerminate = 0;
67static int gForceRender = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050068pthread_mutex_t gForceRendermutex;
Dees_Troyc8b199c2012-09-24 11:55:07 -040069static int gNoAnimation = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +000070static int gGuiInputRunning = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050071blanktimer blankTimer;
Ethan Yonkerfd0439e2015-01-14 11:08:13 -060072int ors_read_fd = -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040073
74// Needed by pages.cpp too
75int gGuiRunning = 0;
76
77static int gRecorder = -1;
78
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020079extern "C" void gr_write_frame_to_file(int fd);
Dees_Troy51a0e822012-09-05 15:24:24 -040080
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020081void flip(void)
Dees_Troy51a0e822012-09-05 15:24:24 -040082{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020083 if (gRecorder != -1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050084 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020085 timespec time;
86 clock_gettime(CLOCK_MONOTONIC, &time);
87 write(gRecorder, &time, sizeof(timespec));
88 gr_write_frame_to_file(gRecorder);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050089 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020090 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -040091}
92
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020093void rapidxml::parse_error_handler(const char *what, void *where)
Dees_Troy51a0e822012-09-05 15:24:24 -040094{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020095 fprintf(stderr, "Parser error: %s\n", what);
96 fprintf(stderr, " Start of string: %s\n",(char *) where);
97 LOGERR("Error parsing XML file.\n");
98 //abort();
Dees_Troy51a0e822012-09-05 15:24:24 -040099}
100
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200101static void curtainSet()
Dees_Troy51a0e822012-09-05 15:24:24 -0400102{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200103 gr_color(0, 0, 0, 255);
104 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
Ethan Yonker751a85e2014-12-12 16:59:10 -0600105 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), TW_X_OFFSET, TW_Y_OFFSET);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200106 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400107}
108
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200109static void curtainRaise(gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400110{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200111 int sy = 0;
112 int h = gr_get_height(gCurtain) - 1;
113 int w = gr_get_width(gCurtain);
114 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400115
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200116 int msw = gr_get_width(surface);
117 int msh = gr_get_height(surface);
118 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400119
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200120 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500121 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200122 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500123 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200124 gr_blit(surface, 0, 0, msw, msh, 0, 0);
125 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
126 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500127 }
128 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200129 gr_blit(surface, 0, 0, msw, msh, 0, 0);
130 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400131}
132
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200133void curtainClose()
Dees_Troy51a0e822012-09-05 15:24:24 -0400134{
135#if 0
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200136 int w = gr_get_width(gCurtain);
137 int h = 1;
138 int sy = gr_get_height(gCurtain) - 1;
139 int fbh = gr_fb_height();
140 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400141
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200142 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500143 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200144 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500145 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200146 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
147 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500148 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200149 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
150 gr_get_height(gCurtain), 0, 0);
151 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400152
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200153 if (gRecorder != -1)
154 close(gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400155
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200156 int fade;
157 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500158 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200159 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
160 gr_get_height(gCurtain), 0, 0);
161 gr_color(0, 0, 0, fade);
162 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
163 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500164 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200165 gr_color(0, 0, 0, 255);
166 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
167 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400168 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500169#else
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200170 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
171 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500172#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400173}
174
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200175static void * input_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400176{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200177 int drag = 0;
178 static int touch_and_hold = 0, dontwait = 0;
179 static int touch_repeat = 0, key_repeat = 0;
180 static int x = 0, y = 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200181 static struct timeval touchStart;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100182 HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100183 MouseCursor *cursor = PageManager::GetMouseCursor();
Dees_Troy51a0e822012-09-05 15:24:24 -0400184
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700185#ifndef TW_NO_SCREEN_TIMEOUT
thatfb759d42015-01-11 12:16:53 +0100186 {
187 string seconds;
188 DataManager::GetValue("tw_screen_timeout_secs", seconds);
189 blankTimer.setTime(atoi(seconds.c_str()));
190 blankTimer.resetTimerAndUnblank();
191 }
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700192#else
thatfb759d42015-01-11 12:16:53 +0100193 LOGINFO("Skipping screen timeout: TW_NO_SCREEN_TIMEOUT is set\n");
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700194#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400195
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200196 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500197 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200198 // wait for the next event
199 struct input_event ev;
200 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400201
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400203
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200204 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500205 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200206 struct timeval curTime;
207 gettimeofday(&curTime, NULL);
208 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400209
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200210 seconds = curTime.tv_sec - touchStart.tv_sec;
211 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500212
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200213 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
214 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500215 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 touch_and_hold = 0;
217 touch_repeat = 1;
218 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400219#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200220 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400221#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200222 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
223 blankTimer.resetTimerAndUnblank();
Dees_Troy51a0e822012-09-05 15:24:24 -0400224 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200225 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500226 {
227#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200228 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500229#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 gettimeofday(&touchStart, NULL);
231 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
232 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500233 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200234 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500235 {
236#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200237 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500238#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200239 gettimeofday(&touchStart, NULL);
240 key_repeat = 2;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100241 kb->KeyRepeat();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200242 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700243
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500244 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500246 {
247#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200248 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500249#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200250 gettimeofday(&touchStart, NULL);
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100251 kb->KeyRepeat();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200252 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500253 }
254 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200255 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500256 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400257
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200258 x = ev.value >> 16;
259 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400260
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200261 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500262 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200263 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500264 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400265#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200266 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400267#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200268 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
269 blankTimer.resetTimerAndUnblank();
270 touch_and_hold = 0;
271 touch_repeat = 0;
272 if (!key_repeat)
273 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400274 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200275 state = 0;
276 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400277 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200278 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500279 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200280 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500281 {
Dees Troy1eba56f2014-04-12 13:09:00 +0000282 if (x != 0 && y != 0) {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500283#ifdef _EVENT_LOGGING
Dees Troy1eba56f2014-04-12 13:09:00 +0000284 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500285#endif
Dees Troy1eba56f2014-04-12 13:09:00 +0000286 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
287 state = 1;
288 drag = 1;
289 touch_and_hold = 1;
290 dontwait = 1;
291 key_repeat = 0;
292 gettimeofday(&touchStart, NULL);
293 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200294 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500295 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200296 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500297 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200298 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500299 {
300#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200301 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500302#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200303 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
304 state = 1;
305 key_repeat = 0;
306 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500307 }
308 }
309 }
310 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200311 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500312 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200313 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500314#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200315 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500316#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100317 // Left mouse button
318 if(ev.code == BTN_LEFT)
319 {
320 if(ev.value == 1)
321 {
322 cursor->GetPos(x, y);
323
324 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
325 state = 1;
326 drag = 1;
327 touch_and_hold = 1;
328 dontwait = 1;
329 key_repeat = 0;
330 gettimeofday(&touchStart, NULL);
331 }
332 else if(drag == 1)
333 {
334 if (state == 0)
335 {
336 cursor->GetPos(x, y);
337
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100338#ifdef _EVENT_LOGGING
339 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
340#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100341 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
342
343 touch_and_hold = 0;
344 touch_repeat = 0;
345 if (!key_repeat)
346 dontwait = 0;
347 }
348 state = 0;
349 drag = 0;
350 }
351 }
352 // side mouse button, often used for "back" function
353 else if(ev.code == BTN_SIDE)
354 {
355 if(ev.value == 1)
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100356 kb->KeyDown(KEY_BACK);
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100357 else
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100358 kb->KeyUp(KEY_BACK);
359 } else if (ev.value != 0) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200360 // This is a key press
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100361 if (kb->KeyDown(ev.code)) {
362 // Key repeat is enabled for this key
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200363 key_repeat = 1;
364 touch_and_hold = 0;
365 touch_repeat = 0;
366 dontwait = 1;
367 gettimeofday(&touchStart, NULL);
368 blankTimer.resetTimerAndUnblank();
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100369 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200370 key_repeat = 0;
371 touch_and_hold = 0;
372 touch_repeat = 0;
373 dontwait = 0;
374 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500375 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100376 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200377 // This is a key release
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100378 kb->KeyUp(ev.code);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200379 key_repeat = 0;
380 touch_and_hold = 0;
381 touch_repeat = 0;
382 dontwait = 0;
383 blankTimer.resetTimerAndUnblank();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500384 }
385 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100386 else if(ev.type == EV_REL)
387 {
388#ifdef _EVENT_LOGGING
389 LOGERR("EV_REL %d %d\n", ev.code, ev.value);
390#endif
391 if(ev.code == REL_X)
392 cursor->Move(ev.value, 0);
393 else if(ev.code == REL_Y)
394 cursor->Move(0, ev.value);
395
396 if(drag == 1) {
397 cursor->GetPos(x, y);
398#ifdef _EVENT_LOGGING
399 LOGERR("TOUCH_DRAG: %d, %d\n", x, y);
400#endif
401 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
402 state = 1;
403 key_repeat = 0;
404 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500405 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500406 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200407 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400408}
409
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600410static void setup_ors_command()
Ethan Yonker03a42f62014-08-08 11:03:51 -0500411{
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600412 ors_read_fd = -1;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500413
414 unlink(ORS_INPUT_FILE);
415 if (mkfifo(ORS_INPUT_FILE, 06660) != 0) {
416 LOGINFO("Unable to mkfifo %s\n", ORS_INPUT_FILE);
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600417 return;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500418 }
419 unlink(ORS_OUTPUT_FILE);
420 if (mkfifo(ORS_OUTPUT_FILE, 06666) != 0) {
421 LOGINFO("Unable to mkfifo %s\n", ORS_OUTPUT_FILE);
422 unlink(ORS_INPUT_FILE);
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600423 return;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500424 }
425
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600426 ors_read_fd = open(ORS_INPUT_FILE, O_RDONLY | O_NONBLOCK);
427 if (ors_read_fd < 0) {
Ethan Yonker03a42f62014-08-08 11:03:51 -0500428 LOGINFO("Unable to open %s\n", ORS_INPUT_FILE);
429 unlink(ORS_INPUT_FILE);
430 unlink(ORS_OUTPUT_FILE);
Ethan Yonker03a42f62014-08-08 11:03:51 -0500431 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600432}
Ethan Yonker03a42f62014-08-08 11:03:51 -0500433
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600434static void ors_command_read()
435{
436 FILE* orsout;
437 char command[1024], result[512];
438 int set_page_done = 0, read_ret = 0;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500439
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600440 if ((read_ret = read(ors_read_fd, &command, sizeof(command))) > 0) {
441 command[1022] = '\n';
442 command[1023] = '\0';
443 LOGINFO("Command '%s' received\n", command);
444 orsout = fopen(ORS_OUTPUT_FILE, "w");
445 if (!orsout) {
446 close(ors_read_fd);
447 ors_read_fd = -1;
448 LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE);
449 unlink(ORS_INPUT_FILE);
450 unlink(ORS_OUTPUT_FILE);
451 return;
452 }
453 if (DataManager::GetIntValue("tw_busy") != 0) {
454 strcpy(result, "Failed, operation in progress\n");
455 fprintf(orsout, "%s", result);
456 LOGINFO("Command cannot be performed, operation in progress.\n");
457 } else {
458 if (gui_console_only() == 0) {
459 LOGINFO("Console started successfully\n");
460 gui_set_FILE(orsout);
461 if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) {
462 char* filename = command + 11;
463 if (OpenRecoveryScript::copy_script_file(filename) == 0) {
464 LOGERR("Unable to copy script file\n");
465 } else {
Ethan Yonker03a42f62014-08-08 11:03:51 -0500466 OpenRecoveryScript::run_script_file();
467 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600468 } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) {
469 char* varname = command + 4;
470 string temp;
471 DataManager::GetValue(varname, temp);
472 gui_print("%s = %s\n", varname, temp.c_str());
473 } else if (strlen(command) > 9 && strncmp(command, "decrypt", 7) == 0) {
474 char* pass = command + 8;
475 gui_print("Attempting to decrypt data partition via command line.\n");
476 if (PartitionManager.Decrypt_Device(pass) == 0) {
477 set_page_done = 1;
478 }
479 } else if (OpenRecoveryScript::Insert_ORS_Command(command)) {
480 OpenRecoveryScript::run_script_file();
Ethan Yonker03a42f62014-08-08 11:03:51 -0500481 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600482 gui_set_FILE(NULL);
483 gGuiConsoleTerminate = 1;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500484 }
Ethan Yonker03a42f62014-08-08 11:03:51 -0500485 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600486 fclose(orsout);
487 LOGINFO("Done reading ORS command from command line\n");
488 if (set_page_done) {
489 DataManager::SetValue("tw_page_done", 1);
490 } else {
491 // The select function will return ready to read and the
492 // read function will return errno 19 no such device unless
493 // we set everything up all over again.
494 close(ors_read_fd);
495 setup_ors_command();
496 }
497 } else {
498 LOGINFO("ORS command line read returned an error: %i, %i, %s\n", read_ret, errno, strerror(errno));
Ethan Yonker03a42f62014-08-08 11:03:51 -0500499 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600500 return;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500501}
502
Dees_Troy51a0e822012-09-05 15:24:24 -0400503// This special function will return immediately the first time, but then
504// always returns 1/30th of a second (or immediately if called later) from
505// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200506static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400507{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200508 static timespec lastCall;
509 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400510
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200511 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400512 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200513 clock_gettime(CLOCK_MONOTONIC, &lastCall);
514 initialized = 1;
515 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400516 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400517
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200518 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500519 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200520 timespec curTime;
521 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400522
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200523 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500524
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200525 // This is really 30 times per second
526 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500527 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200528 lastCall = curTime;
529 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500530 }
531
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200532 // We need to sleep some period time microseconds
533 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
534 usleep(sleepTime);
535 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400536}
537
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600538static int runPages(const char *page_name, const int stop_on_page_done)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500539{
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600540 if (page_name)
541 gui_changePage(page_name);
542
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200543 // Raise the curtain
544 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500545 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200546 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500547
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200548 PageManager::Render();
549 gr_get_surface(&surface);
550 curtainRaise(surface);
551 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500552 }
553
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200554 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500555
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200556 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500557
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100558#ifdef PRINT_RENDER_TIME
559 timespec start, end;
560 int32_t render_t, flip_t;
561#endif
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600562#ifndef TW_OEM_BUILD
563 struct timeval timeout;
564 fd_set fdset;
565 int has_data = 0;
566#endif
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100567
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200568 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500569 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200570 loopTimer();
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600571#ifndef TW_OEM_BUILD
572 if (ors_read_fd > 0) {
573 FD_ZERO(&fdset);
574 FD_SET(ors_read_fd, &fdset);
575 timeout.tv_sec = 0;
576 timeout.tv_usec = 1;
577 has_data = select(ors_read_fd+1, &fdset, NULL, NULL, &timeout);
578 if (has_data > 0) {
579 ors_command_read();
580 }
581 }
582#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500583
Ethan Yonker03a42f62014-08-08 11:03:51 -0500584 if (gGuiConsoleRunning) {
585 continue;
586 }
587
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200588 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500589 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200590 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500591
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200592 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100593
594#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200595 if (ret > 1)
596 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500597
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200598 if (ret > 0)
599 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100600#else
601 if (ret > 1)
602 {
603 clock_gettime(CLOCK_MONOTONIC, &start);
604 PageManager::Render();
605 clock_gettime(CLOCK_MONOTONIC, &end);
606 render_t = TWFunc::timespec_diff_ms(start, end);
607
608 flip();
609 clock_gettime(CLOCK_MONOTONIC, &start);
610 flip_t = TWFunc::timespec_diff_ms(end, start);
611
612 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
613 }
614 else if(ret == 1)
615 flip();
616#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500617 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200618 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500619 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200620 pthread_mutex_lock(&gForceRendermutex);
621 gForceRender = 0;
622 pthread_mutex_unlock(&gForceRendermutex);
623 PageManager::Render();
624 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500625 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200626
thatfb759d42015-01-11 12:16:53 +0100627 blankTimer.checkForTimeout();
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600628 if (stop_on_page_done && DataManager::GetIntValue("tw_page_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200629 {
630 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600631 break;
632 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600633 if (DataManager::GetIntValue("tw_gui_done") != 0)
634 break;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500635 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600636 if (ors_read_fd > 0)
637 close(ors_read_fd);
638 ors_read_fd = -1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200639 gGuiRunning = 0;
640 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500641}
642
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200643int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500644{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200645 pthread_mutex_lock(&gForceRendermutex);
646 gForceRender = 1;
647 pthread_mutex_unlock(&gForceRendermutex);
648 return 0;
649}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500650
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200651int gui_changePage(std::string newPage)
652{
653 LOGINFO("Set page: '%s'\n", newPage.c_str());
654 PageManager::ChangePage(newPage);
655 pthread_mutex_lock(&gForceRendermutex);
656 gForceRender = 1;
657 pthread_mutex_unlock(&gForceRendermutex);
658 return 0;
659}
660
661int gui_changeOverlay(std::string overlay)
662{
663 PageManager::ChangeOverlay(overlay);
664 pthread_mutex_lock(&gForceRendermutex);
665 gForceRender = 1;
666 pthread_mutex_unlock(&gForceRendermutex);
667 return 0;
668}
669
670int gui_changePackage(std::string newPackage)
671{
672 PageManager::SelectPackage(newPackage);
673 pthread_mutex_lock(&gForceRendermutex);
674 gForceRender = 1;
675 pthread_mutex_unlock(&gForceRendermutex);
676 return 0;
677}
678
679std::string gui_parse_text(string inText)
680{
681 // Copied from std::string GUIText::parseText(void)
682 // This function parses text for DataManager values encompassed by %value% in the XML
683 static int counter = 0;
684 std::string str = inText;
685 size_t pos = 0;
686 size_t next = 0, end = 0;
687
688 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500689 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200690 next = str.find('%', pos);
691 if (next == std::string::npos)
692 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500693
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200694 end = str.find('%', next + 1);
695 if (end == std::string::npos)
696 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500697
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200698 // We have a block of data
699 std::string var = str.substr(next + 1,(end - next) - 1);
700 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500701
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200702 if (next + 1 == end)
703 str.insert(next, 1, '%');
704 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500705 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200706 std::string value;
707 if (DataManager::GetValue(var, value) == 0)
708 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500709 }
710
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200711 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500712 }
713}
714
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200715extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500716{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200717 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500718
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200719 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500720 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200721 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500722 ("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 +0200723 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500724 }
725
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200726 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500727
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200728 ev_init();
729 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500730}
731
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200732extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400733{
Ethan Yonker83e82572014-04-04 10:59:28 -0500734#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200735 int check = 0;
736 DataManager::GetValue(TW_IS_ENCRYPTED, check);
737 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200739 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400740 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200741 LOGERR("Failed to load base packages.\n");
742 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400743 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200744 else
745 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500746 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400747
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200748 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
749 {
750 std::string theme_path;
751
752 theme_path = DataManager::GetSettingsStoragePath();
753 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400754 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200755 int retry_count = 5;
756 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400757 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758 usleep(500000);
759 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500760 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200761
762 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500763 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200764 LOGERR("Unable to mount %s during GUI startup.\n",
765 theme_path.c_str());
766 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500767 }
768 }
769
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200770 theme_path += "/TWRP/theme/ui.zip";
771 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500772 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500773#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200774 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500775 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200776 LOGERR("Failed to load base packages.\n");
777 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400778 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500779#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400780 }
781 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500782#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200783 // Set the default package
784 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400785
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200786 gGuiInitialized = 1;
787 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400788
789error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500790 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200791 gGuiInitialized = 0;
792 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400793}
794
Ethan Yonkercf50da52015-01-12 21:59:07 -0600795extern "C" int gui_loadCustomResources(void)
796{
797#ifndef TW_OEM_BUILD
798 if (!PartitionManager.Mount_Settings_Storage(false)) {
799 LOGERR("Unable to mount settings storage during GUI startup.\n");
800 return -1;
801 }
802
803 std::string theme_path = DataManager::GetSettingsStoragePath();
804 theme_path += "/TWRP/theme/ui.zip";
805 // Check for a custom theme
806 if (TWFunc::Path_Exists(theme_path)) {
807 // There is a custom theme, try to load it
808 if (PageManager::ReloadPackage("TWRP", theme_path)) {
809 // Custom theme failed to load, try to load stock theme
810 if (PageManager::ReloadPackage("TWRP", "/res/ui.xml")) {
811 LOGERR("Failed to load base packages.\n");
812 goto error;
813 }
814 }
815 }
816 // Set the default package
817 PageManager::SelectPackage("TWRP");
818#endif
819 return 0;
820
821error:
822 LOGERR("An internal error has occurred: unable to load theme.\n");
823 gGuiInitialized = 0;
824 return -1;
825}
826
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200827extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400828{
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600829 return gui_startPage(NULL, 1, 0);
Dees_Troy51a0e822012-09-05 15:24:24 -0400830}
831
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600832extern "C" int gui_startPage(const char *page_name, const int allow_commands, int stop_on_page_done)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000833{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200834 if (!gGuiInitialized)
835 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000836
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200837 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000838
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200839 while (gGuiConsoleRunning)
840 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000841
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200842 // Set the default package
843 PageManager::SelectPackage("TWRP");
844
845 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500846 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200847 // Start by spinning off an input handler.
848 pthread_t t;
849 pthread_create(&t, NULL, input_thread, NULL);
850 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000851 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600852#ifndef TW_OEM_BUILD
853 if (allow_commands)
854 {
855 if (ors_read_fd < 0)
856 setup_ors_command();
857 } else {
858 if (ors_read_fd >= 0) {
859 close(ors_read_fd);
860 ors_read_fd = -1;
861 }
862 }
863#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200864 DataManager::SetValue("tw_page_done", 0);
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600865 return runPages(page_name, stop_on_page_done);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000866}
867
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200868static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400869{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200870 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400871
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200872 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500873 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200874 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400875
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200876 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500877 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200878 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400879
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200880 ret = PageManager::Update();
881 if (ret > 1)
882 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400883
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200884 if (ret > 0)
885 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400886
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200887 if (ret < 0)
888 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500889 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200890 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500891 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200892 pthread_mutex_lock(&gForceRendermutex);
893 gForceRender = 0;
894 pthread_mutex_unlock(&gForceRendermutex);
895 PageManager::Render();
896 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500897 }
898 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200899 gGuiConsoleRunning = 0;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500900 gForceRender = 1; // this will kickstart the GUI to render again
901 PageManager::EndConsole();
902 LOGINFO("Console stopping\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200903 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400904}
905
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200906extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400907{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200908 if (!gGuiInitialized)
909 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400910
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200911 gGuiConsoleTerminate = 0;
Ethan Yonkerffbd6ff2014-10-22 10:40:40 -0500912
913 if (gGuiConsoleRunning)
914 return 0;
915
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200916 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400917
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200918 // Start by spinning off an input handler.
919 pthread_t t;
920 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400921
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200922 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400923}