blob: 87556891d9da636ea7927740713ee929f556a665 [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);
Dees_Troy34614eb2013-04-05 12:02:14 -050093 LOGERR("Error parsing XML file.\n");
94 //abort ();
Dees_Troy51a0e822012-09-05 15:24:24 -040095}
96
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050097static void
98curtainSet ()
Dees_Troy51a0e822012-09-05 15:24:24 -040099{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500100 gr_color (0, 0, 0, 255);
101 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
102 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
103 0, 0);
104 gr_flip ();
105 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400106}
107
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500108static void
109curtainRaise (gr_surface surface)
Dees_Troy51a0e822012-09-05 15:24:24 -0400110{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500111 int sy = 0;
112 int h = gr_get_height (gCurtain) - 1;
113 int w = gr_get_width (gCurtain);
114 int fy = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400115
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500116 int msw = gr_get_width (surface);
117 int msh = gr_get_height (surface);
118 int CURTAIN_RATE = msh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400119
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500120 if (gNoAnimation == 0)
121 {
122 for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
123 {
124 gr_blit (surface, 0, 0, msw, msh, 0, 0);
125 gr_blit (gCurtain, 0, sy, w, h, 0, 0);
126 gr_flip ();
127 }
128 }
129 gr_blit (surface, 0, 0, msw, msh, 0, 0);
130 flip ();
131 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400132}
133
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500134void
135curtainClose ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400136{
137#if 0
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500138 int w = gr_get_width (gCurtain);
139 int h = 1;
140 int sy = gr_get_height (gCurtain) - 1;
141 int fbh = gr_fb_height ();
142 int CURTAIN_RATE = fbh / 30;
Dees_Troy51a0e822012-09-05 15:24:24 -0400143
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500144 if (gNoAnimation == 0)
145 {
146 for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
147 {
148 gr_blit (gCurtain, 0, sy, w, h, 0, 0);
149 gr_flip ();
150 }
151 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
152 gr_get_height (gCurtain), 0, 0);
153 gr_flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400154
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500155 if (gRecorder != -1)
156 close (gRecorder);
Dees_Troy51a0e822012-09-05 15:24:24 -0400157
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500158 int fade;
159 for (fade = 16; fade < 255; fade += CURTAIN_FADE)
160 {
161 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
162 gr_get_height (gCurtain), 0, 0);
163 gr_color (0, 0, 0, fade);
164 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
165 gr_flip ();
166 }
167 gr_color (0, 0, 0, 255);
168 gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
169 gr_flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400170 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500171#else
172 gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
173 0, 0);
174 gr_flip ();
175#endif
176 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400177}
178
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500179static void *
180input_thread (void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400181{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500182 int drag = 0;
183 static int touch_and_hold = 0, dontwait = 0, touch_repeat = 0, x = 0, y =
184 0, lshift = 0, rshift = 0, key_repeat = 0;
185 static struct timeval touchStart;
186 HardwareKeyboard kb;
bigbiff bigbifff8e2f372013-02-27 20:50:43 -0500187 string seconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400188
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500189 //start screen timeout threads
190 blankTimer.setTimerThread();
bigbiff bigbifff8e2f372013-02-27 20:50:43 -0500191 DataManager::GetValue("tw_screen_timeout_secs", seconds);
192 blankTimer.setTime(atoi(seconds.c_str()));
Dees_Troy51a0e822012-09-05 15:24:24 -0400193
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500194 for (;;)
195 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400196
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500197 // wait for the next event
198 struct input_event ev;
199 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400200
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500201 ret = ev_get (&ev, dontwait);
Dees_Troy51a0e822012-09-05 15:24:24 -0400202
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500203 if (ret < 0)
204 {
205 struct timeval curTime;
206 gettimeofday (&curTime, NULL);
207 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400208
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500209 seconds = curTime.tv_sec - touchStart.tv_sec;
210 useconds = curTime.tv_usec - touchStart.tv_usec;
211
212 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
213 if (touch_and_hold && mtime > 500)
214 {
215 touch_and_hold = 0;
216 touch_repeat = 1;
217 gettimeofday (&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400218#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000219 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400220#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500221 PageManager::NotifyTouch (TOUCH_HOLD, x, y);
222 blankTimer.resetTimerAndUnblank();
Dees_Troy51a0e822012-09-05 15:24:24 -0400223 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500224 else if (touch_repeat && mtime > 100)
225 {
226#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000227 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500228#endif
229 gettimeofday (&touchStart, NULL);
230 PageManager::NotifyTouch (TOUCH_REPEAT, x, y);
231 blankTimer.resetTimerAndUnblank();
232 }
233 else if (key_repeat == 1 && mtime > 500)
234 {
235#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000236 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500237#endif
238 gettimeofday (&touchStart, NULL);
239 key_repeat = 2;
240 kb.KeyRepeat ();
241 blankTimer.resetTimerAndUnblank();
242 }
243 else if (key_repeat == 2 && mtime > 100)
244 {
245#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000246 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500247#endif
248 gettimeofday (&touchStart, NULL);
249 kb.KeyRepeat ();
250 blankTimer.resetTimerAndUnblank();
251 }
252 }
253 else if (ev.type == EV_ABS)
254 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400255
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500256 x = ev.value >> 16;
257 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400258
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500259 if (ev.code == 0)
260 {
261 if (state == 0)
262 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400263#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000264 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400265#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500266 PageManager::NotifyTouch (TOUCH_RELEASE, x, y);
267 blankTimer.resetTimerAndUnblank();
268 touch_and_hold = 0;
269 touch_repeat = 0;
270 if (!key_repeat)
Dees_Troy51a0e822012-09-05 15:24:24 -0400271 dontwait = 0;
272 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500273 state = 0;
274 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400275 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500276 else
277 {
278 if (!drag)
279 {
280#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000281 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500282#endif
283 if (PageManager::NotifyTouch (TOUCH_START, x, y) > 0)
284 state = 1;
285 drag = 1;
286 touch_and_hold = 1;
287 dontwait = 1;
288 key_repeat = 0;
289 gettimeofday (&touchStart, NULL);
290 blankTimer.resetTimerAndUnblank();
291 }
292 else
293 {
294 if (state == 0)
295 {
296#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000297 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500298#endif
299 if (PageManager::NotifyTouch (TOUCH_DRAG, x, y) > 0)
300 state = 1;
301 key_repeat = 0;
302 blankTimer.resetTimerAndUnblank();
303 }
304 }
305 }
306 }
307 else if (ev.type == EV_KEY)
308 {
309 // Handle key-press here
310#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000311 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500312#endif
313 if (ev.value != 0)
314 {
315 // This is a key press
316 if (kb.KeyDown (ev.code))
317 {
318 key_repeat = 1;
319 touch_and_hold = 0;
320 touch_repeat = 0;
321 dontwait = 1;
322 gettimeofday (&touchStart, NULL);
323 blankTimer.resetTimerAndUnblank();
324 }
325 else
326 {
327 key_repeat = 0;
328 touch_and_hold = 0;
329 touch_repeat = 0;
330 dontwait = 0;
331 blankTimer.resetTimerAndUnblank();
332 }
333 }
334 else
335 {
336 // This is a key release
337 kb.KeyUp (ev.code);
338 key_repeat = 0;
339 touch_and_hold = 0;
340 touch_repeat = 0;
341 dontwait = 0;
342 blankTimer.resetTimerAndUnblank();
343 }
344 }
345 }
346 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400347}
348
349// This special function will return immediately the first time, but then
350// always returns 1/30th of a second (or immediately if called later) from
351// the last time it was called
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500352static void
353loopTimer (void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400354{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500355 static timespec lastCall;
356 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400357
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500358 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400359 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500360 clock_gettime (CLOCK_MONOTONIC, &lastCall);
361 initialized = 1;
362 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400363 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400364
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500365 do
366 {
367 timespec curTime;
368 clock_gettime (CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400369
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500370 timespec diff = TWFunc::timespec_diff (lastCall, curTime);
371
372 // This is really 30 times per second
373 if (diff.tv_sec || diff.tv_nsec > 33333333)
374 {
375 lastCall = curTime;
376 return;
377 }
378
379 // We need to sleep some period time microseconds
380 unsigned int sleepTime = 33333 - (diff.tv_nsec / 1000);
381 usleep (sleepTime);
382 }
383 while (1);
384 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400385}
386
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500387static int
388runPages (void)
389{
390 // Raise the curtain
391 if (gCurtain != NULL)
392 {
393 gr_surface surface;
394
395 PageManager::Render ();
396 gr_get_surface (&surface);
397 curtainRaise (surface);
398 gr_free_surface (surface);
399 }
400
401 gGuiRunning = 1;
402
403 DataManager::SetValue ("tw_loaded", 1);
404
405 for (;;)
406 {
407 loopTimer ();
408
409 if (!gForceRender)
410 {
411 int ret;
412
413 ret = PageManager::Update ();
414 if (ret > 1)
415 PageManager::Render ();
416
417 if (ret > 0)
418 flip ();
419 }
420 else
421 {
422 pthread_mutex_lock(&gForceRendermutex);
423 gForceRender = 0;
424 pthread_mutex_unlock(&gForceRendermutex);
425 PageManager::Render ();
426 flip ();
427 }
Dees_Troy6ef66352013-02-21 08:26:57 -0600428 if (DataManager::GetIntValue("tw_gui_done") != 0)
429 {
430 break;
431 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500432 }
433
434 gGuiRunning = 0;
435 return 0;
436}
437
438static int
439runPage (const char *page_name)
440{
441 gui_changePage (page_name);
442
443 // Raise the curtain
444 if (gCurtain != NULL)
445 {
446 gr_surface surface;
447
448 PageManager::Render ();
449 gr_get_surface (&surface);
450 curtainRaise (surface);
451 gr_free_surface (surface);
452 }
453
454 gGuiRunning = 1;
455
456 DataManager::SetValue ("tw_loaded", 1);
457
458 for (;;)
459 {
460 loopTimer ();
461
462 if (!gForceRender)
463 {
464 int ret;
465
466 ret = PageManager::Update ();
467 if (ret > 1)
468 PageManager::Render ();
469
470 if (ret > 0)
471 flip ();
472 }
473 else
474 {
475 pthread_mutex_lock(&gForceRendermutex);
476 gForceRender = 0;
477 pthread_mutex_unlock(&gForceRendermutex);
478 PageManager::Render ();
479 flip ();
480 }
481 if (DataManager::GetIntValue ("tw_page_done") != 0)
482 {
483 gui_changePage ("main");
484 break;
485 }
486 }
487
488 gGuiRunning = 0;
489 return 0;
490}
491
492int
493gui_forceRender (void)
494{
495 pthread_mutex_lock(&gForceRendermutex);
496 gForceRender = 1;
497 pthread_mutex_unlock(&gForceRendermutex);
498 return 0;
499}
500
501int
502gui_changePage (std::string newPage)
503{
Dees_Troy2673cec2013-04-02 20:22:16 +0000504 LOGINFO("Set page: '%s'\n", newPage.c_str ());
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500505 PageManager::ChangePage (newPage);
506 pthread_mutex_lock(&gForceRendermutex);
507 gForceRender = 1;
508 pthread_mutex_unlock(&gForceRendermutex);
509 return 0;
510}
511
512int
513gui_changeOverlay (std::string overlay)
514{
515 PageManager::ChangeOverlay (overlay);
516 pthread_mutex_lock(&gForceRendermutex);
517 gForceRender = 1;
518 pthread_mutex_unlock(&gForceRendermutex);
519 return 0;
520}
521
522int
523gui_changePackage (std::string newPackage)
524{
525 PageManager::SelectPackage (newPackage);
526 pthread_mutex_lock(&gForceRendermutex);
527 gForceRender = 1;
528 pthread_mutex_unlock(&gForceRendermutex);
529 return 0;
530}
531
532std::string gui_parse_text (string inText)
533{
534 // Copied from std::string GUIText::parseText(void)
535 // This function parses text for DataManager values encompassed by %value% in the XML
536 static int counter = 0;
537 std::string str = inText;
538 size_t pos = 0;
539 size_t next = 0, end = 0;
540
541 while (1)
542 {
543 next = str.find ('%', pos);
544 if (next == std::string::npos)
545 return str;
546 end = str.find ('%', next + 1);
547 if (end == std::string::npos)
548 return str;
549
550 // We have a block of data
551 std::string var = str.substr (next + 1, (end - next) - 1);
552 str.erase (next, (end - next) + 1);
553
554 if (next + 1 == end)
555 {
556 str.insert (next, 1, '%');
557 }
558 else
559 {
560 std::string value;
561 if (DataManager::GetValue (var, value) == 0)
562 str.insert (next, value);
563 }
564
565 pos = next + 1;
566 }
567}
568
569extern "C" int
570gui_init ()
571{
572 int fd;
573
574 gr_init ();
575
576 if (res_create_surface ("/res/images/curtain.jpg", &gCurtain))
577 {
578 printf
579 ("Unable to locate '/res/images/curtain.jpg'\nDid you set a DEVICE_RESOLUTION in your config files?\n");
580 return -1;
581 }
582
583 curtainSet ();
584
585 ev_init ();
586 return 0;
587}
588
589extern "C" int
590gui_loadResources ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400591{
Dees_Troy51a0e822012-09-05 15:24:24 -0400592// unlink("/sdcard/video.last");
593// rename("/sdcard/video.bin", "/sdcard/video.last");
594// gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
595
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500596 int check = 0;
597 DataManager::GetValue (TW_IS_ENCRYPTED, check);
598 if (check)
599 {
600 if (PageManager::LoadPackage ("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400601 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000602 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500603 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400604 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500605 else
606 check = 1;
607 }
608 if (check == 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000609 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500610 {
611 std::string theme_path;
Dees_Troy51a0e822012-09-05 15:24:24 -0400612
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500613 theme_path = DataManager::GetSettingsStoragePath ();
Dees_Troy2673cec2013-04-02 20:22:16 +0000614 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400615 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500616 int retry_count = 5;
617 while (retry_count > 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000618 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400619 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500620 usleep (500000);
621 retry_count--;
622 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000623 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500624 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000625 LOGERR("Unable to mount %s during GUI startup.\n",
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500626 theme_path.c_str ());
627 check = 1;
628 }
629 }
630
631 theme_path += "/TWRP/theme/ui.zip";
Dees_Troy2673cec2013-04-02 20:22:16 +0000632 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500633 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000634 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500635 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000636 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500637 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400638 }
639 }
640 }
641
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500642 // Set the default package
643 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400644
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500645 gGuiInitialized = 1;
646 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400647
648error:
Dees_Troy2673cec2013-04-02 20:22:16 +0000649 LOGERR("An internal error has occurred.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500650 gGuiInitialized = 0;
651 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400652}
653
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500654extern "C" int
655gui_start ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400656{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500657 if (!gGuiInitialized)
658 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400659
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500660 gGuiConsoleTerminate = 1;
661 while (gGuiConsoleRunning)
662 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400663
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500664 // Set the default package
665 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400666
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500667 if (!gGuiInputRunning)
668 {
669 // Start by spinning off an input handler.
670 pthread_t t;
671 pthread_create (&t, NULL, input_thread, NULL);
672 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000673 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400674
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500675 return runPages ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400676}
677
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500678extern "C" int
679gui_startPage (const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000680{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500681 if (!gGuiInitialized)
682 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000683
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500684 gGuiConsoleTerminate = 1;
685 while (gGuiConsoleRunning)
686 loopTimer ();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000687
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500688 // Set the default package
Dees_Troy2673cec2013-04-02 20:22:16 +0000689 PageManager::SelectPackage("TWRP");
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000690
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500691 if (!gGuiInputRunning)
692 {
693 // Start by spinning off an input handler.
694 pthread_t t;
695 pthread_create (&t, NULL, input_thread, NULL);
696 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000697 }
698
Dees_Troy2673cec2013-04-02 20:22:16 +0000699 DataManager::SetValue("tw_page_done", 0);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500700 return runPage (page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000701}
702
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500703static void *
704console_thread (void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400705{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500706 PageManager::SwitchToConsole ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400707
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500708 while (!gGuiConsoleTerminate)
709 {
710 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400711
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500712 if (!gForceRender)
713 {
714 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400715
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500716 ret = PageManager::Update ();
717 if (ret > 1)
718 PageManager::Render ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400719
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500720 if (ret > 0)
721 flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400722
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500723 if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000724 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500725 }
726 else
727 {
728 pthread_mutex_lock(&gForceRendermutex);
729 gForceRender = 0;
730 pthread_mutex_unlock(&gForceRendermutex);
731 PageManager::Render ();
732 flip ();
733 }
734 }
735 gGuiConsoleRunning = 0;
736 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400737}
738
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500739extern "C" int
740gui_console_only ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400741{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500742 if (!gGuiInitialized)
743 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400744
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500745 gGuiConsoleTerminate = 0;
746 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400747
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500748 // Start by spinning off an input handler.
749 pthread_t t;
750 pthread_create (&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400751
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500752 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400753}