blob: 9f221383e3e88d60cb52a0c0641749a9e9a2c296 [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_Troy70e11292013-08-07 15:52:20 +0000188 int screen_width = gr_fb_width();
189 int screen_height = gr_fb_height();
Dees_Troy51a0e822012-09-05 15:24:24 -0400190
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500191 //start screen timeout threads
192 blankTimer.setTimerThread();
bigbiff bigbifff8e2f372013-02-27 20:50:43 -0500193 DataManager::GetValue("tw_screen_timeout_secs", seconds);
194 blankTimer.setTime(atoi(seconds.c_str()));
Dees_Troy51a0e822012-09-05 15:24:24 -0400195
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500196 for (;;)
197 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400198
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500199 // wait for the next event
200 struct input_event ev;
201 int state = 0, ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400202
Dees_Troy70e11292013-08-07 15:52:20 +0000203 ret = ev_get (&ev, dontwait, &screen_width, &screen_height);
Dees_Troy51a0e822012-09-05 15:24:24 -0400204
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500205 if (ret < 0)
206 {
207 struct timeval curTime;
208 gettimeofday (&curTime, NULL);
209 long mtime, seconds, useconds;
Dees_Troy51a0e822012-09-05 15:24:24 -0400210
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500211 seconds = curTime.tv_sec - touchStart.tv_sec;
212 useconds = curTime.tv_usec - touchStart.tv_usec;
213
214 mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
215 if (touch_and_hold && mtime > 500)
216 {
217 touch_and_hold = 0;
218 touch_repeat = 1;
219 gettimeofday (&touchStart, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400220#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000221 LOGERR("TOUCH_HOLD: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400222#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500223 PageManager::NotifyTouch (TOUCH_HOLD, x, y);
224 blankTimer.resetTimerAndUnblank();
Dees_Troy51a0e822012-09-05 15:24:24 -0400225 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500226 else if (touch_repeat && mtime > 100)
227 {
228#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000229 LOGERR("TOUCH_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500230#endif
231 gettimeofday (&touchStart, NULL);
232 PageManager::NotifyTouch (TOUCH_REPEAT, x, y);
233 blankTimer.resetTimerAndUnblank();
234 }
235 else if (key_repeat == 1 && mtime > 500)
236 {
237#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000238 LOGERR("KEY_HOLD: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500239#endif
240 gettimeofday (&touchStart, NULL);
241 key_repeat = 2;
242 kb.KeyRepeat ();
243 blankTimer.resetTimerAndUnblank();
244 }
245 else if (key_repeat == 2 && mtime > 100)
246 {
247#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000248 LOGERR("KEY_REPEAT: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500249#endif
250 gettimeofday (&touchStart, NULL);
251 kb.KeyRepeat ();
252 blankTimer.resetTimerAndUnblank();
253 }
254 }
255 else if (ev.type == EV_ABS)
256 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400257
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500258 x = ev.value >> 16;
259 y = ev.value & 0xFFFF;
Dees_Troy51a0e822012-09-05 15:24:24 -0400260
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500261 if (ev.code == 0)
262 {
263 if (state == 0)
264 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400265#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000266 LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400267#endif
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500268 PageManager::NotifyTouch (TOUCH_RELEASE, x, y);
269 blankTimer.resetTimerAndUnblank();
270 touch_and_hold = 0;
271 touch_repeat = 0;
272 if (!key_repeat)
Dees_Troy51a0e822012-09-05 15:24:24 -0400273 dontwait = 0;
274 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500275 state = 0;
276 drag = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400277 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500278 else
279 {
280 if (!drag)
281 {
282#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000283 LOGERR("TOUCH_START: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500284#endif
285 if (PageManager::NotifyTouch (TOUCH_START, x, y) > 0)
286 state = 1;
287 drag = 1;
288 touch_and_hold = 1;
289 dontwait = 1;
290 key_repeat = 0;
291 gettimeofday (&touchStart, NULL);
292 blankTimer.resetTimerAndUnblank();
293 }
294 else
295 {
296 if (state == 0)
297 {
298#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000299 LOGERR("TOUCH_DRAG: %d,%d\n", x, y);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500300#endif
301 if (PageManager::NotifyTouch (TOUCH_DRAG, x, y) > 0)
302 state = 1;
303 key_repeat = 0;
304 blankTimer.resetTimerAndUnblank();
305 }
306 }
307 }
308 }
309 else if (ev.type == EV_KEY)
310 {
311 // Handle key-press here
312#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000313 LOGERR("TOUCH_KEY: %d\n", ev.code);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500314#endif
315 if (ev.value != 0)
316 {
317 // This is a key press
318 if (kb.KeyDown (ev.code))
319 {
320 key_repeat = 1;
321 touch_and_hold = 0;
322 touch_repeat = 0;
323 dontwait = 1;
324 gettimeofday (&touchStart, NULL);
325 blankTimer.resetTimerAndUnblank();
326 }
327 else
328 {
329 key_repeat = 0;
330 touch_and_hold = 0;
331 touch_repeat = 0;
332 dontwait = 0;
333 blankTimer.resetTimerAndUnblank();
334 }
335 }
336 else
337 {
338 // This is a key release
339 kb.KeyUp (ev.code);
340 key_repeat = 0;
341 touch_and_hold = 0;
342 touch_repeat = 0;
343 dontwait = 0;
344 blankTimer.resetTimerAndUnblank();
345 }
346 }
347 }
348 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400349}
350
351// This special function will return immediately the first time, but then
352// always returns 1/30th of a second (or immediately if called later) from
353// the last time it was called
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500354static void
355loopTimer (void)
Dees_Troy51a0e822012-09-05 15:24:24 -0400356{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500357 static timespec lastCall;
358 static int initialized = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400359
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500360 if (!initialized)
Dees_Troyc8b199c2012-09-24 11:55:07 -0400361 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500362 clock_gettime (CLOCK_MONOTONIC, &lastCall);
363 initialized = 1;
364 return;
Dees_Troyc8b199c2012-09-24 11:55:07 -0400365 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400366
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500367 do
368 {
369 timespec curTime;
370 clock_gettime (CLOCK_MONOTONIC, &curTime);
Dees_Troy51a0e822012-09-05 15:24:24 -0400371
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500372 timespec diff = TWFunc::timespec_diff (lastCall, curTime);
373
374 // This is really 30 times per second
375 if (diff.tv_sec || diff.tv_nsec > 33333333)
376 {
377 lastCall = curTime;
378 return;
379 }
380
381 // We need to sleep some period time microseconds
382 unsigned int sleepTime = 33333 - (diff.tv_nsec / 1000);
383 usleep (sleepTime);
384 }
385 while (1);
386 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400387}
388
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500389static int
390runPages (void)
391{
392 // Raise the curtain
393 if (gCurtain != NULL)
394 {
395 gr_surface surface;
396
397 PageManager::Render ();
398 gr_get_surface (&surface);
399 curtainRaise (surface);
400 gr_free_surface (surface);
401 }
402
403 gGuiRunning = 1;
404
405 DataManager::SetValue ("tw_loaded", 1);
406
407 for (;;)
408 {
409 loopTimer ();
410
411 if (!gForceRender)
412 {
413 int ret;
414
415 ret = PageManager::Update ();
416 if (ret > 1)
417 PageManager::Render ();
418
419 if (ret > 0)
420 flip ();
421 }
422 else
423 {
424 pthread_mutex_lock(&gForceRendermutex);
425 gForceRender = 0;
426 pthread_mutex_unlock(&gForceRendermutex);
427 PageManager::Render ();
428 flip ();
429 }
Dees_Troy6ef66352013-02-21 08:26:57 -0600430 if (DataManager::GetIntValue("tw_gui_done") != 0)
431 {
432 break;
433 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500434 }
435
436 gGuiRunning = 0;
437 return 0;
438}
439
440static int
441runPage (const char *page_name)
442{
443 gui_changePage (page_name);
444
445 // Raise the curtain
446 if (gCurtain != NULL)
447 {
448 gr_surface surface;
449
450 PageManager::Render ();
451 gr_get_surface (&surface);
452 curtainRaise (surface);
453 gr_free_surface (surface);
454 }
455
456 gGuiRunning = 1;
457
458 DataManager::SetValue ("tw_loaded", 1);
459
460 for (;;)
461 {
462 loopTimer ();
463
464 if (!gForceRender)
465 {
466 int ret;
467
468 ret = PageManager::Update ();
469 if (ret > 1)
470 PageManager::Render ();
471
472 if (ret > 0)
473 flip ();
474 }
475 else
476 {
477 pthread_mutex_lock(&gForceRendermutex);
478 gForceRender = 0;
479 pthread_mutex_unlock(&gForceRendermutex);
480 PageManager::Render ();
481 flip ();
482 }
483 if (DataManager::GetIntValue ("tw_page_done") != 0)
484 {
485 gui_changePage ("main");
486 break;
487 }
488 }
489
490 gGuiRunning = 0;
491 return 0;
492}
493
494int
495gui_forceRender (void)
496{
497 pthread_mutex_lock(&gForceRendermutex);
498 gForceRender = 1;
499 pthread_mutex_unlock(&gForceRendermutex);
500 return 0;
501}
502
503int
504gui_changePage (std::string newPage)
505{
Dees_Troy2673cec2013-04-02 20:22:16 +0000506 LOGINFO("Set page: '%s'\n", newPage.c_str ());
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500507 PageManager::ChangePage (newPage);
508 pthread_mutex_lock(&gForceRendermutex);
509 gForceRender = 1;
510 pthread_mutex_unlock(&gForceRendermutex);
511 return 0;
512}
513
514int
515gui_changeOverlay (std::string overlay)
516{
517 PageManager::ChangeOverlay (overlay);
518 pthread_mutex_lock(&gForceRendermutex);
519 gForceRender = 1;
520 pthread_mutex_unlock(&gForceRendermutex);
521 return 0;
522}
523
524int
525gui_changePackage (std::string newPackage)
526{
527 PageManager::SelectPackage (newPackage);
528 pthread_mutex_lock(&gForceRendermutex);
529 gForceRender = 1;
530 pthread_mutex_unlock(&gForceRendermutex);
531 return 0;
532}
533
534std::string gui_parse_text (string inText)
535{
536 // Copied from std::string GUIText::parseText(void)
537 // This function parses text for DataManager values encompassed by %value% in the XML
538 static int counter = 0;
539 std::string str = inText;
540 size_t pos = 0;
541 size_t next = 0, end = 0;
542
543 while (1)
544 {
545 next = str.find ('%', pos);
546 if (next == std::string::npos)
547 return str;
548 end = str.find ('%', next + 1);
549 if (end == std::string::npos)
550 return str;
551
552 // We have a block of data
553 std::string var = str.substr (next + 1, (end - next) - 1);
554 str.erase (next, (end - next) + 1);
555
556 if (next + 1 == end)
557 {
558 str.insert (next, 1, '%');
559 }
560 else
561 {
562 std::string value;
563 if (DataManager::GetValue (var, value) == 0)
564 str.insert (next, value);
565 }
566
567 pos = next + 1;
568 }
569}
570
571extern "C" int
572gui_init ()
573{
574 int fd;
575
576 gr_init ();
577
578 if (res_create_surface ("/res/images/curtain.jpg", &gCurtain))
579 {
580 printf
581 ("Unable to locate '/res/images/curtain.jpg'\nDid you set a DEVICE_RESOLUTION in your config files?\n");
582 return -1;
583 }
584
585 curtainSet ();
586
587 ev_init ();
588 return 0;
589}
590
591extern "C" int
592gui_loadResources ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400593{
Dees_Troy51a0e822012-09-05 15:24:24 -0400594// unlink("/sdcard/video.last");
595// rename("/sdcard/video.bin", "/sdcard/video.last");
596// gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);
597
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500598 int check = 0;
599 DataManager::GetValue (TW_IS_ENCRYPTED, check);
600 if (check)
601 {
602 if (PageManager::LoadPackage ("TWRP", "/res/ui.xml", "decrypt"))
Dees_Troy5bf43922012-09-07 16:07:55 -0400603 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000604 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500605 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400606 }
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500607 else
608 check = 1;
609 }
610 if (check == 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000611 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500612 {
613 std::string theme_path;
Dees_Troy51a0e822012-09-05 15:24:24 -0400614
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500615 theme_path = DataManager::GetSettingsStoragePath ();
Dees_Troy2673cec2013-04-02 20:22:16 +0000616 if (!PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400617 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500618 int retry_count = 5;
619 while (retry_count > 0
Dees_Troy2673cec2013-04-02 20:22:16 +0000620 && !PartitionManager.Mount_Settings_Storage(false))
Dees_Troy51a0e822012-09-05 15:24:24 -0400621 {
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500622 usleep (500000);
623 retry_count--;
624 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000625 if (!PartitionManager.Mount_Settings_Storage(false))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500626 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000627 LOGERR("Unable to mount %s during GUI startup.\n",
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500628 theme_path.c_str ());
629 check = 1;
630 }
631 }
632
633 theme_path += "/TWRP/theme/ui.zip";
Dees_Troy2673cec2013-04-02 20:22:16 +0000634 if (check || PageManager::LoadPackage("TWRP", theme_path, "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500635 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000636 if (PageManager::LoadPackage("TWRP", "/res/ui.xml", "main"))
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500637 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000638 LOGERR("Failed to load base packages.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500639 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400640 }
641 }
642 }
643
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500644 // Set the default package
645 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400646
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500647 gGuiInitialized = 1;
648 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400649
650error:
Dees_Troy2673cec2013-04-02 20:22:16 +0000651 LOGERR("An internal error has occurred.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500652 gGuiInitialized = 0;
653 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400654}
655
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500656extern "C" int
657gui_start ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400658{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500659 if (!gGuiInitialized)
660 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400661
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500662 gGuiConsoleTerminate = 1;
663 while (gGuiConsoleRunning)
664 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400665
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500666 // Set the default package
667 PageManager::SelectPackage ("TWRP");
Dees_Troy51a0e822012-09-05 15:24:24 -0400668
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500669 if (!gGuiInputRunning)
670 {
671 // Start by spinning off an input handler.
672 pthread_t t;
673 pthread_create (&t, NULL, input_thread, NULL);
674 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000675 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400676
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500677 return runPages ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400678}
679
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500680extern "C" int
681gui_startPage (const char *page_name)
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000682{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500683 if (!gGuiInitialized)
684 return -1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000685
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500686 gGuiConsoleTerminate = 1;
687 while (gGuiConsoleRunning)
688 loopTimer ();
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000689
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500690 // Set the default package
Dees_Troy2673cec2013-04-02 20:22:16 +0000691 PageManager::SelectPackage("TWRP");
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000692
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500693 if (!gGuiInputRunning)
694 {
695 // Start by spinning off an input handler.
696 pthread_t t;
697 pthread_create (&t, NULL, input_thread, NULL);
698 gGuiInputRunning = 1;
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000699 }
700
Dees_Troy2673cec2013-04-02 20:22:16 +0000701 DataManager::SetValue("tw_page_done", 0);
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500702 return runPage (page_name);
Dees_Troy4bc09ae2013-01-18 17:00:54 +0000703}
704
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500705static void *
706console_thread (void *cookie)
Dees_Troy51a0e822012-09-05 15:24:24 -0400707{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500708 PageManager::SwitchToConsole ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400709
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500710 while (!gGuiConsoleTerminate)
711 {
712 loopTimer ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400713
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500714 if (!gForceRender)
715 {
716 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400717
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500718 ret = PageManager::Update ();
719 if (ret > 1)
720 PageManager::Render ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400721
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500722 if (ret > 0)
723 flip ();
Dees_Troy51a0e822012-09-05 15:24:24 -0400724
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500725 if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000726 LOGERR("An update request has failed.\n");
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500727 }
728 else
729 {
730 pthread_mutex_lock(&gForceRendermutex);
731 gForceRender = 0;
732 pthread_mutex_unlock(&gForceRendermutex);
733 PageManager::Render ();
734 flip ();
735 }
736 }
737 gGuiConsoleRunning = 0;
738 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400739}
740
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500741extern "C" int
742gui_console_only ()
Dees_Troy51a0e822012-09-05 15:24:24 -0400743{
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500744 if (!gGuiInitialized)
745 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400746
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500747 gGuiConsoleTerminate = 0;
748 gGuiConsoleRunning = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400749
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500750 // Start by spinning off an input handler.
751 pthread_t t;
752 pthread_create (&t, NULL, console_thread, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400753
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500754 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400755}