blob: 11fe9b080c54792d0a200d054cb01ba6f6ec6125 [file] [log] [blame]
Dees_Troya13d74f2013-03-24 08:54:55 -05001/*
2 Copyright 2013 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*/
18// pages.cpp - Source to manage GUI base objects
Dees_Troy51a0e822012-09-05 15:24:24 -040019
20#include <stdarg.h>
21#include <stdio.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 <time.h>
32#include <unistd.h>
33#include <stdlib.h>
34
35#include <string>
36
37extern "C" {
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}
41
42#include "rapidxml.hpp"
43#include "objects.hpp"
44
45extern int gGuiRunning;
46
47std::map<std::string, PageSet*> PageManager::mPageSets;
48PageSet* PageManager::mCurrentSet;
49PageSet* PageManager::mBaseSet = NULL;
50
51
52// Helper routine to convert a string to a color declaration
53int ConvertStrToColor(std::string str, COLOR* color)
54{
55 // Set the default, solid black
56 memset(color, 0, sizeof(COLOR));
57 color->alpha = 255;
58
59 // Translate variables
60 DataManager::GetValue(str, str);
61
62 // Look for some defaults
63 if (str == "black") return 0;
64 else if (str == "white") { color->red = color->green = color->blue = 255; return 0; }
65 else if (str == "red") { color->red = 255; return 0; }
66 else if (str == "green") { color->green = 255; return 0; }
67 else if (str == "blue") { color->blue = 255; return 0; }
68
69 // At this point, we require an RGB(A) color
70 if (str[0] != '#') return -1;
71 str.erase(0, 1);
72
Dees_Troy30b962e2012-10-19 20:48:59 -040073 int result;
74 if (str.size() >= 8) {
75 // We have alpha channel
76 string alpha = str.substr(6, 2);
77 result = strtol(alpha.c_str(), NULL, 16);
78 color->alpha = result & 0x000000FF;
79 str.resize(6);
80 result = strtol(str.c_str(), NULL, 16);
81 color->red = (result >> 16) & 0x000000FF;
82 color->green = (result >> 8) & 0x000000FF;
83 color->blue = result & 0x000000FF;
84 } else {
85 result = strtol(str.c_str(), NULL, 16);
86 color->red = (result >> 16) & 0x000000FF;
87 color->green = (result >> 8) & 0x000000FF;
88 color->blue = result & 0x000000FF;
89 }
90 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -040091}
92
93// Helper APIs
94bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */)
95{
96 if (!node) return false;
97
98 std::string value;
99 if (node->first_attribute("x"))
100 {
101 value = node->first_attribute("x")->value();
102 DataManager::GetValue(value, value);
103 *x = atol(value.c_str());
104 }
105
106 if (node->first_attribute("y"))
107 {
108 value = node->first_attribute("y")->value();
109 DataManager::GetValue(value, value);
110 *y = atol(value.c_str());
111 }
112
113 if (w && node->first_attribute("w"))
114 {
115 value = node->first_attribute("w")->value();
116 DataManager::GetValue(value, value);
117 *w = atol(value.c_str());
118 }
119
120 if (h && node->first_attribute("h"))
121 {
122 value = node->first_attribute("h")->value();
123 DataManager::GetValue(value, value);
124 *h = atol(value.c_str());
125 }
126
127 if (placement && node->first_attribute("placement"))
128 {
129 value = node->first_attribute("placement")->value();
130 DataManager::GetValue(value, value);
131 *placement = (RenderObject::Placement) atol(value.c_str());
132 }
133
134 return true;
135}
136
137int ActionObject::SetActionPos(int x, int y, int w, int h)
138{
139 if (x < 0 || y < 0) return -1;
140
141 mActionX = x;
142 mActionY = y;
143 if (w || h)
144 {
145 mActionW = w;
146 mActionH = h;
147 }
148 return 0;
149}
150
151Page::Page(xml_node<>* page, xml_node<>* templates /* = NULL */)
152{
153 mTouchStart = NULL;
154
155 // We can memset the whole structure, because the alpha channel is ignored
156 memset(&mBackground, 0, sizeof(COLOR));
157
158 // With NULL, we make a console-only display
159 if (!page)
160 {
161 mName = "console";
162
163 GUIConsole* element = new GUIConsole(NULL);
164 mRenders.push_back(element);
165 mActions.push_back(element);
166 return;
167 }
168
169 if (page->first_attribute("name"))
170 mName = page->first_attribute("name")->value();
171 else
172 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000173 LOGERR("No page name attribute found!\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400174 return;
175 }
176
Dees_Troy2673cec2013-04-02 20:22:16 +0000177 LOGINFO("Loading page %s\n", mName.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400178
179 // This is a recursive routine for template handling
180 ProcessNode(page, templates);
181
182 return;
183}
184
185bool Page::ProcessNode(xml_node<>* page, xml_node<>* templates /* = NULL */, int depth /* = 0 */)
186{
187 if (depth == 10)
188 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000189 LOGERR("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400190 return false;
191 }
192
193 // Let's retrieve the background value, if any
194 xml_node<>* bg = page->first_node("background");
195 if (bg)
196 {
197 xml_attribute<>* attr = bg->first_attribute("color");
198 if (attr)
199 {
200 std::string color = attr->value();
201 ConvertStrToColor(color, &mBackground);
202 }
203 }
204
205 xml_node<>* child;
206 child = page->first_node("object");
207 while (child)
208 {
209 if (!child->first_attribute("type"))
210 break;
211
212 std::string type = child->first_attribute("type")->value();
213
214 if (type == "text")
215 {
216 GUIText* element = new GUIText(child);
217 mRenders.push_back(element);
218 mActions.push_back(element);
219 }
220 else if (type == "image")
221 {
222 GUIImage* element = new GUIImage(child);
223 mRenders.push_back(element);
224 }
225 else if (type == "fill")
226 {
227 GUIFill* element = new GUIFill(child);
228 mRenders.push_back(element);
229 }
230 else if (type == "action")
231 {
232 GUIAction* element = new GUIAction(child);
233 mActions.push_back(element);
234 }
235 else if (type == "console")
236 {
237 GUIConsole* element = new GUIConsole(child);
238 mRenders.push_back(element);
239 mActions.push_back(element);
240 }
241 else if (type == "button")
242 {
243 GUIButton* element = new GUIButton(child);
244 mRenders.push_back(element);
245 mActions.push_back(element);
246 }
247 else if (type == "checkbox")
248 {
249 GUICheckbox* element = new GUICheckbox(child);
250 mRenders.push_back(element);
251 mActions.push_back(element);
252 }
253 else if (type == "fileselector")
254 {
255 GUIFileSelector* element = new GUIFileSelector(child);
256 mRenders.push_back(element);
257 mActions.push_back(element);
258 }
259 else if (type == "animation")
260 {
261 GUIAnimation* element = new GUIAnimation(child);
262 mRenders.push_back(element);
263 }
264 else if (type == "progressbar")
265 {
266 GUIProgressBar* element = new GUIProgressBar(child);
267 mRenders.push_back(element);
268 mActions.push_back(element);
269 }
270 else if (type == "slider")
271 {
272 GUISlider* element = new GUISlider(child);
273 mRenders.push_back(element);
274 mActions.push_back(element);
275 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200276 else if (type == "slidervalue")
277 {
278 GUISliderValue *element = new GUISliderValue(child);
279 mRenders.push_back(element);
280 mActions.push_back(element);
281 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400282 else if (type == "listbox")
283 {
284 GUIListBox* element = new GUIListBox(child);
285 mRenders.push_back(element);
286 mActions.push_back(element);
287 }
288 else if (type == "keyboard")
289 {
290 GUIKeyboard* element = new GUIKeyboard(child);
291 mRenders.push_back(element);
292 mActions.push_back(element);
293 }
294 else if (type == "input")
295 {
296 GUIInput* element = new GUIInput(child);
297 mRenders.push_back(element);
298 mActions.push_back(element);
299 mInputs.push_back(element);
300 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500301 else if (type == "partitionlist")
302 {
303 GUIPartitionList* element = new GUIPartitionList(child);
304 mRenders.push_back(element);
305 mActions.push_back(element);
306 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400307 else if (type == "template")
308 {
309 if (!templates || !child->first_attribute("name"))
310 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000311 LOGERR("Invalid template request.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400312 }
313 else
314 {
315 std::string name = child->first_attribute("name")->value();
316
317 // We need to find the correct template
318 xml_node<>* node;
319 node = templates->first_node("template");
320
321 while (node)
322 {
323 if (!node->first_attribute("name"))
324 continue;
325
326 if (name == node->first_attribute("name")->value())
327 {
328 if (!ProcessNode(node, templates, depth + 1))
329 return false;
330 else
331 break;
332 }
333 node = node->next_sibling("template");
334 }
335 }
336 }
337 else
338 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000339 LOGERR("Unknown object type.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400340 }
341 child = child->next_sibling("object");
342 }
343 return true;
344}
345
346int Page::Render(void)
347{
348 // Render background
349 gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
350 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
351
352 // Render remaining objects
353 std::vector<RenderObject*>::iterator iter;
354 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
355 {
356 if ((*iter)->Render())
Dees_Troy2673cec2013-04-02 20:22:16 +0000357 LOGERR("A render request has failed.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400358 }
359 return 0;
360}
361
362int Page::Update(void)
363{
364 int retCode = 0;
365
366 std::vector<RenderObject*>::iterator iter;
367 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
368 {
369 int ret = (*iter)->Update();
370 if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000371 LOGERR("An update request has failed.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400372 else if (ret > retCode)
373 retCode = ret;
374 }
375
376 return retCode;
377}
378
379int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
380{
381 // By default, return 1 to ignore further touches if nobody is listening
382 int ret = 1;
383
384 // Don't try to handle a lack of handlers
385 if (mActions.size() == 0) return ret;
386
387 // We record mTouchStart so we can pass all the touch stream to the same handler
388 if (state == TOUCH_START)
389 {
390 std::vector<ActionObject*>::reverse_iterator iter;
391 // We work backwards, from top-most element to bottom-most element
392 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
393 {
394 if ((*iter)->IsInRegion(x, y))
395 {
396 mTouchStart = (*iter);
397 ret = mTouchStart->NotifyTouch(state, x, y);
398 if (ret >= 0) break;
399 mTouchStart = NULL;
400 }
401 }
402 }
403 else if (state == TOUCH_RELEASE && mTouchStart != NULL)
404 {
405 ret = mTouchStart->NotifyTouch(state, x, y);
406 mTouchStart = NULL;
407 }
408 else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
409 {
410 ret = mTouchStart->NotifyTouch(state, x, y);
411 }
412 return ret;
413}
414
415int Page::NotifyKey(int key)
416{
417 std::vector<ActionObject*>::reverse_iterator iter;
418
419 // Don't try to handle a lack of handlers
420 if (mActions.size() == 0) return 1;
421
422 // We work backwards, from top-most element to bottom-most element
423 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
424 {
425 int ret = (*iter)->NotifyKey(key);
426 if (ret == 0)
427 return 0;
428 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000429 LOGERR("An action handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400430 }
431 return 1;
432}
433
434int Page::NotifyKeyboard(int key)
435{
436 std::vector<InputObject*>::reverse_iterator iter;
437
438 // Don't try to handle a lack of handlers
439 if (mInputs.size() == 0) return 1;
440
441 // We work backwards, from top-most element to bottom-most element
442 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
443 {
444 int ret = (*iter)->NotifyKeyboard(key);
445 if (ret == 0)
446 return 0;
447 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000448 LOGERR("A keyboard handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400449 }
450 return 1;
451}
452
453int Page::SetKeyBoardFocus(int inFocus)
454{
455 std::vector<InputObject*>::reverse_iterator iter;
456
457 // Don't try to handle a lack of handlers
458 if (mInputs.size() == 0) return 1;
459
460 // We work backwards, from top-most element to bottom-most element
461 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
462 {
463 int ret = (*iter)->SetInputFocus(inFocus);
464 if (ret == 0)
465 return 0;
466 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000467 LOGERR("An input focus handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400468 }
469 return 1;
470}
471
472void Page::SetPageFocus(int inFocus)
473{
474 // Render remaining objects
475 std::vector<RenderObject*>::iterator iter;
476 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
477 {
478 (*iter)->SetPageFocus(inFocus);
479 }
480 return;
481}
482
483int Page::NotifyVarChange(std::string varName, std::string value)
484{
485 std::vector<ActionObject*>::iterator iter;
486
487 // Don't try to handle a lack of handlers
488 if (mActions.size() == 0) return 1;
489
490 for (iter = mActions.begin(); iter != mActions.end(); ++iter)
491 {
492 if ((*iter)->NotifyVarChange(varName, value))
Dees_Troy2673cec2013-04-02 20:22:16 +0000493 LOGERR("An action handler errored on NotifyVarChange.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400494 }
495 return 0;
496}
497
498PageSet::PageSet(char* xmlFile)
499{
500 mResources = NULL;
501 mCurrentPage = NULL;
502 mOverlayPage = NULL;
503
504 mXmlFile = xmlFile;
505 if (xmlFile)
506 mDoc.parse<0>(mXmlFile);
507 else
508 mCurrentPage = new Page(NULL);
509}
510
511PageSet::~PageSet()
512{
513 delete mResources;
514 free(mXmlFile);
515}
516
517int PageSet::Load(ZipArchive* package)
518{
519 xml_node<>* parent;
520 xml_node<>* child;
521 xml_node<>* templates;
522
523 parent = mDoc.first_node("recovery");
524 if (!parent)
525 parent = mDoc.first_node("install");
526
527 // Now, let's parse the XML
Dees_Troy2673cec2013-04-02 20:22:16 +0000528 LOGINFO("Loading resources...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400529 child = parent->first_node("resources");
530 if (child)
531 mResources = new ResourceManager(child, package);
532
Dees_Troy2673cec2013-04-02 20:22:16 +0000533 LOGINFO("Loading variables...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400534 child = parent->first_node("variables");
535 if (child)
536 LoadVariables(child);
537
Dees_Troy2673cec2013-04-02 20:22:16 +0000538 LOGINFO("Loading pages...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400539 // This may be NULL if no templates are present
540 templates = parent->first_node("templates");
541
542 child = parent->first_node("pages");
543 if (!child)
544 return -1;
545
546 return LoadPages(child, templates);
547}
548
549int PageSet::SetPage(std::string page)
550{
551 Page* tmp = FindPage(page);
552 if (tmp)
553 {
554 if (mCurrentPage) mCurrentPage->SetPageFocus(0);
555 mCurrentPage = tmp;
556 mCurrentPage->SetPageFocus(1);
557 mCurrentPage->NotifyVarChange("", "");
558 return 0;
559 }
560 else
561 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000562 LOGERR("Unable to locate page (%s)\n", page.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400563 }
564 return -1;
565}
566
567int PageSet::SetOverlay(Page* page)
568{
569 if (mOverlayPage) mOverlayPage->SetPageFocus(0);
570 mOverlayPage = page;
571 if (mOverlayPage)
572 {
573 mOverlayPage->SetPageFocus(1);
574 mOverlayPage->NotifyVarChange("", "");
575 }
576 return 0;
577}
578
579Resource* PageSet::FindResource(std::string name)
580{
581 return mResources ? mResources->FindResource(name) : NULL;
582}
583
584Page* PageSet::FindPage(std::string name)
585{
586 std::vector<Page*>::iterator iter;
587
588 for (iter = mPages.begin(); iter != mPages.end(); iter++)
589 {
590 if (name == (*iter)->GetName())
591 return (*iter);
592 }
593 return NULL;
594}
595
596int PageSet::LoadVariables(xml_node<>* vars)
597{
598 xml_node<>* child;
599
600 child = vars->first_node("variable");
601 while (child)
602 {
603 if (!child->first_attribute("name"))
604 break;
605 if (!child->first_attribute("value"))
606 break;
607
608 DataManager::SetValue(child->first_attribute("name")->value(), child->first_attribute("value")->value());
609 child = child->next_sibling("variable");
610 }
611 return 0;
612}
613
614int PageSet::LoadPages(xml_node<>* pages, xml_node<>* templates /* = NULL */)
615{
616 xml_node<>* child;
617
618 if (!pages) return -1;
619
620 child = pages->first_node("page");
621 while (child != NULL)
622 {
623 Page* page = new Page(child, templates);
624 if (page->GetName().empty())
625 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000626 LOGERR("Unable to process load page\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400627 delete page;
628 }
629 else
630 {
631 mPages.push_back(page);
632 }
633 child = child->next_sibling("page");
634 }
635 if (mPages.size() > 0)
636 return 0;
637 return -1;
638}
639
640int PageSet::IsCurrentPage(Page* page)
641{
642 return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
643}
644
645int PageSet::Render(void)
646{
647 int ret;
648
649 ret = (mCurrentPage ? mCurrentPage->Render() : -1);
650 if (ret < 0) return ret;
651 ret = (mOverlayPage ? mOverlayPage->Render() : -1);
652 return ret;
653}
654
655int PageSet::Update(void)
656{
657 int ret;
658
659 ret = (mCurrentPage ? mCurrentPage->Update() : -1);
660 if (ret < 0 || ret > 1) return ret;
661 ret = (mOverlayPage ? mOverlayPage->Update() : -1);
662 return ret;
663}
664
665int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
666{
667 if (mOverlayPage) return (mOverlayPage->NotifyTouch(state, x, y));
668 return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
669}
670
671int PageSet::NotifyKey(int key)
672{
673 if (mOverlayPage) return (mOverlayPage->NotifyKey(key));
674 return (mCurrentPage ? mCurrentPage->NotifyKey(key) : -1);
675}
676
677int PageSet::NotifyKeyboard(int key)
678{
679 if (mOverlayPage) return (mOverlayPage->NotifyKeyboard(key));
680 return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
681}
682
683int PageSet::SetKeyBoardFocus(int inFocus)
684{
685 if (mOverlayPage) return (mOverlayPage->SetKeyBoardFocus(inFocus));
686 return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
687}
688
689int PageSet::NotifyVarChange(std::string varName, std::string value)
690{
691 if (mOverlayPage) mOverlayPage->NotifyVarChange(varName, value);
692 return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
693}
694
695int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
696{
697 int fd;
698 ZipArchive zip, *pZip = NULL;
699 long len;
700 char* xmlFile = NULL;
701 PageSet* pageSet = NULL;
702 int ret;
703
704 // Open the XML file
Dees_Troy2673cec2013-04-02 20:22:16 +0000705 LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400706 if (mzOpenZipArchive(package.c_str(), &zip))
707 {
708 // We can try to load the XML directly...
709 struct stat st;
710 if(stat(package.c_str(),&st) != 0)
711 return -1;
712
713 len = st.st_size;
714 xmlFile = (char*) malloc(len + 1);
715 if (!xmlFile) return -1;
716
717 fd = open(package.c_str(), O_RDONLY);
718 if (fd == -1) goto error;
719
720 read(fd, xmlFile, len);
721 close(fd);
722 }
723 else
724 {
725 pZip = &zip;
726 const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml");
727 if (ui_xml == NULL)
728 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000729 LOGERR("Unable to locate ui.xml in zip file\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400730 goto error;
731 }
732
733 // Allocate the buffer for the file
734 len = mzGetZipEntryUncompLen(ui_xml);
735 xmlFile = (char*) malloc(len + 1);
736 if (!xmlFile) goto error;
737
738 if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile))
739 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000740 LOGERR("Unable to extract ui.xml\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400741 goto error;
742 }
743 }
744
745 // NULL-terminate the string
746 xmlFile[len] = 0x00;
747
748 // Before loading, mCurrentSet must be the loading package so we can find resources
749 pageSet = mCurrentSet;
750 mCurrentSet = new PageSet(xmlFile);
751
752 ret = mCurrentSet->Load(pZip);
753 if (ret == 0)
754 {
755 mCurrentSet->SetPage(startpage);
756 mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
757 }
758 else
759 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000760 LOGERR("Package %s failed to load.\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400761 }
762
763 // The first successful package we loaded is the base
764 if (mBaseSet == NULL)
765 mBaseSet = mCurrentSet;
766
767 mCurrentSet = pageSet;
768
769 if (pZip) mzCloseZipArchive(pZip);
770 return ret;
771
772error:
Dees_Troy2673cec2013-04-02 20:22:16 +0000773 LOGERR("An internal error has occurred.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400774 if (pZip) mzCloseZipArchive(pZip);
775 if (xmlFile) free(xmlFile);
776 return -1;
777}
778
779PageSet* PageManager::FindPackage(std::string name)
780{
781 std::map<std::string, PageSet*>::iterator iter;
782
783 iter = mPageSets.find(name);
784 if (iter != mPageSets.end())
785 {
786 return (*iter).second;
787 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000788 LOGERR("Unable to locate package %s\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400789 return NULL;
790}
791
792PageSet* PageManager::SelectPackage(std::string name)
793{
Dees_Troy2673cec2013-04-02 20:22:16 +0000794 LOGINFO("Switching packages (%s)\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400795 PageSet* tmp;
796
797 tmp = FindPackage(name);
798 if (tmp)
799 mCurrentSet = tmp;
800 else
Dees_Troy2673cec2013-04-02 20:22:16 +0000801 LOGERR("Unable to find package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400802
803 return mCurrentSet;
804}
805
806int PageManager::ReloadPackage(std::string name, std::string package)
807{
808 std::map<std::string, PageSet*>::iterator iter;
809
810 iter = mPageSets.find(name);
811 if (iter == mPageSets.end())
812 return -1;
813
814 PageSet* set = (*iter).second;
815 mPageSets.erase(iter);
816
817 if (LoadPackage(name, package, "main") != 0)
818 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000819 LOGERR("Failed to load package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400820 mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
821 return -1;
822 }
823 if (mCurrentSet == set) SelectPackage(name);
824 delete set;
825 return 0;
826}
827
828void PageManager::ReleasePackage(std::string name)
829{
830 std::map<std::string, PageSet*>::iterator iter;
831
832 iter = mPageSets.find(name);
833 if (iter == mPageSets.end())
834 return;
835
836 PageSet* set = (*iter).second;
837 mPageSets.erase(iter);
838 delete set;
839 return;
840}
841
842int PageManager::ChangePage(std::string name)
843{
844 DataManager::SetValue("tw_operation_state", 0);
845 int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
846 return ret;
847}
848
849int PageManager::ChangeOverlay(std::string name)
850{
851 if (name.empty())
852 return mCurrentSet->SetOverlay(NULL);
853 else
854 {
855 Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
856 return mCurrentSet->SetOverlay(page);
857 }
858}
859
860Resource* PageManager::FindResource(std::string name)
861{
862 return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL);
863}
864
865Resource* PageManager::FindResource(std::string package, std::string name)
866{
867 PageSet* tmp;
868
869 tmp = FindPackage(name);
870 return (tmp ? tmp->FindResource(name) : NULL);
871}
872
873int PageManager::SwitchToConsole(void)
874{
875 PageSet* console = new PageSet(NULL);
876
877 mCurrentSet = console;
878 return 0;
879}
880
881int PageManager::IsCurrentPage(Page* page)
882{
883 return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
884}
885
886int PageManager::Render(void)
887{
888 return (mCurrentSet ? mCurrentSet->Render() : -1);
889}
890
891int PageManager::Update(void)
892{
893 return (mCurrentSet ? mCurrentSet->Update() : -1);
894}
895
896int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
897{
898 return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
899}
900
901int PageManager::NotifyKey(int key)
902{
903 return (mCurrentSet ? mCurrentSet->NotifyKey(key) : -1);
904}
905
906int PageManager::NotifyKeyboard(int key)
907{
908 return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
909}
910
911int PageManager::SetKeyBoardFocus(int inFocus)
912{
913 return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
914}
915
916int PageManager::NotifyVarChange(std::string varName, std::string value)
917{
918 return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
919}
920
921extern "C" void gui_notifyVarChange(const char *name, const char* value)
922{
923 if (!gGuiRunning) return;
924
925 PageManager::NotifyVarChange(name, value);
926}
927