blob: 2098342b04791eb88480fece34a1413c70ffe207 [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
Dees_Troy51a0e822012-09-05 15:24:24 -040060const static int CURTAIN_FADE = 32;
61
62using namespace rapidxml;
63
64// Global values
65static gr_surface gCurtain = NULL;
66static int gGuiInitialized = 0;
67static int gGuiConsoleRunning = 0;
68static int gGuiConsoleTerminate = 0;
69static int gForceRender = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050070pthread_mutex_t gForceRendermutex;
Dees_Troyc8b199c2012-09-24 11:55:07 -040071static int gNoAnimation = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +000072static int gGuiInputRunning = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070073#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050074blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070075#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040076
77// Needed by pages.cpp too
78int gGuiRunning = 0;
79
80static int gRecorder = -1;
81
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020082extern "C" void gr_write_frame_to_file(int fd);
Dees_Troy51a0e822012-09-05 15:24:24 -040083
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020084void flip(void)
Dees_Troy51a0e822012-09-05 15:24:24 -040085{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020086 if (gRecorder != -1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050087 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020088 timespec time;
89 clock_gettime(CLOCK_MONOTONIC, &time);
90 write(gRecorder, &time, sizeof(timespec));
91 gr_write_frame_to_file(gRecorder);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050092 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020093 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -040094}
95
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020096void rapidxml::parse_error_handler(const char *what, void *where)
Dees_Troy51a0e822012-09-05 15:24:24 -040097{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020098 fprintf(stderr, "Parser error: %s\n", what);
99 fprintf(stderr, " Start of string: %s\n",(char *) where);
100 LOGERR("Error parsing XML file.\n");
101 //abort();
Dees_Troy51a0e822012-09-05 15:24:24 -0400102}
103
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200104static void curtainSet()
Dees_Troy51a0e822012-09-05 15:24:24 -0400105{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200106 gr_color(0, 0, 0, 255);
107 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
108 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
109 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400110}
111
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200112static void curtainRaise(gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400113{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200114 int sy = 0;
115 int h = gr_get_height(gCurtain) - 1;
116 int w = gr_get_width(gCurtain);
117 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400118
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200119 int msw = gr_get_width(surface);
120 int msh = gr_get_height(surface);
121 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400122
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200123 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500124 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200125 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500126 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200127 gr_blit(surface, 0, 0, msw, msh, 0, 0);
128 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
129 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500130 }
131 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200132 gr_blit(surface, 0, 0, msw, msh, 0, 0);
133 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400134}
135
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200136void curtainClose()
Dees_Troy51a0e822012-09-05 15:24:24 -0400137{
138#if 0
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200139 int w = gr_get_width(gCurtain);
140 int h = 1;
141 int sy = gr_get_height(gCurtain) - 1;
142 int fbh = gr_fb_height();
143 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400144
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200145 if (gNoAnimation == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500146 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200147 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500148 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200149 gr_blit(gCurtain, 0, sy, w, h, 0, 0);
150 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500151 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200152 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
153 gr_get_height(gCurtain), 0, 0);
154 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400155
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200156 if (gRecorder != -1)
157 close(gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400158
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200159 int fade;
160 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500161 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200162 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain),
163 gr_get_height(gCurtain), 0, 0);
164 gr_color(0, 0, 0, fade);
165 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
166 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500167 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200168 gr_color(0, 0, 0, 255);
169 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
170 gr_flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400171 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500172#else
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200173 gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0);
174 gr_flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500175#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400176}
177
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200178static void * input_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400179{
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700180
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200181 int drag = 0;
182 static int touch_and_hold = 0, dontwait = 0;
183 static int touch_repeat = 0, key_repeat = 0;
184 static int x = 0, y = 0;
185 static int lshift = 0, rshift = 0;
186 static struct timeval touchStart;
187 HardwareKeyboard kb;
188 string seconds;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100189 MouseCursor *cursor = PageManager::GetMouseCursor();
Dees_Troy51a0e822012-09-05 15:24:24 -0400190
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700191#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200192 //start screen timeout threads
193 blankTimer.setTimerThread();
194 DataManager::GetValue("tw_screen_timeout_secs", seconds);
195 blankTimer.setTime(atoi(seconds.c_str()));
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700196#else
197 LOGINFO("Skipping screen timeout threads: TW_NO_SCREEN_TIMEOUT is set\n");
198#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400199
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200200 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500201 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 // wait for the next event
203 struct input_event ev;
204 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400205
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200206 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400207
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200208 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500209 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200210 struct timeval curTime;
211 gettimeofday(&curTime, NULL);
212 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400213
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200214 seconds = curTime.tv_sec - touchStart.tv_sec;
215 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500216
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200217 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
218 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500219 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200220 touch_and_hold = 0;
221 touch_repeat = 1;
222 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400223#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200224 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400225#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200226 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700227#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200228 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700229#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400230 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200231 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500232 {
233#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200234 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500235#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200236 gettimeofday(&touchStart, NULL);
237 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700238#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200239 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700240#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500241 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200242 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500243 {
244#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500246#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200247 gettimeofday(&touchStart, NULL);
248 key_repeat = 2;
249 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700250#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200251 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700252#endif
253
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500254 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200255 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500256 {
257#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200258 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500259#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200260 gettimeofday(&touchStart, NULL);
261 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700262#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200263 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700264#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500265 }
266 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200267 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500268 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400269
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200270 x = ev.value >> 16;
271 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400272
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200273 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500274 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200275 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500276 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400277#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200278 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400279#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200280 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700281#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200282 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700283#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200284 touch_and_hold = 0;
285 touch_repeat = 0;
286 if (!key_repeat)
287 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400288 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200289 state = 0;
290 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400291 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200292 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500293 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200294 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500295 {
296#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200297 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500298#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200299 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
300 state = 1;
301 drag = 1;
302 touch_and_hold = 1;
303 dontwait = 1;
304 key_repeat = 0;
305 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700306#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200307 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700308#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500309 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200310 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500311 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200312 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500313 {
314#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200315 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500316#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200317 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
318 state = 1;
319 key_repeat = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700320#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200321 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700322#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500323 }
324 }
325 }
326 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200327 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500328 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200329 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500330#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200331 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500332#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100333 // Left mouse button
334 if(ev.code == BTN_LEFT)
335 {
336 if(ev.value == 1)
337 {
338 cursor->GetPos(x, y);
339
340 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
341 state = 1;
342 drag = 1;
343 touch_and_hold = 1;
344 dontwait = 1;
345 key_repeat = 0;
346 gettimeofday(&touchStart, NULL);
347 }
348 else if(drag == 1)
349 {
350 if (state == 0)
351 {
352 cursor->GetPos(x, y);
353
354 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
355
356 touch_and_hold = 0;
357 touch_repeat = 0;
358 if (!key_repeat)
359 dontwait = 0;
360 }
361 state = 0;
362 drag = 0;
363 }
364 }
365 // side mouse button, often used for "back" function
366 else if(ev.code == BTN_SIDE)
367 {
368 if(ev.value == 1)
369 kb.KeyDown(KEY_BACK);
370 else
371 kb.KeyUp(KEY_BACK);
372 }
373 else if (ev.value != 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500374 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200375 // This is a key press
376 if (kb.KeyDown(ev.code))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500377 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200378 key_repeat = 1;
379 touch_and_hold = 0;
380 touch_repeat = 0;
381 dontwait = 1;
382 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700383#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200384 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700385#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500386 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200387 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500388 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200389 key_repeat = 0;
390 touch_and_hold = 0;
391 touch_repeat = 0;
392 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700393#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200394 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700395#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500396 }
397 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200398 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500399 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200400 // This is a key release
401 kb.KeyUp(ev.code);
402 key_repeat = 0;
403 touch_and_hold = 0;
404 touch_repeat = 0;
405 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700406#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200407 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700408#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500409 }
410 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100411 else if(ev.type == EV_REL)
412 {
413#ifdef _EVENT_LOGGING
414 LOGERR("EV_REL %d %d\n", ev.code, ev.value);
415#endif
416 if(ev.code == REL_X)
417 cursor->Move(ev.value, 0);
418 else if(ev.code == REL_Y)
419 cursor->Move(0, ev.value);
420
421 if(drag == 1) {
422 cursor->GetPos(x, y);
423#ifdef _EVENT_LOGGING
424 LOGERR("TOUCH_DRAG: %d, %d\n", x, y);
425#endif
426 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
427 state = 1;
428 key_repeat = 0;
429 }
430 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500431 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200432 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400433}
434
435// This special function will return immediately the first time, but then
436// always returns 1/30th of a second (or immediately if called later) from
437// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200438static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400439{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200440 static timespec lastCall;
441 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400442
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200443 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400444 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200445 clock_gettime(CLOCK_MONOTONIC, &lastCall);
446 initialized = 1;
447 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400448 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400449
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200450 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500451 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200452 timespec curTime;
453 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400454
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200455 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500456
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200457 // This is really 30 times per second
458 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500459 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200460 lastCall = curTime;
461 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500462 }
463
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200464 // We need to sleep some period time microseconds
465 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
466 usleep(sleepTime);
467 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400468}
469
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200470static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500471{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200472 // Raise the curtain
473 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500474 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200475 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500476
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200477 PageManager::Render();
478 gr_get_surface(&surface);
479 curtainRaise(surface);
480 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500481 }
482
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200483 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500484
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200485 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500486
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200487 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500488 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200489 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500490
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200491 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500492 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200493 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500494
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200495 ret = PageManager::Update();
496 if (ret > 1)
497 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500498
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200499 if (ret > 0)
500 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500501 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200502 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500503 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200504 pthread_mutex_lock(&gForceRendermutex);
505 gForceRender = 0;
506 pthread_mutex_unlock(&gForceRendermutex);
507 PageManager::Render();
508 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500509 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200510
Dees_Troy6ef66352013-02-21 08:26:57 -0600511 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200512 break;
513 }
514
515 gGuiRunning = 0;
516 return 0;
517}
518
519static int runPage(const char *page_name)
520{
521 gui_changePage(page_name);
522
523 // Raise the curtain
524 if (gCurtain != NULL)
525 {
526 gr_surface surface;
527
528 PageManager::Render();
529 gr_get_surface(&surface);
530 curtainRaise(surface);
531 gr_free_surface(surface);
532 }
533
534 gGuiRunning = 1;
535
536 DataManager::SetValue("tw_loaded", 1);
537
538 for (;;)
539 {
540 loopTimer();
541
542 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600543 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200544 int ret;
545
546 ret = PageManager::Update();
547 if (ret > 1)
548 PageManager::Render();
549
550 if (ret > 0)
551 flip();
552 }
553 else
554 {
555 pthread_mutex_lock(&gForceRendermutex);
556 gForceRender = 0;
557 pthread_mutex_unlock(&gForceRendermutex);
558 PageManager::Render();
559 flip();
560 }
561 if (DataManager::GetIntValue("tw_page_done") != 0)
562 {
563 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600564 break;
565 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500566 }
567
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200568 gGuiRunning = 0;
569 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500570}
571
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200572int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500573{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200574 pthread_mutex_lock(&gForceRendermutex);
575 gForceRender = 1;
576 pthread_mutex_unlock(&gForceRendermutex);
577 return 0;
578}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500579
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200580int gui_changePage(std::string newPage)
581{
582 LOGINFO("Set page: '%s'\n", newPage.c_str());
583 PageManager::ChangePage(newPage);
584 pthread_mutex_lock(&gForceRendermutex);
585 gForceRender = 1;
586 pthread_mutex_unlock(&gForceRendermutex);
587 return 0;
588}
589
590int gui_changeOverlay(std::string overlay)
591{
592 PageManager::ChangeOverlay(overlay);
593 pthread_mutex_lock(&gForceRendermutex);
594 gForceRender = 1;
595 pthread_mutex_unlock(&gForceRendermutex);
596 return 0;
597}
598
599int gui_changePackage(std::string newPackage)
600{
601 PageManager::SelectPackage(newPackage);
602 pthread_mutex_lock(&gForceRendermutex);
603 gForceRender = 1;
604 pthread_mutex_unlock(&gForceRendermutex);
605 return 0;
606}
607
608std::string gui_parse_text(string inText)
609{
610 // Copied from std::string GUIText::parseText(void)
611 // This function parses text for DataManager values encompassed by %value% in the XML
612 static int counter = 0;
613 std::string str = inText;
614 size_t pos = 0;
615 size_t next = 0, end = 0;
616
617 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500618 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200619 next = str.find('%', pos);
620 if (next == std::string::npos)
621 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500622
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200623 end = str.find('%', next + 1);
624 if (end == std::string::npos)
625 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500626
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200627 // We have a block of data
628 std::string var = str.substr(next + 1,(end - next) - 1);
629 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500630
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200631 if (next + 1 == end)
632 str.insert(next, 1, '%');
633 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500634 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200635 std::string value;
636 if (DataManager::GetValue(var, value) == 0)
637 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500638 }
639
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200640 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500641 }
642}
643
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200644extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500645{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200646 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500647
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200648 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500649
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200650 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500651 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200652 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500653 ("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 +0200654 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500655 }
656
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200657 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500658
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200659 ev_init();
660 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500661}
662
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200663extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400664{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200665 // unlink("/sdcard/video.last");
666 // rename("/sdcard/video.bin", "/sdcard/video.last");
667 // gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
Dees_Troy51a0e822012-09-05 15:24:24 -0400668
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200669 int check = 0;
670 DataManager::GetValue(TW_IS_ENCRYPTED, check);
671 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500672 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200673 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400674 {
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 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200678 else
679 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500680 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400681
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200682 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
683 {
684 std::string theme_path;
685
686 theme_path = DataManager::GetSettingsStoragePath();
687 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400688 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200689 int retry_count = 5;
690 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400691 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692 usleep(500000);
693 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500694 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200695
696 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500697 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200698 LOGERR("Unable to mount %s during GUI startup.\n",
699 theme_path.c_str());
700 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500701 }
702 }
703
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200704 theme_path += "/TWRP/theme/ui.zip";
705 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500706 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200707 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500708 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200709 LOGERR("Failed to load base packages.\n");
710 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400711 }
712 }
713 }
714
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200715 // Set the default package
716 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400717
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200718 gGuiInitialized = 1;
719 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400720
721error:
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200722 LOGERR("An internal error has occurred.\n");
723 gGuiInitialized = 0;
724 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400725}
726
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200727extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400728{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200729 if (!gGuiInitialized)
730 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400731
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200732 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400733
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200734 while (gGuiConsoleRunning)
735 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400736
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200737 // Set the default package
738 PageManager::SelectPackage("TWRP");
739
740 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500741 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200742 // Start by spinning off an input handler.
743 pthread_t t;
744 pthread_create(&t, NULL, input_thread, NULL);
745 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000746 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400747
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200748 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400749}
750
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200751extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000752{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200753 if (!gGuiInitialized)
754 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000755
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200756 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000757
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758 while (gGuiConsoleRunning)
759 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000760
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200761 // Set the default package
762 PageManager::SelectPackage("TWRP");
763
764 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500765 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200766 // Start by spinning off an input handler.
767 pthread_t t;
768 pthread_create(&t, NULL, input_thread, NULL);
769 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000770 }
771
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200772 DataManager::SetValue("tw_page_done", 0);
773 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000774}
775
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200776static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400777{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200778 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400779
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200780 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500781 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200782 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400783
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200784 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500785 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200786 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400787
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200788 ret = PageManager::Update();
789 if (ret > 1)
790 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400791
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200792 if (ret > 0)
793 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400794
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200795 if (ret < 0)
796 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500797 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200798 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500799 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200800 pthread_mutex_lock(&gForceRendermutex);
801 gForceRender = 0;
802 pthread_mutex_unlock(&gForceRendermutex);
803 PageManager::Render();
804 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500805 }
806 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200807 gGuiConsoleRunning = 0;
808 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400809}
810
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200811extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400812{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200813 if (!gGuiInitialized)
814 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400815
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200816 gGuiConsoleTerminate = 0;
817 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400818
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200819 // Start by spinning off an input handler.
820 pthread_t t;
821 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400822
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200823 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400824}