blob: 0164ec393759483bd7c9e30426be673789560479 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/*
Dees Troy3be70a82013-10-22 14:25:12 +00002 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
Dees_Troy51a0e822012-09-05 15:24:24 -040018
19#include <linux/input.h>
20#include <pthread.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <errno.h>
24#include <stdlib.h>
25#include <string.h>
26#include <fcntl.h>
27#include <sys/reboot.h>
28#include <sys/stat.h>
29#include <sys/time.h>
30#include <sys/mman.h>
31#include <sys/types.h>
32#include <sys/ioctl.h>
33#include <sys/mount.h>
34#include <time.h>
35#include <unistd.h>
36#include <stdlib.h>
37
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050038extern "C"
39{
Dees_Troy2673cec2013-04-02 20:22:16 +000040#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040041#include "../minuitwrp/minui.h"
Dees Troyb7ae0982013-09-10 20:47:35 +000042#ifdef HAVE_SELINUX
Dees_Troy51a0e822012-09-05 15:24:24 -040043#include "../minzip/Zip.h"
Dees Troyb7ae0982013-09-10 20:47:35 +000044#else
45#include "../minzipold/Zip.h"
46#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040047#include <pixelflinger/pixelflinger.h>
48}
49
50#include "rapidxml.hpp"
51#include "objects.hpp"
52#include "../data.hpp"
53#include "../variables.h"
Dees_Troy5bf43922012-09-07 16:07:55 -040054#include "../partitions.hpp"
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050055#include "../twrp-functions.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070056#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050057#include "blanktimer.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070058#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040059
Vojtech Boceke5ffcd12014-02-06 21:17:32 +010060// Enable to print render time of each frame to the log file
61//#define PRINT_RENDER_TIME 1
62
Dees_Troy51a0e822012-09-05 15:24:24 -040063const static int CURTAIN_FADE = 32;
64
65using namespace rapidxml;
66
67// Global values
68static gr_surface gCurtain = NULL;
69static int gGuiInitialized = 0;
70static int gGuiConsoleRunning = 0;
71static int gGuiConsoleTerminate = 0;
72static int gForceRender = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050073pthread_mutex_t gForceRendermutex;
Dees_Troyc8b199c2012-09-24 11:55:07 -040074static int gNoAnimation = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +000075static int gGuiInputRunning = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070076#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050077blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070078#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040079
80// Needed by pages.cpp too
81int gGuiRunning = 0;
82
83static int gRecorder = -1;
84
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020085extern "C" void gr_write_frame_to_file(int fd);
Dees_Troy51a0e822012-09-05 15:24:24 -040086
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020087void flip(void)
Dees_Troy51a0e822012-09-05 15:24:24 -040088{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020089 if (gRecorder != -1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050090 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020091 timespec time;
92 clock_gettime(CLOCK_MONOTONIC, &time);
93 write(gRecorder, &time, sizeof(timespec));
94 gr_write_frame_to_file(gRecorder);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050095 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020096 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -040097}
98
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020099void rapidxml::parse_error_handler(const char *what, void *where)
Dees_Troy51a0e822012-09-05 15:24:24 -0400100{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200101 fprintf(stderr, "Parser error: %s\n", what);
102 fprintf(stderr, " Start of string: %s\n",(char *) where);
103 LOGERR("Error parsing XML file.\n");
104 //abort();
Dees_Troy51a0e822012-09-05 15:24:24 -0400105}
106
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200107static void curtainSet()
Dees_Troy51a0e822012-09-05 15:24:24 -0400108{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200109 gr_color(0, 0, 0, 255);
110 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
111 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
112 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400113}
114
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200115static void curtainRaise(gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400116{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200117 int sy = 0;
118 int h = gr_get_height(gCurtain) - 1;
119 int w = gr_get_width(gCurtain);
120 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400121
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200122 int msw = gr_get_width(surface);
123 int msh = gr_get_height(surface);
124 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400125
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200126 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500127 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200128 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500129 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200130 gr_blit(surface, 0, 0, msw, msh, 0, 0);
131 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
132 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500133 }
134 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200135 gr_blit(surface, 0, 0, msw, msh, 0, 0);
136 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400137}
138
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200139void curtainClose()
Dees_Troy51a0e822012-09-05 15:24:24 -0400140{
141#if 0
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200142 int w = gr_get_width(gCurtain);
143 int h = 1;
144 int sy = gr_get_height(gCurtain) - 1;
145 int fbh = gr_fb_height();
146 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400147
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200148 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500149 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200150 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500151 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200152 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
153 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500154 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200155 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
156 gr_get_height(gCurtain), 0, 0);
157 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400158
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200159 if (gRecorder != -1)
160 close(gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400161
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200162 int fade;
163 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500164 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200165 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
166 gr_get_height(gCurtain), 0, 0);
167 gr_color(0, 0, 0, fade);
168 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
169 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500170 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200171 gr_color(0, 0, 0, 255);
172 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
173 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400174 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500175#else
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200176 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
177 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500178#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400179}
180
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200181static void * input_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400182{
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700183
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200184 int drag = 0;
185 static int touch_and_hold = 0, dontwait = 0;
186 static int touch_repeat = 0, key_repeat = 0;
187 static int x = 0, y = 0;
188 static int lshift = 0, rshift = 0;
189 static struct timeval touchStart;
190 HardwareKeyboard kb;
191 string seconds;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100192 MouseCursor *cursor = PageManager::GetMouseCursor();
Dees_Troy51a0e822012-09-05 15:24:24 -0400193
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700194#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200195 //start screen timeout threads
196 blankTimer.setTimerThread();
197 DataManager::GetValue("tw_screen_timeout_secs", seconds);
198 blankTimer.setTime(atoi(seconds.c_str()));
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700199#else
200 LOGINFO("Skipping screen timeout threads: TW_NO_SCREEN_TIMEOUT is set\n");
201#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400202
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200203 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500204 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 // wait for the next event
206 struct input_event ev;
207 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400208
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200209 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400210
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200211 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500212 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200213 struct timeval curTime;
214 gettimeofday(&curTime, NULL);
215 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400216
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200217 seconds = curTime.tv_sec - touchStart.tv_sec;
218 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500219
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200220 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
221 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500222 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 touch_and_hold = 0;
224 touch_repeat = 1;
225 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400226#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200227 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400228#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200229 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700230#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200231 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700232#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400233 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200234 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500235 {
236#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200237 LOGERR("TOUCH_REPEAT: %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 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700241#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200242 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700243#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500244 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500246 {
247#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200248 LOGERR("KEY_HOLD: %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);
251 key_repeat = 2;
252 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700253#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200254 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700255#endif
256
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500257 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200258 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500259 {
260#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200261 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500262#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200263 gettimeofday(&touchStart, NULL);
264 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700265#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200266 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700267#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500268 }
269 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200270 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500271 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400272
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200273 x = ev.value >> 16;
274 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400275
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200276 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500277 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200278 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500279 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400280#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200281 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400282#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200283 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700284#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200285 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700286#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200287 touch_and_hold = 0;
288 touch_repeat = 0;
289 if (!key_repeat)
290 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400291 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200292 state = 0;
293 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400294 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200295 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500296 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200297 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500298 {
Dees Troy1eba56f2014-04-12 13:09:00 +0000299 if (x != 0 && y != 0) {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500300#ifdef _EVENT_LOGGING
Dees Troy1eba56f2014-04-12 13:09:00 +0000301 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500302#endif
Dees Troy1eba56f2014-04-12 13:09:00 +0000303 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
304 state = 1;
305 drag = 1;
306 touch_and_hold = 1;
307 dontwait = 1;
308 key_repeat = 0;
309 gettimeofday(&touchStart, NULL);
310 }
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700311#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200312 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700313#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500314 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200315 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500316 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200317 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500318 {
319#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200320 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500321#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200322 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
323 state = 1;
324 key_repeat = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700325#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200326 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700327#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500328 }
329 }
330 }
331 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200332 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500333 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200334 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500335#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200336 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500337#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100338 // Left mouse button
339 if(ev.code == BTN_LEFT)
340 {
341 if(ev.value == 1)
342 {
343 cursor->GetPos(x, y);
344
345 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
346 state = 1;
347 drag = 1;
348 touch_and_hold = 1;
349 dontwait = 1;
350 key_repeat = 0;
351 gettimeofday(&touchStart, NULL);
352 }
353 else if(drag == 1)
354 {
355 if (state == 0)
356 {
357 cursor->GetPos(x, y);
358
359 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
360
361 touch_and_hold = 0;
362 touch_repeat = 0;
363 if (!key_repeat)
364 dontwait = 0;
365 }
366 state = 0;
367 drag = 0;
368 }
369 }
370 // side mouse button, often used for "back" function
371 else if(ev.code == BTN_SIDE)
372 {
373 if(ev.value == 1)
374 kb.KeyDown(KEY_BACK);
375 else
376 kb.KeyUp(KEY_BACK);
377 }
378 else if (ev.value != 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500379 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200380 // This is a key press
381 if (kb.KeyDown(ev.code))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500382 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200383 key_repeat = 1;
384 touch_and_hold = 0;
385 touch_repeat = 0;
386 dontwait = 1;
387 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700388#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200389 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700390#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500391 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200392 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500393 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200394 key_repeat = 0;
395 touch_and_hold = 0;
396 touch_repeat = 0;
397 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700398#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200399 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700400#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500401 }
402 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200403 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500404 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200405 // This is a key release
406 kb.KeyUp(ev.code);
407 key_repeat = 0;
408 touch_and_hold = 0;
409 touch_repeat = 0;
410 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700411#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200412 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700413#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500414 }
415 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100416 else if(ev.type == EV_REL)
417 {
418#ifdef _EVENT_LOGGING
419 LOGERR("EV_REL %d %d\n", ev.code, ev.value);
420#endif
421 if(ev.code == REL_X)
422 cursor->Move(ev.value, 0);
423 else if(ev.code == REL_Y)
424 cursor->Move(0, ev.value);
425
426 if(drag == 1) {
427 cursor->GetPos(x, y);
428#ifdef _EVENT_LOGGING
429 LOGERR("TOUCH_DRAG: %d, %d\n", x, y);
430#endif
431 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
432 state = 1;
433 key_repeat = 0;
434 }
435 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500436 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200437 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400438}
439
440// This special function will return immediately the first time, but then
441// always returns 1/30th of a second (or immediately if called later) from
442// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200443static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400444{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200445 static timespec lastCall;
446 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400447
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200448 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400449 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200450 clock_gettime(CLOCK_MONOTONIC, &lastCall);
451 initialized = 1;
452 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400453 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400454
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200455 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500456 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200457 timespec curTime;
458 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400459
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200460 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500461
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200462 // This is really 30 times per second
463 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500464 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200465 lastCall = curTime;
466 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500467 }
468
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200469 // We need to sleep some period time microseconds
470 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
471 usleep(sleepTime);
472 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400473}
474
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200475static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500476{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200477 // Raise the curtain
478 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500479 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200480 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500481
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200482 PageManager::Render();
483 gr_get_surface(&surface);
484 curtainRaise(surface);
485 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500486 }
487
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200488 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500489
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200490 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500491
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100492#ifdef PRINT_RENDER_TIME
493 timespec start, end;
494 int32_t render_t, flip_t;
495#endif
496
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200497 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500498 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200499 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500500
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200501 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500502 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200503 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500504
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200505 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100506
507#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200508 if (ret > 1)
509 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500510
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200511 if (ret > 0)
512 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100513#else
514 if (ret > 1)
515 {
516 clock_gettime(CLOCK_MONOTONIC, &start);
517 PageManager::Render();
518 clock_gettime(CLOCK_MONOTONIC, &end);
519 render_t = TWFunc::timespec_diff_ms(start, end);
520
521 flip();
522 clock_gettime(CLOCK_MONOTONIC, &start);
523 flip_t = TWFunc::timespec_diff_ms(end, start);
524
525 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
526 }
527 else if(ret == 1)
528 flip();
529#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500530 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200531 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500532 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200533 pthread_mutex_lock(&gForceRendermutex);
534 gForceRender = 0;
535 pthread_mutex_unlock(&gForceRendermutex);
536 PageManager::Render();
537 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500538 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200539
Dees_Troy6ef66352013-02-21 08:26:57 -0600540 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200541 break;
542 }
543
544 gGuiRunning = 0;
545 return 0;
546}
547
548static int runPage(const char *page_name)
549{
550 gui_changePage(page_name);
551
552 // Raise the curtain
553 if (gCurtain != NULL)
554 {
555 gr_surface surface;
556
557 PageManager::Render();
558 gr_get_surface(&surface);
559 curtainRaise(surface);
560 gr_free_surface(surface);
561 }
562
563 gGuiRunning = 1;
564
565 DataManager::SetValue("tw_loaded", 1);
566
567 for (;;)
568 {
569 loopTimer();
570
571 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600572 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200573 int ret;
574
575 ret = PageManager::Update();
576 if (ret > 1)
577 PageManager::Render();
578
579 if (ret > 0)
580 flip();
581 }
582 else
583 {
584 pthread_mutex_lock(&gForceRendermutex);
585 gForceRender = 0;
586 pthread_mutex_unlock(&gForceRendermutex);
587 PageManager::Render();
588 flip();
589 }
590 if (DataManager::GetIntValue("tw_page_done") != 0)
591 {
592 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600593 break;
594 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500595 }
596
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200597 gGuiRunning = 0;
598 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500599}
600
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200601int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500602{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200603 pthread_mutex_lock(&gForceRendermutex);
604 gForceRender = 1;
605 pthread_mutex_unlock(&gForceRendermutex);
606 return 0;
607}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500608
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200609int gui_changePage(std::string newPage)
610{
611 LOGINFO("Set page: '%s'\n", newPage.c_str());
612 PageManager::ChangePage(newPage);
613 pthread_mutex_lock(&gForceRendermutex);
614 gForceRender = 1;
615 pthread_mutex_unlock(&gForceRendermutex);
616 return 0;
617}
618
619int gui_changeOverlay(std::string overlay)
620{
621 PageManager::ChangeOverlay(overlay);
622 pthread_mutex_lock(&gForceRendermutex);
623 gForceRender = 1;
624 pthread_mutex_unlock(&gForceRendermutex);
625 return 0;
626}
627
628int gui_changePackage(std::string newPackage)
629{
630 PageManager::SelectPackage(newPackage);
631 pthread_mutex_lock(&gForceRendermutex);
632 gForceRender = 1;
633 pthread_mutex_unlock(&gForceRendermutex);
634 return 0;
635}
636
637std::string gui_parse_text(string inText)
638{
639 // Copied from std::string GUIText::parseText(void)
640 // This function parses text for DataManager values encompassed by %value% in the XML
641 static int counter = 0;
642 std::string str = inText;
643 size_t pos = 0;
644 size_t next = 0, end = 0;
645
646 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500647 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200648 next = str.find('%', pos);
649 if (next == std::string::npos)
650 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500651
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200652 end = str.find('%', next + 1);
653 if (end == std::string::npos)
654 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500655
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200656 // We have a block of data
657 std::string var = str.substr(next + 1,(end - next) - 1);
658 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500659
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200660 if (next + 1 == end)
661 str.insert(next, 1, '%');
662 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500663 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200664 std::string value;
665 if (DataManager::GetValue(var, value) == 0)
666 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500667 }
668
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200669 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500670 }
671}
672
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200673extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500674{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200675 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500676
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200677 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500678
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200679 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500680 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200681 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500682 ("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 +0200683 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500684 }
685
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200686 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500687
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200688 ev_init();
689 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500690}
691
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400693{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200694 // unlink("/sdcard/video.last");
695 // rename("/sdcard/video.bin", "/sdcard/video.last");
696 // gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
Ethan Yonker83e82572014-04-04 10:59:28 -0500697#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200698 int check = 0;
699 DataManager::GetValue(TW_IS_ENCRYPTED, check);
700 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500701 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200702 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400703 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200704 LOGERR("Failed to load base packages.\n");
705 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400706 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200707 else
708 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500709 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400710
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200711 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
712 {
713 std::string theme_path;
714
715 theme_path = DataManager::GetSettingsStoragePath();
716 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400717 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200718 int retry_count = 5;
719 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400720 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200721 usleep(500000);
722 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500723 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200724
725 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500726 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200727 LOGERR("Unable to mount %s during GUI startup.\n",
728 theme_path.c_str());
729 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500730 }
731 }
732
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200733 theme_path += "/TWRP/theme/ui.zip";
734 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500735 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500736#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200737 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200739 LOGERR("Failed to load base packages.\n");
740 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400741 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500742#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400743 }
744 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500745#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200746 // Set the default package
747 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400748
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200749 gGuiInitialized = 1;
750 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400751
752error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500753 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200754 gGuiInitialized = 0;
755 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400756}
757
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400759{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200760 if (!gGuiInitialized)
761 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400762
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200763 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400764
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200765 while (gGuiConsoleRunning)
766 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400767
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200768 // Set the default package
769 PageManager::SelectPackage("TWRP");
770
771 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500772 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200773 // Start by spinning off an input handler.
774 pthread_t t;
775 pthread_create(&t, NULL, input_thread, NULL);
776 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000777 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400778
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200779 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400780}
781
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200782extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000783{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200784 if (!gGuiInitialized)
785 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000786
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200787 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000788
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200789 while (gGuiConsoleRunning)
790 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000791
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200792 // Set the default package
793 PageManager::SelectPackage("TWRP");
794
795 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500796 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200797 // Start by spinning off an input handler.
798 pthread_t t;
799 pthread_create(&t, NULL, input_thread, NULL);
800 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000801 }
802
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200803 DataManager::SetValue("tw_page_done", 0);
804 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000805}
806
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200807static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400808{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200809 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400810
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200811 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500812 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200813 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400814
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200815 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500816 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200817 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400818
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200819 ret = PageManager::Update();
820 if (ret > 1)
821 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400822
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200823 if (ret > 0)
824 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400825
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200826 if (ret < 0)
827 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500828 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200829 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500830 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200831 pthread_mutex_lock(&gForceRendermutex);
832 gForceRender = 0;
833 pthread_mutex_unlock(&gForceRendermutex);
834 PageManager::Render();
835 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500836 }
837 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200838 gGuiConsoleRunning = 0;
839 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400840}
841
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200842extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400843{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200844 if (!gGuiInitialized)
845 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400846
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200847 gGuiConsoleTerminate = 0;
848 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400849
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200850 // Start by spinning off an input handler.
851 pthread_t t;
852 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400853
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200854 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400855}