blob: 6b3b9c99548cf46ebb9093692cc586345707f7d7 [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"
Ethan Yonker04536952015-01-27 08:41:28 -060054#include "../tw_atomic.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040055
Vojtech Boceke5ffcd12014-02-06 21:17:32 +010056// Enable to print render time of each frame to the log file
57//#define PRINT_RENDER_TIME 1
58
Dees_Troy51a0e822012-09-05 15:24:24 -040059const static int CURTAIN_FADE = 32;
60
61using namespace rapidxml;
62
63// Global values
64static gr_surface gCurtain = NULL;
65static int gGuiInitialized = 0;
Ethan Yonker04536952015-01-27 08:41:28 -060066static TWAtomicInt gGuiConsoleRunning;
67static TWAtomicInt gGuiConsoleTerminate;
68static TWAtomicInt gForceRender;
69const 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);
Ethan Yonker04536952015-01-27 08:41:28 -0600483 gGuiConsoleTerminate.set_value(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 Yonker04536952015-01-27 08:41:28 -0600584 if (gGuiConsoleRunning.get_value()) {
Ethan Yonker03a42f62014-08-08 11:03:51 -0500585 continue;
586 }
587
Ethan Yonker04536952015-01-27 08:41:28 -0600588 if (!gForceRender.get_value())
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 {
Ethan Yonker04536952015-01-27 08:41:28 -0600620 gForceRender.set_value(0);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200621 PageManager::Render();
622 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500623 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200624
thatfb759d42015-01-11 12:16:53 +0100625 blankTimer.checkForTimeout();
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600626 if (stop_on_page_done && DataManager::GetIntValue("tw_page_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200627 {
628 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600629 break;
630 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600631 if (DataManager::GetIntValue("tw_gui_done") != 0)
632 break;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500633 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600634 if (ors_read_fd > 0)
635 close(ors_read_fd);
636 ors_read_fd = -1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200637 gGuiRunning = 0;
638 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500639}
640
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200641int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500642{
Ethan Yonker04536952015-01-27 08:41:28 -0600643 gForceRender.set_value(1);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200644 return 0;
645}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500646
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200647int gui_changePage(std::string newPage)
648{
649 LOGINFO("Set page: '%s'\n", newPage.c_str());
650 PageManager::ChangePage(newPage);
Ethan Yonker04536952015-01-27 08:41:28 -0600651 gForceRender.set_value(1);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200652 return 0;
653}
654
655int gui_changeOverlay(std::string overlay)
656{
657 PageManager::ChangeOverlay(overlay);
Ethan Yonker04536952015-01-27 08:41:28 -0600658 gForceRender.set_value(1);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200659 return 0;
660}
661
662int gui_changePackage(std::string newPackage)
663{
664 PageManager::SelectPackage(newPackage);
Ethan Yonker04536952015-01-27 08:41:28 -0600665 gForceRender.set_value(1);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200666 return 0;
667}
668
669std::string gui_parse_text(string inText)
670{
671 // Copied from std::string GUIText::parseText(void)
672 // This function parses text for DataManager values encompassed by %value% in the XML
673 static int counter = 0;
674 std::string str = inText;
675 size_t pos = 0;
676 size_t next = 0, end = 0;
677
678 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500679 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200680 next = str.find('%', pos);
681 if (next == std::string::npos)
682 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500683
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200684 end = str.find('%', next + 1);
685 if (end == std::string::npos)
686 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500687
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200688 // We have a block of data
689 std::string var = str.substr(next + 1,(end - next) - 1);
690 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500691
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692 if (next + 1 == end)
693 str.insert(next, 1, '%');
694 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500695 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200696 std::string value;
697 if (DataManager::GetValue(var, value) == 0)
698 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500699 }
700
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200701 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500702 }
703}
704
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200705extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500706{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200707 gr_init();
Dees Troy3454ade2015-01-20 19:21:04 +0000708 std::string curtain_path = TWRES "images/curtain.jpg";
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500709
Dees Troy3454ade2015-01-20 19:21:04 +0000710 if (res_create_surface(curtain_path.c_str(), &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500711 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200712 printf
Dees Troy3454ade2015-01-20 19:21:04 +0000713 ("Unable to locate '%s'\nDid you set a DEVICE_RESOLUTION in your config files?\n", curtain_path.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200714 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500715 }
716
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200717 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500718
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200719 ev_init();
720 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500721}
722
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200723extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400724{
Ethan Yonker83e82572014-04-04 10:59:28 -0500725#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200726 int check = 0;
727 DataManager::GetValue(TW_IS_ENCRYPTED, check);
Dees Troy3454ade2015-01-20 19:21:04 +0000728
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200729 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500730 {
Dees Troy3454ade2015-01-20 19:21:04 +0000731 if (PageManager::LoadPackage("TWRP", TWRES "ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400732 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200733 LOGERR("Failed to load base packages.\n");
734 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400735 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200736 else
737 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400739
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200740 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
741 {
742 std::string theme_path;
743
744 theme_path = DataManager::GetSettingsStoragePath();
745 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400746 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200747 int retry_count = 5;
748 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400749 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200750 usleep(500000);
751 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500752 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200753
754 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500755 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200756 LOGERR("Unable to mount %s during GUI startup.\n",
757 theme_path.c_str());
758 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500759 }
760 }
761
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200762 theme_path += "/TWRP/theme/ui.zip";
763 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500764 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500765#endif // ifndef TW_OEM_BUILD
Dees Troy3454ade2015-01-20 19:21:04 +0000766 if (PageManager::LoadPackage("TWRP", TWRES "ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500767 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200768 LOGERR("Failed to load base packages.\n");
769 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400770 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500771#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400772 }
773 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500774#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200775 // Set the default package
776 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400777
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200778 gGuiInitialized = 1;
779 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400780
781error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500782 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200783 gGuiInitialized = 0;
784 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400785}
786
Ethan Yonkercf50da52015-01-12 21:59:07 -0600787extern "C" int gui_loadCustomResources(void)
788{
789#ifndef TW_OEM_BUILD
790 if (!PartitionManager.Mount_Settings_Storage(false)) {
791 LOGERR("Unable to mount settings storage during GUI startup.\n");
792 return -1;
793 }
794
795 std::string theme_path = DataManager::GetSettingsStoragePath();
796 theme_path += "/TWRP/theme/ui.zip";
797 // Check for a custom theme
798 if (TWFunc::Path_Exists(theme_path)) {
799 // There is a custom theme, try to load it
800 if (PageManager::ReloadPackage("TWRP", theme_path)) {
801 // Custom theme failed to load, try to load stock theme
Dees Troy3454ade2015-01-20 19:21:04 +0000802 if (PageManager::ReloadPackage("TWRP", TWRES "ui.xml")) {
Ethan Yonkercf50da52015-01-12 21:59:07 -0600803 LOGERR("Failed to load base packages.\n");
804 goto error;
805 }
806 }
807 }
808 // Set the default package
809 PageManager::SelectPackage("TWRP");
810#endif
811 return 0;
812
813error:
814 LOGERR("An internal error has occurred: unable to load theme.\n");
815 gGuiInitialized = 0;
816 return -1;
817}
818
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200819extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400820{
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600821 return gui_startPage(NULL, 1, 0);
Dees_Troy51a0e822012-09-05 15:24:24 -0400822}
823
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600824extern "C" int gui_startPage(const char *page_name, const int allow_commands, int stop_on_page_done)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000825{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200826 if (!gGuiInitialized)
827 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000828
Ethan Yonker04536952015-01-27 08:41:28 -0600829 gGuiConsoleTerminate.set_value(1);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000830
Ethan Yonker04536952015-01-27 08:41:28 -0600831 while (gGuiConsoleRunning.get_value())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200832 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000833
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200834 // Set the default package
835 PageManager::SelectPackage("TWRP");
836
837 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500838 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200839 // Start by spinning off an input handler.
840 pthread_t t;
841 pthread_create(&t, NULL, input_thread, NULL);
842 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000843 }
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600844#ifndef TW_OEM_BUILD
845 if (allow_commands)
846 {
847 if (ors_read_fd < 0)
848 setup_ors_command();
849 } else {
850 if (ors_read_fd >= 0) {
851 close(ors_read_fd);
852 ors_read_fd = -1;
853 }
854 }
855#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200856 DataManager::SetValue("tw_page_done", 0);
Ethan Yonkerfd0439e2015-01-14 11:08:13 -0600857 return runPages(page_name, stop_on_page_done);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000858}
859
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200860static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400861{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200862 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400863
Ethan Yonker04536952015-01-27 08:41:28 -0600864 while (!gGuiConsoleTerminate.get_value())
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500865 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200866 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400867
Ethan Yonker04536952015-01-27 08:41:28 -0600868 if (!gForceRender.get_value())
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500869 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200870 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400871
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200872 ret = PageManager::Update();
873 if (ret > 1)
874 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400875
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200876 if (ret > 0)
877 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400878
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200879 if (ret < 0)
880 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500881 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200882 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500883 {
Ethan Yonker04536952015-01-27 08:41:28 -0600884 gForceRender.set_value(0);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200885 PageManager::Render();
886 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500887 }
888 }
Ethan Yonker04536952015-01-27 08:41:28 -0600889 gGuiConsoleRunning.set_value(0);
890 gForceRender.set_value(1); // this will kickstart the GUI to render again
Ethan Yonker03a42f62014-08-08 11:03:51 -0500891 PageManager::EndConsole();
892 LOGINFO("Console stopping\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200893 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400894}
895
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200896extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400897{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200898 if (!gGuiInitialized)
899 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400900
Ethan Yonker04536952015-01-27 08:41:28 -0600901 gGuiConsoleTerminate.set_value(0);
Ethan Yonkerffbd6ff2014-10-22 10:40:40 -0500902
Ethan Yonker04536952015-01-27 08:41:28 -0600903 if (gGuiConsoleRunning.get_value())
Ethan Yonkerffbd6ff2014-10-22 10:40:40 -0500904 return 0;
905
Ethan Yonker04536952015-01-27 08:41:28 -0600906 gGuiConsoleRunning.set_value(1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400907
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200908 // Start by spinning off an input handler.
909 pthread_t t;
910 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400911
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200912 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400913}