diff --git a/gui/input.cpp b/gui/input.cpp
new file mode 100644
index 0000000..2418c4c
--- /dev/null
+++ b/gui/input.cpp
@@ -0,0 +1,738 @@
+// input.cpp - GUIInput object
+
+#include <linux/input.h>
+#include <pthread.h>
+#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"
+#include "../data.hpp"
+
+GUIInput::GUIInput(xml_node<>* node)
+    : Conditional(node)
+{
+    xml_attribute<>* attr;
+    xml_node<>* child;
+
+    mInputText = NULL;
+	mAction = NULL;
+	mBackground = NULL;
+	mCursor = NULL;
+	mFont = NULL;
+    mRendered = false;
+	HasMask = false;
+	DrawCursor = false;
+	isLocalChange = true;
+	HasAllowed = false;
+	HasDisabled = false;
+	skipChars = scrollingX = mFontHeight = mFontY = lastX = 0;
+	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0;
+	mCursorLocation = -1; // -1 is always the end of the string
+	CursorWidth = 3;
+	ConvertStrToColor("black", &mBackgroundColor);
+	ConvertStrToColor("white", &mCursorColor);
+
+    if (!node)  return;
+
+    // Load text directly from the node
+    mInputText = new GUIText(node);
+	// Load action directly from the node
+	mAction = new GUIAction(node);
+
+	if (mInputText->Render() < 0)
+    {
+        delete mInputText;
+        mInputText = NULL;
+    }
+
+	// Load the background
+	child = node->first_node("background");
+	if (child)
+	{
+		attr = child->first_attribute("resource");
+		if (attr)
+			mBackground = PageManager::FindResource(attr->value());
+		attr = child->first_attribute("color");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mBackgroundColor);
+		}
+	}
+	if (mBackground && mBackground->GetResource())
+	{
+		mBackgroundW = gr_get_width(mBackground->GetResource());
+		mBackgroundH = gr_get_height(mBackground->GetResource());
+	}
+
+	// Load the cursor color
+	child = node->first_node("cursor");
+	if (child)
+	{
+		attr = child->first_attribute("resource");
+		if (attr)
+			mCursor = PageManager::FindResource(attr->value());
+		attr = child->first_attribute("color");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mCursorColor);
+		}
+		attr = child->first_attribute("hasfocus");
+		if (attr)
+		{
+			std::string color = attr->value();
+			SetInputFocus(atoi(color.c_str()));
+		}
+		attr = child->first_attribute("width");
+		if (attr)
+		{
+			std::string cwidth = gui_parse_text(attr->value());
+			CursorWidth = atoi(cwidth.c_str());
+		}
+	}
+	DrawCursor = HasInputFocus;
+
+	// Load the font, and possibly override the color
+    child = node->first_node("font");
+    if (child)
+    {
+        attr = child->first_attribute("resource");
+        if (attr) {
+            mFont = PageManager::FindResource(attr->value());
+			gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
+		}
+    }
+
+	child = node->first_node("text");
+    if (child)  mText = child->value();
+	mLastValue = gui_parse_text(mText);
+
+	child = node->first_node("data");
+	if (child)
+	{
+		attr = child->first_attribute("name");
+		if (attr)
+			mVariable = attr->value();
+		attr = child->first_attribute("default");
+		if (attr)
+			DataManager::SetValue(mVariable, attr->value());
+		attr = child->first_attribute("mask");
+		if (attr) {
+			mMask = attr->value();
+			HasMask = true;
+		}
+		attr = child->first_attribute("maskvariable");
+		if (attr)
+			mMaskVariable = attr->value();
+		else
+			mMaskVariable = mVariable;
+	}
+
+	// Load input restrictions
+	child = node->first_node("restrict");
+	if (child)
+	{
+		attr = child->first_attribute("minlen");
+		if (attr) {
+			std::string attrib = attr->value();
+			MinLen = atoi(attrib.c_str());
+		}
+		attr = child->first_attribute("maxlen");
+		if (attr) {
+			std::string attrib = attr->value();
+			MaxLen = atoi(attrib.c_str());
+		}
+		attr = child->first_attribute("allow");
+		if (attr) {
+			HasAllowed = true;
+			AllowedList = attr->value();
+		}
+		attr = child->first_attribute("disable");
+		if (attr) {
+			HasDisabled = true;
+			DisabledList = attr->value();
+		}
+	}
+
+    // Load the placement
+	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
+	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
+
+	if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
+		mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
+		mInputText->SetRenderPos(mRenderX, mFontY);
+	} else
+		mFontY = mRenderY;
+
+	if (mInputText)
+		mInputText->SetMaxWidth(mRenderW);
+
+	isLocalChange = false;
+	HandleTextLocation(-3);
+
+    return;
+}
+
+GUIInput::~GUIInput()
+{
+    if (mInputText)     delete mInputText;
+	if (mBackground)    delete mBackground;
+	if (mCursor)        delete mCursor;
+	if (mFont)          delete mFont;
+	if (mAction)        delete mAction;
+}
+
+int GUIInput::HandleTextLocation(int x)
+{
+	int textWidth;
+	string displayValue, originalValue, insertChar;
+	void* fontResource = NULL;
+
+	if (mFont)  fontResource = mFont->GetResource();
+
+	DataManager::GetValue(mVariable, originalValue);
+	displayValue = originalValue;
+	if (HasMask) {
+		int index, string_size = displayValue.size();
+		string maskedValue;
+		for (index=0; index<string_size; index++)
+			maskedValue += mMask;
+		displayValue = maskedValue;
+	}
+	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
+	if (textWidth <= mRenderW) {
+		lastX = x;
+		scrollingX = 0;
+		skipChars = 0;
+		mInputText->SkipCharCount(skipChars);
+		mRendered = false;
+		return 0;
+	}
+	if (skipChars && skipChars < displayValue.size()) {
+		displayValue.erase(0, skipChars);
+	}
+	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
+	mRendered = false;
+
+	int deltaX, deltaText, newWidth;
+
+	if (x < -1000) {
+		// No change in scrolling
+		if (x == -1003) {
+			mCursorLocation = -1;
+		}
+		if (mCursorLocation == -1) {
+			displayValue = originalValue;
+			skipChars = 0;
+			textWidth = gr_measureEx(displayValue.c_str(), fontResource);
+			while (textWidth > mRenderW) {
+				displayValue.erase(0, 1);
+				skipChars++;
+				textWidth = gr_measureEx(displayValue.c_str(), fontResource);
+			}
+			scrollingX = mRenderW - textWidth;
+			mInputText->SkipCharCount(skipChars);
+		} else if (x == -1001) {
+			// Added a new character
+			int adjust_scrollingX = 0;
+			string cursorLocate;
+
+			cursorLocate = displayValue;
+			cursorLocate.resize(mCursorLocation);
+			textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
+			while (textWidth > mRenderW) {
+				skipChars++;
+				mCursorLocation--;
+				cursorLocate.erase(0, 1);
+				textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
+				adjust_scrollingX = -1;
+			}
+			if (adjust_scrollingX) {
+				scrollingX = mRenderW - textWidth;
+				if (scrollingX < 0)
+					scrollingX = 0;
+			}
+			mInputText->SkipCharCount(skipChars);
+		} else if (x == -1002) {
+			// Deleted a character
+			while (-1) {
+				if (skipChars == 0) {
+					scrollingX = 0;
+					mInputText->SkipCharCount(skipChars);
+					return 0;
+				}
+				insertChar = originalValue.substr(skipChars - 1, 1);
+				displayValue.insert(0, insertChar);
+				newWidth = gr_measureEx(displayValue.c_str(), fontResource);
+				deltaText = newWidth - textWidth;
+				if (newWidth > mRenderW) {
+					scrollingX = mRenderW - textWidth;
+					if (scrollingX < 0)
+						scrollingX = 0;
+					mInputText->SkipCharCount(skipChars);
+					return 0;
+				} else {
+					textWidth = newWidth;
+					skipChars--;
+					mCursorLocation++;
+				}
+			}
+		} else
+			LOGI("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
+	} else if (x > lastX) {
+		// Dragging to right, scrolling left
+		while (-1) {
+			deltaX = x - lastX + scrollingX;
+			if (skipChars == 0 || deltaX == 0) {
+				scrollingX = 0;
+				lastX = x;
+				mInputText->SkipCharCount(skipChars);
+				return 0;
+			}
+			insertChar = originalValue.substr(skipChars - 1, 1);
+			displayValue.insert(0, insertChar);
+			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
+			deltaText = newWidth - textWidth;
+			if (deltaText < deltaX) {
+				lastX += deltaText;
+				textWidth = newWidth;
+				skipChars--;
+			} else {
+				scrollingX = deltaX;
+				lastX = x;
+				mInputText->SkipCharCount(skipChars);
+				return 0;
+			}
+		}
+	} else if (x < lastX) {
+		// Dragging to left, scrolling right
+		if (textWidth <= mRenderW) {
+			lastX = x;
+			scrollingX = mRenderW - textWidth;
+			return 0;
+		}
+		if (scrollingX) {
+			deltaX = lastX - x;
+			if (scrollingX > deltaX) {
+				scrollingX -= deltaX;
+				lastX = x;
+				return 0;
+			} else {
+				lastX -= deltaX;
+				scrollingX = 0;
+			}
+		}
+		while (-1) {
+			deltaX = lastX - x;
+			displayValue.erase(0, 1);
+			skipChars++;
+			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
+			deltaText = textWidth - newWidth;
+			if (newWidth <= mRenderW) {
+				scrollingX = mRenderW - newWidth;
+				lastX = x;
+				mInputText->SkipCharCount(skipChars);
+				return 0;
+			}
+			if (deltaText < deltaX) {
+				lastX -= deltaText;
+				textWidth = newWidth;
+			} else {
+				scrollingX = deltaText - deltaX;
+				lastX = x;
+				mInputText->SkipCharCount(skipChars);
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
+int GUIInput::Render(void)
+{
+	if (!isConditionTrue())
+    {
+        mRendered = false;
+        return 0;
+    }
+
+	void* fontResource = NULL;
+	if (mFont)  fontResource = mFont->GetResource();
+
+    // First step, fill background
+	gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
+	gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
+
+	// Next, render the background resource (if it exists)
+	if (mBackground && mBackground->GetResource())
+	{
+		mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
+		mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
+		gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
+	}
+
+	int ret = 0;
+
+    // Render the text
+	mInputText->SetRenderPos(mRenderX + scrollingX, mFontY);
+	mInputText->SetMaxWidth(mRenderW - scrollingX);
+	if (mInputText)     ret = mInputText->Render();
+    if (ret < 0)        return ret;
+
+	if (HasInputFocus && DrawCursor) {
+		// Render the cursor
+		string displayValue;
+		int cursorX;
+		DataManager::GetValue(mVariable, displayValue);
+		if (HasMask) {
+			int index, string_size = displayValue.size();
+			string maskedValue;
+			for (index=0; index<string_size; index++)
+				maskedValue += mMask;
+			displayValue = maskedValue;
+		}
+		if (displayValue.size() == 0) {
+			skipChars = 0;
+			mCursorLocation = -1;
+			cursorX = mRenderX;
+		} else {
+			if (skipChars && skipChars < displayValue.size()) {
+				displayValue.erase(0, skipChars);
+			}
+			if (mCursorLocation == 0) {
+				// Cursor is at the beginning
+				cursorX = mRenderX;
+			} else if (mCursorLocation > 0) {
+				// Cursor is in the middle
+				if (displayValue.size() > (unsigned)mCursorLocation) {
+					string cursorDisplay;
+
+					cursorDisplay = displayValue;
+					cursorDisplay.resize(mCursorLocation);
+					cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX;
+				} else {
+					// Cursor location is after the end of the text  - reset to -1
+					mCursorLocation = -1;
+					cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
+				}
+			} else {
+				// Cursor is at the end (-1)
+				cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
+			}
+		}
+		cursorX += scrollingX;
+		// Make sure that the cursor doesn't go past the boundaries of the box
+		if (cursorX + (int)CursorWidth > mRenderX + mRenderW)
+			cursorX = mRenderX + mRenderW - CursorWidth;
+
+		// Set the color for the cursor
+		gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255);
+		gr_fill(cursorX, mFontY, CursorWidth, mFontHeight);
+	}
+
+    mRendered = true;
+    return ret;
+}
+
+int GUIInput::Update(void)
+{
+    if (!isConditionTrue())     return (mRendered ? 2 : 0);
+    if (!mRendered)             return 2;
+
+    int ret = 0;
+
+    if (mInputText)         ret = mInputText->Update();
+    if (ret < 0)            return ret;
+
+    return ret;
+}
+
+int GUIInput::GetSelection(int x, int y)
+{
+	if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1;
+	return (x - mRenderX);
+}
+
+int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+    static int startSelection = -1;
+	int textWidth;
+	string displayValue, originalValue;
+	void* fontResource = NULL;
+
+	if (mFont)  fontResource = mFont->GetResource();
+
+	if (!isConditionTrue())     return -1;
+
+	if (!HasInputFocus) {
+		if (state != TOUCH_RELEASE)
+			return 0; // Only change focus if touch releases within the input box
+		if (GetSelection(x, y) >= 0) {
+			// When changing focus, we don't scroll or change the cursor location
+			PageManager::SetKeyBoardFocus(0);
+			PageManager::NotifyKeyboard(0);
+			SetInputFocus(1);
+			DrawCursor = true;
+			mRendered = false;
+		}
+	} else {
+		switch (state) {
+		case TOUCH_HOLD:
+		case TOUCH_REPEAT:
+			break;
+		case TOUCH_START:
+			startSelection = GetSelection(x,y);
+			lastX = x;
+			DrawCursor = false;
+			mRendered = false;
+			break;
+
+		case TOUCH_DRAG:
+			// Check if we dragged out of the selection window
+			if (GetSelection(x, y) == -1) {
+				lastX = 0;
+				break;
+			}
+
+			DrawCursor = false;
+
+			// Provide some debounce on initial touches
+			if (startSelection != -1 && abs(x - lastX) < 6) {
+				break;
+			}
+
+			startSelection = -1;
+			if (lastX != x)
+				HandleTextLocation(x);
+			break;
+
+		case TOUCH_RELEASE:
+			// We've moved the cursor location
+			int relativeX = x - mRenderX;
+
+			mRendered = false;
+			DrawCursor = true;
+			DataManager::GetValue(mVariable, displayValue);
+			if (HasMask) {
+				int index, string_size = displayValue.size();
+				string maskedValue;
+				for (index=0; index<string_size; index++)
+					maskedValue += mMask;
+				displayValue = maskedValue;
+			}
+			if (displayValue.size() == 0) {
+				skipChars = 0;
+				mCursorLocation = -1;
+				return 0;
+			} else if (skipChars && skipChars < displayValue.size()) {
+				displayValue.erase(0, skipChars);
+			}
+
+			string cursorString;
+			int cursorX = 0;
+			unsigned index = 0;
+
+			for(index=0; index<displayValue.size(); index++)
+			{
+				cursorString = displayValue.substr(0, index);
+				cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX;
+				if (cursorX > x) {
+					if (index > 0)
+						mCursorLocation = index - 1;
+					else
+						mCursorLocation = index;
+					return 0;
+				}
+			}
+			mCursorLocation = -1;
+			break;
+		}
+	}
+    return 0;
+}
+
+int GUIInput::NotifyVarChange(std::string varName, std::string value)
+{
+	if (varName == mVariable && !isLocalChange) {
+		HandleTextLocation(-1003);
+		return 0;
+	}
+	return 0;
+}
+
+int GUIInput::NotifyKeyboard(int key)
+{
+	string variableValue;
+
+	if (HasInputFocus) {
+		if (key == KEYBOARD_BACKSPACE) {
+			//Backspace
+			DataManager::GetValue(mVariable, variableValue);
+			if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) {
+				if (mCursorLocation == -1) {
+					variableValue.resize(variableValue.size() - 1);
+				} else {
+					variableValue.erase(mCursorLocation + skipChars - 1, 1);
+					if (mCursorLocation > 0)
+						mCursorLocation--;
+					else if (skipChars > 0)
+						skipChars--;
+				}
+				isLocalChange = true;
+				DataManager::SetValue(mVariable, variableValue);
+				isLocalChange = false;
+
+				if (HasMask) {
+					int index, string_size = variableValue.size();
+					string maskedValue;
+					for (index=0; index<string_size; index++)
+						maskedValue += mMask;
+					DataManager::SetValue(mMaskVariable, maskedValue);
+				}
+				HandleTextLocation(-1002);
+			}
+		} else if (key == KEYBOARD_SWIPE_LEFT) {
+			// Delete all
+			isLocalChange = true;
+			if (mCursorLocation == -1) {
+				DataManager::SetValue (mVariable, "");
+				if (HasMask)
+					DataManager::SetValue(mMaskVariable, "");
+				mCursorLocation = -1;
+			} else {
+				DataManager::GetValue(mVariable, variableValue);
+				variableValue.erase(0, mCursorLocation + skipChars);
+				DataManager::SetValue(mVariable, variableValue);
+				if (HasMask) {
+					DataManager::GetValue(mMaskVariable, variableValue);
+					variableValue.erase(0, mCursorLocation + skipChars);
+					DataManager::SetValue(mMaskVariable, variableValue);
+				}
+				mCursorLocation = 0;
+			}
+			skipChars = 0;
+			scrollingX = 0;
+			mInputText->SkipCharCount(skipChars);
+			isLocalChange = false;
+			mRendered = false;
+			return 0;
+		} else if (key == KEYBOARD_ARROW_LEFT) {
+			if (mCursorLocation == 0 && skipChars == 0)
+				return 0; // we're already at the beginning
+			if (mCursorLocation == -1) {
+				DataManager::GetValue(mVariable, variableValue);
+				if (variableValue.size() == 0)
+					return 0;
+				mCursorLocation = variableValue.size() - skipChars - 1;
+			} else if (mCursorLocation == 0) {
+				skipChars--;
+				HandleTextLocation(-1002);
+			} else {
+				mCursorLocation--;
+				HandleTextLocation(-1002);
+			}
+			mRendered = false;
+			return 0;
+		} else if (key == KEYBOARD_ARROW_RIGHT) {
+			if (mCursorLocation == -1)
+				return 0; // we're already at the end
+			mCursorLocation++;
+			DataManager::GetValue(mVariable, variableValue);
+			if (variableValue.size() <= mCursorLocation + skipChars)
+				mCursorLocation = -1;
+			HandleTextLocation(-1001);
+			mRendered = false;
+			return 0;
+		} else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) {
+			DataManager::GetValue(mVariable, variableValue);
+			if (variableValue.size() == 0)
+				return 0;
+			mCursorLocation = 0;
+			skipChars = 0;
+			mRendered = false;
+			HandleTextLocation(-1002);
+			return 0;
+		} else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) {
+			mCursorLocation = -1;
+			mRendered = false;
+			HandleTextLocation(-1003);
+			return 0;
+		} else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) {
+			// Regular key
+			if (HasAllowed && AllowedList.find((char)key) == string::npos) {
+				return 0;
+			}
+			if (HasDisabled && DisabledList.find((char)key) != string::npos) {
+				return 0;
+			}
+			DataManager::GetValue(mVariable, variableValue);
+			if (MaxLen != 0 && variableValue.size() >= MaxLen) {
+				return 0;
+			}
+			if (mCursorLocation == -1) {
+				variableValue += key;
+			} else {
+				const char newchar = (char)key;
+				const char* a = &newchar;
+				string newstring = a;
+				newstring.resize(1);
+				variableValue.insert(mCursorLocation + skipChars, newstring);
+				mCursorLocation++;
+			}
+			isLocalChange = true;
+			DataManager::SetValue(mVariable, variableValue);
+			HandleTextLocation(-1001);
+			isLocalChange = false;
+
+			if (HasMask) {
+				int index, string_size = variableValue.size();
+				string maskedValue;
+				for (index=0; index<string_size; index++)
+					maskedValue += mMask;
+				DataManager::SetValue(mMaskVariable, maskedValue);
+			}
+		} else if (key == KEYBOARD_ACTION) {
+			// Action
+			DataManager::GetValue(mVariable, variableValue);
+			if (mAction) {
+				unsigned inputLen = variableValue.length();
+				if (inputLen < MinLen)
+					return 0;
+				else if (MaxLen != 0 && inputLen > MaxLen)
+					return 0;
+				else
+					return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1);
+			}
+		}
+		return 0;
+	} else {
+		if (key == 0) {
+			// Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor
+			mRendered = false;
+			return 1;
+		}
+	}
+	return 1;
+}
