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