blob: e9efc1db909108501654b239696d4524567e04e4 [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;
Dees_Troy51a0e822012-09-05 15:24:24 -0400189
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700190#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200191 //start screen timeout threads
192 blankTimer.setTimerThread();
193 DataManager::GetValue("tw_screen_timeout_secs", seconds);
194 blankTimer.setTime(atoi(seconds.c_str()));
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700195#else
196 LOGINFO("Skipping screen timeout threads: TW_NO_SCREEN_TIMEOUT is set\n");
197#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400198
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200199 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500200 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200201 // wait for the next event
202 struct input_event ev;
203 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400204
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 ret = ev_get(&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400206
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200207 if (ret < 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500208 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200209 struct timeval curTime;
210 gettimeofday(&curTime, NULL);
211 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400212
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200213 seconds = curTime.tv_sec - touchStart.tv_sec;
214 useconds = curTime.tv_usec - touchStart.tv_usec;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500215
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200216 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
217 if (touch_and_hold && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500218 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 touch_and_hold = 0;
220 touch_repeat = 1;
221 gettimeofday(&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400222#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400224#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200225 PageManager::NotifyTouch(TOUCH_HOLD, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700226#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200227 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700228#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400229 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 else if (touch_repeat && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500231 {
232#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200233 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500234#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200235 gettimeofday(&touchStart, NULL);
236 PageManager::NotifyTouch(TOUCH_REPEAT, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700237#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200238 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700239#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500240 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200241 else if (key_repeat == 1 && mtime > 500)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500242 {
243#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200244 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500245#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200246 gettimeofday(&touchStart, NULL);
247 key_repeat = 2;
248 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700249#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200250 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700251#endif
252
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500253 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200254 else if (key_repeat == 2 && mtime > 100)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500255 {
256#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500258#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200259 gettimeofday(&touchStart, NULL);
260 kb.KeyRepeat();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700261#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200262 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700263#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500264 }
265 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200266 else if (ev.type == EV_ABS)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500267 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400268
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200269 x = ev.value >> 16;
270 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400271
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200272 if (ev.code == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500273 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200274 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500275 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400276#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200277 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400278#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200279 PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700280#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200281 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700282#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200283 touch_and_hold = 0;
284 touch_repeat = 0;
285 if (!key_repeat)
286 dontwait = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400287 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200288 state = 0;
289 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400290 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200291 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500292 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200293 if (!drag)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500294 {
295#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200296 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500297#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200298 if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0)
299 state = 1;
300 drag = 1;
301 touch_and_hold = 1;
302 dontwait = 1;
303 key_repeat = 0;
304 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700305#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200306 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700307#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500308 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200309 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500310 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200311 if (state == 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500312 {
313#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200314 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500315#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200316 if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0)
317 state = 1;
318 key_repeat = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700319#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200320 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700321#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500322 }
323 }
324 }
325 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200326 else if (ev.type == EV_KEY)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500327 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200328 // Handle key-press here
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500329#ifdef _EVENT_LOGGING
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200330 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500331#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200332 if (ev.value != 0)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500333 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200334 // This is a key press
335 if (kb.KeyDown(ev.code))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500336 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200337 key_repeat = 1;
338 touch_and_hold = 0;
339 touch_repeat = 0;
340 dontwait = 1;
341 gettimeofday(&touchStart, NULL);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700342#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200343 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700344#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500345 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200346 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500347 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200348 key_repeat = 0;
349 touch_and_hold = 0;
350 touch_repeat = 0;
351 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700352#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200353 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700354#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500355 }
356 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200357 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500358 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200359 // This is a key release
360 kb.KeyUp(ev.code);
361 key_repeat = 0;
362 touch_and_hold = 0;
363 touch_repeat = 0;
364 dontwait = 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700365#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200366 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700367#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500368 }
369 }
370 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200371 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400372}
373
374// This special function will return immediately the first time, but then
375// always returns 1/30th of a second (or immediately if called later) from
376// the last time it was called
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200377static void loopTimer(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400378{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200379 static timespec lastCall;
380 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400381
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200382 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400383 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200384 clock_gettime(CLOCK_MONOTONIC, &lastCall);
385 initialized = 1;
386 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400387 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400388
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200389 do
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500390 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200391 timespec curTime;
392 clock_gettime(CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400393
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200394 timespec diff = TWFunc::timespec_diff(lastCall, curTime);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500395
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200396 // This is really 30 times per second
397 if (diff.tv_sec || diff.tv_nsec > 33333333)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500398 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200399 lastCall = curTime;
400 return;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500401 }
402
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200403 // We need to sleep some period time microseconds
404 unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000);
405 usleep(sleepTime);
406 } while (1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400407}
408
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200409static int runPages(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500410{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200411 // Raise the curtain
412 if (gCurtain != NULL)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500413 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200414 gr_surface surface;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500415
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200416 PageManager::Render();
417 gr_get_surface(&surface);
418 curtainRaise(surface);
419 gr_free_surface(surface);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500420 }
421
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200422 gGuiRunning = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500423
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200424 DataManager::SetValue("tw_loaded", 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500425
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200426 for (;;)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500427 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200428 loopTimer();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500429
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200430 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500431 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200432 int ret;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500433
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200434 ret = PageManager::Update();
435 if (ret > 1)
436 PageManager::Render();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500437
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200438 if (ret > 0)
439 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500440 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200441 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500442 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200443 pthread_mutex_lock(&gForceRendermutex);
444 gForceRender = 0;
445 pthread_mutex_unlock(&gForceRendermutex);
446 PageManager::Render();
447 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500448 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200449
Dees_Troy6ef66352013-02-21 08:26:57 -0600450 if (DataManager::GetIntValue("tw_gui_done") != 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200451 break;
452 }
453
454 gGuiRunning = 0;
455 return 0;
456}
457
458static int runPage(const char *page_name)
459{
460 gui_changePage(page_name);
461
462 // Raise the curtain
463 if (gCurtain != NULL)
464 {
465 gr_surface surface;
466
467 PageManager::Render();
468 gr_get_surface(&surface);
469 curtainRaise(surface);
470 gr_free_surface(surface);
471 }
472
473 gGuiRunning = 1;
474
475 DataManager::SetValue("tw_loaded", 1);
476
477 for (;;)
478 {
479 loopTimer();
480
481 if (!gForceRender)
Dees_Troy6ef66352013-02-21 08:26:57 -0600482 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200483 int ret;
484
485 ret = PageManager::Update();
486 if (ret > 1)
487 PageManager::Render();
488
489 if (ret > 0)
490 flip();
491 }
492 else
493 {
494 pthread_mutex_lock(&gForceRendermutex);
495 gForceRender = 0;
496 pthread_mutex_unlock(&gForceRendermutex);
497 PageManager::Render();
498 flip();
499 }
500 if (DataManager::GetIntValue("tw_page_done") != 0)
501 {
502 gui_changePage("main");
Dees_Troy6ef66352013-02-21 08:26:57 -0600503 break;
504 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500505 }
506
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200507 gGuiRunning = 0;
508 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500509}
510
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200511int gui_forceRender(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500512{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200513 pthread_mutex_lock(&gForceRendermutex);
514 gForceRender = 1;
515 pthread_mutex_unlock(&gForceRendermutex);
516 return 0;
517}
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500518
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200519int gui_changePage(std::string newPage)
520{
521 LOGINFO("Set page: '%s'\n", newPage.c_str());
522 PageManager::ChangePage(newPage);
523 pthread_mutex_lock(&gForceRendermutex);
524 gForceRender = 1;
525 pthread_mutex_unlock(&gForceRendermutex);
526 return 0;
527}
528
529int gui_changeOverlay(std::string overlay)
530{
531 PageManager::ChangeOverlay(overlay);
532 pthread_mutex_lock(&gForceRendermutex);
533 gForceRender = 1;
534 pthread_mutex_unlock(&gForceRendermutex);
535 return 0;
536}
537
538int gui_changePackage(std::string newPackage)
539{
540 PageManager::SelectPackage(newPackage);
541 pthread_mutex_lock(&gForceRendermutex);
542 gForceRender = 1;
543 pthread_mutex_unlock(&gForceRendermutex);
544 return 0;
545}
546
547std::string gui_parse_text(string inText)
548{
549 // Copied from std::string GUIText::parseText(void)
550 // This function parses text for DataManager values encompassed by %value% in the XML
551 static int counter = 0;
552 std::string str = inText;
553 size_t pos = 0;
554 size_t next = 0, end = 0;
555
556 while (1)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500557 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200558 next = str.find('%', pos);
559 if (next == std::string::npos)
560 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500561
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200562 end = str.find('%', next + 1);
563 if (end == std::string::npos)
564 return str;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500565
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200566 // We have a block of data
567 std::string var = str.substr(next + 1,(end - next) - 1);
568 str.erase(next,(end - next) + 1);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500569
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200570 if (next + 1 == end)
571 str.insert(next, 1, '%');
572 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500573 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200574 std::string value;
575 if (DataManager::GetValue(var, value) == 0)
576 str.insert(next, value);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500577 }
578
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200579 pos = next + 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500580 }
581}
582
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200583extern "C" int gui_init(void)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500584{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200585 int fd;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500586
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200587 gr_init();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500588
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200589 if (res_create_surface("/res/images/curtain.jpg", &gCurtain))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500590 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200591 printf
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500592 ("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 +0200593 return -1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500594 }
595
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200596 curtainSet();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500597
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200598 ev_init();
599 return 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500600}
601
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200602extern "C" int gui_loadResources(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400603{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200604 // unlink("/sdcard/video.last");
605 // rename("/sdcard/video.bin", "/sdcard/video.last");
606 // gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
Dees_Troy51a0e822012-09-05 15:24:24 -0400607
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200608 int check = 0;
609 DataManager::GetValue(TW_IS_ENCRYPTED, check);
610 if (check)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500611 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200612 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400613 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200614 LOGERR("Failed to load base packages.\n");
615 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400616 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200617 else
618 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500619 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400620
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200621 if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
622 {
623 std::string theme_path;
624
625 theme_path = DataManager::GetSettingsStoragePath();
626 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400627 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200628 int retry_count = 5;
629 while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400630 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200631 usleep(500000);
632 retry_count--;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500633 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200634
635 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500636 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200637 LOGERR("Unable to mount %s during GUI startup.\n",
638 theme_path.c_str());
639 check = 1;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500640 }
641 }
642
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200643 theme_path += "/TWRP/theme/ui.zip";
644 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500645 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200646 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500647 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200648 LOGERR("Failed to load base packages.\n");
649 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400650 }
651 }
652 }
653
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200654 // Set the default package
655 PageManager::SelectPackage("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400656
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200657 gGuiInitialized = 1;
658 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400659
660error:
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200661 LOGERR("An internal error has occurred.\n");
662 gGuiInitialized = 0;
663 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400664}
665
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200666extern "C" int gui_start(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400667{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200668 if (!gGuiInitialized)
669 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400670
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200671 gGuiConsoleTerminate = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400672
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200673 while (gGuiConsoleRunning)
674 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400675
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200676 // Set the default package
677 PageManager::SelectPackage("TWRP");
678
679 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500680 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200681 // Start by spinning off an input handler.
682 pthread_t t;
683 pthread_create(&t, NULL, input_thread, NULL);
684 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000685 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400686
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200687 return runPages();
Dees_Troy51a0e822012-09-05 15:24:24 -0400688}
689
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200690extern "C" int gui_startPage(const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000691{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200692 if (!gGuiInitialized)
693 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000694
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200695 gGuiConsoleTerminate = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000696
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200697 while (gGuiConsoleRunning)
698 loopTimer();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000699
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200700 // Set the default package
701 PageManager::SelectPackage("TWRP");
702
703 if (!gGuiInputRunning)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500704 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200705 // Start by spinning off an input handler.
706 pthread_t t;
707 pthread_create(&t, NULL, input_thread, NULL);
708 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000709 }
710
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200711 DataManager::SetValue("tw_page_done", 0);
712 return runPage(page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000713}
714
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200715static void * console_thread(void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400716{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200717 PageManager::SwitchToConsole();
Dees_Troy51a0e822012-09-05 15:24:24 -0400718
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200719 while (!gGuiConsoleTerminate)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500720 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200721 loopTimer();
Dees_Troy51a0e822012-09-05 15:24:24 -0400722
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200723 if (!gForceRender)
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500724 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200725 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400726
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200727 ret = PageManager::Update();
728 if (ret > 1)
729 PageManager::Render();
Dees_Troy51a0e822012-09-05 15:24:24 -0400730
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200731 if (ret > 0)
732 flip();
Dees_Troy51a0e822012-09-05 15:24:24 -0400733
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200734 if (ret < 0)
735 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500736 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200737 else
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200739 pthread_mutex_lock(&gForceRendermutex);
740 gForceRender = 0;
741 pthread_mutex_unlock(&gForceRendermutex);
742 PageManager::Render();
743 flip();
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500744 }
745 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200746 gGuiConsoleRunning = 0;
747 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400748}
749
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200750extern "C" int gui_console_only(void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400751{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752 if (!gGuiInitialized)
753 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400754
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200755 gGuiConsoleTerminate = 0;
756 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400757
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200758 // Start by spinning off an input handler.
759 pthread_t t;
760 pthread_create(&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400761
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200762 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400763}