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