blob: 3632cc311ecc0746a42542af3d36b5067f9b6f39 [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>
35
36#include <string>
37
38extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000039#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040040#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040041}
42
43#include "rapidxml.hpp"
44#include "objects.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070045#ifndef TW_NO_SCREEN_TIMEOUT
gordon13370d9133d2013-06-08 14:17:07 +020046#include "blanktimer.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070047#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040048
49extern int gGuiRunning;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070050#ifndef TW_NO_SCREEN_TIMEOUT
gordon13370d9133d2013-06-08 14:17:07 +020051extern blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070052#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040053
54std::map<std::string, PageSet*> PageManager::mPageSets;
55PageSet* PageManager::mCurrentSet;
56PageSet* PageManager::mBaseSet = NULL;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +010057MouseCursor *PageManager::mMouseCursor = NULL;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +010058HardwareKeyboard *PageManager::mHardwareKeyboard = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -040059
Dees_Troy51a0e822012-09-05 15:24:24 -040060// Helper routine to convert a string to a color declaration
61int ConvertStrToColor(std::string str, COLOR* color)
62{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020063 // Set the default, solid black
64 memset(color, 0, sizeof(COLOR));
65 color->alpha = 255;
Dees_Troy51a0e822012-09-05 15:24:24 -040066
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020067 // Translate variables
68 DataManager::GetValue(str, str);
Matt Mowerfb1c4ff2014-04-16 13:43:36 -050069
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020070 // Look for some defaults
71 if (str == "black") return 0;
72 else if (str == "white") { color->red = color->green = color->blue = 255; return 0; }
73 else if (str == "red") { color->red = 255; return 0; }
74 else if (str == "green") { color->green = 255; return 0; }
75 else if (str == "blue") { color->blue = 255; return 0; }
Dees_Troy51a0e822012-09-05 15:24:24 -040076
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020077 // At this point, we require an RGB(A) color
78 if (str[0] != '#')
79 return -1;
80
81 str.erase(0, 1);
Dees_Troy51a0e822012-09-05 15:24:24 -040082
Dees_Troy30b962e2012-10-19 20:48:59 -040083 int result;
84 if (str.size() >= 8) {
85 // We have alpha channel
86 string alpha = str.substr(6, 2);
87 result = strtol(alpha.c_str(), NULL, 16);
88 color->alpha = result & 0x000000FF;
89 str.resize(6);
90 result = strtol(str.c_str(), NULL, 16);
91 color->red = (result >> 16) & 0x000000FF;
92 color->green = (result >> 8) & 0x000000FF;
93 color->blue = result & 0x000000FF;
94 } else {
95 result = strtol(str.c_str(), NULL, 16);
96 color->red = (result >> 16) & 0x000000FF;
97 color->green = (result >> 8) & 0x000000FF;
98 color->blue = result & 0x000000FF;
99 }
100 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400101}
102
103// Helper APIs
104bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */)
105{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200106 if (!node)
107 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400108
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200109 std::string value;
110 if (node->first_attribute("x"))
111 {
112 value = node->first_attribute("x")->value();
113 DataManager::GetValue(value, value);
114 *x = atol(value.c_str());
115 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400116
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200117 if (node->first_attribute("y"))
118 {
119 value = node->first_attribute("y")->value();
120 DataManager::GetValue(value, value);
121 *y = atol(value.c_str());
122 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400123
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200124 if (w && node->first_attribute("w"))
125 {
126 value = node->first_attribute("w")->value();
127 DataManager::GetValue(value, value);
128 *w = atol(value.c_str());
129 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400130
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200131 if (h && node->first_attribute("h"))
132 {
133 value = node->first_attribute("h")->value();
134 DataManager::GetValue(value, value);
135 *h = atol(value.c_str());
136 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400137
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200138 if (placement && node->first_attribute("placement"))
139 {
140 value = node->first_attribute("placement")->value();
141 DataManager::GetValue(value, value);
142 *placement = (RenderObject::Placement) atol(value.c_str());
143 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400144
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200145 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400146}
147
148int ActionObject::SetActionPos(int x, int y, int w, int h)
149{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200150 if (x < 0 || y < 0)
151 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400152
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500153 mActionX = x;
154 mActionY = y;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200155 if (w || h)
156 {
157 mActionW = w;
158 mActionH = h;
159 }
160 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400161}
162
Ethan Yonker780cd392014-07-21 15:24:39 -0500163Page::Page(xml_node<>* page, std::vector<xml_node<>*> *templates /* = NULL */)
Dees_Troy51a0e822012-09-05 15:24:24 -0400164{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200165 mTouchStart = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400166
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200167 // We can memset the whole structure, because the alpha channel is ignored
168 memset(&mBackground, 0, sizeof(COLOR));
Dees_Troy51a0e822012-09-05 15:24:24 -0400169
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200170 // With NULL, we make a console-only display
171 if (!page)
172 {
173 mName = "console";
Dees_Troy51a0e822012-09-05 15:24:24 -0400174
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200175 GUIConsole* element = new GUIConsole(NULL);
176 mRenders.push_back(element);
177 mActions.push_back(element);
178 return;
179 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400180
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200181 if (page->first_attribute("name"))
182 mName = page->first_attribute("name")->value();
183 else
184 {
185 LOGERR("No page name attribute found!\n");
186 return;
187 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400188
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200189 LOGINFO("Loading page %s\n", mName.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400190
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200191 // This is a recursive routine for template handling
192 ProcessNode(page, templates);
Dees_Troy51a0e822012-09-05 15:24:24 -0400193
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200194 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400195}
196
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100197Page::~Page()
198{
199 for (std::vector<GUIObject*>::iterator itr = mObjects.begin(); itr != mObjects.end(); ++itr)
200 delete *itr;
201}
202
Ethan Yonker780cd392014-07-21 15:24:39 -0500203bool Page::ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates /* = NULL */, int depth /* = 0 */)
Dees_Troy51a0e822012-09-05 15:24:24 -0400204{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 if (depth == 10)
206 {
207 LOGERR("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n");
208 return false;
209 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400210
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200211 // Let's retrieve the background value, if any
212 xml_node<>* bg = page->first_node("background");
213 if (bg)
214 {
215 xml_attribute<>* attr = bg->first_attribute("color");
216 if (attr)
217 {
218 std::string color = attr->value();
219 ConvertStrToColor(color, &mBackground);
220 }
221 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400222
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 xml_node<>* child;
224 child = page->first_node("object");
225 while (child)
226 {
227 if (!child->first_attribute("type"))
228 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400229
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 std::string type = child->first_attribute("type")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400231
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200232 if (type == "text")
233 {
234 GUIText* element = new GUIText(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100235 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200236 mRenders.push_back(element);
237 mActions.push_back(element);
238 }
239 else if (type == "image")
240 {
241 GUIImage* element = new GUIImage(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100242 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200243 mRenders.push_back(element);
244 }
245 else if (type == "fill")
246 {
247 GUIFill* element = new GUIFill(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100248 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200249 mRenders.push_back(element);
250 }
251 else if (type == "action")
252 {
253 GUIAction* element = new GUIAction(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100254 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200255 mActions.push_back(element);
256 }
257 else if (type == "console")
258 {
259 GUIConsole* element = new GUIConsole(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100260 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200261 mRenders.push_back(element);
262 mActions.push_back(element);
263 }
264 else if (type == "button")
265 {
266 GUIButton* element = new GUIButton(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100267 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200268 mRenders.push_back(element);
269 mActions.push_back(element);
270 }
271 else if (type == "checkbox")
272 {
273 GUICheckbox* element = new GUICheckbox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100274 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200275 mRenders.push_back(element);
276 mActions.push_back(element);
277 }
278 else if (type == "fileselector")
279 {
280 GUIFileSelector* element = new GUIFileSelector(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100281 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200282 mRenders.push_back(element);
283 mActions.push_back(element);
284 }
285 else if (type == "animation")
286 {
287 GUIAnimation* element = new GUIAnimation(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100288 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200289 mRenders.push_back(element);
290 }
291 else if (type == "progressbar")
292 {
293 GUIProgressBar* element = new GUIProgressBar(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100294 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200295 mRenders.push_back(element);
296 mActions.push_back(element);
297 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400298 else if (type == "slider")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200299 {
300 GUISlider* element = new GUISlider(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100301 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200302 mRenders.push_back(element);
303 mActions.push_back(element);
304 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200305 else if (type == "slidervalue")
306 {
307 GUISliderValue *element = new GUISliderValue(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100308 mObjects.push_back(element);
Vojtech Bocek85932342013-04-01 22:11:33 +0200309 mRenders.push_back(element);
310 mActions.push_back(element);
311 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400312 else if (type == "listbox")
313 {
314 GUIListBox* element = new GUIListBox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100315 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400316 mRenders.push_back(element);
317 mActions.push_back(element);
318 }
319 else if (type == "keyboard")
320 {
321 GUIKeyboard* element = new GUIKeyboard(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100322 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400323 mRenders.push_back(element);
324 mActions.push_back(element);
325 }
326 else if (type == "input")
327 {
328 GUIInput* element = new GUIInput(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100329 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400330 mRenders.push_back(element);
331 mActions.push_back(element);
332 mInputs.push_back(element);
333 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500334 else if (type == "partitionlist")
335 {
336 GUIPartitionList* element = new GUIPartitionList(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100337 mObjects.push_back(element);
Dees_Troya13d74f2013-03-24 08:54:55 -0500338 mRenders.push_back(element);
339 mActions.push_back(element);
340 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200341 else if (type == "template")
342 {
343 if (!templates || !child->first_attribute("name"))
344 {
345 LOGERR("Invalid template request.\n");
346 }
347 else
348 {
349 std::string name = child->first_attribute("name")->value();
Ethan Yonker780cd392014-07-21 15:24:39 -0500350 xml_node<>* node;
351 bool node_found = false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400352
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200353 // We need to find the correct template
Ethan Yonker780cd392014-07-21 15:24:39 -0500354 for (std::vector<xml_node<>*>::iterator itr = templates->begin(); itr != templates->end(); itr++) {
355 node = (*itr)->first_node("template");
Dees_Troy51a0e822012-09-05 15:24:24 -0400356
Ethan Yonker780cd392014-07-21 15:24:39 -0500357 while (node)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200358 {
Ethan Yonker780cd392014-07-21 15:24:39 -0500359 if (!node->first_attribute("name"))
360 continue;
361
362 if (name == node->first_attribute("name")->value())
363 {
364 if (!ProcessNode(node, templates, depth + 1))
365 return false;
366 else {
367 node_found = true;
368 break;
369 }
370 }
371 if (node_found)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200372 break;
Ethan Yonker780cd392014-07-21 15:24:39 -0500373 node = node->next_sibling("template");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200374 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200375 }
376 }
377 }
378 else
379 {
380 LOGERR("Unknown object type.\n");
381 }
382 child = child->next_sibling("object");
383 }
384 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400385}
386
387int Page::Render(void)
388{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200389 // Render background
390 gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
391 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
Dees_Troy51a0e822012-09-05 15:24:24 -0400392
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200393 // Render remaining objects
394 std::vector<RenderObject*>::iterator iter;
395 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
396 {
397 if ((*iter)->Render())
398 LOGERR("A render request has failed.\n");
399 }
400 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400401}
402
403int Page::Update(void)
404{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200405 int retCode = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400406
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200407 std::vector<RenderObject*>::iterator iter;
408 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
409 {
410 int ret = (*iter)->Update();
411 if (ret < 0)
412 LOGERR("An update request has failed.\n");
413 else if (ret > retCode)
414 retCode = ret;
415 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400416
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200417 return retCode;
Dees_Troy51a0e822012-09-05 15:24:24 -0400418}
419
420int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
421{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200422 // By default, return 1 to ignore further touches if nobody is listening
423 int ret = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400424
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200425 // Don't try to handle a lack of handlers
426 if (mActions.size() == 0)
427 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400428
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200429 // We record mTouchStart so we can pass all the touch stream to the same handler
430 if (state == TOUCH_START)
431 {
432 std::vector<ActionObject*>::reverse_iterator iter;
433 // We work backwards, from top-most element to bottom-most element
434 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
435 {
436 if ((*iter)->IsInRegion(x, y))
437 {
438 mTouchStart = (*iter);
439 ret = mTouchStart->NotifyTouch(state, x, y);
440 if (ret >= 0)
441 break;
442 mTouchStart = NULL;
443 }
444 }
445 }
446 else if (state == TOUCH_RELEASE && mTouchStart != NULL)
447 {
448 ret = mTouchStart->NotifyTouch(state, x, y);
449 mTouchStart = NULL;
450 }
451 else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
452 {
453 ret = mTouchStart->NotifyTouch(state, x, y);
454 }
455 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400456}
457
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100458int Page::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400459{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200460 std::vector<ActionObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400461
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200462 // Don't try to handle a lack of handlers
463 if (mActions.size() == 0)
464 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400465
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100466 int ret = 1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200467 // We work backwards, from top-most element to bottom-most element
468 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
469 {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100470 ret = (*iter)->NotifyKey(key, down);
471 if (ret < 0) {
472 LOGERR("An action handler has returned an error\n");
473 ret = 1;
474 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200475 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100476 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400477}
478
479int Page::NotifyKeyboard(int key)
480{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200481 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400482
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200483 // Don't try to handle a lack of handlers
484 if (mInputs.size() == 0)
485 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400486
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200487 // We work backwards, from top-most element to bottom-most element
488 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
489 {
490 int ret = (*iter)->NotifyKeyboard(key);
491 if (ret == 0)
492 return 0;
493 else if (ret < 0)
494 LOGERR("A keyboard handler has returned an error");
495 }
496 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400497}
498
499int Page::SetKeyBoardFocus(int inFocus)
500{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200501 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400502
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200503 // Don't try to handle a lack of handlers
504 if (mInputs.size() == 0)
505 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400506
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200507 // We work backwards, from top-most element to bottom-most element
508 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
509 {
510 int ret = (*iter)->SetInputFocus(inFocus);
511 if (ret == 0)
512 return 0;
513 else if (ret < 0)
514 LOGERR("An input focus handler has returned an error");
515 }
516 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400517}
518
519void Page::SetPageFocus(int inFocus)
520{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200521 // Render remaining objects
522 std::vector<RenderObject*>::iterator iter;
523 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
524 (*iter)->SetPageFocus(inFocus);
525
526 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400527}
528
529int Page::NotifyVarChange(std::string varName, std::string value)
530{
Vojtech Bocek07220562014-02-08 02:05:33 +0100531 std::vector<GUIObject*>::iterator iter;
532 for (iter = mObjects.begin(); iter != mObjects.end(); ++iter)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200533 {
534 if ((*iter)->NotifyVarChange(varName, value))
535 LOGERR("An action handler errored on NotifyVarChange.\n");
536 }
537 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400538}
539
540PageSet::PageSet(char* xmlFile)
541{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200542 mResources = NULL;
543 mCurrentPage = NULL;
544 mOverlayPage = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400545
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200546 mXmlFile = xmlFile;
547 if (xmlFile)
548 mDoc.parse<0>(mXmlFile);
549 else
550 mCurrentPage = new Page(NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400551}
552
553PageSet::~PageSet()
554{
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100555 for (std::vector<Page*>::iterator itr = mPages.begin(); itr != mPages.end(); ++itr)
556 delete *itr;
Ethan Yonker780cd392014-07-21 15:24:39 -0500557 for (std::vector<xml_node<>*>::iterator itr2 = templates.begin(); itr2 != templates.end(); ++itr2)
558 delete *itr2;
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100559
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200560 delete mResources;
561 free(mXmlFile);
Dees_Troy51a0e822012-09-05 15:24:24 -0400562}
563
564int PageSet::Load(ZipArchive* package)
565{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200566 xml_node<>* parent;
567 xml_node<>* child;
Ethan Yonker780cd392014-07-21 15:24:39 -0500568 xml_node<>* xmltemplate;
569 xml_node<>* blank_templates;
570 int pages_loaded = -1, ret;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500571
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200572 parent = mDoc.first_node("recovery");
573 if (!parent)
574 parent = mDoc.first_node("install");
Dees_Troy51a0e822012-09-05 15:24:24 -0400575
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200576 // Now, let's parse the XML
577 LOGINFO("Loading resources...\n");
578 child = parent->first_node("resources");
579 if (child)
580 mResources = new ResourceManager(child, package);
Dees_Troy51a0e822012-09-05 15:24:24 -0400581
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200582 LOGINFO("Loading variables...\n");
583 child = parent->first_node("variables");
584 if (child)
585 LoadVariables(child);
Dees_Troy51a0e822012-09-05 15:24:24 -0400586
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100587 LOGINFO("Loading mouse cursor...\n");
588 child = parent->first_node("mousecursor");
589 if(child)
590 PageManager::LoadCursorData(child);
591
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200592 LOGINFO("Loading pages...\n");
593 // This may be NULL if no templates are present
Ethan Yonker780cd392014-07-21 15:24:39 -0500594 xmltemplate = parent->first_node("templates");
595 if (xmltemplate)
596 templates.push_back(xmltemplate);
Dees_Troy51a0e822012-09-05 15:24:24 -0400597
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200598 child = parent->first_node("pages");
Ethan Yonker780cd392014-07-21 15:24:39 -0500599 if (child) {
600 if (LoadPages(child)) {
601 LOGERR("PageSet::Load returning -1\n");
602 return -1;
603 }
604 }
605
606 return CheckInclude(package, &mDoc);
607}
Dees_Troy51a0e822012-09-05 15:24:24 -0400608
Ethan Yonker780cd392014-07-21 15:24:39 -0500609int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc)
610{
611 xml_node<>* par;
612 xml_node<>* par2;
613 xml_node<>* chld;
614 xml_node<>* parent;
615 xml_node<>* child;
616 xml_node<>* xmltemplate;
617 long len;
618 char* xmlFile = NULL;
619 string filename;
620 xml_document<> doc;
621
622 par = parentDoc->first_node("recovery");
623 if (!par) {
624 par = parentDoc->first_node("install");
625 }
626 if (!par) {
627 return 0;
628 }
629
630 par2 = par->first_node("include");
631 if (!par2)
632 return 0;
633 chld = par2->first_node("xmlfile");
634 while (chld != NULL) {
635 xml_attribute<>* attr = chld->first_attribute("name");
636 if (!attr)
637 break;
638
639 LOGINFO("PageSet::CheckInclude loading filename: '%s'\n", filename.c_str());
640 if (!package) {
641 // We can try to load the XML directly...
642 filename = "/res/";
643 filename += attr->value();
644 struct stat st;
645 if(stat(filename.c_str(),&st) != 0) {
646 LOGERR("Unable to locate '%s'\n", filename.c_str());
647 return -1;
648 }
649
650 len = st.st_size;
651 xmlFile = (char*) malloc(len + 1);
652 if (!xmlFile)
653 return -1;
654
655 int fd = open(filename.c_str(), O_RDONLY);
656 if (fd == -1)
657 return -1;
658
659 read(fd, xmlFile, len);
660 close(fd);
661 } else {
662 filename += attr->value();
663 const ZipEntry* ui_xml = mzFindZipEntry(package, filename.c_str());
664 if (ui_xml == NULL)
665 {
666 LOGERR("Unable to locate '%s' in zip file\n", filename.c_str());
667 return -1;
668 }
669
670 // Allocate the buffer for the file
671 len = mzGetZipEntryUncompLen(ui_xml);
672 xmlFile = (char*) malloc(len + 1);
673 if (!xmlFile)
674 return -1;
675
676 if (!mzExtractZipEntryToBuffer(package, ui_xml, (unsigned char*) xmlFile))
677 {
678 LOGERR("Unable to extract '%s'\n", filename.c_str());
679 return -1;
680 }
681 }
682 doc.parse<0>(xmlFile);
683
684 parent = doc.first_node("recovery");
685 if (!parent)
686 parent = doc.first_node("install");
687
688 // Now, let's parse the XML
689 LOGINFO("Loading included resources...\n");
690 child = parent->first_node("resources");
691 if (child)
692 mResources->LoadResources(child, package);
693
694 LOGINFO("Loading included variables...\n");
695 child = parent->first_node("variables");
696 if (child)
697 LoadVariables(child);
698
699 LOGINFO("Loading mouse cursor...\n");
700 child = parent->first_node("mousecursor");
701 if(child)
702 PageManager::LoadCursorData(child);
703
704 LOGINFO("Loading included pages...\n");
705 // This may be NULL if no templates are present
706 xmltemplate = parent->first_node("templates");
707 if (xmltemplate)
708 templates.push_back(xmltemplate);
709
710 child = parent->first_node("pages");
711 if (child)
712 if (LoadPages(child))
713 return -1;
714
715 if (CheckInclude(package, &doc))
716 return -1;
717
718 chld = chld->next_sibling("xmlfile");
719 }
720
721 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400722}
723
724int PageSet::SetPage(std::string page)
725{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200726 Page* tmp = FindPage(page);
727 if (tmp)
728 {
729 if (mCurrentPage) mCurrentPage->SetPageFocus(0);
730 mCurrentPage = tmp;
731 mCurrentPage->SetPageFocus(1);
732 mCurrentPage->NotifyVarChange("", "");
733 return 0;
734 }
735 else
736 {
737 LOGERR("Unable to locate page (%s)\n", page.c_str());
738 }
739 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400740}
741
742int PageSet::SetOverlay(Page* page)
743{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200744 if (mOverlayPage) mOverlayPage->SetPageFocus(0);
745 mOverlayPage = page;
746 if (mOverlayPage)
747 {
748 mOverlayPage->SetPageFocus(1);
749 mOverlayPage->NotifyVarChange("", "");
750 }
751 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400752}
753
754Resource* PageSet::FindResource(std::string name)
755{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200756 return mResources ? mResources->FindResource(name) : NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400757}
758
759Page* PageSet::FindPage(std::string name)
760{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200761 std::vector<Page*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400762
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200763 for (iter = mPages.begin(); iter != mPages.end(); iter++)
764 {
765 if (name == (*iter)->GetName())
766 return (*iter);
767 }
768 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400769}
770
771int PageSet::LoadVariables(xml_node<>* vars)
772{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200773 xml_node<>* child;
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100774 xml_attribute<> *name, *value, *persist;
775 int p;
Dees_Troy51a0e822012-09-05 15:24:24 -0400776
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200777 child = vars->first_node("variable");
778 while (child)
779 {
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100780 name = child->first_attribute("name");
781 value = child->first_attribute("value");
782 persist = child->first_attribute("persist");
783 if(name && value)
784 {
785 p = persist ? atoi(persist->value()) : 0;
Ethan Yonker96acb3d2014-08-05 09:20:30 -0500786 string temp = value->value();
787 string valstr = gui_parse_text(temp);
788
789 if (valstr.find("+") != string::npos) {
790 string val1str = valstr;
791 val1str = val1str.substr(0, val1str.find('+'));
792 string val2str = valstr;
793 val2str = val2str.substr(val2str.find('+') + 1, string::npos);
794 int val1 = atoi(val1str.c_str());
795 int val2 = atoi(val2str.c_str());
796 int val = val1 + val2;
797
798 DataManager::SetValue(name->value(), val, p);
799 } else if (valstr.find("-") != string::npos) {
800 string val1str = valstr;
801 val1str = val1str.substr(0, val1str.find('-'));
802 string val2str = valstr;
803 val2str = val2str.substr(val2str.find('-') + 1, string::npos);
804 int val1 = atoi(val1str.c_str());
805 int val2 = atoi(val2str.c_str());
806 int val = val1 - val2;
807
808 DataManager::SetValue(name->value(), val, p);
809 } else {
810 DataManager::SetValue(name->value(), valstr, p);
811 }
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100812 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400813
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200814 child = child->next_sibling("variable");
815 }
816 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400817}
818
Ethan Yonker780cd392014-07-21 15:24:39 -0500819int PageSet::LoadPages(xml_node<>* pages)
Dees_Troy51a0e822012-09-05 15:24:24 -0400820{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200821 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -0400822
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200823 if (!pages)
824 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400825
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200826 child = pages->first_node("page");
827 while (child != NULL)
828 {
Ethan Yonker780cd392014-07-21 15:24:39 -0500829 Page* page = new Page(child, &templates);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200830 if (page->GetName().empty())
831 {
832 LOGERR("Unable to process load page\n");
833 delete page;
834 }
835 else
836 {
837 mPages.push_back(page);
838 }
839 child = child->next_sibling("page");
840 }
841 if (mPages.size() > 0)
842 return 0;
843 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400844}
845
846int PageSet::IsCurrentPage(Page* page)
847{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200848 return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -0400849}
850
851int PageSet::Render(void)
852{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200853 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400854
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200855 ret = (mCurrentPage ? mCurrentPage->Render() : -1);
856 if (ret < 0)
857 return ret;
858 ret = (mOverlayPage ? mOverlayPage->Render() : -1);
859 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400860}
861
862int PageSet::Update(void)
863{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200864 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400865
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200866 ret = (mCurrentPage ? mCurrentPage->Update() : -1);
867 if (ret < 0 || ret > 1)
868 return ret;
869 ret = (mOverlayPage ? mOverlayPage->Update() : -1);
870 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400871}
872
873int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
874{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200875 if (mOverlayPage)
876 return (mOverlayPage->NotifyTouch(state, x, y));
877
878 return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400879}
880
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100881int PageSet::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400882{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200883 if (mOverlayPage)
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100884 return (mOverlayPage->NotifyKey(key, down));
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200885
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100886 return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400887}
888
889int PageSet::NotifyKeyboard(int key)
890{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200891 if (mOverlayPage)
892 return (mOverlayPage->NotifyKeyboard(key));
893
894 return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400895}
896
897int PageSet::SetKeyBoardFocus(int inFocus)
898{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200899 if (mOverlayPage)
900 return (mOverlayPage->SetKeyBoardFocus(inFocus));
901
902 return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400903}
904
905int PageSet::NotifyVarChange(std::string varName, std::string value)
906{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200907 if (mOverlayPage)
908 mOverlayPage->NotifyVarChange(varName, value);
909
910 return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400911}
912
913int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
914{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200915 int fd;
916 ZipArchive zip, *pZip = NULL;
917 long len;
918 char* xmlFile = NULL;
919 PageSet* pageSet = NULL;
920 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400921
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200922 // Open the XML file
923 LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
924 if (mzOpenZipArchive(package.c_str(), &zip))
925 {
926 // We can try to load the XML directly...
927 struct stat st;
928 if(stat(package.c_str(),&st) != 0)
929 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400930
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200931 len = st.st_size;
932 xmlFile = (char*) malloc(len + 1);
933 if (!xmlFile)
934 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400935
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200936 fd = open(package.c_str(), O_RDONLY);
937 if (fd == -1)
938 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400939
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200940 read(fd, xmlFile, len);
941 close(fd);
942 }
943 else
944 {
945 pZip = &zip;
946 const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml");
947 if (ui_xml == NULL)
948 {
949 LOGERR("Unable to locate ui.xml in zip file\n");
950 goto error;
951 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500952
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200953 // Allocate the buffer for the file
954 len = mzGetZipEntryUncompLen(ui_xml);
955 xmlFile = (char*) malloc(len + 1);
956 if (!xmlFile)
957 goto error;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500958
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200959 if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile))
960 {
961 LOGERR("Unable to extract ui.xml\n");
962 goto error;
963 }
964 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400965
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200966 // NULL-terminate the string
967 xmlFile[len] = 0x00;
Dees_Troy51a0e822012-09-05 15:24:24 -0400968
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200969 // Before loading, mCurrentSet must be the loading package so we can find resources
970 pageSet = mCurrentSet;
971 mCurrentSet = new PageSet(xmlFile);
972
973 ret = mCurrentSet->Load(pZip);
974 if (ret == 0)
975 {
976 mCurrentSet->SetPage(startpage);
977 mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
978 }
979 else
980 {
981 LOGERR("Package %s failed to load.\n", name.c_str());
982 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500983
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200984 // The first successful package we loaded is the base
985 if (mBaseSet == NULL)
986 mBaseSet = mCurrentSet;
987
988 mCurrentSet = pageSet;
989
990 if (pZip)
991 mzCloseZipArchive(pZip);
992 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400993
994error:
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200995 LOGERR("An internal error has occurred.\n");
996 if (pZip)
997 mzCloseZipArchive(pZip);
998 if (xmlFile)
999 free(xmlFile);
1000 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001001}
1002
1003PageSet* PageManager::FindPackage(std::string name)
1004{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001005 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001006
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001007 iter = mPageSets.find(name);
1008 if (iter != mPageSets.end())
1009 return (*iter).second;
1010
1011 LOGERR("Unable to locate package %s\n", name.c_str());
1012 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -04001013}
1014
1015PageSet* PageManager::SelectPackage(std::string name)
1016{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001017 LOGINFO("Switching packages (%s)\n", name.c_str());
1018 PageSet* tmp;
Dees_Troy51a0e822012-09-05 15:24:24 -04001019
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001020 tmp = FindPackage(name);
1021 if (tmp)
Vojtech Bocek07220562014-02-08 02:05:33 +01001022 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001023 mCurrentSet = tmp;
Vojtech Bocek07220562014-02-08 02:05:33 +01001024 mCurrentSet->NotifyVarChange("", "");
1025 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001026 else
1027 LOGERR("Unable to find package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001028
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001029 return mCurrentSet;
Dees_Troy51a0e822012-09-05 15:24:24 -04001030}
1031
1032int PageManager::ReloadPackage(std::string name, std::string package)
1033{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001034 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001035
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001036 iter = mPageSets.find(name);
1037 if (iter == mPageSets.end())
1038 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001039
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001040 if(mMouseCursor)
1041 mMouseCursor->ResetData(gr_fb_width(), gr_fb_height());
1042
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001043 PageSet* set = (*iter).second;
1044 mPageSets.erase(iter);
Dees_Troy51a0e822012-09-05 15:24:24 -04001045
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001046 if (LoadPackage(name, package, "main") != 0)
1047 {
1048 LOGERR("Failed to load package.\n");
1049 mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
1050 return -1;
1051 }
1052 if (mCurrentSet == set)
1053 SelectPackage(name);
Vojtech Bocekbfb63342014-02-08 00:32:31 +01001054 if (mBaseSet == set)
1055 mBaseSet = mCurrentSet;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001056 delete set;
1057 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001058}
1059
1060void PageManager::ReleasePackage(std::string name)
1061{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001062 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001063
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001064 iter = mPageSets.find(name);
1065 if (iter == mPageSets.end())
1066 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001067
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001068 PageSet* set = (*iter).second;
1069 mPageSets.erase(iter);
1070 delete set;
1071 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001072}
1073
1074int PageManager::ChangePage(std::string name)
1075{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001076 DataManager::SetValue("tw_operation_state", 0);
1077 int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
1078 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001079}
1080
1081int PageManager::ChangeOverlay(std::string name)
1082{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001083 if (name.empty())
1084 return mCurrentSet->SetOverlay(NULL);
1085 else
1086 {
1087 Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
1088 return mCurrentSet->SetOverlay(page);
1089 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001090}
1091
1092Resource* PageManager::FindResource(std::string name)
1093{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001094 return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001095}
1096
1097Resource* PageManager::FindResource(std::string package, std::string name)
1098{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001099 PageSet* tmp;
Dees_Troy51a0e822012-09-05 15:24:24 -04001100
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001101 tmp = FindPackage(name);
1102 return (tmp ? tmp->FindResource(name) : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001103}
1104
1105int PageManager::SwitchToConsole(void)
1106{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001107 PageSet* console = new PageSet(NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001108
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001109 mCurrentSet = console;
1110 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001111}
1112
Ethan Yonker03a42f62014-08-08 11:03:51 -05001113int PageManager::EndConsole(void)
1114{
1115 if (mCurrentSet && mBaseSet) {
1116 delete mCurrentSet;
1117 mCurrentSet = mBaseSet;
1118 return 0;
1119 }
1120 return -1;
1121}
1122
Dees_Troy51a0e822012-09-05 15:24:24 -04001123int PageManager::IsCurrentPage(Page* page)
1124{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001125 return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -04001126}
1127
1128int PageManager::Render(void)
1129{
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001130 int res = (mCurrentSet ? mCurrentSet->Render() : -1);
1131 if(mMouseCursor)
1132 mMouseCursor->Render();
1133 return res;
1134}
1135
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001136HardwareKeyboard *PageManager::GetHardwareKeyboard()
1137{
1138 if(!mHardwareKeyboard)
1139 mHardwareKeyboard = new HardwareKeyboard();
1140 return mHardwareKeyboard;
1141}
1142
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001143MouseCursor *PageManager::GetMouseCursor()
1144{
1145 if(!mMouseCursor)
1146 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1147 return mMouseCursor;
1148}
1149
1150void PageManager::LoadCursorData(xml_node<>* node)
1151{
1152 if(!mMouseCursor)
1153 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1154
1155 mMouseCursor->LoadData(node);
Dees_Troy51a0e822012-09-05 15:24:24 -04001156}
1157
1158int PageManager::Update(void)
1159{
Ricardo Gomezc9ecd442013-07-05 16:13:52 -07001160#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001161 if(blankTimer.IsScreenOff())
1162 return 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -07001163#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001164
1165 int res = (mCurrentSet ? mCurrentSet->Update() : -1);
1166
1167 if(mMouseCursor)
1168 {
1169 int c_res = mMouseCursor->Update();
1170 if(c_res > res)
1171 res = c_res;
1172 }
1173 return res;
Dees_Troy51a0e822012-09-05 15:24:24 -04001174}
1175
1176int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
1177{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001178 return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001179}
1180
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001181int PageManager::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -04001182{
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001183 return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001184}
1185
1186int PageManager::NotifyKeyboard(int key)
1187{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001188 return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001189}
1190
1191int PageManager::SetKeyBoardFocus(int inFocus)
1192{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001193 return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001194}
1195
1196int PageManager::NotifyVarChange(std::string varName, std::string value)
1197{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001198 return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001199}
1200
1201extern "C" void gui_notifyVarChange(const char *name, const char* value)
1202{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001203 if (!gGuiRunning)
1204 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001205
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001206 PageManager::NotifyVarChange(name, value);
Dees_Troy51a0e822012-09-05 15:24:24 -04001207}