blob: adc8a412b0b5d67e739823840d316d10e4771d76 [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;
Dees_Troy51a0e822012-09-05 15:24:24 -0400192
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700193#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200194 //start screen timeout threads
195 blankTimer.setTimerThread();
196 DataManager::GetValue("tw_screen_timeout_secs", seconds);
197 blankTimer.setTime(atoi(seconds.c_str()));
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700198#else
199 LOGINFO("Skipping screen timeout threads: TW_NO_SCREEN_TIMEOUT is set\n");
200#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400201
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500203 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200204 // wait for the next event
205 struct input_event ev;
206 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400207
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200208 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400209
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200210 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500211 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200212 struct timeval curTime;
213 gettimeofday(&curTime, NULL);
214 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400215
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 seconds = curTime.tv_sec - touchStart.tv_sec;
217 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500218
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
220 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500221 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200222 touch_and_hold = 0;
223 touch_repeat = 1;
224 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400225#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200226 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400227#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200228 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700229#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700231#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400232 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200233 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500234 {
235#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200236 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500237#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200238 gettimeofday(&touchStart, NULL);
239 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700240#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200241 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700242#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500243 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200244 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500245 {
246#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200247 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500248#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200249 gettimeofday(&touchStart, NULL);
250 key_repeat = 2;
251 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700252#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200253 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700254#endif
255
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500256 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500258 {
259#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200260 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500261#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200262 gettimeofday(&touchStart, NULL);
263 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700264#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200265 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700266#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500267 }
268 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200269 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500270 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400271
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200272 x = ev.value >> 16;
273 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400274
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200275 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500276 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200277 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500278 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400279#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200280 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400281#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200282 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700283#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200284 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700285#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200286 touch_and_hold = 0;
287 touch_repeat = 0;
288 if (!key_repeat)
289 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400290 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200291 state = 0;
292 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400293 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200294 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500295 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200296 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500297 {
298#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200299 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500300#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200301 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
302 state = 1;
303 drag = 1;
304 touch_and_hold = 1;
305 dontwait = 1;
306 key_repeat = 0;
307 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700308#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200309 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700310#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500311 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200312 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500313 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200314 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500315 {
316#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200317 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500318#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200319 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
320 state = 1;
321 key_repeat = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700322#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200323 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700324#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500325 }
326 }
327 }
328 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200329 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500330 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200331 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500332#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200333 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500334#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200335 if (ev.value != 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500336 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200337 // This is a key press
338 if (kb.KeyDown(ev.code))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500339 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200340 key_repeat = 1;
341 touch_and_hold = 0;
342 touch_repeat = 0;
343 dontwait = 1;
344 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700345#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200346 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700347#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500348 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200349 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500350 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200351 key_repeat = 0;
352 touch_and_hold = 0;
353 touch_repeat = 0;
354 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700355#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200356 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700357#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500358 }
359 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200360 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500361 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200362 // This is a key release
363 kb.KeyUp(ev.code);
364 key_repeat = 0;
365 touch_and_hold = 0;
366 touch_repeat = 0;
367 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700368#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200369 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700370#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500371 }
372 }
373 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200374 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400375}
376
377// This special function will return immediately the first time, but then
378// always returns 1/30th of a second (or immediately if called later) from
379// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200380static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400381{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200382 static timespec lastCall;
383 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400384
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200385 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400386 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200387 clock_gettime(CLOCK_MONOTONIC, &lastCall);
388 initialized = 1;
389 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400390 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400391
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200392 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500393 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200394 timespec curTime;
395 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400396
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200397 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500398
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200399 // This is really 30 times per second
400 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500401 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200402 lastCall = curTime;
403 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500404 }
405
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200406 // We need to sleep some period time microseconds
407 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
408 usleep(sleepTime);
409 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400410}
411
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200412static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500413{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200414 // Raise the curtain
415 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500416 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200417 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500418
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200419 PageManager::Render();
420 gr_get_surface(&surface);
421 curtainRaise(surface);
422 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500423 }
424
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200425 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500426
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200427 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500428
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100429#ifdef PRINT_RENDER_TIME
430 timespec start, end;
431 int32_t render_t, flip_t;
432#endif
433
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200434 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500435 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200436 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500437
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200438 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500439 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200440 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500441
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200442 ret = PageManager::Update();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100443
444#ifndef PRINT_RENDER_TIME
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200445 if (ret > 1)
446 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500447
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200448 if (ret > 0)
449 flip();
Vojtech Boceke5ffcd12014-02-06 21:17:32 +0100450#else
451 if (ret > 1)
452 {
453 clock_gettime(CLOCK_MONOTONIC, &start);
454 PageManager::Render();
455 clock_gettime(CLOCK_MONOTONIC, &end);
456 render_t = TWFunc::timespec_diff_ms(start, end);
457
458 flip();
459 clock_gettime(CLOCK_MONOTONIC, &start);
460 flip_t = TWFunc::timespec_diff_ms(end, start);
461
462 LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t);
463 }
464 else if(ret == 1)
465 flip();
466#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500467 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200468 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500469 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200470 pthread_mutex_lock(&gForceRendermutex);
471 gForceRender = 0;
472 pthread_mutex_unlock(&gForceRendermutex);
473 PageManager::Render();
474 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500475 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200476
Dees_Troy6ef66352013-02-21 08:26:57 -0600477 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200478 break;
479 }
480
481 gGuiRunning = 0;
482 return 0;
483}
484
485static int runPage(const char *page_name)
486{
487 gui_changePage(page_name);
488
489 // Raise the curtain
490 if (gCurtain != NULL)
491 {
492 gr_surface surface;
493
494 PageManager::Render();
495 gr_get_surface(&surface);
496 curtainRaise(surface);
497 gr_free_surface(surface);
498 }
499
500 gGuiRunning = 1;
501
502 DataManager::SetValue("tw_loaded", 1);
503
504 for (;;)
505 {
506 loopTimer();
507
508 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600509 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200510 int ret;
511
512 ret = PageManager::Update();
513 if (ret > 1)
514 PageManager::Render();
515
516 if (ret > 0)
517 flip();
518 }
519 else
520 {
521 pthread_mutex_lock(&gForceRendermutex);
522 gForceRender = 0;
523 pthread_mutex_unlock(&gForceRendermutex);
524 PageManager::Render();
525 flip();
526 }
527 if (DataManager::GetIntValue("tw_page_done") != 0)
528 {
529 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600530 break;
531 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500532 }
533
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200534 gGuiRunning = 0;
535 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500536}
537
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200538int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500539{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200540 pthread_mutex_lock(&gForceRendermutex);
541 gForceRender = 1;
542 pthread_mutex_unlock(&gForceRendermutex);
543 return 0;
544}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500545
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200546int gui_changePage(std::string newPage)
547{
548 LOGINFO("Set page: '%s'\n", newPage.c_str());
549 PageManager::ChangePage(newPage);
550 pthread_mutex_lock(&gForceRendermutex);
551 gForceRender = 1;
552 pthread_mutex_unlock(&gForceRendermutex);
553 return 0;
554}
555
556int gui_changeOverlay(std::string overlay)
557{
558 PageManager::ChangeOverlay(overlay);
559 pthread_mutex_lock(&gForceRendermutex);
560 gForceRender = 1;
561 pthread_mutex_unlock(&gForceRendermutex);
562 return 0;
563}
564
565int gui_changePackage(std::string newPackage)
566{
567 PageManager::SelectPackage(newPackage);
568 pthread_mutex_lock(&gForceRendermutex);
569 gForceRender = 1;
570 pthread_mutex_unlock(&gForceRendermutex);
571 return 0;
572}
573
574std::string gui_parse_text(string inText)
575{
576 // Copied from std::string GUIText::parseText(void)
577 // This function parses text for DataManager values encompassed by %value% in the XML
578 static int counter = 0;
579 std::string str = inText;
580 size_t pos = 0;
581 size_t next = 0, end = 0;
582
583 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500584 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200585 next = str.find('%', pos);
586 if (next == std::string::npos)
587 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500588
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200589 end = str.find('%', next + 1);
590 if (end == std::string::npos)
591 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500592
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200593 // We have a block of data
594 std::string var = str.substr(next + 1,(end - next) - 1);
595 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500596
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200597 if (next + 1 == end)
598 str.insert(next, 1, '%');
599 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500600 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200601 std::string value;
602 if (DataManager::GetValue(var, value) == 0)
603 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500604 }
605
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200606 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500607 }
608}
609
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200610extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500611{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200612 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500613
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200614 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500615
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200616 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500617 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200618 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500619 ("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 +0200620 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500621 }
622
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200623 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500624
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200625 ev_init();
626 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500627}
628
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200629extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400630{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200631 // unlink("/sdcard/video.last");
632 // rename("/sdcard/video.bin", "/sdcard/video.last");
633 // gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
Dees_Troy51a0e822012-09-05 15:24:24 -0400634
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200635 int check = 0;
636 DataManager::GetValue(TW_IS_ENCRYPTED, check);
637 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500638 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200639 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400640 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200641 LOGERR("Failed to load base packages.\n");
642 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400643 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200644 else
645 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500646 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400647
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200648 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
649 {
650 std::string theme_path;
651
652 theme_path = DataManager::GetSettingsStoragePath();
653 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400654 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200655 int retry_count = 5;
656 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400657 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200658 usleep(500000);
659 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500660 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200661
662 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500663 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200664 LOGERR("Unable to mount %s during GUI startup.\n",
665 theme_path.c_str());
666 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500667 }
668 }
669
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200670 theme_path += "/TWRP/theme/ui.zip";
671 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500672 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200673 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500674 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200675 LOGERR("Failed to load base packages.\n");
676 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400677 }
678 }
679 }
680
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200681 // Set the default package
682 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400683
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200684 gGuiInitialized = 1;
685 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400686
687error:
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200688 LOGERR("An internal error has occurred.\n");
689 gGuiInitialized = 0;
690 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400691}
692
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200693extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400694{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200695 if (!gGuiInitialized)
696 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400697
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200698 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400699
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200700 while (gGuiConsoleRunning)
701 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400702
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200703 // Set the default package
704 PageManager::SelectPackage("TWRP");
705
706 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500707 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200708 // Start by spinning off an input handler.
709 pthread_t t;
710 pthread_create(&t, NULL, input_thread, NULL);
711 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000712 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400713
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200714 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400715}
716
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200717extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000718{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200719 if (!gGuiInitialized)
720 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000721
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200722 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000723
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200724 while (gGuiConsoleRunning)
725 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000726
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200727 // Set the default package
728 PageManager::SelectPackage("TWRP");
729
730 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500731 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200732 // Start by spinning off an input handler.
733 pthread_t t;
734 pthread_create(&t, NULL, input_thread, NULL);
735 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000736 }
737
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200738 DataManager::SetValue("tw_page_done", 0);
739 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000740}
741
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200742static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400743{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200744 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400745
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200746 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500747 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200748 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400749
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200750 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500751 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400753
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200754 ret = PageManager::Update();
755 if (ret > 1)
756 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400757
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758 if (ret > 0)
759 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400760
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200761 if (ret < 0)
762 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500763 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200764 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500765 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200766 pthread_mutex_lock(&gForceRendermutex);
767 gForceRender = 0;
768 pthread_mutex_unlock(&gForceRendermutex);
769 PageManager::Render();
770 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500771 }
772 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200773 gGuiConsoleRunning = 0;
774 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400775}
776
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200777extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400778{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200779 if (!gGuiInitialized)
780 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400781
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200782 gGuiConsoleTerminate = 0;
783 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400784
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200785 // Start by spinning off an input handler.
786 pthread_t t;
787 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400788
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200789 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400790}