diff --git a/gui/pages.cpp b/gui/pages.cpp
new file mode 100644
index 0000000..7e9274d
--- /dev/null
+++ b/gui/pages.cpp
@@ -0,0 +1,892 @@
+// base_objects.cpp - Source to manage GUI base objects
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <string>
+
+extern "C" {
+#include "../common.h"
+#include "../minuitwrp/minui.h"
+#include "../recovery_ui.h"
+}
+
+#include "rapidxml.hpp"
+#include "objects.hpp"
+
+extern int gGuiRunning;
+
+std::map<std::string, PageSet*> PageManager::mPageSets;
+PageSet* PageManager::mCurrentSet;
+PageSet* PageManager::mBaseSet = NULL;
+
+
+// Helper routine to convert a string to a color declaration
+int ConvertStrToColor(std::string str, COLOR* color)
+{
+    // Set the default, solid black
+    memset(color, 0, sizeof(COLOR));
+    color->alpha = 255;
+
+    // Translate variables
+    DataManager::GetValue(str, str);
+    
+    // Look for some defaults
+    if (str == "black")         return 0;
+    else if (str == "white")    { color->red = color->green = color->blue = 255; return 0; }
+    else if (str == "red")      { color->red = 255; return 0; }
+    else if (str == "green")    { color->green = 255; return 0; }
+    else if (str == "blue")     { color->blue = 255; return 0; }
+
+    // At this point, we require an RGB(A) color
+    if (str[0] != '#')          return -1;
+    str.erase(0, 1);
+
+    int result = strtol(str.c_str(), NULL, 16);
+    if (str.size() > 6)
+    {
+        // We have alpha channel
+        color->alpha = result & 0x000000FF;
+        result = result >> 8;
+    }
+    color->red = (result >> 16) & 0x000000FF;
+    color->green = (result >> 8) & 0x000000FF;
+    color->blue = result & 0x000000FF;
+    return 0;
+}
+
+// Helper APIs
+bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */)
+{
+    if (!node)      return false;
+
+    std::string value;
+    if (node->first_attribute("x"))
+    {
+        value = node->first_attribute("x")->value();
+        DataManager::GetValue(value, value);
+        *x = atol(value.c_str());
+    }
+
+    if (node->first_attribute("y"))
+    {
+        value = node->first_attribute("y")->value();
+        DataManager::GetValue(value, value);
+        *y = atol(value.c_str());
+    }
+
+    if (w && node->first_attribute("w"))
+    {
+        value = node->first_attribute("w")->value();
+        DataManager::GetValue(value, value);
+        *w = atol(value.c_str());
+    }
+
+    if (h && node->first_attribute("h"))
+    {
+        value = node->first_attribute("h")->value();
+        DataManager::GetValue(value, value);
+        *h = atol(value.c_str());
+    }
+
+    if (placement && node->first_attribute("placement"))
+    {
+        value = node->first_attribute("placement")->value();
+        DataManager::GetValue(value, value);
+        *placement = (RenderObject::Placement) atol(value.c_str());
+    }
+
+    return true;
+}
+
+int ActionObject::SetActionPos(int x, int y, int w, int h)
+{
+    if (x < 0 || y < 0)                                     return -1;
+
+    mActionX = x; 
+    mActionY = y; 
+    if (w || h)
+    {
+        mActionW = w;
+        mActionH = h;
+    }
+    return 0;
+}
+
+Page::Page(xml_node<>* page, xml_node<>* templates /* = NULL */)
+{
+    mTouchStart = NULL;
+
+    // We can memset the whole structure, because the alpha channel is ignored
+    memset(&mBackground, 0, sizeof(COLOR));
+
+    // With NULL, we make a console-only display
+    if (!page)
+    {
+        mName = "console";
+
+        GUIConsole* element = new GUIConsole(NULL);
+        mRenders.push_back(element);
+        mActions.push_back(element);
+        return;
+    }
+
+    if (page->first_attribute("name"))
+        mName = page->first_attribute("name")->value();
+    else
+    {
+        LOGE("No page name attribute found!\n");
+        return;
+    }
+
+    LOGI("Loading page %s\n", mName.c_str());
+
+    // This is a recursive routine for template handling
+    ProcessNode(page, templates);
+
+    return;
+}
+
+bool Page::ProcessNode(xml_node<>* page, xml_node<>* templates /* = NULL */, int depth /* = 0 */)
+{
+    if (depth == 10)
+    {
+        LOGE("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n");
+        return false;
+    }
+
+    // Let's retrieve the background value, if any
+    xml_node<>* bg = page->first_node("background");
+    if (bg)
+    {
+        xml_attribute<>* attr = bg->first_attribute("color");
+        if (attr)
+        {
+            std::string color = attr->value();
+            ConvertStrToColor(color, &mBackground);
+        }
+    }
+
+    xml_node<>* child;
+    child = page->first_node("object");
+    while (child)
+    {
+        if (!child->first_attribute("type"))
+            break;
+
+        std::string type = child->first_attribute("type")->value();
+
+        if (type == "text")
+        {
+            GUIText* element = new GUIText(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+        else if (type == "image")
+        {
+            GUIImage* element = new GUIImage(child);
+            mRenders.push_back(element);
+        }
+        else if (type == "fill")
+        {
+            GUIFill* element = new GUIFill(child);
+            mRenders.push_back(element);
+        }
+        else if (type == "action")
+        {
+            GUIAction* element = new GUIAction(child);
+            mActions.push_back(element);
+        }
+        else if (type == "console")
+        {
+            GUIConsole* element = new GUIConsole(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+        else if (type == "button")
+        {
+            GUIButton* element = new GUIButton(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+        else if (type == "checkbox")
+        {
+            GUICheckbox* element = new GUICheckbox(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+        else if (type == "fileselector")
+        {
+            GUIFileSelector* element = new GUIFileSelector(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+        else if (type == "animation")
+        {
+            GUIAnimation* element = new GUIAnimation(child);
+            mRenders.push_back(element);
+        }
+        else if (type == "progressbar")
+        {
+            GUIProgressBar* element = new GUIProgressBar(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+		else if (type == "slider")
+        {
+            GUISlider* element = new GUISlider(child);
+            mRenders.push_back(element);
+            mActions.push_back(element);
+        }
+		else if (type == "listbox")
+		{
+			GUIListBox* element = new GUIListBox(child);
+			mRenders.push_back(element);
+			mActions.push_back(element);
+		}
+		else if (type == "keyboard")
+		{
+			GUIKeyboard* element = new GUIKeyboard(child);
+			mRenders.push_back(element);
+			mActions.push_back(element);
+		}
+		else if (type == "input")
+		{
+			GUIInput* element = new GUIInput(child);
+			mRenders.push_back(element);
+			mActions.push_back(element);
+			mInputs.push_back(element);
+		}
+        else if (type == "template")
+        {
+            if (!templates || !child->first_attribute("name"))
+            {
+                LOGE("Invalid template request.\n");
+            }
+            else
+            {
+                std::string name = child->first_attribute("name")->value();
+
+                // We need to find the correct template
+                xml_node<>* node;
+                node = templates->first_node("template");
+
+                while (node)
+                {
+                    if (!node->first_attribute("name"))
+                        continue;
+
+                    if (name == node->first_attribute("name")->value())
+                    {
+                        if (!ProcessNode(node, templates, depth + 1))
+                            return false;
+                        else
+                            break;
+                    }
+                    node = node->next_sibling("template");
+                }
+            }
+        }
+        else
+        {
+            LOGE("Unknown object type.\n");
+        }
+        child = child->next_sibling("object");
+    }
+    return true;
+}
+
+int Page::Render(void)
+{
+    // Render background
+    gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha);
+    gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+
+    // Render remaining objects
+    std::vector<RenderObject*>::iterator iter;
+    for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
+    {
+        if ((*iter)->Render())
+            LOGE("A render request has failed.\n");
+    }
+    return 0;
+}
+
+int Page::Update(void)
+{
+    int retCode = 0;
+
+    std::vector<RenderObject*>::iterator iter;
+    for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
+    {
+        int ret = (*iter)->Update();
+        if (ret < 0)
+            LOGE("An update request has failed.\n");
+        else if (ret > retCode)
+            retCode = ret;
+    }
+
+    return retCode;
+}
+
+int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+    // By default, return 1 to ignore further touches if nobody is listening
+    int ret = 1;
+
+    // Don't try to handle a lack of handlers
+    if (mActions.size() == 0)   return ret;
+
+    // We record mTouchStart so we can pass all the touch stream to the same handler
+    if (state == TOUCH_START)
+    {
+        std::vector<ActionObject*>::reverse_iterator iter;
+        // We work backwards, from top-most element to bottom-most element
+        for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
+        {
+            if ((*iter)->IsInRegion(x, y))
+            {
+                mTouchStart = (*iter);
+                ret = mTouchStart->NotifyTouch(state, x, y);
+                if (ret >= 0)   break;
+                mTouchStart = NULL;
+            }
+        }
+    }
+    else if (state == TOUCH_RELEASE && mTouchStart != NULL)
+    {
+        ret = mTouchStart->NotifyTouch(state, x, y);
+        mTouchStart = NULL;
+    }
+    else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL)
+    {
+        ret = mTouchStart->NotifyTouch(state, x, y);
+    }
+    return ret;
+}
+
+int Page::NotifyKey(int key)
+{
+    std::vector<ActionObject*>::reverse_iterator iter;
+
+    // Don't try to handle a lack of handlers
+    if (mActions.size() == 0)   return 1;
+
+    // We work backwards, from top-most element to bottom-most element
+    for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
+    {
+        int ret = (*iter)->NotifyKey(key);
+        if (ret == 0)
+            return 0;
+        else if (ret < 0)
+            LOGE("An action handler has returned an error");
+    }
+    return 1;
+}
+
+int Page::NotifyKeyboard(int key)
+{
+    std::vector<InputObject*>::reverse_iterator iter;
+
+    // Don't try to handle a lack of handlers
+    if (mInputs.size() == 0)   return 1;
+
+    // We work backwards, from top-most element to bottom-most element
+    for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
+    {
+        int ret = (*iter)->NotifyKeyboard(key);
+        if (ret == 0)
+            return 0;
+        else if (ret < 0)
+            LOGE("A keyboard handler has returned an error");
+    }
+    return 1;
+}
+
+int Page::SetKeyBoardFocus(int inFocus)
+{
+    std::vector<InputObject*>::reverse_iterator iter;
+
+    // Don't try to handle a lack of handlers
+    if (mInputs.size() == 0)   return 1;
+
+    // We work backwards, from top-most element to bottom-most element
+    for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++)
+    {
+        int ret = (*iter)->SetInputFocus(inFocus);
+        if (ret == 0)
+            return 0;
+        else if (ret < 0)
+            LOGE("An input focus handler has returned an error");
+    }
+    return 1;
+}
+
+void Page::SetPageFocus(int inFocus)
+{
+    // Render remaining objects
+    std::vector<RenderObject*>::iterator iter;
+    for (iter = mRenders.begin(); iter != mRenders.end(); iter++)
+    {
+        (*iter)->SetPageFocus(inFocus);
+    }
+    return;
+}
+
+int Page::NotifyVarChange(std::string varName, std::string value)
+{
+    std::vector<ActionObject*>::iterator iter;
+
+    // Don't try to handle a lack of handlers
+    if (mActions.size() == 0)   return 1;
+
+    for (iter = mActions.begin(); iter != mActions.end(); ++iter)
+    {
+        if ((*iter)->NotifyVarChange(varName, value))
+            LOGE("An action handler errored on NotifyVarChange.\n");
+    }
+    return 0;
+}
+
+PageSet::PageSet(char* xmlFile)
+{
+    mResources = NULL;
+    mCurrentPage = NULL;
+    mOverlayPage = NULL;
+
+    mXmlFile = xmlFile;
+    if (xmlFile)
+        mDoc.parse<0>(mXmlFile);
+    else
+        mCurrentPage = new Page(NULL);
+}
+
+PageSet::~PageSet()
+{
+    delete mResources;
+    free(mXmlFile);
+}
+
+int PageSet::Load(ZipArchive* package)
+{
+    xml_node<>* parent;
+    xml_node<>* child;
+    xml_node<>* templates;
+ 
+    parent = mDoc.first_node("recovery");
+    if (!parent)
+        parent = mDoc.first_node("install");
+
+    // Now, let's parse the XML
+    LOGI("Loading resources...\n");
+    child = parent->first_node("resources");
+    if (child)
+        mResources = new ResourceManager(child, package);
+
+    LOGI("Loading variables...\n");
+    child = parent->first_node("variables");
+    if (child)
+        LoadVariables(child);
+
+    LOGI("Loading pages...\n");
+    // This may be NULL if no templates are present
+    templates = parent->first_node("templates");
+
+    child = parent->first_node("pages");
+    if (!child)
+        return -1;
+
+    return LoadPages(child, templates);
+}
+
+int PageSet::SetPage(std::string page)
+{
+    Page* tmp = FindPage(page);
+    if (tmp)
+    {
+        if (mCurrentPage)   mCurrentPage->SetPageFocus(0);
+        mCurrentPage = tmp;
+        mCurrentPage->SetPageFocus(1);
+        mCurrentPage->NotifyVarChange("", "");
+        return 0;
+    }
+    else
+    {
+        LOGE("Unable to locate page (%s)\n", page.c_str());
+    }
+    return -1;
+}
+
+int PageSet::SetOverlay(Page* page)
+{
+    if (mOverlayPage)   mOverlayPage->SetPageFocus(0);
+    mOverlayPage = page;
+    if (mOverlayPage)
+    {
+        mOverlayPage->SetPageFocus(1);
+        mOverlayPage->NotifyVarChange("", "");
+    }
+    return 0;
+}
+
+Resource* PageSet::FindResource(std::string name)
+{
+    return mResources ? mResources->FindResource(name) : NULL;
+}
+
+Page* PageSet::FindPage(std::string name)
+{
+    std::vector<Page*>::iterator iter;
+
+    for (iter = mPages.begin(); iter != mPages.end(); iter++)
+    {
+        if (name == (*iter)->GetName())
+            return (*iter);
+    }
+    return NULL;
+}
+
+int PageSet::LoadVariables(xml_node<>* vars)
+{
+    xml_node<>* child;
+
+    child = vars->first_node("variable");
+    while (child)
+    {
+        if (!child->first_attribute("name"))
+            break;
+        if (!child->first_attribute("value"))
+            break;
+
+        DataManager::SetValue(child->first_attribute("name")->value(), child->first_attribute("value")->value());
+        child = child->next_sibling("variable");
+    }
+    return 0;
+}
+
+int PageSet::LoadPages(xml_node<>* pages, xml_node<>* templates /* = NULL */)
+{
+    xml_node<>* child;
+
+    if (!pages)    return -1;
+
+    child = pages->first_node("page");
+    while (child != NULL)
+    {
+        Page* page = new Page(child, templates);
+        if (page->GetName().empty())
+        {
+            LOGE("Unable to process load page\n");
+            delete page;
+        }
+        else
+        {
+            mPages.push_back(page);
+        }
+        child = child->next_sibling("page");
+    }
+    if (mPages.size() > 0)
+        return 0;
+    return -1;
+}
+
+int PageSet::IsCurrentPage(Page* page)
+{
+    return ((mCurrentPage && mCurrentPage == page) ? 1 : 0);
+}
+
+int PageSet::Render(void)
+{
+    int ret;
+
+    ret = (mCurrentPage ? mCurrentPage->Render() : -1);
+    if (ret < 0)    return ret;
+    ret = (mOverlayPage ? mOverlayPage->Render() : -1);
+    return ret;
+}
+
+int PageSet::Update(void)
+{
+    int ret;
+
+    ret = (mCurrentPage ? mCurrentPage->Update() : -1);
+    if (ret < 0 || ret > 1)     return ret;
+    ret = (mOverlayPage ? mOverlayPage->Update() : -1);
+    return ret;
+}
+
+int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+    if (mOverlayPage)   return (mOverlayPage->NotifyTouch(state, x, y));
+    return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
+}
+
+int PageSet::NotifyKey(int key)
+{
+    if (mOverlayPage)   return (mOverlayPage->NotifyKey(key));
+    return (mCurrentPage ? mCurrentPage->NotifyKey(key) : -1);
+}
+
+int PageSet::NotifyKeyboard(int key)
+{
+    if (mOverlayPage)   return (mOverlayPage->NotifyKeyboard(key));
+    return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1);
+}
+
+int PageSet::SetKeyBoardFocus(int inFocus)
+{
+    if (mOverlayPage)   return (mOverlayPage->SetKeyBoardFocus(inFocus));
+    return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1);
+}
+
+int PageSet::NotifyVarChange(std::string varName, std::string value)
+{
+    if (mOverlayPage)   mOverlayPage->NotifyVarChange(varName, value);
+    return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1);
+}
+
+int PageManager::LoadPackage(std::string name, std::string package, std::string startpage)
+{
+    int fd;
+    ZipArchive zip, *pZip = NULL;
+    long len;
+    char* xmlFile = NULL;
+    PageSet* pageSet = NULL;
+    int ret;
+
+    // Open the XML file
+    LOGI("Loading package: %s (%s)\n", name.c_str(), package.c_str());
+    if (mzOpenZipArchive(package.c_str(), &zip))
+    {
+        // We can try to load the XML directly...
+        struct stat st;
+        if(stat(package.c_str(),&st) != 0)
+            return -1;
+
+        len = st.st_size;
+        xmlFile = (char*) malloc(len + 1);
+        if (!xmlFile)       return -1;
+
+        fd = open(package.c_str(), O_RDONLY);
+        if (fd == -1)       goto error;
+
+        read(fd, xmlFile, len);
+        close(fd);
+    }
+    else
+    {
+        pZip = &zip;
+        const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml");
+        if (ui_xml == NULL)
+        {
+            LOGE("Unable to locate ui.xml in zip file\n");
+            goto error;
+        }
+    
+        // Allocate the buffer for the file
+        len = mzGetZipEntryUncompLen(ui_xml);
+        xmlFile = (char*) malloc(len + 1);
+        if (!xmlFile)        goto error;
+    
+        if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile))
+        {
+            LOGE("Unable to extract ui.xml\n");
+            goto error;
+        }
+    }
+
+    // NULL-terminate the string
+    xmlFile[len] = 0x00;
+
+    // Before loading, mCurrentSet must be the loading package so we can find resources
+    pageSet = mCurrentSet;
+    mCurrentSet = new PageSet(xmlFile);
+
+    ret = mCurrentSet->Load(pZip);
+    if (ret == 0)
+    {
+        mCurrentSet->SetPage(startpage);
+        mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet));
+    }
+    else
+    {
+        LOGE("Package %s failed to load.\n", name.c_str());
+    }
+	
+    // The first successful package we loaded is the base
+    if (mBaseSet == NULL)
+        mBaseSet = mCurrentSet;
+
+    mCurrentSet = pageSet;
+
+    if (pZip)   mzCloseZipArchive(pZip);
+    return ret;
+
+error:
+    LOGE("An internal error has occurred.\n");
+    if (pZip)       mzCloseZipArchive(pZip);
+    if (xmlFile)    free(xmlFile);
+    return -1;
+}
+
+PageSet* PageManager::FindPackage(std::string name)
+{
+    std::map<std::string, PageSet*>::iterator iter;
+
+    iter = mPageSets.find(name);
+    if (iter != mPageSets.end())
+    {
+        return (*iter).second;
+    }
+    LOGE("Unable to locate package %s\n", name.c_str());
+    return NULL;
+}
+
+PageSet* PageManager::SelectPackage(std::string name)
+{
+    LOGI("Switching packages (%s)\n", name.c_str());
+    PageSet* tmp;
+
+    tmp = FindPackage(name);
+    if (tmp)
+        mCurrentSet = tmp;
+    else
+        LOGE("Unable to find package.\n");
+
+    return mCurrentSet;
+}
+
+int PageManager::ReloadPackage(std::string name, std::string package)
+{
+    std::map<std::string, PageSet*>::iterator iter;
+
+    iter = mPageSets.find(name);
+    if (iter == mPageSets.end())
+        return -1;
+
+    PageSet* set = (*iter).second;
+    mPageSets.erase(iter);
+
+    if (LoadPackage(name, package, "main") != 0)
+    {
+        LOGE("Failed to load package.\n");
+        mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
+        return -1;
+    }
+    if (mCurrentSet == set)     SelectPackage(name);
+    delete set;
+    return 0;
+}
+
+void PageManager::ReleasePackage(std::string name)
+{
+    std::map<std::string, PageSet*>::iterator iter;
+
+    iter = mPageSets.find(name);
+    if (iter == mPageSets.end())
+        return;
+
+    PageSet* set = (*iter).second;
+    mPageSets.erase(iter);
+    delete set;
+    return;
+}
+
+int PageManager::ChangePage(std::string name)
+{
+    DataManager::SetValue("tw_operation_state", 0);
+    int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1);
+    return ret;
+}
+
+int PageManager::ChangeOverlay(std::string name)
+{
+    if (name.empty())
+        return mCurrentSet->SetOverlay(NULL);
+    else
+    {
+        Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL;
+        return mCurrentSet->SetOverlay(page);
+    }
+}
+
+Resource* PageManager::FindResource(std::string name)
+{
+    return (mCurrentSet ? mCurrentSet->FindResource(name) : NULL);
+}
+
+Resource* PageManager::FindResource(std::string package, std::string name)
+{
+    PageSet* tmp;
+
+    tmp = FindPackage(name);
+    return (tmp ? tmp->FindResource(name) : NULL);
+}
+
+int PageManager::SwitchToConsole(void)
+{
+    PageSet* console = new PageSet(NULL);
+
+    mCurrentSet = console;
+    return 0;
+}
+
+int PageManager::IsCurrentPage(Page* page)
+{
+    return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0);
+}
+
+int PageManager::Render(void)
+{
+    return (mCurrentSet ? mCurrentSet->Render() : -1);
+}
+
+int PageManager::Update(void)
+{
+    return (mCurrentSet ? mCurrentSet->Update() : -1);
+}
+
+int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+    return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
+}
+
+int PageManager::NotifyKey(int key)
+{
+    return (mCurrentSet ? mCurrentSet->NotifyKey(key) : -1);
+}
+
+int PageManager::NotifyKeyboard(int key)
+{
+    return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1);
+}
+
+int PageManager::SetKeyBoardFocus(int inFocus)
+{
+    return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1);
+}
+
+int PageManager::NotifyVarChange(std::string varName, std::string value)
+{
+    return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1);
+}
+
+extern "C" void gui_notifyVarChange(const char *name, const char* value)
+{
+    if (!gGuiRunning)   return;
+
+    PageManager::NotifyVarChange(name, value);
+}
+
