blob: b110e3820aae69ddc1998a655b827beba11cc78d [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 Yonker75bf0412014-11-21 13:54:27 -060042#if (ANDROID_VERSION >= 5)
Ethan Yonkera2dc2f22014-11-08 08:13:40 -060043#include "../minzip/SysUtil.h"
44#include "../minzip/Zip.h"
Ethan Yonker75bf0412014-11-21 13:54:27 -060045#else
46#include "../minzipold/SysUtil.h"
47#include "../minzipold/Zip.h"
48#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040049}
50
51#include "rapidxml.hpp"
52#include "objects.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070053#ifndef TW_NO_SCREEN_TIMEOUT
gordon13370d9133d2013-06-08 14:17:07 +020054#include "blanktimer.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070055#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040056
57extern int gGuiRunning;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070058#ifndef TW_NO_SCREEN_TIMEOUT
gordon13370d9133d2013-06-08 14:17:07 +020059extern blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070060#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040061
62std::map<std::string, PageSet*> PageManager::mPageSets;
63PageSet* PageManager::mCurrentSet;
64PageSet* PageManager::mBaseSet = NULL;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +010065MouseCursor *PageManager::mMouseCursor = NULL;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +010066HardwareKeyboard *PageManager::mHardwareKeyboard = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -040067
Dees_Troy51a0e822012-09-05 15:24:24 -040068// Helper routine to convert a string to a color declaration
69int ConvertStrToColor(std::string str, COLOR* color)
70{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020071 // Set the default, solid black
72 memset(color, 0, sizeof(COLOR));
73 color->alpha = 255;
Dees_Troy51a0e822012-09-05 15:24:24 -040074
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020075 // Translate variables
76 DataManager::GetValue(str, str);
Matt Mowerfb1c4ff2014-04-16 13:43:36 -050077
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020078 // Look for some defaults
79 if (str == "black") return 0;
80 else if (str == "white") { color->red = color->green = color->blue = 255; return 0; }
81 else if (str == "red") { color->red = 255; return 0; }
82 else if (str == "green") { color->green = 255; return 0; }
83 else if (str == "blue") { color->blue = 255; return 0; }
Dees_Troy51a0e822012-09-05 15:24:24 -040084
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020085 // At this point, we require an RGB(A) color
86 if (str[0] != '#')
87 return -1;
88
89 str.erase(0, 1);
Dees_Troy51a0e822012-09-05 15:24:24 -040090
Dees_Troy30b962e2012-10-19 20:48:59 -040091 int result;
92 if (str.size() >= 8) {
93 // We have alpha channel
94 string alpha = str.substr(6, 2);
95 result = strtol(alpha.c_str(), NULL, 16);
96 color->alpha = result & 0x000000FF;
97 str.resize(6);
98 result = strtol(str.c_str(), NULL, 16);
99 color->red = (result >> 16) & 0x000000FF;
100 color->green = (result >> 8) & 0x000000FF;
101 color->blue = result & 0x000000FF;
102 } else {
103 result = strtol(str.c_str(), NULL, 16);
104 color->red = (result >> 16) & 0x000000FF;
105 color->green = (result >> 8) & 0x000000FF;
106 color->blue = result & 0x000000FF;
107 }
108 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400109}
110
111// Helper APIs
112bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */)
113{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200114 if (!node)
115 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400116
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200117 std::string value;
118 if (node->first_attribute("x"))
119 {
120 value = node->first_attribute("x")->value();
121 DataManager::GetValue(value, value);
122 *x = atol(value.c_str());
123 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400124
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200125 if (node->first_attribute("y"))
126 {
127 value = node->first_attribute("y")->value();
128 DataManager::GetValue(value, value);
129 *y = atol(value.c_str());
130 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400131
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200132 if (w && node->first_attribute("w"))
133 {
134 value = node->first_attribute("w")->value();
135 DataManager::GetValue(value, value);
136 *w = atol(value.c_str());
137 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400138
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200139 if (h && node->first_attribute("h"))
140 {
141 value = node->first_attribute("h")->value();
142 DataManager::GetValue(value, value);
143 *h = atol(value.c_str());
144 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400145
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200146 if (placement && node->first_attribute("placement"))
147 {
148 value = node->first_attribute("placement")->value();
149 DataManager::GetValue(value, value);
150 *placement = (RenderObject::Placement) atol(value.c_str());
151 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400152
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200153 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400154}
155
156int ActionObject::SetActionPos(int x, int y, int w, int h)
157{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200158 if (x < 0 || y < 0)
159 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400160
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500161 mActionX = x;
162 mActionY = y;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200163 if (w || h)
164 {
165 mActionW = w;
166 mActionH = h;
167 }
168 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400169}
170
Ethan Yonker780cd392014-07-21 15:24:39 -0500171Page::Page(xml_node<>* page, std::vector<xml_node<>*> *templates /* = NULL */)
Dees_Troy51a0e822012-09-05 15:24:24 -0400172{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200173 mTouchStart = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400174
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200175 // We can memset the whole structure, because the alpha channel is ignored
176 memset(&mBackground, 0, sizeof(COLOR));
Dees_Troy51a0e822012-09-05 15:24:24 -0400177
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200178 // With NULL, we make a console-only display
179 if (!page)
180 {
181 mName = "console";
Dees_Troy51a0e822012-09-05 15:24:24 -0400182
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200183 GUIConsole* element = new GUIConsole(NULL);
184 mRenders.push_back(element);
185 mActions.push_back(element);
186 return;
187 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400188
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200189 if (page->first_attribute("name"))
190 mName = page->first_attribute("name")->value();
191 else
192 {
193 LOGERR("No page name attribute found!\n");
194 return;
195 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400196
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200197 LOGINFO("Loading page %s\n", mName.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400198
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200199 // This is a recursive routine for template handling
200 ProcessNode(page, templates);
Dees_Troy51a0e822012-09-05 15:24:24 -0400201
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400203}
204
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100205Page::~Page()
206{
207 for (std::vector<GUIObject*>::iterator itr = mObjects.begin(); itr != mObjects.end(); ++itr)
208 delete *itr;
209}
210
Ethan Yonker780cd392014-07-21 15:24:39 -0500211bool Page::ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates /* = NULL */, int depth /* = 0 */)
Dees_Troy51a0e822012-09-05 15:24:24 -0400212{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200213 if (depth == 10)
214 {
215 LOGERR("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n");
216 return false;
217 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400218
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200219 // Let's retrieve the background value, if any
220 xml_node<>* bg = page->first_node("background");
221 if (bg)
222 {
223 xml_attribute<>* attr = bg->first_attribute("color");
224 if (attr)
225 {
226 std::string color = attr->value();
227 ConvertStrToColor(color, &mBackground);
228 }
229 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400230
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200231 xml_node<>* child;
232 child = page->first_node("object");
233 while (child)
234 {
235 if (!child->first_attribute("type"))
236 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400237
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200238 std::string type = child->first_attribute("type")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -0400239
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200240 if (type == "text")
241 {
242 GUIText* element = new GUIText(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100243 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200244 mRenders.push_back(element);
245 mActions.push_back(element);
246 }
247 else if (type == "image")
248 {
249 GUIImage* element = new GUIImage(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100250 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200251 mRenders.push_back(element);
252 }
253 else if (type == "fill")
254 {
255 GUIFill* element = new GUIFill(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100256 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 mRenders.push_back(element);
258 }
259 else if (type == "action")
260 {
261 GUIAction* element = new GUIAction(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100262 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200263 mActions.push_back(element);
264 }
265 else if (type == "console")
266 {
267 GUIConsole* element = new GUIConsole(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100268 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200269 mRenders.push_back(element);
270 mActions.push_back(element);
271 }
272 else if (type == "button")
273 {
274 GUIButton* element = new GUIButton(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100275 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200276 mRenders.push_back(element);
277 mActions.push_back(element);
278 }
279 else if (type == "checkbox")
280 {
281 GUICheckbox* element = new GUICheckbox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100282 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200283 mRenders.push_back(element);
284 mActions.push_back(element);
285 }
286 else if (type == "fileselector")
287 {
288 GUIFileSelector* element = new GUIFileSelector(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100289 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200290 mRenders.push_back(element);
291 mActions.push_back(element);
292 }
293 else if (type == "animation")
294 {
295 GUIAnimation* element = new GUIAnimation(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100296 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200297 mRenders.push_back(element);
298 }
299 else if (type == "progressbar")
300 {
301 GUIProgressBar* element = new GUIProgressBar(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100302 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200303 mRenders.push_back(element);
304 mActions.push_back(element);
305 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400306 else if (type == "slider")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200307 {
308 GUISlider* element = new GUISlider(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100309 mObjects.push_back(element);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200310 mRenders.push_back(element);
311 mActions.push_back(element);
312 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200313 else if (type == "slidervalue")
314 {
315 GUISliderValue *element = new GUISliderValue(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100316 mObjects.push_back(element);
Vojtech Bocek85932342013-04-01 22:11:33 +0200317 mRenders.push_back(element);
318 mActions.push_back(element);
319 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400320 else if (type == "listbox")
321 {
322 GUIListBox* element = new GUIListBox(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100323 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400324 mRenders.push_back(element);
325 mActions.push_back(element);
326 }
327 else if (type == "keyboard")
328 {
329 GUIKeyboard* element = new GUIKeyboard(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100330 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400331 mRenders.push_back(element);
332 mActions.push_back(element);
333 }
334 else if (type == "input")
335 {
336 GUIInput* element = new GUIInput(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100337 mObjects.push_back(element);
Dees_Troy51a0e822012-09-05 15:24:24 -0400338 mRenders.push_back(element);
339 mActions.push_back(element);
340 mInputs.push_back(element);
341 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500342 else if (type == "partitionlist")
343 {
344 GUIPartitionList* element = new GUIPartitionList(child);
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100345 mObjects.push_back(element);
Dees_Troya13d74f2013-03-24 08:54:55 -0500346 mRenders.push_back(element);
347 mActions.push_back(element);
348 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200349 else if (type == "template")
350 {
351 if (!templates || !child->first_attribute("name"))
352 {
353 LOGERR("Invalid template request.\n");
354 }
355 else
356 {
357 std::string name = child->first_attribute("name")->value();
Ethan Yonker780cd392014-07-21 15:24:39 -0500358 xml_node<>* node;
359 bool node_found = false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400360
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200361 // We need to find the correct template
Ethan Yonker780cd392014-07-21 15:24:39 -0500362 for (std::vector<xml_node<>*>::iterator itr = templates->begin(); itr != templates->end(); itr++) {
363 node = (*itr)->first_node("template");
Dees_Troy51a0e822012-09-05 15:24:24 -0400364
Ethan Yonker780cd392014-07-21 15:24:39 -0500365 while (node)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200366 {
Ethan Yonker780cd392014-07-21 15:24:39 -0500367 if (!node->first_attribute("name"))
368 continue;
369
370 if (name == node->first_attribute("name")->value())
371 {
372 if (!ProcessNode(node, templates, depth + 1))
373 return false;
374 else {
375 node_found = true;
376 break;
377 }
378 }
379 if (node_found)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200380 break;
Ethan Yonker780cd392014-07-21 15:24:39 -0500381 node = node->next_sibling("template");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200382 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200383 }
384 }
385 }
386 else
387 {
388 LOGERR("Unknown object type.\n");
389 }
390 child = child->next_sibling("object");
391 }
392 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400393}
394
395int Page::Render(void)
396{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200397 // Render background
398 gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
399 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
Dees_Troy51a0e822012-09-05 15:24:24 -0400400
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200401 // Render remaining objects
402 std::vector<RenderObject*>::iterator iter;
403 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
404 {
405 if ((*iter)->Render())
406 LOGERR("A render request has failed.\n");
407 }
408 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400409}
410
411int Page::Update(void)
412{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200413 int retCode = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400414
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200415 std::vector<RenderObject*>::iterator iter;
416 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
417 {
418 int ret = (*iter)->Update();
419 if (ret < 0)
420 LOGERR("An update request has failed.\n");
421 else if (ret > retCode)
422 retCode = ret;
423 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400424
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200425 return retCode;
Dees_Troy51a0e822012-09-05 15:24:24 -0400426}
427
428int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
429{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200430 // By default, return 1 to ignore further touches if nobody is listening
431 int ret = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400432
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200433 // Don't try to handle a lack of handlers
434 if (mActions.size() == 0)
435 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400436
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200437 // We record mTouchStart so we can pass all the touch stream to the same handler
438 if (state == TOUCH_START)
439 {
440 std::vector<ActionObject*>::reverse_iterator iter;
441 // We work backwards, from top-most element to bottom-most element
442 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
443 {
444 if ((*iter)->IsInRegion(x, y))
445 {
446 mTouchStart = (*iter);
447 ret = mTouchStart->NotifyTouch(state, x, y);
448 if (ret >= 0)
449 break;
450 mTouchStart = NULL;
451 }
452 }
453 }
454 else if (state == TOUCH_RELEASE && mTouchStart != NULL)
455 {
456 ret = mTouchStart->NotifyTouch(state, x, y);
457 mTouchStart = NULL;
458 }
459 else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
460 {
461 ret = mTouchStart->NotifyTouch(state, x, y);
462 }
463 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400464}
465
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100466int Page::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400467{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200468 std::vector<ActionObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400469
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200470 // Don't try to handle a lack of handlers
471 if (mActions.size() == 0)
472 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400473
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100474 int ret = 1;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200475 // We work backwards, from top-most element to bottom-most element
476 for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
477 {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100478 ret = (*iter)->NotifyKey(key, down);
479 if (ret < 0) {
480 LOGERR("An action handler has returned an error\n");
481 ret = 1;
482 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200483 }
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100484 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400485}
486
487int Page::NotifyKeyboard(int key)
488{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200489 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400490
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200491 // Don't try to handle a lack of handlers
492 if (mInputs.size() == 0)
493 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400494
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200495 // We work backwards, from top-most element to bottom-most element
496 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
497 {
498 int ret = (*iter)->NotifyKeyboard(key);
499 if (ret == 0)
500 return 0;
501 else if (ret < 0)
502 LOGERR("A keyboard handler has returned an error");
503 }
504 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400505}
506
507int Page::SetKeyBoardFocus(int inFocus)
508{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200509 std::vector<InputObject*>::reverse_iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400510
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200511 // Don't try to handle a lack of handlers
512 if (mInputs.size() == 0)
513 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400514
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200515 // We work backwards, from top-most element to bottom-most element
516 for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
517 {
518 int ret = (*iter)->SetInputFocus(inFocus);
519 if (ret == 0)
520 return 0;
521 else if (ret < 0)
522 LOGERR("An input focus handler has returned an error");
523 }
524 return 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400525}
526
527void Page::SetPageFocus(int inFocus)
528{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200529 // Render remaining objects
530 std::vector<RenderObject*>::iterator iter;
531 for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
532 (*iter)->SetPageFocus(inFocus);
533
534 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400535}
536
537int Page::NotifyVarChange(std::string varName, std::string value)
538{
Vojtech Bocek07220562014-02-08 02:05:33 +0100539 std::vector<GUIObject*>::iterator iter;
540 for (iter = mObjects.begin(); iter != mObjects.end(); ++iter)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200541 {
542 if ((*iter)->NotifyVarChange(varName, value))
543 LOGERR("An action handler errored on NotifyVarChange.\n");
544 }
545 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400546}
547
548PageSet::PageSet(char* xmlFile)
549{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200550 mResources = NULL;
551 mCurrentPage = NULL;
552 mOverlayPage = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400553
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200554 mXmlFile = xmlFile;
555 if (xmlFile)
556 mDoc.parse<0>(mXmlFile);
557 else
558 mCurrentPage = new Page(NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -0400559}
560
561PageSet::~PageSet()
562{
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100563 for (std::vector<Page*>::iterator itr = mPages.begin(); itr != mPages.end(); ++itr)
564 delete *itr;
Ethan Yonker780cd392014-07-21 15:24:39 -0500565 for (std::vector<xml_node<>*>::iterator itr2 = templates.begin(); itr2 != templates.end(); ++itr2)
566 delete *itr2;
Vojtech Bocekbfb63342014-02-08 00:32:31 +0100567
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200568 delete mResources;
569 free(mXmlFile);
Dees_Troy51a0e822012-09-05 15:24:24 -0400570}
571
572int PageSet::Load(ZipArchive* package)
573{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200574 xml_node<>* parent;
575 xml_node<>* child;
Ethan Yonker780cd392014-07-21 15:24:39 -0500576 xml_node<>* xmltemplate;
577 xml_node<>* blank_templates;
578 int pages_loaded = -1, ret;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500579
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200580 parent = mDoc.first_node("recovery");
581 if (!parent)
582 parent = mDoc.first_node("install");
Dees_Troy51a0e822012-09-05 15:24:24 -0400583
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200584 // Now, let's parse the XML
585 LOGINFO("Loading resources...\n");
586 child = parent->first_node("resources");
587 if (child)
588 mResources = new ResourceManager(child, package);
Dees_Troy51a0e822012-09-05 15:24:24 -0400589
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200590 LOGINFO("Loading variables...\n");
591 child = parent->first_node("variables");
592 if (child)
593 LoadVariables(child);
Dees_Troy51a0e822012-09-05 15:24:24 -0400594
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100595 LOGINFO("Loading mouse cursor...\n");
596 child = parent->first_node("mousecursor");
597 if(child)
598 PageManager::LoadCursorData(child);
599
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200600 LOGINFO("Loading pages...\n");
601 // This may be NULL if no templates are present
Ethan Yonker780cd392014-07-21 15:24:39 -0500602 xmltemplate = parent->first_node("templates");
603 if (xmltemplate)
604 templates.push_back(xmltemplate);
Dees_Troy51a0e822012-09-05 15:24:24 -0400605
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200606 child = parent->first_node("pages");
Ethan Yonker780cd392014-07-21 15:24:39 -0500607 if (child) {
608 if (LoadPages(child)) {
609 LOGERR("PageSet::Load returning -1\n");
610 return -1;
611 }
612 }
613
614 return CheckInclude(package, &mDoc);
615}
Dees_Troy51a0e822012-09-05 15:24:24 -0400616
Ethan Yonker780cd392014-07-21 15:24:39 -0500617int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc)
618{
619 xml_node<>* par;
620 xml_node<>* par2;
621 xml_node<>* chld;
622 xml_node<>* parent;
623 xml_node<>* child;
624 xml_node<>* xmltemplate;
625 long len;
626 char* xmlFile = NULL;
627 string filename;
628 xml_document<> doc;
629
630 par = parentDoc->first_node("recovery");
631 if (!par) {
632 par = parentDoc->first_node("install");
633 }
634 if (!par) {
635 return 0;
636 }
637
638 par2 = par->first_node("include");
639 if (!par2)
640 return 0;
641 chld = par2->first_node("xmlfile");
642 while (chld != NULL) {
643 xml_attribute<>* attr = chld->first_attribute("name");
644 if (!attr)
645 break;
646
647 LOGINFO("PageSet::CheckInclude loading filename: '%s'\n", filename.c_str());
648 if (!package) {
649 // We can try to load the XML directly...
650 filename = "/res/";
651 filename += attr->value();
652 struct stat st;
653 if(stat(filename.c_str(),&st) != 0) {
654 LOGERR("Unable to locate '%s'\n", filename.c_str());
655 return -1;
656 }
657
658 len = st.st_size;
659 xmlFile = (char*) malloc(len + 1);
660 if (!xmlFile)
661 return -1;
662
663 int fd = open(filename.c_str(), O_RDONLY);
664 if (fd == -1)
665 return -1;
666
667 read(fd, xmlFile, len);
668 close(fd);
669 } else {
670 filename += attr->value();
671 const ZipEntry* ui_xml = mzFindZipEntry(package, filename.c_str());
672 if (ui_xml == NULL)
673 {
674 LOGERR("Unable to locate '%s' in zip file\n", filename.c_str());
675 return -1;
676 }
677
678 // Allocate the buffer for the file
679 len = mzGetZipEntryUncompLen(ui_xml);
680 xmlFile = (char*) malloc(len + 1);
681 if (!xmlFile)
682 return -1;
683
684 if (!mzExtractZipEntryToBuffer(package, ui_xml, (unsigned char*) xmlFile))
685 {
686 LOGERR("Unable to extract '%s'\n", filename.c_str());
687 return -1;
688 }
689 }
690 doc.parse<0>(xmlFile);
691
692 parent = doc.first_node("recovery");
693 if (!parent)
694 parent = doc.first_node("install");
695
696 // Now, let's parse the XML
697 LOGINFO("Loading included resources...\n");
698 child = parent->first_node("resources");
699 if (child)
700 mResources->LoadResources(child, package);
701
702 LOGINFO("Loading included variables...\n");
703 child = parent->first_node("variables");
704 if (child)
705 LoadVariables(child);
706
707 LOGINFO("Loading mouse cursor...\n");
708 child = parent->first_node("mousecursor");
709 if(child)
710 PageManager::LoadCursorData(child);
711
712 LOGINFO("Loading included pages...\n");
713 // This may be NULL if no templates are present
714 xmltemplate = parent->first_node("templates");
715 if (xmltemplate)
716 templates.push_back(xmltemplate);
717
718 child = parent->first_node("pages");
719 if (child)
720 if (LoadPages(child))
721 return -1;
722
723 if (CheckInclude(package, &doc))
724 return -1;
725
726 chld = chld->next_sibling("xmlfile");
727 }
728
729 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400730}
731
732int PageSet::SetPage(std::string page)
733{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200734 Page* tmp = FindPage(page);
735 if (tmp)
736 {
737 if (mCurrentPage) mCurrentPage->SetPageFocus(0);
738 mCurrentPage = tmp;
739 mCurrentPage->SetPageFocus(1);
740 mCurrentPage->NotifyVarChange("", "");
741 return 0;
742 }
743 else
744 {
745 LOGERR("Unable to locate page (%s)\n", page.c_str());
746 }
747 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400748}
749
750int PageSet::SetOverlay(Page* page)
751{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200752 if (mOverlayPage) mOverlayPage->SetPageFocus(0);
753 mOverlayPage = page;
754 if (mOverlayPage)
755 {
756 mOverlayPage->SetPageFocus(1);
757 mOverlayPage->NotifyVarChange("", "");
758 }
759 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400760}
761
762Resource* PageSet::FindResource(std::string name)
763{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200764 return mResources ? mResources->FindResource(name) : NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400765}
766
767Page* PageSet::FindPage(std::string name)
768{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200769 std::vector<Page*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -0400770
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200771 for (iter = mPages.begin(); iter != mPages.end(); iter++)
772 {
773 if (name == (*iter)->GetName())
774 return (*iter);
775 }
776 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400777}
778
779int PageSet::LoadVariables(xml_node<>* vars)
780{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200781 xml_node<>* child;
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100782 xml_attribute<> *name, *value, *persist;
783 int p;
Dees_Troy51a0e822012-09-05 15:24:24 -0400784
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200785 child = vars->first_node("variable");
786 while (child)
787 {
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100788 name = child->first_attribute("name");
789 value = child->first_attribute("value");
790 persist = child->first_attribute("persist");
791 if(name && value)
792 {
793 p = persist ? atoi(persist->value()) : 0;
Ethan Yonker96acb3d2014-08-05 09:20:30 -0500794 string temp = value->value();
795 string valstr = gui_parse_text(temp);
796
797 if (valstr.find("+") != string::npos) {
798 string val1str = valstr;
799 val1str = val1str.substr(0, val1str.find('+'));
800 string val2str = valstr;
801 val2str = val2str.substr(val2str.find('+') + 1, string::npos);
802 int val1 = atoi(val1str.c_str());
803 int val2 = atoi(val2str.c_str());
804 int val = val1 + val2;
805
806 DataManager::SetValue(name->value(), val, p);
807 } else if (valstr.find("-") != string::npos) {
808 string val1str = valstr;
809 val1str = val1str.substr(0, val1str.find('-'));
810 string val2str = valstr;
811 val2str = val2str.substr(val2str.find('-') + 1, string::npos);
812 int val1 = atoi(val1str.c_str());
813 int val2 = atoi(val2str.c_str());
814 int val = val1 - val2;
815
816 DataManager::SetValue(name->value(), val, p);
817 } else {
818 DataManager::SetValue(name->value(), valstr, p);
819 }
Vojtech Bocek81c29dc2013-12-07 23:02:09 +0100820 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400821
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200822 child = child->next_sibling("variable");
823 }
824 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400825}
826
Ethan Yonker780cd392014-07-21 15:24:39 -0500827int PageSet::LoadPages(xml_node<>* pages)
Dees_Troy51a0e822012-09-05 15:24:24 -0400828{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200829 xml_node<>* child;
Dees_Troy51a0e822012-09-05 15:24:24 -0400830
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200831 if (!pages)
832 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400833
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200834 child = pages->first_node("page");
835 while (child != NULL)
836 {
Ethan Yonker780cd392014-07-21 15:24:39 -0500837 Page* page = new Page(child, &templates);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200838 if (page->GetName().empty())
839 {
840 LOGERR("Unable to process load page\n");
841 delete page;
842 }
843 else
844 {
845 mPages.push_back(page);
846 }
847 child = child->next_sibling("page");
848 }
849 if (mPages.size() > 0)
850 return 0;
851 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400852}
853
854int PageSet::IsCurrentPage(Page* page)
855{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200856 return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -0400857}
858
859int PageSet::Render(void)
860{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200861 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400862
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200863 ret = (mCurrentPage ? mCurrentPage->Render() : -1);
864 if (ret < 0)
865 return ret;
866 ret = (mOverlayPage ? mOverlayPage->Render() : -1);
867 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400868}
869
870int PageSet::Update(void)
871{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200872 int ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400873
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200874 ret = (mCurrentPage ? mCurrentPage->Update() : -1);
875 if (ret < 0 || ret > 1)
876 return ret;
877 ret = (mOverlayPage ? mOverlayPage->Update() : -1);
878 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400879}
880
881int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
882{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200883 if (mOverlayPage)
884 return (mOverlayPage->NotifyTouch(state, x, y));
885
886 return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400887}
888
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100889int PageSet::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400890{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200891 if (mOverlayPage)
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100892 return (mOverlayPage->NotifyKey(key, down));
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200893
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100894 return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400895}
896
897int PageSet::NotifyKeyboard(int key)
898{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200899 if (mOverlayPage)
900 return (mOverlayPage->NotifyKeyboard(key));
901
902 return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400903}
904
905int PageSet::SetKeyBoardFocus(int inFocus)
906{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200907 if (mOverlayPage)
908 return (mOverlayPage->SetKeyBoardFocus(inFocus));
909
910 return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400911}
912
913int PageSet::NotifyVarChange(std::string varName, std::string value)
914{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200915 if (mOverlayPage)
916 mOverlayPage->NotifyVarChange(varName, value);
917
918 return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400919}
920
921int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
922{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200923 int fd;
924 ZipArchive zip, *pZip = NULL;
925 long len;
926 char* xmlFile = NULL;
927 PageSet* pageSet = NULL;
928 int ret;
Ethan Yonker75bf0412014-11-21 13:54:27 -0600929#if (ANDROID_VERSION >= 5)
Ethan Yonkera2dc2f22014-11-08 08:13:40 -0600930 MemMapping map;
Ethan Yonker75bf0412014-11-21 13:54:27 -0600931#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400932
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200933 // Open the XML file
934 LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
Ethan Yonkera2dc2f22014-11-08 08:13:40 -0600935 if (package.size() > 4 && package.substr(package.size() - 4) != ".zip")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200936 {
Ethan Yonkera2dc2f22014-11-08 08:13:40 -0600937 LOGINFO("Load XML directly\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200938 // We can try to load the XML directly...
939 struct stat st;
940 if(stat(package.c_str(),&st) != 0)
941 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400942
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200943 len = st.st_size;
944 xmlFile = (char*) malloc(len + 1);
945 if (!xmlFile)
946 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400947
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200948 fd = open(package.c_str(), O_RDONLY);
949 if (fd == -1)
950 goto error;
Dees_Troy51a0e822012-09-05 15:24:24 -0400951
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200952 read(fd, xmlFile, len);
953 close(fd);
954 }
955 else
956 {
Ethan Yonkera2dc2f22014-11-08 08:13:40 -0600957 LOGINFO("Loading zip theme\n");
Ethan Yonker75bf0412014-11-21 13:54:27 -0600958#if (ANDROID_VERSION >= 5)
Ethan Yonkera2dc2f22014-11-08 08:13:40 -0600959 if (!TWFunc::Path_Exists(package))
960 return -1;
961 if (sysMapFile(package.c_str(), &map) != 0) {
962 LOGERR("Failed to map '%s'\n", package.c_str());
963 return -1;
964 }
965 if (mzOpenZipArchive(map.addr, map.length, &zip)) {
966 LOGERR("Unable to open zip archive '%s'\n", package.c_str());
967 sysReleaseMap(&map);
968 return -1;
969 }
Ethan Yonker75bf0412014-11-21 13:54:27 -0600970#else
971 if (mzOpenZipArchive(package.c_str(), &zip)) {
972 LOGERR("Failed to open theme zip.\n");
973 return -1;
974 }
975#endif
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200976 pZip = &zip;
977 const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml");
978 if (ui_xml == NULL)
979 {
980 LOGERR("Unable to locate ui.xml in zip file\n");
981 goto error;
982 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500983
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200984 // Allocate the buffer for the file
985 len = mzGetZipEntryUncompLen(ui_xml);
986 xmlFile = (char*) malloc(len + 1);
987 if (!xmlFile)
988 goto error;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500989
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200990 if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile))
991 {
992 LOGERR("Unable to extract ui.xml\n");
993 goto error;
994 }
995 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400996
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200997 // NULL-terminate the string
998 xmlFile[len] = 0x00;
Dees_Troy51a0e822012-09-05 15:24:24 -0400999
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001000 // Before loading, mCurrentSet must be the loading package so we can find resources
1001 pageSet = mCurrentSet;
1002 mCurrentSet = new PageSet(xmlFile);
1003
1004 ret = mCurrentSet->Load(pZip);
1005 if (ret == 0)
1006 {
1007 mCurrentSet->SetPage(startpage);
1008 mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
1009 }
1010 else
1011 {
1012 LOGERR("Package %s failed to load.\n", name.c_str());
1013 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -05001014
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001015 // The first successful package we loaded is the base
1016 if (mBaseSet == NULL)
1017 mBaseSet = mCurrentSet;
1018
1019 mCurrentSet = pageSet;
1020
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001021 if (pZip) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001022 mzCloseZipArchive(pZip);
Ethan Yonker75bf0412014-11-21 13:54:27 -06001023#if (ANDROID_VERSION >= 5)
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001024 sysReleaseMap(&map);
Ethan Yonker75bf0412014-11-21 13:54:27 -06001025#endif
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001026 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001027 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001028
1029error:
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001030 LOGERR("An internal error has occurred.\n");
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001031 if (pZip) {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001032 mzCloseZipArchive(pZip);
Ethan Yonker75bf0412014-11-21 13:54:27 -06001033#if (ANDROID_VERSION >= 5)
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001034 sysReleaseMap(&map);
Ethan Yonker75bf0412014-11-21 13:54:27 -06001035#endif
Ethan Yonkera2dc2f22014-11-08 08:13:40 -06001036 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001037 if (xmlFile)
1038 free(xmlFile);
1039 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001040}
1041
1042PageSet* PageManager::FindPackage(std::string name)
1043{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001044 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001045
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001046 iter = mPageSets.find(name);
1047 if (iter != mPageSets.end())
1048 return (*iter).second;
1049
1050 LOGERR("Unable to locate package %s\n", name.c_str());
1051 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -04001052}
1053
1054PageSet* PageManager::SelectPackage(std::string name)
1055{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001056 LOGINFO("Switching packages (%s)\n", name.c_str());
1057 PageSet* tmp;
Dees_Troy51a0e822012-09-05 15:24:24 -04001058
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001059 tmp = FindPackage(name);
1060 if (tmp)
Vojtech Bocek07220562014-02-08 02:05:33 +01001061 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001062 mCurrentSet = tmp;
Vojtech Bocek07220562014-02-08 02:05:33 +01001063 mCurrentSet->NotifyVarChange("", "");
1064 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001065 else
1066 LOGERR("Unable to find package.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001067
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001068 return mCurrentSet;
Dees_Troy51a0e822012-09-05 15:24:24 -04001069}
1070
1071int PageManager::ReloadPackage(std::string name, std::string package)
1072{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001073 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001074
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001075 iter = mPageSets.find(name);
1076 if (iter == mPageSets.end())
1077 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001078
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001079 if(mMouseCursor)
1080 mMouseCursor->ResetData(gr_fb_width(), gr_fb_height());
1081
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001082 PageSet* set = (*iter).second;
1083 mPageSets.erase(iter);
Dees_Troy51a0e822012-09-05 15:24:24 -04001084
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001085 if (LoadPackage(name, package, "main") != 0)
1086 {
1087 LOGERR("Failed to load package.\n");
1088 mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
1089 return -1;
1090 }
1091 if (mCurrentSet == set)
1092 SelectPackage(name);
Vojtech Bocekbfb63342014-02-08 00:32:31 +01001093 if (mBaseSet == set)
1094 mBaseSet = mCurrentSet;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001095 delete set;
1096 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001097}
1098
1099void PageManager::ReleasePackage(std::string name)
1100{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001101 std::map<std::string, PageSet*>::iterator iter;
Dees_Troy51a0e822012-09-05 15:24:24 -04001102
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001103 iter = mPageSets.find(name);
1104 if (iter == mPageSets.end())
1105 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001106
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001107 PageSet* set = (*iter).second;
1108 mPageSets.erase(iter);
1109 delete set;
1110 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001111}
1112
1113int PageManager::ChangePage(std::string name)
1114{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001115 DataManager::SetValue("tw_operation_state", 0);
1116 int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
1117 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001118}
1119
1120int PageManager::ChangeOverlay(std::string name)
1121{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001122 if (name.empty())
1123 return mCurrentSet->SetOverlay(NULL);
1124 else
1125 {
1126 Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
1127 return mCurrentSet->SetOverlay(page);
1128 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001129}
1130
1131Resource* PageManager::FindResource(std::string name)
1132{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001133 return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001134}
1135
1136Resource* PageManager::FindResource(std::string package, std::string name)
1137{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001138 PageSet* tmp;
Dees_Troy51a0e822012-09-05 15:24:24 -04001139
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001140 tmp = FindPackage(name);
1141 return (tmp ? tmp->FindResource(name) : NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001142}
1143
1144int PageManager::SwitchToConsole(void)
1145{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001146 PageSet* console = new PageSet(NULL);
Dees_Troy51a0e822012-09-05 15:24:24 -04001147
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001148 mCurrentSet = console;
1149 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001150}
1151
Ethan Yonker03a42f62014-08-08 11:03:51 -05001152int PageManager::EndConsole(void)
1153{
1154 if (mCurrentSet && mBaseSet) {
1155 delete mCurrentSet;
1156 mCurrentSet = mBaseSet;
1157 return 0;
1158 }
1159 return -1;
1160}
1161
Dees_Troy51a0e822012-09-05 15:24:24 -04001162int PageManager::IsCurrentPage(Page* page)
1163{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001164 return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
Dees_Troy51a0e822012-09-05 15:24:24 -04001165}
1166
1167int PageManager::Render(void)
1168{
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001169 int res = (mCurrentSet ? mCurrentSet->Render() : -1);
1170 if(mMouseCursor)
1171 mMouseCursor->Render();
1172 return res;
1173}
1174
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001175HardwareKeyboard *PageManager::GetHardwareKeyboard()
1176{
1177 if(!mHardwareKeyboard)
1178 mHardwareKeyboard = new HardwareKeyboard();
1179 return mHardwareKeyboard;
1180}
1181
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001182MouseCursor *PageManager::GetMouseCursor()
1183{
1184 if(!mMouseCursor)
1185 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1186 return mMouseCursor;
1187}
1188
1189void PageManager::LoadCursorData(xml_node<>* node)
1190{
1191 if(!mMouseCursor)
1192 mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height());
1193
1194 mMouseCursor->LoadData(node);
Dees_Troy51a0e822012-09-05 15:24:24 -04001195}
1196
1197int PageManager::Update(void)
1198{
Ricardo Gomezc9ecd442013-07-05 16:13:52 -07001199#ifndef TW_NO_SCREEN_TIMEOUT
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001200 if(blankTimer.IsScreenOff())
1201 return 0;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -07001202#endif
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +01001203
1204 int res = (mCurrentSet ? mCurrentSet->Update() : -1);
1205
1206 if(mMouseCursor)
1207 {
1208 int c_res = mMouseCursor->Update();
1209 if(c_res > res)
1210 res = c_res;
1211 }
1212 return res;
Dees_Troy51a0e822012-09-05 15:24:24 -04001213}
1214
1215int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
1216{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001217 return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001218}
1219
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001220int PageManager::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -04001221{
Vojtech Bocek0b7fe502014-03-13 17:36:52 +01001222 return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001223}
1224
1225int PageManager::NotifyKeyboard(int key)
1226{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001227 return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001228}
1229
1230int PageManager::SetKeyBoardFocus(int inFocus)
1231{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001232 return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001233}
1234
1235int PageManager::NotifyVarChange(std::string varName, std::string value)
1236{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001237 return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
Dees_Troy51a0e822012-09-05 15:24:24 -04001238}
1239
1240extern "C" void gui_notifyVarChange(const char *name, const char* value)
1241{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001242 if (!gGuiRunning)
1243 return;
Dees_Troy51a0e822012-09-05 15:24:24 -04001244
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001245 PageManager::NotifyVarChange(name, value);
Dees_Troy51a0e822012-09-05 15:24:24 -04001246}