blob: 4c7bf5b23371d9d93b608c44cb356358927b4757 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <linux/input.h>
18#include <pthread.h>
19#include <stdarg.h>
20#include <stdio.h>
21#include <errno.h>
22#include <stdlib.h>
23#include <string.h>
24#include <fcntl.h>
25#include <sys/reboot.h>
26#include <sys/stat.h>
27#include <sys/time.h>
28#include <sys/mman.h>
29#include <sys/types.h>
30#include <sys/ioctl.h>
31#include <sys/mount.h>
32#include <time.h>
33#include <unistd.h>
34#include <stdlib.h>
35
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050036extern "C"
37{
Dees_Troy2673cec2013-04-02 20:22:16 +000038#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040039#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040040#include "../minzip/Zip.h"
41#include <pixelflinger/pixelflinger.h>
42}
43
44#include "rapidxml.hpp"
45#include "objects.hpp"
46#include "../data.hpp"
47#include "../variables.h"
Dees_Troy5bf43922012-09-07 16:07:55 -040048#include "../partitions.hpp"
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050049#include "../twrp-functions.hpp"
50#include "blanktimer.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040051
Dees_Troy51a0e822012-09-05 15:24:24 -040052const static int CURTAIN_FADE = 32;
53
54using namespace rapidxml;
55
56// Global values
57static gr_surface gCurtain = NULL;
58static int gGuiInitialized = 0;
59static int gGuiConsoleRunning = 0;
60static int gGuiConsoleTerminate = 0;
61static int gForceRender = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050062pthread_mutex_t gForceRendermutex;
Dees_Troyc8b199c2012-09-24 11:55:07 -040063static int gNoAnimation = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +000064static int gGuiInputRunning = 0;
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050065blanktimer blankTimer;
Dees_Troy51a0e822012-09-05 15:24:24 -040066
67// Needed by pages.cpp too
68int gGuiRunning = 0;
69
70static int gRecorder = -1;
71
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050072extern "C" void gr_write_frame_to_file (int fd);
Dees_Troy51a0e822012-09-05 15:24:24 -040073
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050074void
75flip (void)
Dees_Troy51a0e822012-09-05 15:24:24 -040076{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050077 if (gRecorder != -1)
78 {
79 timespec time;
80 clock_gettime (CLOCK_MONOTONIC, &time);
81 write (gRecorder, &time, sizeof (timespec));
82 gr_write_frame_to_file (gRecorder);
83 }
84 gr_flip ();
85 return;
Dees_Troy51a0e822012-09-05 15:24:24 -040086}
87
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050088void
89rapidxml::parse_error_handler (const char *what, void *where)
Dees_Troy51a0e822012-09-05 15:24:24 -040090{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050091 fprintf (stderr, "Parser error: %s\n", what);
92 fprintf (stderr, " Start of string: %s\n", (char *) where);
93 abort ();
Dees_Troy51a0e822012-09-05 15:24:24 -040094}
95
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050096static void
97curtainSet ()
Dees_Troy51a0e822012-09-05 15:24:24 -040098{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050099 gr_color (0, 0, 0, 255);
100 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
101 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
102 0, 0);
103 gr_flip ();
104 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400105}
106
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500107static void
108curtainRaise (gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400109{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500110 int sy = 0;
111 int h = gr_get_height (gCurtain) - 1;
112 int w = gr_get_width (gCurtain);
113 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400114
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500115 int msw = gr_get_width (surface);
116 int msh = gr_get_height (surface);
117 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400118
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500119 if (gNoAnimation == 0)
120 {
121 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
122 {
123 gr_blit (surface, 0, 0, msw, msh, 0, 0);
124 gr_blit (gCurtain, 0, sy, w, h, 0, 0);
125 gr_flip ();
126 }
127 }
128 gr_blit (surface, 0, 0, msw, msh, 0, 0);
129 flip ();
130 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400131}
132
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500133void
134curtainClose ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400135{
136#if 0
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500137 int w = gr_get_width (gCurtain);
138 int h = 1;
139 int sy = gr_get_height (gCurtain) - 1;
140 int fbh = gr_fb_height ();
141 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400142
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500143 if (gNoAnimation == 0)
144 {
145 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
146 {
147 gr_blit (gCurtain, 0, sy, w, h, 0, 0);
148 gr_flip ();
149 }
150 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
151 gr_get_height (gCurtain), 0, 0);
152 gr_flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400153
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500154 if (gRecorder != -1)
155 close (gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400156
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500157 int fade;
158 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
159 {
160 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
161 gr_get_height (gCurtain), 0, 0);
162 gr_color (0, 0, 0, fade);
163 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
164 gr_flip ();
165 }
166 gr_color (0, 0, 0, 255);
167 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
168 gr_flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400169 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500170#else
171 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
172 0, 0);
173 gr_flip ();
174#endif
175 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400176}
177
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500178static void *
179input_thread (void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400180{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500181 int drag = 0;
182 static int touch_and_hold = 0, dontwait = 0, touch_repeat = 0, x = 0, y =
183 0, lshift = 0, rshift = 0, key_repeat = 0;
184 static struct timeval touchStart;
185 HardwareKeyboard kb;
bigbiff bigbifff8e2f372013-02-27 20:50:43 -0500186 string seconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400187
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500188 //start screen timeout threads
189 blankTimer.setTimerThread();
bigbiff bigbifff8e2f372013-02-27 20:50:43 -0500190 DataManager::GetValue("tw_screen_timeout_secs", seconds);
191 blankTimer.setTime(atoi(seconds.c_str()));
Dees_Troy51a0e822012-09-05 15:24:24 -0400192
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500193 for (;;)
194 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400195
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500196 // wait for the next event
197 struct input_event ev;
198 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400199
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500200 ret = ev_get (&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400201
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500202 if (ret < 0)
203 {
204 struct timeval curTime;
205 gettimeofday (&curTime, NULL);
206 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400207
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500208 seconds = curTime.tv_sec - touchStart.tv_sec;
209 useconds = curTime.tv_usec - touchStart.tv_usec;
210
211 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
212 if (touch_and_hold && mtime > 500)
213 {
214 touch_and_hold = 0;
215 touch_repeat = 1;
216 gettimeofday (&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400217#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000218 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400219#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500220 PageManager::NotifyTouch (TOUCH_HOLD, x, y);
221 blankTimer.resetTimerAndUnblank();
Dees_Troy51a0e822012-09-05 15:24:24 -0400222 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500223 else if (touch_repeat && mtime > 100)
224 {
225#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000226 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500227#endif
228 gettimeofday (&touchStart, NULL);
229 PageManager::NotifyTouch (TOUCH_REPEAT, x, y);
230 blankTimer.resetTimerAndUnblank();
231 }
232 else if (key_repeat == 1 && mtime > 500)
233 {
234#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000235 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500236#endif
237 gettimeofday (&touchStart, NULL);
238 key_repeat = 2;
239 kb.KeyRepeat ();
240 blankTimer.resetTimerAndUnblank();
241 }
242 else if (key_repeat == 2 && mtime > 100)
243 {
244#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000245 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500246#endif
247 gettimeofday (&touchStart, NULL);
248 kb.KeyRepeat ();
249 blankTimer.resetTimerAndUnblank();
250 }
251 }
252 else if (ev.type == EV_ABS)
253 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400254
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500255 x = ev.value >> 16;
256 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400257
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500258 if (ev.code == 0)
259 {
260 if (state == 0)
261 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400262#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000263 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400264#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500265 PageManager::NotifyTouch (TOUCH_RELEASE, x, y);
266 blankTimer.resetTimerAndUnblank();
267 touch_and_hold = 0;
268 touch_repeat = 0;
269 if (!key_repeat)
Dees_Troy51a0e822012-09-05 15:24:24 -0400270 dontwait = 0;
271 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500272 state = 0;
273 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400274 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500275 else
276 {
277 if (!drag)
278 {
279#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000280 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500281#endif
282 if (PageManager::NotifyTouch (TOUCH_START, x, y) > 0)
283 state = 1;
284 drag = 1;
285 touch_and_hold = 1;
286 dontwait = 1;
287 key_repeat = 0;
288 gettimeofday (&touchStart, NULL);
289 blankTimer.resetTimerAndUnblank();
290 }
291 else
292 {
293 if (state == 0)
294 {
295#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000296 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500297#endif
298 if (PageManager::NotifyTouch (TOUCH_DRAG, x, y) > 0)
299 state = 1;
300 key_repeat = 0;
301 blankTimer.resetTimerAndUnblank();
302 }
303 }
304 }
305 }
306 else if (ev.type == EV_KEY)
307 {
308 // Handle key-press here
309#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000310 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500311#endif
312 if (ev.value != 0)
313 {
314 // This is a key press
315 if (kb.KeyDown (ev.code))
316 {
317 key_repeat = 1;
318 touch_and_hold = 0;
319 touch_repeat = 0;
320 dontwait = 1;
321 gettimeofday (&touchStart, NULL);
322 blankTimer.resetTimerAndUnblank();
323 }
324 else
325 {
326 key_repeat = 0;
327 touch_and_hold = 0;
328 touch_repeat = 0;
329 dontwait = 0;
330 blankTimer.resetTimerAndUnblank();
331 }
332 }
333 else
334 {
335 // This is a key release
336 kb.KeyUp (ev.code);
337 key_repeat = 0;
338 touch_and_hold = 0;
339 touch_repeat = 0;
340 dontwait = 0;
341 blankTimer.resetTimerAndUnblank();
342 }
343 }
344 }
345 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400346}
347
348// This special function will return immediately the first time, but then
349// always returns 1/30th of a second (or immediately if called later) from
350// the last time it was called
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500351static void
352loopTimer (void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400353{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500354 static timespec lastCall;
355 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400356
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500357 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400358 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500359 clock_gettime (CLOCK_MONOTONIC, &lastCall);
360 initialized = 1;
361 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400362 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400363
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500364 do
365 {
366 timespec curTime;
367 clock_gettime (CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400368
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500369 timespec diff = TWFunc::timespec_diff (lastCall, curTime);
370
371 // This is really 30 times per second
372 if (diff.tv_sec || diff.tv_nsec > 33333333)
373 {
374 lastCall = curTime;
375 return;
376 }
377
378 // We need to sleep some period time microseconds
379 unsigned int sleepTime = 33333 - (diff.tv_nsec / 1000);
380 usleep (sleepTime);
381 }
382 while (1);
383 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400384}
385
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500386static int
387runPages (void)
388{
389 // Raise the curtain
390 if (gCurtain != NULL)
391 {
392 gr_surface surface;
393
394 PageManager::Render ();
395 gr_get_surface (&surface);
396 curtainRaise (surface);
397 gr_free_surface (surface);
398 }
399
400 gGuiRunning = 1;
401
402 DataManager::SetValue ("tw_loaded", 1);
403
404 for (;;)
405 {
406 loopTimer ();
407
408 if (!gForceRender)
409 {
410 int ret;
411
412 ret = PageManager::Update ();
413 if (ret > 1)
414 PageManager::Render ();
415
416 if (ret > 0)
417 flip ();
418 }
419 else
420 {
421 pthread_mutex_lock(&gForceRendermutex);
422 gForceRender = 0;
423 pthread_mutex_unlock(&gForceRendermutex);
424 PageManager::Render ();
425 flip ();
426 }
Dees_Troy6ef66352013-02-21 08:26:57 -0600427 if (DataManager::GetIntValue("tw_gui_done") != 0)
428 {
429 break;
430 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500431 }
432
433 gGuiRunning = 0;
434 return 0;
435}
436
437static int
438runPage (const char *page_name)
439{
440 gui_changePage (page_name);
441
442 // Raise the curtain
443 if (gCurtain != NULL)
444 {
445 gr_surface surface;
446
447 PageManager::Render ();
448 gr_get_surface (&surface);
449 curtainRaise (surface);
450 gr_free_surface (surface);
451 }
452
453 gGuiRunning = 1;
454
455 DataManager::SetValue ("tw_loaded", 1);
456
457 for (;;)
458 {
459 loopTimer ();
460
461 if (!gForceRender)
462 {
463 int ret;
464
465 ret = PageManager::Update ();
466 if (ret > 1)
467 PageManager::Render ();
468
469 if (ret > 0)
470 flip ();
471 }
472 else
473 {
474 pthread_mutex_lock(&gForceRendermutex);
475 gForceRender = 0;
476 pthread_mutex_unlock(&gForceRendermutex);
477 PageManager::Render ();
478 flip ();
479 }
480 if (DataManager::GetIntValue ("tw_page_done") != 0)
481 {
482 gui_changePage ("main");
483 break;
484 }
485 }
486
487 gGuiRunning = 0;
488 return 0;
489}
490
491int
492gui_forceRender (void)
493{
494 pthread_mutex_lock(&gForceRendermutex);
495 gForceRender = 1;
496 pthread_mutex_unlock(&gForceRendermutex);
497 return 0;
498}
499
500int
501gui_changePage (std::string newPage)
502{
Dees_Troy2673cec2013-04-02 20:22:16 +0000503 LOGINFO("Set page: '%s'\n", newPage.c_str ());
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500504 PageManager::ChangePage (newPage);
505 pthread_mutex_lock(&gForceRendermutex);
506 gForceRender = 1;
507 pthread_mutex_unlock(&gForceRendermutex);
508 return 0;
509}
510
511int
512gui_changeOverlay (std::string overlay)
513{
514 PageManager::ChangeOverlay (overlay);
515 pthread_mutex_lock(&gForceRendermutex);
516 gForceRender = 1;
517 pthread_mutex_unlock(&gForceRendermutex);
518 return 0;
519}
520
521int
522gui_changePackage (std::string newPackage)
523{
524 PageManager::SelectPackage (newPackage);
525 pthread_mutex_lock(&gForceRendermutex);
526 gForceRender = 1;
527 pthread_mutex_unlock(&gForceRendermutex);
528 return 0;
529}
530
531std::string gui_parse_text (string inText)
532{
533 // Copied from std::string GUIText::parseText(void)
534 // This function parses text for DataManager values encompassed by %value% in the XML
535 static int counter = 0;
536 std::string str = inText;
537 size_t pos = 0;
538 size_t next = 0, end = 0;
539
540 while (1)
541 {
542 next = str.find ('%', pos);
543 if (next == std::string::npos)
544 return str;
545 end = str.find ('%', next + 1);
546 if (end == std::string::npos)
547 return str;
548
549 // We have a block of data
550 std::string var = str.substr (next + 1, (end - next) - 1);
551 str.erase (next, (end - next) + 1);
552
553 if (next + 1 == end)
554 {
555 str.insert (next, 1, '%');
556 }
557 else
558 {
559 std::string value;
560 if (DataManager::GetValue (var, value) == 0)
561 str.insert (next, value);
562 }
563
564 pos = next + 1;
565 }
566}
567
568extern "C" int
569gui_init ()
570{
571 int fd;
572
573 gr_init ();
574
575 if (res_create_surface ("/res/images/curtain.jpg", &gCurtain))
576 {
577 printf
578 ("Unable to locate '/res/images/curtain.jpg'\nDid you set a DEVICE_RESOLUTION in your config files?\n");
579 return -1;
580 }
581
582 curtainSet ();
583
584 ev_init ();
585 return 0;
586}
587
588extern "C" int
589gui_loadResources ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400590{
Dees_Troy51a0e822012-09-05 15:24:24 -0400591// unlink("/sdcard/video.last");
592// rename("/sdcard/video.bin", "/sdcard/video.last");
593// gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
594
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500595 int check = 0;
596 DataManager::GetValue (TW_IS_ENCRYPTED, check);
597 if (check)
598 {
599 if (PageManager::LoadPackage ("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400600 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000601 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500602 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400603 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500604 else
605 check = 1;
606 }
607 if (check == 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000608 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500609 {
610 std::string theme_path;
Dees_Troy51a0e822012-09-05 15:24:24 -0400611
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500612 theme_path = DataManager::GetSettingsStoragePath ();
Dees_Troy2673cec2013-04-02 20:22:16 +0000613 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400614 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500615 int retry_count = 5;
616 while (retry_count > 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000617 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400618 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500619 usleep (500000);
620 retry_count--;
621 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000622 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500623 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000624 LOGERR("Unable to mount %s during GUI startup.\n",
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500625 theme_path.c_str ());
626 check = 1;
627 }
628 }
629
630 theme_path += "/TWRP/theme/ui.zip";
Dees_Troy2673cec2013-04-02 20:22:16 +0000631 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500632 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000633 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500634 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000635 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500636 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400637 }
638 }
639 }
640
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500641 // Set the default package
642 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400643
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500644 gGuiInitialized = 1;
645 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400646
647error:
Dees_Troy2673cec2013-04-02 20:22:16 +0000648 LOGERR("An internal error has occurred.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500649 gGuiInitialized = 0;
650 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400651}
652
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500653extern "C" int
654gui_start ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400655{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500656 if (!gGuiInitialized)
657 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400658
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500659 gGuiConsoleTerminate = 1;
660 while (gGuiConsoleRunning)
661 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400662
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500663 // Set the default package
664 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400665
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500666 if (!gGuiInputRunning)
667 {
668 // Start by spinning off an input handler.
669 pthread_t t;
670 pthread_create (&t, NULL, input_thread, NULL);
671 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000672 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400673
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500674 return runPages ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400675}
676
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500677extern "C" int
678gui_startPage (const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000679{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500680 if (!gGuiInitialized)
681 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000682
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500683 gGuiConsoleTerminate = 1;
684 while (gGuiConsoleRunning)
685 loopTimer ();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000686
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500687 // Set the default package
Dees_Troy2673cec2013-04-02 20:22:16 +0000688 PageManager::SelectPackage("TWRP");
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000689
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500690 if (!gGuiInputRunning)
691 {
692 // Start by spinning off an input handler.
693 pthread_t t;
694 pthread_create (&t, NULL, input_thread, NULL);
695 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000696 }
697
Dees_Troy2673cec2013-04-02 20:22:16 +0000698 DataManager::SetValue("tw_page_done", 0);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500699 return runPage (page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000700}
701
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500702static void *
703console_thread (void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400704{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500705 PageManager::SwitchToConsole ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400706
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500707 while (!gGuiConsoleTerminate)
708 {
709 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400710
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500711 if (!gForceRender)
712 {
713 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400714
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500715 ret = PageManager::Update ();
716 if (ret > 1)
717 PageManager::Render ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400718
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500719 if (ret > 0)
720 flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400721
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500722 if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000723 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500724 }
725 else
726 {
727 pthread_mutex_lock(&gForceRendermutex);
728 gForceRender = 0;
729 pthread_mutex_unlock(&gForceRendermutex);
730 PageManager::Render ();
731 flip ();
732 }
733 }
734 gGuiConsoleRunning = 0;
735 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400736}
737
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500738extern "C" int
739gui_console_only ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400740{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500741 if (!gGuiInitialized)
742 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400743
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500744 gGuiConsoleTerminate = 0;
745 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400746
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500747 // Start by spinning off an input handler.
748 pthread_t t;
749 pthread_create (&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400750
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500751 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400752}