blob: bf44b38561bfc46e25060a97f03f34bbd0f5e5e4 [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 }
276 else if (type == "listbox")
277 {
278 GUIListBox* element = new GUIListBox(child);
279 mRenders.push_back(element);
280 mActions.push_back(element);
281 }
282 else if (type == "keyboard")
283 {
284 GUIKeyboard* element = new GUIKeyboard(child);
285 mRenders.push_back(element);
286 mActions.push_back(element);
287 }
288 else if (type == "input")
289 {
290 GUIInput* element = new GUIInput(child);
291 mRenders.push_back(element);
292 mActions.push_back(element);
293 mInputs.push_back(element);
294 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500295 else if (type == "partitionlist")
296 {
297 GUIPartitionList* element = new GUIPartitionList(child);
298 mRenders.push_back(element);
299 mActions.push_back(element);
300 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400301 else if (type == "template")
302 {
303 if (!templates || !child->first_attribute("name"))
304 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000305 LOGERR("Invalid template request.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400306 }
307 else
308 {
309 std::string name = child->first_attribute("name")->value();
310
311 // We need to find the correct template
312 xml_node<>* node;
313 node = templates->first_node("template");
314
315 while (node)
316 {
317 if (!node->first_attribute("name"))
318 continue;
319
320 if (name == node->first_attribute("name")->value())
321 {
322 if (!ProcessNode(node, templates, depth + 1))
323 return false;
324 else
325 break;
326 }
327 node = node->next_sibling("template");
328 }
329 }
330 }
331 else
332 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000333 LOGERR("Unknown object type.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400334 }
335 child = child->next_sibling("object");
336 }
337 return true;
338}
339
340int Page::Render(void)
341{
342 // Render background
343 gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
344 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
345
346 // Render remaining objects
347 std::vector<RenderObject*>::iterator iter;
348 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
349 {
350 if ((*iter)->Render())
Dees_Troy2673cec2013-04-02 20:22:16 +0000351 LOGERR("A render request has failed.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400352 }
353 return 0;
354}
355
356int Page::Update(void)
357{
358 int retCode = 0;
359
360 std::vector<RenderObject*>::iterator iter;
361 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
362 {
363 int ret = (*iter)->Update();
364 if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000365 LOGERR("An update request has failed.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400366 else if (ret > retCode)
367 retCode = ret;
368 }
369
370 return retCode;
371}
372
373int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
374{
375 // By default, return 1 to ignore further touches if nobody is listening
376 int ret = 1;
377
378 // Don't try to handle a lack of handlers
379 if (mActions.size() == 0) return ret;
380
381 // We record mTouchStart so we can pass all the touch stream to the same handler
382 if (state == TOUCH_START)
383 {
384 std::vector<ActionObject*>::reverse_iterator iter;
385 // We work backwards, from top-most element to bottom-most element
386 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
387 {
388 if ((*iter)->IsInRegion(x, y))
389 {
390 mTouchStart = (*iter);
391 ret = mTouchStart->NotifyTouch(state, x, y);
392 if (ret >= 0) break;
393 mTouchStart = NULL;
394 }
395 }
396 }
397 else if (state == TOUCH_RELEASE && mTouchStart != NULL)
398 {
399 ret = mTouchStart->NotifyTouch(state, x, y);
400 mTouchStart = NULL;
401 }
402 else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
403 {
404 ret = mTouchStart->NotifyTouch(state, x, y);
405 }
406 return ret;
407}
408
409int Page::NotifyKey(int key)
410{
411 std::vector<ActionObject*>::reverse_iterator iter;
412
413 // Don't try to handle a lack of handlers
414 if (mActions.size() == 0) return 1;
415
416 // We work backwards, from top-most element to bottom-most element
417 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
418 {
419 int ret = (*iter)->NotifyKey(key);
420 if (ret == 0)
421 return 0;
422 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000423 LOGERR("An action handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400424 }
425 return 1;
426}
427
428int Page::NotifyKeyboard(int key)
429{
430 std::vector<InputObject*>::reverse_iterator iter;
431
432 // Don't try to handle a lack of handlers
433 if (mInputs.size() == 0) return 1;
434
435 // We work backwards, from top-most element to bottom-most element
436 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
437 {
438 int ret = (*iter)->NotifyKeyboard(key);
439 if (ret == 0)
440 return 0;
441 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000442 LOGERR("A keyboard handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400443 }
444 return 1;
445}
446
447int Page::SetKeyBoardFocus(int inFocus)
448{
449 std::vector<InputObject*>::reverse_iterator iter;
450
451 // Don't try to handle a lack of handlers
452 if (mInputs.size() == 0) return 1;
453
454 // We work backwards, from top-most element to bottom-most element
455 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
456 {
457 int ret = (*iter)->SetInputFocus(inFocus);
458 if (ret == 0)
459 return 0;
460 else if (ret < 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000461 LOGERR("An input focus handler has returned an error");
Dees_Troy51a0e822012-09-05 15:24:24 -0400462 }
463 return 1;
464}
465
466void Page::SetPageFocus(int inFocus)
467{
468 // Render remaining objects
469 std::vector<RenderObject*>::iterator iter;
470 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
471 {
472 (*iter)->SetPageFocus(inFocus);
473 }
474 return;
475}
476
477int Page::NotifyVarChange(std::string varName, std::string value)
478{
479 std::vector<ActionObject*>::iterator iter;
480
481 // Don't try to handle a lack of handlers
482 if (mActions.size() == 0) return 1;
483
484 for (iter = mActions.begin(); iter != mActions.end(); ++iter)
485 {
486 if ((*iter)->NotifyVarChange(varName, value))
Dees_Troy2673cec2013-04-02 20:22:16 +0000487 LOGERR("An action handler errored on NotifyVarChange.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400488 }
489 return 0;
490}
491
492PageSet::PageSet(char* xmlFile)
493{
494 mResources = NULL;
495 mCurrentPage = NULL;
496 mOverlayPage = NULL;
497
498 mXmlFile = xmlFile;
499 if (xmlFile)
500 mDoc.parse<0>(mXmlFile);
501 else
502 mCurrentPage = new Page(NULL);
503}
504
505PageSet::~PageSet()
506{
507 delete mResources;
508 free(mXmlFile);
509}
510
511int PageSet::Load(ZipArchive* package)
512{
513 xml_node<>* parent;
514 xml_node<>* child;
515 xml_node<>* templates;
516
517 parent = mDoc.first_node("recovery");
518 if (!parent)
519 parent = mDoc.first_node("install");
520
521 // Now, let's parse the XML
Dees_Troy2673cec2013-04-02 20:22:16 +0000522 LOGINFO("Loading resources...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400523 child = parent->first_node("resources");
524 if (child)
525 mResources = new ResourceManager(child, package);
526
Dees_Troy2673cec2013-04-02 20:22:16 +0000527 LOGINFO("Loading variables...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400528 child = parent->first_node("variables");
529 if (child)
530 LoadVariables(child);
531
Dees_Troy2673cec2013-04-02 20:22:16 +0000532 LOGINFO("Loading pages...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400533 // This may be NULL if no templates are present
534 templates = parent->first_node("templates");
535
536 child = parent->first_node("pages");
537 if (!child)
538 return -1;
539
540 return LoadPages(child, templates);
541}
542
543int PageSet::SetPage(std::string page)
544{
545 Page* tmp = FindPage(page);
546 if (tmp)
547 {
548 if (mCurrentPage) mCurrentPage->SetPageFocus(0);
549 mCurrentPage = tmp;
550 mCurrentPage->SetPageFocus(1);
551 mCurrentPage->NotifyVarChange("", "");
552 return 0;
553 }
554 else
555 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000556 LOGERR("Unable to locate page (%s)\n", page.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400557 }
558 return -1;
559}
560
561int PageSet::SetOverlay(Page* page)
562{
563 if (mOverlayPage) mOverlayPage->SetPageFocus(0);
564 mOverlayPage = page;
565 if (mOverlayPage)
566 {
567 mOverlayPage->SetPageFocus(1);
568 mOverlayPage->NotifyVarChange("", "");
569 }
570 return 0;
571}
572
573Resource* PageSet::FindResource(std::string name)
574{
575 return mResources ? mResources->FindResource(name) : NULL;
576}
577
578Page* PageSet::FindPage(std::string name)
579{
580 std::vector<Page*>::iterator iter;
581
582 for (iter = mPages.begin(); iter != mPages.end(); iter++)
583 {
584 if (name == (*iter)->GetName())
585 return (*iter);
586 }
587 return NULL;
588}
589
590int PageSet::LoadVariables(xml_node<>* vars)
591{
592 xml_node<>* child;
593
594 child = vars->first_node("variable");
595 while (child)
596 {
597 if (!child->first_attribute("name"))
598 break;
599 if (!child->first_attribute("value"))
600 break;
601
602 DataManager::SetValue(child->first_attribute("name")->value(), child->first_attribute("value")->value());
603 child = child->next_sibling("variable");
604 }
605 return 0;
606}
607
608int PageSet::LoadPages(xml_node<>* pages, xml_node<>* templates /* = NULL */)
609{
610 xml_node<>* child;
611
612 if (!pages) return -1;
613
614 child = pages->first_node("page");
615 while (child != NULL)
616 {
617 Page* page = new Page(child, templates);
618 if (page->GetName().empty())
619 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000620 LOGERR("Unable to process load page\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400621 delete page;
622 }
623 else
624 {
625 mPages.push_back(page);
626 }
627 child = child->next_sibling("page");
628 }
629 if (mPages.size() > 0)
630 return 0;
631 return -1;
632}
633
634int PageSet::IsCurrentPage(Page* page)
635{
636 return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
637}
638
639int PageSet::Render(void)
640{
641 int ret;
642
643 ret = (mCurrentPage ? mCurrentPage->Render() : -1);
644 if (ret < 0) return ret;
645 ret = (mOverlayPage ? mOverlayPage->Render() : -1);
646 return ret;
647}
648
649int PageSet::Update(void)
650{
651 int ret;
652
653 ret = (mCurrentPage ? mCurrentPage->Update() : -1);
654 if (ret < 0 || ret > 1) return ret;
655 ret = (mOverlayPage ? mOverlayPage->Update() : -1);
656 return ret;
657}
658
659int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
660{
661 if (mOverlayPage) return (mOverlayPage->NotifyTouch(state, x, y));
662 return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
663}
664
665int PageSet::NotifyKey(int key)
666{
667 if (mOverlayPage) return (mOverlayPage->NotifyKey(key));
668 return (mCurrentPage ? mCurrentPage->NotifyKey(key) : -1);
669}
670
671int PageSet::NotifyKeyboard(int key)
672{
673 if (mOverlayPage) return (mOverlayPage->NotifyKeyboard(key));
674 return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
675}
676
677int PageSet::SetKeyBoardFocus(int inFocus)
678{
679 if (mOverlayPage) return (mOverlayPage->SetKeyBoardFocus(inFocus));
680 return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
681}
682
683int PageSet::NotifyVarChange(std::string varName, std::string value)
684{
685 if (mOverlayPage) mOverlayPage->NotifyVarChange(varName, value);
686 return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
687}
688
689int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
690{
691 int fd;
692 ZipArchive zip, *pZip = NULL;
693 long len;
694 char* xmlFile = NULL;
695 PageSet* pageSet = NULL;
696 int ret;
697
698 // Open the XML file
Dees_Troy2673cec2013-04-02 20:22:16 +0000699 LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400700 if (mzOpenZipArchive(package.c_str(), &zip))
701 {
702 // We can try to load the XML directly...
703 struct stat st;
704 if(stat(package.c_str(),&st) != 0)
705 return -1;
706
707 len = st.st_size;
708 xmlFile = (char*) malloc(len + 1);
709 if (!xmlFile) return -1;
710
711 fd = open(package.c_str(), O_RDONLY);
712 if (fd == -1) goto error;
713
714 read(fd, xmlFile, len);
715 close(fd);
716 }
717 else
718 {
719 pZip = &zip;
720 const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml");
721 if (ui_xml == NULL)
722 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000723 LOGERR("Unable to locate ui.xml in zip file\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400724 goto error;
725 }
726
727 // Allocate the buffer for the file
728 len = mzGetZipEntryUncompLen(ui_xml);
729 xmlFile = (char*) malloc(len + 1);
730 if (!xmlFile) goto error;
731
732 if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile))
733 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000734 LOGERR("Unable to extract ui.xml\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400735 goto error;
736 }
737 }
738
739 // NULL-terminate the string
740 xmlFile[len] = 0x00;
741
742 // Before loading, mCurrentSet must be the loading package so we can find resources
743 pageSet = mCurrentSet;
744 mCurrentSet = new PageSet(xmlFile);
745
746 ret = mCurrentSet->Load(pZip);
747 if (ret == 0)
748 {
749 mCurrentSet->SetPage(startpage);
750 mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
751 }
752 else
753 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000754 LOGERR("Package %s failed to load.\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400755 }
756
757 // The first successful package we loaded is the base
758 if (mBaseSet == NULL)
759 mBaseSet = mCurrentSet;
760
761 mCurrentSet = pageSet;
762
763 if (pZip) mzCloseZipArchive(pZip);
764 return ret;
765
766error:
Dees_Troy2673cec2013-04-02 20:22:16 +0000767 LOGERR("An internal error has occurred.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400768 if (pZip) mzCloseZipArchive(pZip);
769 if (xmlFile) free(xmlFile);
770 return -1;
771}
772
773PageSet* PageManager::FindPackage(std::string name)
774{
775 std::map<std::string, PageSet*>::iterator iter;
776
777 iter = mPageSets.find(name);
778 if (iter != mPageSets.end())
779 {
780 return (*iter).second;
781 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000782 LOGERR("Unable to locate package %s\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400783 return NULL;
784}
785
786PageSet* PageManager::SelectPackage(std::string name)
787{
Dees_Troy2673cec2013-04-02 20:22:16 +0000788 LOGINFO("Switching packages (%s)\n", name.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400789 PageSet* tmp;
790
791 tmp = FindPackage(name);
792 if (tmp)
793 mCurrentSet = tmp;
794 else
Dees_Troy2673cec2013-04-02 20:22:16 +0000795 LOGERR("Unable to find package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400796
797 return mCurrentSet;
798}
799
800int PageManager::ReloadPackage(std::string name, std::string package)
801{
802 std::map<std::string, PageSet*>::iterator iter;
803
804 iter = mPageSets.find(name);
805 if (iter == mPageSets.end())
806 return -1;
807
808 PageSet* set = (*iter).second;
809 mPageSets.erase(iter);
810
811 if (LoadPackage(name, package, "main") != 0)
812 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000813 LOGERR("Failed to load package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400814 mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
815 return -1;
816 }
817 if (mCurrentSet == set) SelectPackage(name);
818 delete set;
819 return 0;
820}
821
822void PageManager::ReleasePackage(std::string name)
823{
824 std::map<std::string, PageSet*>::iterator iter;
825
826 iter = mPageSets.find(name);
827 if (iter == mPageSets.end())
828 return;
829
830 PageSet* set = (*iter).second;
831 mPageSets.erase(iter);
832 delete set;
833 return;
834}
835
836int PageManager::ChangePage(std::string name)
837{
838 DataManager::SetValue("tw_operation_state", 0);
839 int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
840 return ret;
841}
842
843int PageManager::ChangeOverlay(std::string name)
844{
845 if (name.empty())
846 return mCurrentSet->SetOverlay(NULL);
847 else
848 {
849 Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
850 return mCurrentSet->SetOverlay(page);
851 }
852}
853
854Resource* PageManager::FindResource(std::string name)
855{
856 return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL);
857}
858
859Resource* PageManager::FindResource(std::string package, std::string name)
860{
861 PageSet* tmp;
862
863 tmp = FindPackage(name);
864 return (tmp ? tmp->FindResource(name) : NULL);
865}
866
867int PageManager::SwitchToConsole(void)
868{
869 PageSet* console = new PageSet(NULL);
870
871 mCurrentSet = console;
872 return 0;
873}
874
875int PageManager::IsCurrentPage(Page* page)
876{
877 return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
878}
879
880int PageManager::Render(void)
881{
882 return (mCurrentSet ? mCurrentSet->Render() : -1);
883}
884
885int PageManager::Update(void)
886{
887 return (mCurrentSet ? mCurrentSet->Update() : -1);
888}
889
890int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
891{
892 return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
893}
894
895int PageManager::NotifyKey(int key)
896{
897 return (mCurrentSet ? mCurrentSet->NotifyKey(key) : -1);
898}
899
900int PageManager::NotifyKeyboard(int key)
901{
902 return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
903}
904
905int PageManager::SetKeyBoardFocus(int inFocus)
906{
907 return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
908}
909
910int PageManager::NotifyVarChange(std::string varName, std::string value)
911{
912 return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
913}
914
915extern "C" void gui_notifyVarChange(const char *name, const char* value)
916{
917 if (!gGuiRunning) return;
918
919 PageManager::NotifyVarChange(name, value);
920}
921