blob: 0a1de96f37f069a1f036629800e5f2a2264bf4d5 [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*/
Dees Troy3be70a82013-10-22 14:25:12 +000018
Dees_Troya13d74f2013-03-24 08:54:55 -050019// pages.cpp - Source to manage GUI base objects
Dees_Troy51a0e822012-09-05 15:24:24 -040020
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <fcntl.h>
26#include <sys/reboot.h>
27#include <sys/stat.h>
28#include <sys/time.h>
29#include <sys/mman.h>
30#include <sys/types.h>
31#include <sys/ioctl.h>
32#include <time.h>
33#include <unistd.h>
34#include <stdlib.h>
Ethan Yonkera2dc2f22014-11-08 08:13:40 -060035#include "../twrp-functions.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040036
37#include <string>
38
39extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000040#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040041#include "../minuitwrp/minui.h"
Ethan Yonkera2dc2f22014-11-08 08:13:40 -060042#include "../minzip/SysUtil.h"
43#include "../minzip/Zip.h"
Ethan Yonker63e414f2015-02-06 15:44:39 -060044#include "gui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040045}
46
47#include "rapidxml.hpp"
48#include "objects.hpp"
gordon13370d9133d2013-06-08 14:17:07 +020049#include "blanktimer.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040050
51extern int gGuiRunning;
52
53std::map<std::string, PageSet*> PageManager::mPageSets;
54PageSet* PageManager::mCurrentSet;
55PageSet* PageManager::mBaseSet = NULL;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +010056MouseCursor *PageManager::mMouseCursor = NULL;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +010057HardwareKeyboard *PageManager::mHardwareKeyboard = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -040058
Ethan Yonker751a85e2014-12-12 16:59:10 -060059int tw_x_offset = 0;
60int tw_y_offset = 0;
61
Dees_Troy51a0e822012-09-05 15:24:24 -040062// Helper routine to convert a string to a color declaration
63int ConvertStrToColor(std::string str, COLOR* color)
64{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020065 // Set the default, solid black
66 memset(color, 0, sizeof(COLOR));
67 color->alpha = 255;
Dees_Troy51a0e822012-09-05 15:24:24 -040068
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020069 // Translate variables
70 DataManager::GetValue(str, str);
Matt Mowerfb1c4ff2014-04-16 13:43:36 -050071
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020072 // Look for some defaults
thatf6ed8fc2015-02-14 20:23:16 +010073 if (str == "black") return 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020074 else if (str == "white") { color->red = color->green = color->blue = 255; return 0; }
75 else if (str == "red") { color->red = 255; return 0; }
76 else if (str == "green") { color->green = 255; return 0; }
77 else if (str == "blue") { color->blue = 255; return 0; }
Dees_Troy51a0e822012-09-05 15:24:24 -040078
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020079 // At this point, we require an RGB(A) color
80 if (str[0] != '#')
81 return -1;
82
83 str.erase(0, 1);
Dees_Troy51a0e822012-09-05 15:24:24 -040084
Dees_Troy30b962e2012-10-19 20:48:59 -040085 int result;
86 if (str.size() >= 8) {
87 // We have alpha channel
88 string alpha = str.substr(6, 2);
89 result = strtol(alpha.c_str(), NULL, 16);
90 color->alpha = result & 0x000000FF;
91 str.resize(6);
92 result = strtol(str.c_str(), NULL, 16);
93 color->red = (result >> 16) & 0x000000FF;
94 color->green = (result >> 8) & 0x000000FF;
95 color->blue = result & 0x000000FF;
96 } else {
97 result = strtol(str.c_str(), NULL, 16);
98 color->red = (result >> 16) & 0x000000FF;
99 color->green = (result >> 8) & 0x000000FF;
100 color->blue = result & 0x000000FF;
101 }
102 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400103}
104
105// Helper APIs
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600106xml_node<>* FindNode(xml_node<>* parent, const char* nodename, int depth /* = 0 */)
107{
that8d46c092015-02-26 01:30:04 +0100108 if (!parent)
109 return NULL;
110
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600111 xml_node<>* child = parent->first_node(nodename);
112 if (child)
113 return child;
114
115 if (depth == 10) {
116 LOGERR("Too many style loops detected.\n");
117 return NULL;
118 }
119
120 xml_node<>* style = parent->first_node("style");
121 if (style) {
122 while (style) {
123 if (!style->first_attribute("name")) {
124 LOGERR("No name given for style.\n");
125 continue;
126 } else {
127 std::string name = style->first_attribute("name")->value();
128 xml_node<>* node = PageManager::FindStyle(name);
129
130 if (node) {
131 // We found the style that was named
132 xml_node<>* stylenode = FindNode(node, nodename, depth + 1);
133 if (stylenode)
134 return stylenode;
135 }
136 }
137 style = style->next_sibling("style");
138 }
139 } else {
that54e9c832015-11-04 21:46:01 +0100140 // Search for stylename in the parent node <object type="foo" style="foo2">
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600141 xml_attribute<>* attr = parent->first_attribute("style");
142 // If no style is found anywhere else and the node wasn't found in the object itself
143 // as a special case we will search for a style that uses the same style name as the
144 // object type, so <object type="button"> would search for a style named "button"
145 if (!attr)
146 attr = parent->first_attribute("type");
that54e9c832015-11-04 21:46:01 +0100147 // if there's no attribute type, the object type must be the element name
148 std::string stylename = attr ? attr->value() : parent->name();
149 xml_node<>* node = PageManager::FindStyle(stylename);
150 if (node) {
151 xml_node<>* stylenode = FindNode(node, nodename, depth + 1);
152 if (stylenode)
153 return stylenode;
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600154 }
155 }
156 return NULL;
157}
158
thatf6ed8fc2015-02-14 20:23:16 +0100159std::string LoadAttrString(xml_node<>* element, const char* attrname, const char* defaultvalue)
160{
161 if (!element)
162 return defaultvalue;
163
164 xml_attribute<>* attr = element->first_attribute(attrname);
165 return attr ? attr->value() : defaultvalue;
166}
167
168int LoadAttrInt(xml_node<>* element, const char* attrname, int defaultvalue)
169{
170 string value = LoadAttrString(element, attrname);
171 // resolve variables
172 DataManager::GetValue(value, value);
173 return value.empty() ? defaultvalue : atoi(value.c_str());
174}
175
176int LoadAttrIntScaleX(xml_node<>* element, const char* attrname, int defaultvalue)
177{
178 return scale_theme_x(LoadAttrInt(element, attrname, defaultvalue));
179}
180
181int LoadAttrIntScaleY(xml_node<>* element, const char* attrname, int defaultvalue)
182{
183 return scale_theme_y(LoadAttrInt(element, attrname, defaultvalue));
184}
185
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600186COLOR LoadAttrColor(xml_node<>* element, const char* attrname, bool* found_color, COLOR defaultvalue)
thatf6ed8fc2015-02-14 20:23:16 +0100187{
188 string value = LoadAttrString(element, attrname);
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600189 *found_color = !value.empty();
thatf6ed8fc2015-02-14 20:23:16 +0100190 // resolve variables
191 DataManager::GetValue(value, value);
192 COLOR ret = defaultvalue;
193 if (ConvertStrToColor(value, &ret) == 0)
194 return ret;
195 else
196 return defaultvalue;
197}
198
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600199COLOR LoadAttrColor(xml_node<>* element, const char* attrname, COLOR defaultvalue)
200{
201 bool found_color = false;
202 return LoadAttrColor(element, attrname, &found_color, defaultvalue);
203}
204
thatf6ed8fc2015-02-14 20:23:16 +0100205FontResource* LoadAttrFont(xml_node<>* element, const char* attrname)
206{
207 std::string name = LoadAttrString(element, attrname, "");
208 if (name.empty())
209 return NULL;
210 else
that74ac6062015-03-04 22:39:34 +0100211 return PageManager::GetResources()->FindFont(name);
thatf6ed8fc2015-02-14 20:23:16 +0100212}
213
214ImageResource* LoadAttrImage(xml_node<>* element, const char* attrname)
215{
216 std::string name = LoadAttrString(element, attrname, "");
217 if (name.empty())
218 return NULL;
219 else
that74ac6062015-03-04 22:39:34 +0100220 return PageManager::GetResources()->FindImage(name);
thatf6ed8fc2015-02-14 20:23:16 +0100221}
222
223AnimationResource* LoadAttrAnimation(xml_node<>* element, const char* attrname)
224{
225 std::string name = LoadAttrString(element, attrname, "");
226 if (name.empty())
227 return NULL;
228 else
that74ac6062015-03-04 22:39:34 +0100229 return PageManager::GetResources()->FindAnimation(name);
thatf6ed8fc2015-02-14 20:23:16 +0100230}
231
Ethan Yonkerb7a54a32015-10-05 10:16:27 -0500232bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, Placement* placement /* = NULL */)
Dees_Troy51a0e822012-09-05 15:24:24 -0400233{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200234 if (!node)
235 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400236
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200237 if (node->first_attribute("x"))
thatf6ed8fc2015-02-14 20:23:16 +0100238 *x = LoadAttrIntScaleX(node, "x") + tw_x_offset;
Dees_Troy51a0e822012-09-05 15:24:24 -0400239
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200240 if (node->first_attribute("y"))
thatf6ed8fc2015-02-14 20:23:16 +0100241 *y = LoadAttrIntScaleY(node, "y") + tw_y_offset;
Dees_Troy51a0e822012-09-05 15:24:24 -0400242
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200243 if (w && node->first_attribute("w"))
thatf6ed8fc2015-02-14 20:23:16 +0100244 *w = LoadAttrIntScaleX(node, "w");
Dees_Troy51a0e822012-09-05 15:24:24 -0400245
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200246 if (h && node->first_attribute("h"))
thatf6ed8fc2015-02-14 20:23:16 +0100247 *h = LoadAttrIntScaleY(node, "h");
Dees_Troy51a0e822012-09-05 15:24:24 -0400248
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200249 if (placement && node->first_attribute("placement"))
Ethan Yonkerb7a54a32015-10-05 10:16:27 -0500250 *placement = (Placement) LoadAttrInt(node, "placement");
Dees_Troy51a0e822012-09-05 15:24:24 -0400251
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200252 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400253}
254
255int ActionObject::SetActionPos(int x, int y, int w, int h)
256{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 if (x < 0 || y < 0)
258 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400259
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500260 mActionX = x;
261 mActionY = y;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200262 if (w || h)
263 {
264 mActionW = w;
265 mActionH = h;
266 }
267 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400268}
269
thatb63e2f92015-06-27 21:35:11 +0200270Page::Page(xml_node<>* page, std::vector<xml_node<>*> *templates)
Dees_Troy51a0e822012-09-05 15:24:24 -0400271{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200272 mTouchStart = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400273
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200274 // We can memset the whole structure, because the alpha channel is ignored
275 memset(&mBackground, 0, sizeof(COLOR));
Dees_Troy51a0e822012-09-05 15:24:24 -0400276
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200277 // With NULL, we make a console-only display
278 if (!page)
279 {
280 mName = "console";
Dees_Troy51a0e822012-09-05 15:24:24 -0400281
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200282 GUIConsole* element = new GUIConsole(NULL);
283 mRenders.push_back(element);
284 mActions.push_back(element);
285 return;
286 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400287
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200288 if (page->first_attribute("name"))
289 mName = page->first_attribute("name")->value();
290 else
291 {
292 LOGERR("No page name attribute found!\n");
293 return;
294 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400295
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200296 LOGINFO("Loading page %s\n", mName.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400297
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200298 // This is a recursive routine for template handling
thatb63e2f92015-06-27 21:35:11 +0200299 ProcessNode(page, templates, 0);
Dees_Troy51a0e822012-09-05 15:24:24 -0400300}
301
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100302Page::~Page()
303{
304 for (std::vector<GUIObject*>::iterator itr = mObjects.begin(); itr != mObjects.end(); ++itr)
305 delete *itr;
306}
307
thatb63e2f92015-06-27 21:35:11 +0200308bool Page::ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates, int depth)
Dees_Troy51a0e822012-09-05 15:24:24 -0400309{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200310 if (depth == 10)
311 {
312 LOGERR("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n");
313 return false;
314 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400315
thatb63e2f92015-06-27 21:35:11 +0200316 for (xml_node<>* child = page->first_node(); child; child = child->next_sibling())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200317 {
thatb63e2f92015-06-27 21:35:11 +0200318 std::string type = child->name();
319
320 if (type == "background") {
321 mBackground = LoadAttrColor(child, "color", COLOR(0,0,0,0));
322 continue;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200323 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400324
thatb63e2f92015-06-27 21:35:11 +0200325 if (type == "object") {
326 // legacy format : <object type="...">
327 xml_attribute<>* attr = child->first_attribute("type");
328 type = attr ? attr->value() : "*unspecified*";
329 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400330
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200331 if (type == "text")
332 {
333 GUIText* element = new GUIText(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100334 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200335 mRenders.push_back(element);
336 mActions.push_back(element);
337 }
338 else if (type == "image")
339 {
340 GUIImage* element = new GUIImage(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100341 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200342 mRenders.push_back(element);
343 }
344 else if (type == "fill")
345 {
346 GUIFill* element = new GUIFill(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100347 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200348 mRenders.push_back(element);
349 }
350 else if (type == "action")
351 {
352 GUIAction* element = new GUIAction(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100353 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200354 mActions.push_back(element);
355 }
356 else if (type == "console")
357 {
358 GUIConsole* element = new GUIConsole(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100359 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200360 mRenders.push_back(element);
361 mActions.push_back(element);
362 }
363 else if (type == "button")
364 {
365 GUIButton* element = new GUIButton(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100366 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200367 mRenders.push_back(element);
368 mActions.push_back(element);
369 }
370 else if (type == "checkbox")
371 {
372 GUICheckbox* element = new GUICheckbox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100373 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200374 mRenders.push_back(element);
375 mActions.push_back(element);
376 }
377 else if (type == "fileselector")
378 {
379 GUIFileSelector* element = new GUIFileSelector(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100380 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200381 mRenders.push_back(element);
382 mActions.push_back(element);
383 }
384 else if (type == "animation")
385 {
386 GUIAnimation* element = new GUIAnimation(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100387 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200388 mRenders.push_back(element);
389 }
390 else if (type == "progressbar")
391 {
392 GUIProgressBar* element = new GUIProgressBar(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100393 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200394 mRenders.push_back(element);
395 mActions.push_back(element);
396 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400397 else if (type == "slider")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200398 {
399 GUISlider* element = new GUISlider(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100400 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200401 mRenders.push_back(element);
402 mActions.push_back(element);
403 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200404 else if (type == "slidervalue")
405 {
406 GUISliderValue *element = new GUISliderValue(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100407 mObjects.push_back(element);
Vojtech Bocek85932342013-04-01 22:11:33 +0200408 mRenders.push_back(element);
409 mActions.push_back(element);
410 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400411 else if (type == "listbox")
412 {
413 GUIListBox* element = new GUIListBox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100414 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400415 mRenders.push_back(element);
416 mActions.push_back(element);
417 }
418 else if (type == "keyboard")
419 {
420 GUIKeyboard* element = new GUIKeyboard(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100421 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400422 mRenders.push_back(element);
423 mActions.push_back(element);
424 }
425 else if (type == "input")
426 {
427 GUIInput* element = new GUIInput(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100428 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400429 mRenders.push_back(element);
430 mActions.push_back(element);
431 mInputs.push_back(element);
432 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500433 else if (type == "partitionlist")
434 {
435 GUIPartitionList* element = new GUIPartitionList(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100436 mObjects.push_back(element);
Dees_Troya13d74f2013-03-24 08:54:55 -0500437 mRenders.push_back(element);
438 mActions.push_back(element);
439 }
Vojtech Bocek7e11ac52015-03-05 23:21:49 +0100440 else if (type == "patternpassword")
441 {
442 GUIPatternPassword* element = new GUIPatternPassword(child);
443 mObjects.push_back(element);
444 mRenders.push_back(element);
445 mActions.push_back(element);
446 }
Ethan Yonker44925ad2015-07-22 12:33:59 -0500447 else if (type == "textbox")
448 {
449 GUITextBox* element = new GUITextBox(child);
450 mObjects.push_back(element);
451 mRenders.push_back(element);
452 mActions.push_back(element);
453 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200454 else if (type == "template")
455 {
456 if (!templates || !child->first_attribute("name"))
457 {
458 LOGERR("Invalid template request.\n");
459 }
460 else
461 {
462 std::string name = child->first_attribute("name")->value();
Ethan Yonker780cd392014-07-21 15:24:39 -0500463 xml_node<>* node;
464 bool node_found = false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400465
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200466 // We need to find the correct template
Ethan Yonker780cd392014-07-21 15:24:39 -0500467 for (std::vector<xml_node<>*>::iterator itr = templates->begin(); itr != templates->end(); itr++) {
468 node = (*itr)->first_node("template");
Dees_Troy51a0e822012-09-05 15:24:24 -0400469
Ethan Yonker780cd392014-07-21 15:24:39 -0500470 while (node)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200471 {
Ethan Yonker780cd392014-07-21 15:24:39 -0500472 if (!node->first_attribute("name"))
473 continue;
474
475 if (name == node->first_attribute("name")->value())
476 {
477 if (!ProcessNode(node, templates, depth + 1))
478 return false;
479 else {
480 node_found = true;
481 break;
482 }
483 }
484 if (node_found)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200485 break;
Ethan Yonker780cd392014-07-21 15:24:39 -0500486 node = node->next_sibling("template");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200487 }
thatb63e2f92015-06-27 21:35:11 +0200488 // [check] why is there no if (node_found) here too?
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200489 }
490 }
491 }
492 else
493 {
thatb63e2f92015-06-27 21:35:11 +0200494 LOGERR("Unknown object type: %s.\n", type.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200495 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200496 }
497 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400498}
499
500int Page::Render(void)
501{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200502 // Render background
503 gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
504 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
Dees_Troy51a0e822012-09-05 15:24:24 -0400505
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200506 // Render remaining objects
507 std::vector<RenderObject*>::iterator iter;
508 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
509 {
510 if ((*iter)->Render())
511 LOGERR("A render request has failed.\n");
512 }
513 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400514}
515
516int Page::Update(void)
517{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200518 int retCode = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400519
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200520 std::vector<RenderObject*>::iterator iter;
521 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
522 {
523 int ret = (*iter)->Update();
524 if (ret < 0)
525 LOGERR("An update request has failed.\n");
526 else if (ret > retCode)
527 retCode = ret;
528 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400529
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200530 return retCode;
Dees_Troy51a0e822012-09-05 15:24:24 -0400531}
532
533int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
534{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200535 // By default, return 1 to ignore further touches if nobody is listening
536 int ret = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400537
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200538 // Don't try to handle a lack of handlers
539 if (mActions.size() == 0)
540 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400541
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200542 // We record mTouchStart so we can pass all the touch stream to the same handler
543 if (state == TOUCH_START)
544 {
545 std::vector<ActionObject*>::reverse_iterator iter;
546 // We work backwards, from top-most element to bottom-most element
547 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
548 {
549 if ((*iter)->IsInRegion(x, y))
550 {
551 mTouchStart = (*iter);
552 ret = mTouchStart->NotifyTouch(state, x, y);
553 if (ret >= 0)
554 break;
555 mTouchStart = NULL;
556 }
557 }
558 }
559 else if (state == TOUCH_RELEASE && mTouchStart != NULL)
560 {
561 ret = mTouchStart->NotifyTouch(state, x, y);
562 mTouchStart = NULL;
563 }
564 else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
565 {
566 ret = mTouchStart->NotifyTouch(state, x, y);
567 }
568 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400569}
570
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100571int Page::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400572{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200573 std::vector<ActionObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400574
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200575 // Don't try to handle a lack of handlers
576 if (mActions.size() == 0)
577 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400578
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100579 int ret = 1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200580 // We work backwards, from top-most element to bottom-most element
581 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
582 {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100583 ret = (*iter)->NotifyKey(key, down);
584 if (ret < 0) {
585 LOGERR("An action handler has returned an error\n");
586 ret = 1;
587 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200588 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100589 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400590}
591
592int Page::NotifyKeyboard(int key)
593{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200594 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400595
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200596 // Don't try to handle a lack of handlers
597 if (mInputs.size() == 0)
598 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400599
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200600 // We work backwards, from top-most element to bottom-most element
601 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
602 {
603 int ret = (*iter)->NotifyKeyboard(key);
604 if (ret == 0)
605 return 0;
606 else if (ret < 0)
607 LOGERR("A keyboard handler has returned an error");
608 }
609 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400610}
611
612int Page::SetKeyBoardFocus(int inFocus)
613{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200614 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400615
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200616 // Don't try to handle a lack of handlers
617 if (mInputs.size() == 0)
618 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400619
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200620 // We work backwards, from top-most element to bottom-most element
621 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
622 {
623 int ret = (*iter)->SetInputFocus(inFocus);
624 if (ret == 0)
625 return 0;
626 else if (ret < 0)
627 LOGERR("An input focus handler has returned an error");
628 }
629 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400630}
631
632void Page::SetPageFocus(int inFocus)
633{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200634 // Render remaining objects
635 std::vector<RenderObject*>::iterator iter;
636 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
637 (*iter)->SetPageFocus(inFocus);
638
639 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400640}
641
642int Page::NotifyVarChange(std::string varName, std::string value)
643{
Vojtech Bocek07220562014-02-08 02:05:33 +0100644 std::vector<GUIObject*>::iterator iter;
645 for (iter = mObjects.begin(); iter != mObjects.end(); ++iter)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200646 {
647 if ((*iter)->NotifyVarChange(varName, value))
648 LOGERR("An action handler errored on NotifyVarChange.\n");
649 }
650 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400651}
652
653PageSet::PageSet(char* xmlFile)
654{
that74ac6062015-03-04 22:39:34 +0100655 mResources = new ResourceManager;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200656 mCurrentPage = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400657
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200658 mXmlFile = xmlFile;
659 if (xmlFile)
660 mDoc.parse<0>(mXmlFile);
661 else
thatb63e2f92015-06-27 21:35:11 +0200662 mCurrentPage = new Page(NULL, NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400663}
664
665PageSet::~PageSet()
666{
Ethan Yonker1c273312015-03-16 12:18:56 -0500667 mOverlays.clear();
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100668 for (std::vector<Page*>::iterator itr = mPages.begin(); itr != mPages.end(); ++itr)
669 delete *itr;
670
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200671 delete mResources;
672 free(mXmlFile);
Vojtech Boceke979abd2015-01-12 18:29:12 +0100673
674 mDoc.clear();
675
676 for (std::vector<xml_document<>*>::iterator itr = mIncludedDocs.begin(); itr != mIncludedDocs.end(); ++itr) {
677 (*itr)->clear();
678 delete *itr;
679 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400680}
681
682int PageSet::Load(ZipArchive* package)
683{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200684 xml_node<>* parent;
685 xml_node<>* child;
Ethan Yonker780cd392014-07-21 15:24:39 -0500686 xml_node<>* xmltemplate;
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600687 xml_node<>* xmlstyle;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500688
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200689 parent = mDoc.first_node("recovery");
690 if (!parent)
691 parent = mDoc.first_node("install");
Dees_Troy51a0e822012-09-05 15:24:24 -0400692
Ethan Yonker63e414f2015-02-06 15:44:39 -0600693 set_scale_values(1, 1); // Reset any previous scaling values
694
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200695 // Now, let's parse the XML
Ethan Yonker63e414f2015-02-06 15:44:39 -0600696 LOGINFO("Checking resolution...\n");
697 child = parent->first_node("details");
698 if (child) {
699 xml_node<>* resolution = child->first_node("resolution");
700 if (resolution) {
701 xml_attribute<>* width_attr = resolution->first_attribute("width");
702 xml_attribute<>* height_attr = resolution->first_attribute("height");
703 xml_attribute<>* noscale_attr = resolution->first_attribute("noscaling");
704 if (width_attr && height_attr && !noscale_attr) {
705 int width = atoi(width_attr->value());
706 int height = atoi(height_attr->value());
707 int offx = 0, offy = 0;
708#ifdef TW_ROUND_SCREEN
709 xml_node<>* roundscreen = child->first_node("roundscreen");
710 if (roundscreen) {
711 LOGINFO("TW_ROUND_SCREEN := true, using round screen XML settings.\n");
712 xml_attribute<>* offx_attr = roundscreen->first_attribute("offset_x");
713 xml_attribute<>* offy_attr = roundscreen->first_attribute("offset_y");
714 if (offx_attr) {
715 offx = atoi(offx_attr->value());
716 }
717 if (offy_attr) {
718 offy = atoi(offy_attr->value());
719 }
720 }
721#endif
722 if (width != 0 && height != 0) {
723 float scale_w = ((float)gr_fb_width() - ((float)offx * 2.0)) / (float)width;
724 float scale_h = ((float)gr_fb_height() - ((float)offy * 2.0)) / (float)height;
725#ifdef TW_ROUND_SCREEN
726 float scale_off_w = (float)gr_fb_width() / (float)width;
727 float scale_off_h = (float)gr_fb_height() / (float)height;
728 tw_x_offset = offx * scale_off_w;
729 tw_y_offset = offy * scale_off_h;
730#endif
731 if (scale_w != 1 || scale_h != 1) {
732 LOGINFO("Scaling theme width %fx and height %fx, offsets x: %i y: %i\n", scale_w, scale_h, tw_x_offset, tw_y_offset);
733 set_scale_values(scale_w, scale_h);
734 }
735 }
736 } else {
737 LOGINFO("XML does not contain width and height, no scaling will be applied\n");
738 }
739 } else {
740 LOGINFO("XML contains no resolution tag, no scaling will be applied.\n");
741 }
742 } else {
743 LOGINFO("XML contains no details tag, no scaling will be applied.\n");
744 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200745 LOGINFO("Loading resources...\n");
746 child = parent->first_node("resources");
747 if (child)
that74ac6062015-03-04 22:39:34 +0100748 mResources->LoadResources(child, package);
Dees_Troy51a0e822012-09-05 15:24:24 -0400749
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200750 LOGINFO("Loading variables...\n");
751 child = parent->first_node("variables");
752 if (child)
753 LoadVariables(child);
Dees_Troy51a0e822012-09-05 15:24:24 -0400754
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100755 LOGINFO("Loading mouse cursor...\n");
756 child = parent->first_node("mousecursor");
757 if(child)
758 PageManager::LoadCursorData(child);
759
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200760 LOGINFO("Loading pages...\n");
761 // This may be NULL if no templates are present
Ethan Yonker780cd392014-07-21 15:24:39 -0500762 xmltemplate = parent->first_node("templates");
763 if (xmltemplate)
764 templates.push_back(xmltemplate);
Dees_Troy51a0e822012-09-05 15:24:24 -0400765
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600766 // Load styles if present
767 xmlstyle = parent->first_node("styles");
768 if (xmlstyle)
769 styles.push_back(xmlstyle);
770
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200771 child = parent->first_node("pages");
Ethan Yonker780cd392014-07-21 15:24:39 -0500772 if (child) {
773 if (LoadPages(child)) {
774 LOGERR("PageSet::Load returning -1\n");
775 return -1;
776 }
777 }
Vojtech Boceke979abd2015-01-12 18:29:12 +0100778
Ethan Yonker780cd392014-07-21 15:24:39 -0500779 return CheckInclude(package, &mDoc);
780}
Dees_Troy51a0e822012-09-05 15:24:24 -0400781
Ethan Yonker780cd392014-07-21 15:24:39 -0500782int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc)
783{
784 xml_node<>* par;
785 xml_node<>* par2;
786 xml_node<>* chld;
787 xml_node<>* parent;
788 xml_node<>* child;
789 xml_node<>* xmltemplate;
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600790 xml_node<>* xmlstyle;
Ethan Yonker780cd392014-07-21 15:24:39 -0500791 long len;
792 char* xmlFile = NULL;
793 string filename;
Vojtech Boceke979abd2015-01-12 18:29:12 +0100794 xml_document<> *doc = NULL;
Ethan Yonker780cd392014-07-21 15:24:39 -0500795
796 par = parentDoc->first_node("recovery");
797 if (!par) {
798 par = parentDoc->first_node("install");
799 }
800 if (!par) {
801 return 0;
802 }
803
804 par2 = par->first_node("include");
805 if (!par2)
806 return 0;
807 chld = par2->first_node("xmlfile");
808 while (chld != NULL) {
809 xml_attribute<>* attr = chld->first_attribute("name");
810 if (!attr)
811 break;
812
Ethan Yonker780cd392014-07-21 15:24:39 -0500813 if (!package) {
814 // We can try to load the XML directly...
Dees Troy3454ade2015-01-20 19:21:04 +0000815 filename = TWRES;
Ethan Yonker780cd392014-07-21 15:24:39 -0500816 filename += attr->value();
Ethan Yonker780cd392014-07-21 15:24:39 -0500817 } else {
818 filename += attr->value();
Ethan Yonker561c58d2015-10-05 08:48:22 -0500819 }
820 xmlFile = PageManager::LoadFileToBuffer(filename, package);
821 if (xmlFile == NULL) {
822 LOGERR("PageSet::CheckInclude unable to load '%s'\n", filename.c_str());
823 return -1;
Ethan Yonker780cd392014-07-21 15:24:39 -0500824 }
Ethan Yonker780cd392014-07-21 15:24:39 -0500825
Vojtech Boceke979abd2015-01-12 18:29:12 +0100826 doc = new xml_document<>();
827 doc->parse<0>(xmlFile);
828
829 parent = doc->first_node("recovery");
Ethan Yonker780cd392014-07-21 15:24:39 -0500830 if (!parent)
Vojtech Boceke979abd2015-01-12 18:29:12 +0100831 parent = doc->first_node("install");
Ethan Yonker780cd392014-07-21 15:24:39 -0500832
833 // Now, let's parse the XML
834 LOGINFO("Loading included resources...\n");
835 child = parent->first_node("resources");
836 if (child)
837 mResources->LoadResources(child, package);
838
839 LOGINFO("Loading included variables...\n");
840 child = parent->first_node("variables");
841 if (child)
842 LoadVariables(child);
843
844 LOGINFO("Loading mouse cursor...\n");
845 child = parent->first_node("mousecursor");
846 if(child)
847 PageManager::LoadCursorData(child);
848
849 LOGINFO("Loading included pages...\n");
850 // This may be NULL if no templates are present
851 xmltemplate = parent->first_node("templates");
852 if (xmltemplate)
853 templates.push_back(xmltemplate);
854
Ethan Yonker21ff02a2015-02-18 14:35:00 -0600855 // Load styles if present
856 xmlstyle = parent->first_node("styles");
857 if (xmlstyle)
858 styles.push_back(xmlstyle);
859
Ethan Yonker780cd392014-07-21 15:24:39 -0500860 child = parent->first_node("pages");
Vojtech Boceke979abd2015-01-12 18:29:12 +0100861 if (child && LoadPages(child))
862 {
863 templates.pop_back();
864 doc->clear();
865 delete doc;
Ethan Yonker561c58d2015-10-05 08:48:22 -0500866 free(xmlFile);
Vojtech Boceke979abd2015-01-12 18:29:12 +0100867 return -1;
868 }
Ethan Yonker780cd392014-07-21 15:24:39 -0500869
Vojtech Boceke979abd2015-01-12 18:29:12 +0100870 mIncludedDocs.push_back(doc);
871
Ethan Yonker561c58d2015-10-05 08:48:22 -0500872 if (CheckInclude(package, doc)) {
873 free(xmlFile);
Ethan Yonker780cd392014-07-21 15:24:39 -0500874 return -1;
Ethan Yonker561c58d2015-10-05 08:48:22 -0500875 }
Ethan Yonker780cd392014-07-21 15:24:39 -0500876
877 chld = chld->next_sibling("xmlfile");
878 }
Ethan Yonker561c58d2015-10-05 08:48:22 -0500879 if (xmlFile)
880 free(xmlFile);
Ethan Yonker780cd392014-07-21 15:24:39 -0500881 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400882}
883
884int PageSet::SetPage(std::string page)
885{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200886 Page* tmp = FindPage(page);
887 if (tmp)
888 {
889 if (mCurrentPage) mCurrentPage->SetPageFocus(0);
890 mCurrentPage = tmp;
891 mCurrentPage->SetPageFocus(1);
892 mCurrentPage->NotifyVarChange("", "");
893 return 0;
894 }
895 else
896 {
897 LOGERR("Unable to locate page (%s)\n", page.c_str());
898 }
899 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400900}
901
902int PageSet::SetOverlay(Page* page)
903{
Ethan Yonker1c273312015-03-16 12:18:56 -0500904 if (page) {
905 if (mOverlays.size() >= 10) {
906 LOGERR("Too many overlays requested, max is 10.\n");
907 return -1;
908 }
Matt Mowerd411f8d2015-04-09 16:04:12 -0500909
910 std::vector<Page*>::iterator iter;
911 for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) {
912 if ((*iter)->GetName() == page->GetName()) {
913 mOverlays.erase(iter);
914 // SetOverlay() is (and should stay) the only function which
915 // adds to mOverlays. Then, each page can appear at most once.
916 break;
917 }
918 }
919
Ethan Yonker1c273312015-03-16 12:18:56 -0500920 page->SetPageFocus(1);
921 page->NotifyVarChange("", "");
922
923 if (!mOverlays.empty())
924 mOverlays.back()->SetPageFocus(0);
925
926 mOverlays.push_back(page);
927 } else {
928 if (!mOverlays.empty()) {
929 mOverlays.back()->SetPageFocus(0);
930 mOverlays.pop_back();
931 if (!mOverlays.empty())
932 mOverlays.back()->SetPageFocus(1);
933 else if (mCurrentPage)
934 mCurrentPage->SetPageFocus(1); // Just in case somehow the regular page lost focus, we'll set it again
935 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200936 }
937 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400938}
939
that74ac6062015-03-04 22:39:34 +0100940const ResourceManager* PageSet::GetResources()
Dees_Troy51a0e822012-09-05 15:24:24 -0400941{
that74ac6062015-03-04 22:39:34 +0100942 return mResources;
Dees_Troy51a0e822012-09-05 15:24:24 -0400943}
944
945Page* PageSet::FindPage(std::string name)
946{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200947 std::vector<Page*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400948
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200949 for (iter = mPages.begin(); iter != mPages.end(); iter++)
950 {
951 if (name == (*iter)->GetName())
952 return (*iter);
953 }
954 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400955}
956
957int PageSet::LoadVariables(xml_node<>* vars)
958{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200959 xml_node<>* child;
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100960 xml_attribute<> *name, *value, *persist;
961 int p;
Dees_Troy51a0e822012-09-05 15:24:24 -0400962
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200963 child = vars->first_node("variable");
964 while (child)
965 {
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100966 name = child->first_attribute("name");
967 value = child->first_attribute("value");
968 persist = child->first_attribute("persist");
969 if(name && value)
970 {
Ethan Yonker751a85e2014-12-12 16:59:10 -0600971 if (strcmp(name->value(), "tw_x_offset") == 0) {
972 tw_x_offset = atoi(value->value());
973 child = child->next_sibling("variable");
974 continue;
975 }
976 if (strcmp(name->value(), "tw_y_offset") == 0) {
977 tw_y_offset = atoi(value->value());
978 child = child->next_sibling("variable");
979 continue;
980 }
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100981 p = persist ? atoi(persist->value()) : 0;
Ethan Yonker96acb3d2014-08-05 09:20:30 -0500982 string temp = value->value();
983 string valstr = gui_parse_text(temp);
984
985 if (valstr.find("+") != string::npos) {
986 string val1str = valstr;
987 val1str = val1str.substr(0, val1str.find('+'));
988 string val2str = valstr;
989 val2str = val2str.substr(val2str.find('+') + 1, string::npos);
990 int val1 = atoi(val1str.c_str());
991 int val2 = atoi(val2str.c_str());
992 int val = val1 + val2;
993
994 DataManager::SetValue(name->value(), val, p);
995 } else if (valstr.find("-") != string::npos) {
996 string val1str = valstr;
997 val1str = val1str.substr(0, val1str.find('-'));
998 string val2str = valstr;
999 val2str = val2str.substr(val2str.find('-') + 1, string::npos);
1000 int val1 = atoi(val1str.c_str());
1001 int val2 = atoi(val2str.c_str());
1002 int val = val1 - val2;
1003
1004 DataManager::SetValue(name->value(), val, p);
1005 } else {
1006 DataManager::SetValue(name->value(), valstr, p);
1007 }
Vojtech Bocek81c29dc2013-12-07 23:02:09 +01001008 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001009
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001010 child = child->next_sibling("variable");
1011 }
1012 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001013}
1014
Ethan Yonker780cd392014-07-21 15:24:39 -05001015int PageSet::LoadPages(xml_node<>* pages)
Dees_Troy51a0e822012-09-05 15:24:24 -04001016{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001017 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -04001018
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001019 if (!pages)
1020 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001021
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001022 child = pages->first_node("page");
1023 while (child != NULL)
1024 {
Ethan Yonker780cd392014-07-21 15:24:39 -05001025 Page* page = new Page(child, &templates);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001026 if (page->GetName().empty())
1027 {
1028 LOGERR("Unable to process load page\n");
1029 delete page;
1030 }
1031 else
1032 {
1033 mPages.push_back(page);
1034 }
1035 child = child->next_sibling("page");
1036 }
1037 if (mPages.size() > 0)
1038 return 0;
1039 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001040}
1041
1042int PageSet::IsCurrentPage(Page* page)
1043{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001044 return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -04001045}
1046
1047int PageSet::Render(void)
1048{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001049 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001050
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001051 ret = (mCurrentPage ? mCurrentPage->Render() : -1);
1052 if (ret < 0)
1053 return ret;
Ethan Yonker1c273312015-03-16 12:18:56 -05001054
1055 std::vector<Page*>::iterator iter;
1056
1057 for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) {
1058 ret = ((*iter) ? (*iter)->Render() : -1);
1059 if (ret < 0)
1060 return ret;
1061 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001062 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001063}
1064
1065int PageSet::Update(void)
1066{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001067 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001068
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001069 ret = (mCurrentPage ? mCurrentPage->Update() : -1);
1070 if (ret < 0 || ret > 1)
1071 return ret;
Ethan Yonker1c273312015-03-16 12:18:56 -05001072
1073 std::vector<Page*>::iterator iter;
1074
1075 for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) {
1076 ret = ((*iter) ? (*iter)->Update() : -1);
1077 if (ret < 0)
1078 return ret;
1079 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001080 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001081}
1082
1083int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
1084{
Ethan Yonker1c273312015-03-16 12:18:56 -05001085 if (!mOverlays.empty())
1086 return mOverlays.back()->NotifyTouch(state, x, y);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001087
1088 return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001089}
1090
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001091int PageSet::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -04001092{
Ethan Yonker1c273312015-03-16 12:18:56 -05001093 if (!mOverlays.empty())
1094 return mOverlays.back()->NotifyKey(key, down);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001095
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001096 return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001097}
1098
1099int PageSet::NotifyKeyboard(int key)
1100{
Ethan Yonker1c273312015-03-16 12:18:56 -05001101 if (!mOverlays.empty())
1102 return mOverlays.back()->NotifyKeyboard(key);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001103
1104 return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001105}
1106
1107int PageSet::SetKeyBoardFocus(int inFocus)
1108{
Ethan Yonker1c273312015-03-16 12:18:56 -05001109 if (!mOverlays.empty())
1110 return mOverlays.back()->SetKeyBoardFocus(inFocus);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001111
1112 return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001113}
1114
1115int PageSet::NotifyVarChange(std::string varName, std::string value)
1116{
Ethan Yonker1c273312015-03-16 12:18:56 -05001117 std::vector<Page*>::iterator iter;
1118
1119 for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++)
1120 (*iter)->NotifyVarChange(varName, value);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001121
1122 return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001123}
1124
Ethan Yonker561c58d2015-10-05 08:48:22 -05001125char* PageManager::LoadFileToBuffer(std::string filename, ZipArchive* package) {
1126 size_t len;
1127 char* buffer = NULL;
1128
1129 if (!package) {
1130 // We can try to load the XML directly...
1131 LOGINFO("PageManager::LoadFileToBuffer loading filename: '%s' directly\n", filename.c_str());
1132 struct stat st;
1133 if(stat(filename.c_str(),&st) != 0) {
1134 // This isn't always an error, sometimes we request files that don't exist.
1135 return NULL;
1136 }
1137
1138 len = (size_t)st.st_size;
1139
1140 buffer = (char*) malloc(len + 1);
1141 if (!buffer) {
1142 LOGERR("PageManager::LoadFileToBuffer failed to malloc\n");
1143 return NULL;
1144 }
1145
1146 int fd = open(filename.c_str(), O_RDONLY);
1147 if (fd == -1) {
1148 LOGERR("PageManager::LoadFileToBuffer failed to open '%s' - (%s)\n", filename.c_str(), strerror(errno));
1149 free(buffer);
1150 return NULL;
1151 }
1152
1153 if (read(fd, buffer, len) < 0) {
1154 LOGERR("PageManager::LoadFileToBuffer failed to read '%s' - (%s)\n", filename.c_str(), strerror(errno));
1155 free(buffer);
1156 close(fd);
1157 return NULL;
1158 }
1159 close(fd);
1160 } else {
1161 LOGINFO("PageManager::LoadFileToBuffer loading filename: '%s' from zip\n", filename.c_str());
1162 const ZipEntry* zipentry = mzFindZipEntry(package, filename.c_str());
1163 if (zipentry == NULL) {
1164 LOGERR("Unable to locate '%s' in zip file\n", filename.c_str());
1165 return NULL;
1166 }
1167
1168 // Allocate the buffer for the file
1169 len = mzGetZipEntryUncompLen(zipentry);
1170 buffer = (char*) malloc(len + 1);
1171 if (!buffer)
1172 return NULL;
1173
1174 if (!mzExtractZipEntryToBuffer(package, zipentry, (unsigned char*) buffer)) {
1175 LOGERR("Unable to extract '%s'\n", filename.c_str());
1176 free(buffer);
1177 return NULL;
1178 }
1179 }
1180 // NULL-terminate the string
1181 buffer[len] = 0x00;
1182 return buffer;
1183}
1184
Dees_Troy51a0e822012-09-05 15:24:24 -04001185int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
1186{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001187 int fd;
1188 ZipArchive zip, *pZip = NULL;
1189 long len;
1190 char* xmlFile = NULL;
1191 PageSet* pageSet = NULL;
1192 int ret;
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001193 MemMapping map;
Dees_Troy51a0e822012-09-05 15:24:24 -04001194
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001195 // Open the XML file
1196 LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001197 if (package.size() > 4 && package.substr(package.size() - 4) != ".zip")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001198 {
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001199 LOGINFO("Load XML directly\n");
Ethan Yonker751a85e2014-12-12 16:59:10 -06001200 tw_x_offset = TW_X_OFFSET;
1201 tw_y_offset = TW_Y_OFFSET;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001202 }
1203 else
1204 {
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001205 LOGINFO("Loading zip theme\n");
Ethan Yonker751a85e2014-12-12 16:59:10 -06001206 tw_x_offset = 0;
1207 tw_y_offset = 0;
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001208 if (!TWFunc::Path_Exists(package))
1209 return -1;
1210 if (sysMapFile(package.c_str(), &map) != 0) {
1211 LOGERR("Failed to map '%s'\n", package.c_str());
Ethan Yonker561c58d2015-10-05 08:48:22 -05001212 goto error;
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001213 }
1214 if (mzOpenZipArchive(map.addr, map.length, &zip)) {
1215 LOGERR("Unable to open zip archive '%s'\n", package.c_str());
1216 sysReleaseMap(&map);
Ethan Yonker561c58d2015-10-05 08:48:22 -05001217 goto error;
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001218 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001219 pZip = &zip;
Ethan Yonker561c58d2015-10-05 08:48:22 -05001220 package = "ui.xml";
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001221 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001222
Ethan Yonker561c58d2015-10-05 08:48:22 -05001223 xmlFile = LoadFileToBuffer(package, pZip);
1224 if (xmlFile == NULL) {
1225 goto error;
1226 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001227
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001228 // Before loading, mCurrentSet must be the loading package so we can find resources
1229 pageSet = mCurrentSet;
1230 mCurrentSet = new PageSet(xmlFile);
1231
1232 ret = mCurrentSet->Load(pZip);
1233 if (ret == 0)
1234 {
1235 mCurrentSet->SetPage(startpage);
1236 mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
1237 }
1238 else
1239 {
1240 LOGERR("Package %s failed to load.\n", name.c_str());
1241 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -05001242
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001243 // The first successful package we loaded is the base
1244 if (mBaseSet == NULL)
1245 mBaseSet = mCurrentSet;
1246
1247 mCurrentSet = pageSet;
1248
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001249 if (pZip) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001250 mzCloseZipArchive(pZip);
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001251 sysReleaseMap(&map);
1252 }
Ethan Yonker561c58d2015-10-05 08:48:22 -05001253 free(xmlFile);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001254 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001255
1256error:
Ethan Yonker561c58d2015-10-05 08:48:22 -05001257 // Sometimes we get here without a real error
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001258 if (pZip) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001259 mzCloseZipArchive(pZip);
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001260 sysReleaseMap(&map);
1261 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001262 if (xmlFile)
1263 free(xmlFile);
1264 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001265}
1266
1267PageSet* PageManager::FindPackage(std::string name)
1268{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001269 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001270
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001271 iter = mPageSets.find(name);
1272 if (iter != mPageSets.end())
1273 return (*iter).second;
1274
1275 LOGERR("Unable to locate package %s\n", name.c_str());
1276 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -04001277}
1278
1279PageSet* PageManager::SelectPackage(std::string name)
1280{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001281 LOGINFO("Switching packages (%s)\n", name.c_str());
1282 PageSet* tmp;
Dees_Troy51a0e822012-09-05 15:24:24 -04001283
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001284 tmp = FindPackage(name);
1285 if (tmp)
Vojtech Bocek07220562014-02-08 02:05:33 +01001286 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001287 mCurrentSet = tmp;
Vojtech Bocek07220562014-02-08 02:05:33 +01001288 mCurrentSet->NotifyVarChange("", "");
1289 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001290 else
1291 LOGERR("Unable to find package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001292
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001293 return mCurrentSet;
Dees_Troy51a0e822012-09-05 15:24:24 -04001294}
1295
1296int PageManager::ReloadPackage(std::string name, std::string package)
1297{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001298 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001299
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001300 iter = mPageSets.find(name);
1301 if (iter == mPageSets.end())
1302 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001303
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001304 if(mMouseCursor)
1305 mMouseCursor->ResetData(gr_fb_width(), gr_fb_height());
1306
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001307 PageSet* set = (*iter).second;
1308 mPageSets.erase(iter);
Dees_Troy51a0e822012-09-05 15:24:24 -04001309
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001310 if (LoadPackage(name, package, "main") != 0)
1311 {
Dees Troy3454ade2015-01-20 19:21:04 +00001312 LOGERR("Failed to load package '%s'.\n", package.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001313 mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
1314 return -1;
1315 }
1316 if (mCurrentSet == set)
1317 SelectPackage(name);
Vojtech Bocekbfb63342014-02-08 00:32:31 +01001318 if (mBaseSet == set)
1319 mBaseSet = mCurrentSet;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001320 delete set;
1321 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001322}
1323
1324void PageManager::ReleasePackage(std::string name)
1325{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001326 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001327
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001328 iter = mPageSets.find(name);
1329 if (iter == mPageSets.end())
1330 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001331
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001332 PageSet* set = (*iter).second;
1333 mPageSets.erase(iter);
1334 delete set;
1335 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001336}
1337
1338int PageManager::ChangePage(std::string name)
1339{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001340 DataManager::SetValue("tw_operation_state", 0);
1341 int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
1342 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001343}
1344
1345int PageManager::ChangeOverlay(std::string name)
1346{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001347 if (name.empty())
1348 return mCurrentSet->SetOverlay(NULL);
1349 else
1350 {
1351 Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
1352 return mCurrentSet->SetOverlay(page);
1353 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001354}
1355
that74ac6062015-03-04 22:39:34 +01001356const ResourceManager* PageManager::GetResources()
Dees_Troy51a0e822012-09-05 15:24:24 -04001357{
that74ac6062015-03-04 22:39:34 +01001358 return (mCurrentSet ? mCurrentSet->GetResources() : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001359}
1360
1361int PageManager::SwitchToConsole(void)
1362{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001363 PageSet* console = new PageSet(NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001364
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001365 mCurrentSet = console;
1366 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001367}
1368
Ethan Yonker03a42f62014-08-08 11:03:51 -05001369int PageManager::EndConsole(void)
1370{
1371 if (mCurrentSet && mBaseSet) {
1372 delete mCurrentSet;
1373 mCurrentSet = mBaseSet;
1374 return 0;
1375 }
1376 return -1;
1377}
1378
Dees_Troy51a0e822012-09-05 15:24:24 -04001379int PageManager::IsCurrentPage(Page* page)
1380{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001381 return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -04001382}
1383
1384int PageManager::Render(void)
1385{
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001386 int res = (mCurrentSet ? mCurrentSet->Render() : -1);
1387 if(mMouseCursor)
1388 mMouseCursor->Render();
1389 return res;
1390}
1391
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001392HardwareKeyboard *PageManager::GetHardwareKeyboard()
1393{
1394 if(!mHardwareKeyboard)
1395 mHardwareKeyboard = new HardwareKeyboard();
1396 return mHardwareKeyboard;
1397}
1398
Ethan Yonker21ff02a2015-02-18 14:35:00 -06001399xml_node<>* PageManager::FindStyle(std::string name)
1400{
1401 for (std::vector<xml_node<>*>::iterator itr = mCurrentSet->styles.begin(); itr != mCurrentSet->styles.end(); itr++) {
1402 xml_node<>* node = (*itr)->first_node("style");
1403
1404 while (node) {
1405 if (!node->first_attribute("name"))
1406 continue;
1407
1408 if (name == node->first_attribute("name")->value())
1409 return node;
1410 node = node->next_sibling("style");
1411 }
1412 }
1413 return NULL;
1414}
1415
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001416MouseCursor *PageManager::GetMouseCursor()
1417{
1418 if(!mMouseCursor)
1419 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1420 return mMouseCursor;
1421}
1422
1423void PageManager::LoadCursorData(xml_node<>* node)
1424{
1425 if(!mMouseCursor)
1426 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1427
1428 mMouseCursor->LoadData(node);
Dees_Troy51a0e822012-09-05 15:24:24 -04001429}
1430
1431int PageManager::Update(void)
1432{
thatfb759d42015-01-11 12:16:53 +01001433 if(blankTimer.isScreenOff())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001434 return 0;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001435
1436 int res = (mCurrentSet ? mCurrentSet->Update() : -1);
1437
1438 if(mMouseCursor)
1439 {
1440 int c_res = mMouseCursor->Update();
1441 if(c_res > res)
1442 res = c_res;
1443 }
1444 return res;
Dees_Troy51a0e822012-09-05 15:24:24 -04001445}
1446
1447int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
1448{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001449 return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001450}
1451
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001452int PageManager::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -04001453{
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001454 return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001455}
1456
1457int PageManager::NotifyKeyboard(int key)
1458{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001459 return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001460}
1461
1462int PageManager::SetKeyBoardFocus(int inFocus)
1463{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001464 return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001465}
1466
1467int PageManager::NotifyVarChange(std::string varName, std::string value)
1468{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001469 return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001470}
1471
1472extern "C" void gui_notifyVarChange(const char *name, const char* value)
1473{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001474 if (!gGuiRunning)
1475 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001476
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001477 PageManager::NotifyVarChange(name, value);
Dees_Troy51a0e822012-09-05 15:24:24 -04001478}