blob: b7680909cdfdc98cd88edc151eba88e29a0b53fd [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;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200190 string seconds;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100191 HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
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;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100252 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);
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100264 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
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100359#ifdef _EVENT_LOGGING
360 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
361#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100362 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
363
364 touch_and_hold = 0;
365 touch_repeat = 0;
366 if (!key_repeat)
367 dontwait = 0;
368 }
369 state = 0;
370 drag = 0;
371 }
372 }
373 // side mouse button, often used for "back" function
374 else if(ev.code == BTN_SIDE)
375 {
376 if(ev.value == 1)
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100377 kb->KeyDown(KEY_BACK);
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100378 else
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100379 kb->KeyUp(KEY_BACK);
380 } else if (ev.value != 0) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200381 // This is a key press
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100382 if (kb->KeyDown(ev.code)) {
383 // Key repeat is enabled for this key
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200384 key_repeat = 1;
385 touch_and_hold = 0;
386 touch_repeat = 0;
387 dontwait = 1;
388 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700389#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200390 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700391#endif
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100392 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200393 key_repeat = 0;
394 touch_and_hold = 0;
395 touch_repeat = 0;
396 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700397#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200398 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700399#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500400 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100401 } else {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200402 // This is a key release
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100403 kb->KeyUp(ev.code);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200404 key_repeat = 0;
405 touch_and_hold = 0;
406 touch_repeat = 0;
407 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700408#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200409 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700410#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500411 }
412 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100413 else if(ev.type == EV_REL)
414 {
415#ifdef _EVENT_LOGGING
416 LOGERR("EV_REL %d %d\n", ev.code, ev.value);
417#endif
418 if(ev.code == REL_X)
419 cursor->Move(ev.value, 0);
420 else if(ev.code == REL_Y)
421 cursor->Move(0, ev.value);
422
423 if(drag == 1) {
424 cursor->GetPos(x, y);
425#ifdef _EVENT_LOGGING
426 LOGERR("TOUCH_DRAG: %d, %d\n", x, y);
427#endif
428 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
429 state = 1;
430 key_repeat = 0;
431 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500432 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500433 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200434 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400435}
436
437// This special function will return immediately the first time, but then
438// always returns 1/30th of a second (or immediately if called later) from
439// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200440static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400441{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200442 static timespec lastCall;
443 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400444
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200445 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400446 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200447 clock_gettime(CLOCK_MONOTONIC, &lastCall);
448 initialized = 1;
449 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400450 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400451
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200452 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500453 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200454 timespec curTime;
455 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400456
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200457 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500458
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200459 // This is really 30 times per second
460 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500461 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200462 lastCall = curTime;
463 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500464 }
465
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200466 // We need to sleep some period time microseconds
467 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
468 usleep(sleepTime);
469 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400470}
471
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200472static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500473{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200474 // Raise the curtain
475 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500476 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200477 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500478
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200479 PageManager::Render();
480 gr_get_surface(&surface);
481 curtainRaise(surface);
482 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500483 }
484
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200485 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500486
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200487 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500488
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100489#ifdef PRINT_RENDER_TIME
490 timespec start, end;
491 int32_t render_t, flip_t;
492#endif
493
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200494 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500495 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200496 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500497
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200498 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500499 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200500 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500501
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200502 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100503
504#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200505 if (ret > 1)
506 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500507
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200508 if (ret > 0)
509 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100510#else
511 if (ret > 1)
512 {
513 clock_gettime(CLOCK_MONOTONIC, &start);
514 PageManager::Render();
515 clock_gettime(CLOCK_MONOTONIC, &end);
516 render_t = TWFunc::timespec_diff_ms(start, end);
517
518 flip();
519 clock_gettime(CLOCK_MONOTONIC, &start);
520 flip_t = TWFunc::timespec_diff_ms(end, start);
521
522 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
523 }
524 else if(ret == 1)
525 flip();
526#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500527 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200528 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500529 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200530 pthread_mutex_lock(&gForceRendermutex);
531 gForceRender = 0;
532 pthread_mutex_unlock(&gForceRendermutex);
533 PageManager::Render();
534 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500535 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200536
Dees_Troy6ef66352013-02-21 08:26:57 -0600537 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200538 break;
539 }
540
541 gGuiRunning = 0;
542 return 0;
543}
544
545static int runPage(const char *page_name)
546{
547 gui_changePage(page_name);
548
549 // Raise the curtain
550 if (gCurtain != NULL)
551 {
552 gr_surface surface;
553
554 PageManager::Render();
555 gr_get_surface(&surface);
556 curtainRaise(surface);
557 gr_free_surface(surface);
558 }
559
560 gGuiRunning = 1;
561
562 DataManager::SetValue("tw_loaded", 1);
563
564 for (;;)
565 {
566 loopTimer();
567
568 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600569 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200570 int ret;
571
572 ret = PageManager::Update();
573 if (ret > 1)
574 PageManager::Render();
575
576 if (ret > 0)
577 flip();
578 }
579 else
580 {
581 pthread_mutex_lock(&gForceRendermutex);
582 gForceRender = 0;
583 pthread_mutex_unlock(&gForceRendermutex);
584 PageManager::Render();
585 flip();
586 }
587 if (DataManager::GetIntValue("tw_page_done") != 0)
588 {
589 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600590 break;
591 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500592 }
593
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200594 gGuiRunning = 0;
595 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500596}
597
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200598int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500599{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200600 pthread_mutex_lock(&gForceRendermutex);
601 gForceRender = 1;
602 pthread_mutex_unlock(&gForceRendermutex);
603 return 0;
604}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500605
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200606int gui_changePage(std::string newPage)
607{
608 LOGINFO("Set page: '%s'\n", newPage.c_str());
609 PageManager::ChangePage(newPage);
610 pthread_mutex_lock(&gForceRendermutex);
611 gForceRender = 1;
612 pthread_mutex_unlock(&gForceRendermutex);
613 return 0;
614}
615
616int gui_changeOverlay(std::string overlay)
617{
618 PageManager::ChangeOverlay(overlay);
619 pthread_mutex_lock(&gForceRendermutex);
620 gForceRender = 1;
621 pthread_mutex_unlock(&gForceRendermutex);
622 return 0;
623}
624
625int gui_changePackage(std::string newPackage)
626{
627 PageManager::SelectPackage(newPackage);
628 pthread_mutex_lock(&gForceRendermutex);
629 gForceRender = 1;
630 pthread_mutex_unlock(&gForceRendermutex);
631 return 0;
632}
633
634std::string gui_parse_text(string inText)
635{
636 // Copied from std::string GUIText::parseText(void)
637 // This function parses text for DataManager values encompassed by %value% in the XML
638 static int counter = 0;
639 std::string str = inText;
640 size_t pos = 0;
641 size_t next = 0, end = 0;
642
643 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500644 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200645 next = str.find('%', pos);
646 if (next == std::string::npos)
647 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500648
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200649 end = str.find('%', next + 1);
650 if (end == std::string::npos)
651 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500652
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200653 // We have a block of data
654 std::string var = str.substr(next + 1,(end - next) - 1);
655 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500656
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200657 if (next + 1 == end)
658 str.insert(next, 1, '%');
659 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500660 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200661 std::string value;
662 if (DataManager::GetValue(var, value) == 0)
663 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500664 }
665
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200666 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500667 }
668}
669
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200670extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500671{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200672 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500673
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200674 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500675
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200676 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500677 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200678 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500679 ("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 +0200680 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500681 }
682
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200683 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500684
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200685 ev_init();
686 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500687}
688
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200689extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400690{
Ethan Yonker83e82572014-04-04 10:59:28 -0500691#ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692 int check = 0;
693 DataManager::GetValue(TW_IS_ENCRYPTED, check);
694 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500695 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200696 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400697 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200698 LOGERR("Failed to load base packages.\n");
699 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400700 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200701 else
702 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500703 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400704
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200705 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
706 {
707 std::string theme_path;
708
709 theme_path = DataManager::GetSettingsStoragePath();
710 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400711 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200712 int retry_count = 5;
713 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400714 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200715 usleep(500000);
716 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500717 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200718
719 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500720 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200721 LOGERR("Unable to mount %s during GUI startup.\n",
722 theme_path.c_str());
723 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500724 }
725 }
726
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200727 theme_path += "/TWRP/theme/ui.zip";
728 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500729 {
Ethan Yonker83e82572014-04-04 10:59:28 -0500730#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200731 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500732 {
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 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500736#ifndef TW_OEM_BUILD
Dees_Troy51a0e822012-09-05 15:24:24 -0400737 }
738 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500739#endif // ifndef TW_OEM_BUILD
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200740 // Set the default package
741 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400742
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200743 gGuiInitialized = 1;
744 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400745
746error:
Ethan Yonker83e82572014-04-04 10:59:28 -0500747 LOGERR("An internal error has occurred: unable to load theme.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200748 gGuiInitialized = 0;
749 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400750}
751
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400753{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200754 if (!gGuiInitialized)
755 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400756
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200757 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400758
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200759 while (gGuiConsoleRunning)
760 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400761
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200762 // Set the default package
763 PageManager::SelectPackage("TWRP");
764
765 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500766 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200767 // Start by spinning off an input handler.
768 pthread_t t;
769 pthread_create(&t, NULL, input_thread, NULL);
770 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000771 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400772
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200773 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400774}
775
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200776extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000777{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200778 if (!gGuiInitialized)
779 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000780
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200781 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000782
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200783 while (gGuiConsoleRunning)
784 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000785
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200786 // Set the default package
787 PageManager::SelectPackage("TWRP");
788
789 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500790 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200791 // Start by spinning off an input handler.
792 pthread_t t;
793 pthread_create(&t, NULL, input_thread, NULL);
794 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000795 }
796
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200797 DataManager::SetValue("tw_page_done", 0);
798 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000799}
800
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200801static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400802{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200803 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400804
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200805 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500806 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200807 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400808
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200809 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500810 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200811 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400812
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200813 ret = PageManager::Update();
814 if (ret > 1)
815 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400816
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200817 if (ret > 0)
818 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400819
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200820 if (ret < 0)
821 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500822 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200823 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500824 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200825 pthread_mutex_lock(&gForceRendermutex);
826 gForceRender = 0;
827 pthread_mutex_unlock(&gForceRendermutex);
828 PageManager::Render();
829 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500830 }
831 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200832 gGuiConsoleRunning = 0;
833 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400834}
835
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200836extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400837{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200838 if (!gGuiInitialized)
839 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400840
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200841 gGuiConsoleTerminate = 0;
842 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400843
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200844 // Start by spinning off an input handler.
845 pthread_t t;
846 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400847
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200848 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400849}