blob: 61e5de1fbe211c72fe5c298aaf5bcff628e24e9d [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;
Ethan Yonker03a42f62014-08-08 11:03:51 -050071static int gCmdLineRunning = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050072blanktimer blankTimer;
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 Yonker03a42f62014-08-08 11:03:51 -0500410static void * command_thread(void *cookie)
411{
412 int read_fd;
413 FILE* orsout;
414 char command[1024], result[512];
415
416 LOGINFO("Starting command line thread\n");
417
418 unlink(ORS_INPUT_FILE);
419 if (mkfifo(ORS_INPUT_FILE, 06660) != 0) {
420 LOGINFO("Unable to mkfifo %s\n", ORS_INPUT_FILE);
421 return 0;
422 }
423 unlink(ORS_OUTPUT_FILE);
424 if (mkfifo(ORS_OUTPUT_FILE, 06666) != 0) {
425 LOGINFO("Unable to mkfifo %s\n", ORS_OUTPUT_FILE);
426 unlink(ORS_INPUT_FILE);
427 return 0;
428 }
429
430 read_fd = open(ORS_INPUT_FILE, O_RDONLY);
431 if (read_fd < 0) {
432 LOGINFO("Unable to open %s\n", ORS_INPUT_FILE);
433 unlink(ORS_INPUT_FILE);
434 unlink(ORS_OUTPUT_FILE);
435 return 0;
436 }
437
438 while (!gGuiRunning)
439 sleep(1);
440
441 for (;;) {
442 while (read(read_fd, &command, sizeof(command)) > 0) {
443 command[1022] = '\n';
444 command[1023] = '\0';
445 LOGINFO("Command '%s' received\n", command);
446 orsout = fopen(ORS_OUTPUT_FILE, "w");
447 if (!orsout) {
448 close(read_fd);
449 LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE);
450 unlink(ORS_INPUT_FILE);
451 unlink(ORS_OUTPUT_FILE);
452 return 0;
453 }
454 if (DataManager::GetIntValue("tw_busy") != 0) {
455 strcpy(result, "Failed, operation in progress\n");
456 fprintf(orsout, "%s", result);
457 LOGINFO("Command cannot be performed, operation in progress.\n");
458 } else {
459 if (gui_console_only() == 0) {
460 LOGINFO("Console started successfully\n");
461 gui_set_FILE(orsout);
462 if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) {
463 char* filename = command + 11;
464 if (OpenRecoveryScript::copy_script_file(filename) == 0) {
465 LOGERR("Unable to copy script file\n");
466 } else {
467 OpenRecoveryScript::run_script_file();
468 }
469 } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) {
470 char* varname = command + 4;
471 string temp;
472 DataManager::GetValue(varname, temp);
473 gui_print("%s = %s\n", varname, temp.c_str());
474 } else if (OpenRecoveryScript::Insert_ORS_Command(command)) {
475 OpenRecoveryScript::run_script_file();
476 }
477 gui_set_FILE(NULL);
478 gGuiConsoleTerminate = 1;
479 }
480 }
481 fclose(orsout);
482 }
483 }
484 close(read_fd);
485 LOGINFO("Command thread exiting\n");
486 return 0;
487}
488
Dees_Troy51a0e822012-09-05 15:24:24 -0400489// This special function will return immediately the first time, but then
490// always returns 1/30th of a second (or immediately if called later) from
491// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200492static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400493{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200494 static timespec lastCall;
495 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400496
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200497 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400498 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200499 clock_gettime(CLOCK_MONOTONIC, &lastCall);
500 initialized = 1;
501 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400502 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400503
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200504 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500505 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200506 timespec curTime;
507 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400508
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200509 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500510
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200511 // This is really 30 times per second
512 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500513 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200514 lastCall = curTime;
515 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500516 }
517
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200518 // We need to sleep some period time microseconds
519 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
520 usleep(sleepTime);
521 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400522}
523
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200524static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500525{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200526 // Raise the curtain
527 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500528 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200529 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500530
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200531 PageManager::Render();
532 gr_get_surface(&surface);
533 curtainRaise(surface);
534 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500535 }
536
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200537 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500538
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200539 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500540
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100541#ifdef PRINT_RENDER_TIME
542 timespec start, end;
543 int32_t render_t, flip_t;
544#endif
545
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200546 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500547 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200548 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500549
Ethan Yonker03a42f62014-08-08 11:03:51 -0500550 if (gGuiConsoleRunning) {
551 continue;
552 }
553
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200554 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500555 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200556 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500557
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200558 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100559
560#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200561 if (ret > 1)
562 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500563
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200564 if (ret > 0)
565 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100566#else
567 if (ret > 1)
568 {
569 clock_gettime(CLOCK_MONOTONIC, &start);
570 PageManager::Render();
571 clock_gettime(CLOCK_MONOTONIC, &end);
572 render_t = TWFunc::timespec_diff_ms(start, end);
573
574 flip();
575 clock_gettime(CLOCK_MONOTONIC, &start);
576 flip_t = TWFunc::timespec_diff_ms(end, start);
577
578 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
579 }
580 else if(ret == 1)
581 flip();
582#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500583 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200584 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500585 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200586 pthread_mutex_lock(&gForceRendermutex);
587 gForceRender = 0;
588 pthread_mutex_unlock(&gForceRendermutex);
589 PageManager::Render();
590 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500591 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200592
thatfb759d42015-01-11 12:16:53 +0100593 blankTimer.checkForTimeout();
Dees_Troy6ef66352013-02-21 08:26:57 -0600594 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200595 break;
596 }
597
598 gGuiRunning = 0;
599 return 0;
600}
601
602static int runPage(const char *page_name)
603{
604 gui_changePage(page_name);
605
606 // Raise the curtain
607 if (gCurtain != NULL)
608 {
609 gr_surface surface;
610
611 PageManager::Render();
612 gr_get_surface(&surface);
613 curtainRaise(surface);
614 gr_free_surface(surface);
615 }
616
617 gGuiRunning = 1;
618
619 DataManager::SetValue("tw_loaded", 1);
620
621 for (;;)
622 {
623 loopTimer();
624
625 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600626 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200627 int ret;
628
629 ret = PageManager::Update();
630 if (ret > 1)
631 PageManager::Render();
632
633 if (ret > 0)
634 flip();
635 }
636 else
637 {
638 pthread_mutex_lock(&gForceRendermutex);
639 gForceRender = 0;
640 pthread_mutex_unlock(&gForceRendermutex);
641 PageManager::Render();
642 flip();
643 }
thatfb759d42015-01-11 12:16:53 +0100644 blankTimer.checkForTimeout();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200645 if (DataManager::GetIntValue("tw_page_done") != 0)
646 {
647 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600648 break;
649 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500650 }
651
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200652 gGuiRunning = 0;
653 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500654}
655
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200656int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500657{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200658 pthread_mutex_lock(&gForceRendermutex);
659 gForceRender = 1;
660 pthread_mutex_unlock(&gForceRendermutex);
661 return 0;
662}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500663
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200664int gui_changePage(std::string newPage)
665{
666 LOGINFO("Set page: '%s'\n", newPage.c_str());
667 PageManager::ChangePage(newPage);
668 pthread_mutex_lock(&gForceRendermutex);
669 gForceRender = 1;
670 pthread_mutex_unlock(&gForceRendermutex);
671 return 0;
672}
673
674int gui_changeOverlay(std::string overlay)
675{
676 PageManager::ChangeOverlay(overlay);
677 pthread_mutex_lock(&gForceRendermutex);
678 gForceRender = 1;
679 pthread_mutex_unlock(&gForceRendermutex);
680 return 0;
681}
682
683int gui_changePackage(std::string newPackage)
684{
685 PageManager::SelectPackage(newPackage);
686 pthread_mutex_lock(&gForceRendermutex);
687 gForceRender = 1;
688 pthread_mutex_unlock(&gForceRendermutex);
689 return 0;
690}
691
692std::string gui_parse_text(string inText)
693{
694 // Copied from std::string GUIText::parseText(void)
695 // This function parses text for DataManager values encompassed by %value% in the XML
696 static int counter = 0;
697 std::string str = inText;
698 size_t pos = 0;
699 size_t next = 0, end = 0;
700
701 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500702 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200703 next = str.find('%', pos);
704 if (next == std::string::npos)
705 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500706
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200707 end = str.find('%', next + 1);
708 if (end == std::string::npos)
709 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500710
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200711 // We have a block of data
712 std::string var = str.substr(next + 1,(end - next) - 1);
713 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500714
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200715 if (next + 1 == end)
716 str.insert(next, 1, '%');
717 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500718 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200719 std::string value;
720 if (DataManager::GetValue(var, value) == 0)
721 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500722 }
723
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200724 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500725 }
726}
727
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200728extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500729{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200730 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500731
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200732 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500733 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200734 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500735 ("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 +0200736 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500737 }
738
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200739 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500740
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200741 ev_init();
742 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500743}
744
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200745extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400746{
Ethan Yonker83e82572014-04-04 10:59:28 -0500747#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200748 int check = 0;
749 DataManager::GetValue(TW_IS_ENCRYPTED, check);
750 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500751 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400753 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200754 LOGERR("Failed to load base packages.\n");
755 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400756 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200757 else
758 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500759 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400760
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200761 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
762 {
763 std::string theme_path;
764
765 theme_path = DataManager::GetSettingsStoragePath();
766 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400767 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200768 int retry_count = 5;
769 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400770 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200771 usleep(500000);
772 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500773 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200774
775 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500776 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200777 LOGERR("Unable to mount %s during GUI startup.\n",
778 theme_path.c_str());
779 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500780 }
781 }
782
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200783 theme_path += "/TWRP/theme/ui.zip";
784 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500785 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500786#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200787 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500788 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200789 LOGERR("Failed to load base packages.\n");
790 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400791 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500792#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400793 }
794 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500795#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200796 // Set the default package
797 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400798
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200799 gGuiInitialized = 1;
800 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400801
802error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500803 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200804 gGuiInitialized = 0;
805 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400806}
807
Ethan Yonkercf50da52015-01-12 21:59:07 -0600808extern "C" int gui_loadCustomResources(void)
809{
810#ifndef TW_OEM_BUILD
811 if (!PartitionManager.Mount_Settings_Storage(false)) {
812 LOGERR("Unable to mount settings storage during GUI startup.\n");
813 return -1;
814 }
815
816 std::string theme_path = DataManager::GetSettingsStoragePath();
817 theme_path += "/TWRP/theme/ui.zip";
818 // Check for a custom theme
819 if (TWFunc::Path_Exists(theme_path)) {
820 // There is a custom theme, try to load it
821 if (PageManager::ReloadPackage("TWRP", theme_path)) {
822 // Custom theme failed to load, try to load stock theme
823 if (PageManager::ReloadPackage("TWRP", "/res/ui.xml")) {
824 LOGERR("Failed to load base packages.\n");
825 goto error;
826 }
827 }
828 }
829 // Set the default package
830 PageManager::SelectPackage("TWRP");
831#endif
832 return 0;
833
834error:
835 LOGERR("An internal error has occurred: unable to load theme.\n");
836 gGuiInitialized = 0;
837 return -1;
838}
839
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200840extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400841{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200842 if (!gGuiInitialized)
843 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400844
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200845 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400846
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200847 while (gGuiConsoleRunning)
848 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400849
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200850 // Set the default package
851 PageManager::SelectPackage("TWRP");
852
853 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500854 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200855 // Start by spinning off an input handler.
856 pthread_t t;
857 pthread_create(&t, NULL, input_thread, NULL);
858 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000859 }
Ethan Yonker03a42f62014-08-08 11:03:51 -0500860#ifndef TW_OEM_BUILD
861 if (!gCmdLineRunning)
862 {
863 // Start by spinning off an input handler.
864 pthread_t t;
865 pthread_create(&t, NULL, command_thread, NULL);
866 gCmdLineRunning = 1;
867 }
868#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200869 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400870}
871
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200872extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000873{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200874 if (!gGuiInitialized)
875 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000876
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200877 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000878
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200879 while (gGuiConsoleRunning)
880 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000881
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200882 // Set the default package
883 PageManager::SelectPackage("TWRP");
884
885 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500886 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200887 // Start by spinning off an input handler.
888 pthread_t t;
889 pthread_create(&t, NULL, input_thread, NULL);
890 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000891 }
892
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200893 DataManager::SetValue("tw_page_done", 0);
894 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000895}
896
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200897static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400898{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200899 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400900
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200901 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500902 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200903 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400904
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200905 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500906 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200907 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400908
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200909 ret = PageManager::Update();
910 if (ret > 1)
911 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400912
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200913 if (ret > 0)
914 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400915
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200916 if (ret < 0)
917 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500918 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200919 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500920 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200921 pthread_mutex_lock(&gForceRendermutex);
922 gForceRender = 0;
923 pthread_mutex_unlock(&gForceRendermutex);
924 PageManager::Render();
925 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500926 }
927 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200928 gGuiConsoleRunning = 0;
Ethan Yonker03a42f62014-08-08 11:03:51 -0500929 gForceRender = 1; // this will kickstart the GUI to render again
930 PageManager::EndConsole();
931 LOGINFO("Console stopping\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200932 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400933}
934
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200935extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400936{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200937 if (!gGuiInitialized)
938 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400939
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200940 gGuiConsoleTerminate = 0;
Ethan Yonkerffbd6ff2014-10-22 10:40:40 -0500941
942 if (gGuiConsoleRunning)
943 return 0;
944
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200945 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400946
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200947 // Start by spinning off an input handler.
948 pthread_t t;
949 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400950
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200951 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400952}