aboutsummaryrefslogtreecommitdiff
path: root/backends/common
diff options
context:
space:
mode:
authorStephen Kennedy2008-07-07 14:52:30 +0000
committerStephen Kennedy2008-07-07 14:52:30 +0000
commit7e3639e68b054c2259124d86bcd3bde0edc72d9e (patch)
treef848e33765967d59d6f2a0eb4a70e6935d15574f /backends/common
parent98f999f8e01c4752a771f1a8c6aec77b6efe3fb5 (diff)
downloadscummvm-rg350-7e3639e68b054c2259124d86bcd3bde0edc72d9e.tar.gz
scummvm-rg350-7e3639e68b054c2259124d86bcd3bde0edc72d9e.tar.bz2
scummvm-rg350-7e3639e68b054c2259124d86bcd3bde0edc72d9e.zip
- moved VirtualKeyboard files into backends/common directory
svn-id: r32941
Diffstat (limited to 'backends/common')
-rw-r--r--backends/common/virtualKeyboard.cpp261
-rw-r--r--backends/common/virtualKeyboard.h147
-rw-r--r--backends/common/virtualKeyboardParser.cpp292
-rw-r--r--backends/common/virtualKeyboardParser.h70
4 files changed, 770 insertions, 0 deletions
diff --git a/backends/common/virtualKeyboard.cpp b/backends/common/virtualKeyboard.cpp
new file mode 100644
index 0000000000..9937127df4
--- /dev/null
+++ b/backends/common/virtualKeyboard.cpp
@@ -0,0 +1,261 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "backends/common/virtualKeyboard.h"
+#include "backends/common/virtualKeyboardParser.h"
+#include "common/config-manager.h"
+#include "common/events.h"
+#include "graphics/imageman.h"
+#include "common/unzip.h"
+
+namespace GUI {
+
+VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) {
+ assert(g_system);
+ _system = g_system;
+
+ _parser = new VirtualKeyboardParser(this);
+ _loaded = _displaying = false;
+}
+
+VirtualKeyboard::~VirtualKeyboard() {
+ // TODO: clean up event data pointers
+ delete _parser;
+}
+
+void VirtualKeyboard::reset() {
+ // TODO: clean up event data pointers
+ _modes.clear();
+ _initialMode = _currentMode = 0;
+ _pos.x = _pos.y = 0;
+ _hAlignment = kAlignCentre;
+ _vAlignment = kAlignBottom;
+ _keyQueue.clear();
+ _keyDown = 0;
+ _displaying = false;
+}
+
+bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
+ // reset to default settings
+ reset();
+
+ if (ConfMan.hasKey("extrapath"))
+ Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath"));
+
+ if (Common::File::exists(packName + ".xml")) {
+ // uncompressed keyboard pack
+ if (!_parser->loadFile(packName + ".xml"))
+ return false;
+
+ } else if (Common::File::exists(packName + ".zip")) {
+ // compressed keyboard pack
+#ifdef USE_ZLIB
+ unzFile zipFile = unzOpen((packName + ".zip").c_str());
+ if (zipFile && unzLocateFile(zipFile, (packName + ".xml").c_str(), 2) == UNZ_OK) {
+ unz_file_info fileInfo;
+ unzOpenCurrentFile(zipFile);
+ unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
+ byte *buffer = new byte[fileInfo.uncompressed_size+1];
+ assert(buffer);
+ memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(byte));
+ unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
+ unzCloseCurrentFile(zipFile);
+ if (!_parser->loadBuffer(buffer, fileInfo.uncompressed_size+1, true)) {
+ unzClose(zipFile);
+ return false;
+ }
+ } else {
+ unzClose(zipFile);
+ return false;
+ }
+ unzClose(zipFile);
+
+ ImageMan.addArchive(packName + ".zip");
+#else
+ return false;
+#endif
+ } else {
+ warning("Keyboard pack not found");
+ return false;
+ }
+
+ if (!_parser->parse())
+ return false;
+
+ if (!_initialMode)
+ warning("Initial mode of keyboard pack not defined");
+
+ ModeMap::iterator it;
+ for (it = _modes.begin(); it != _modes.end(); it++) {
+ // if no image then it means layout tag for the
+ // required resolution was missing from the mode tag.
+ if (!it->_value.image) {
+ warning("'%s' layout missing from '%s' mode", it->_value.resolution, it->_value.name);
+ return false;
+ }
+ }
+
+ _loaded = true;
+ return true;
+}
+
+void VirtualKeyboard::reposition()
+{
+ // calculate keyboard co-ordinates
+ int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
+ int16 keyW = _currentMode->image->w, keyH = _currentMode->image->h;
+ if (scrW != keyW) {
+ switch (_hAlignment) {
+ case kAlignCentre:
+ _pos.x = (scrW - keyW) / 2;
+ break;
+ case kAlignRight:
+ _pos.x = scrW - keyW;
+ break;
+ }
+ }
+ if (scrH != keyH) {
+ switch (_vAlignment) {
+ case kAlignMiddle:
+ _pos.y = (scrH - keyH) / 2;
+ break;
+ case kAlignBottom:
+ _pos.y = scrH - keyH;
+ break;
+ }
+ }
+}
+
+void VirtualKeyboard::processClick(int16 x, int16 y)
+{
+ x -= _pos.x;
+ y -= _pos.y;
+ if (x < 0 || x > _currentMode->image->w) return;
+ if (y < 0 || y > _currentMode->image->h) return;
+
+ Common::MapArea *area = _currentMode->imageMap.findMapArea(x, y);
+ if (!area) return;
+ if (!_currentMode->events.contains(area->getTarget())) return;
+ Event evt = _currentMode->events[area->getTarget()];
+
+ switch (evt.type) {
+ case kEventKey:
+ // add virtual keypress to queue
+ _keyQueue.push_back(*(Common::KeyState*)evt.data);
+ break;
+ case kEventSwitchMode:
+ // switch to new mode
+ switchMode(*(Common::String *)evt.data);
+ break;
+ case kEventClose:
+ // close virtual keyboard
+ _displaying = false;
+ break;
+ }
+}
+
+void VirtualKeyboard::switchMode(Mode *newMode) {
+ _currentMode = newMode;
+ reposition();
+ _needRedraw = true;
+}
+
+void VirtualKeyboard::switchMode(const Common::String& newMode) {
+ if (!_modes.contains(newMode)) {
+ warning("Keyboard mode '%s' unknown", newMode.c_str());
+ return;
+ }
+ _currentMode = &_modes[newMode];
+ reposition();
+ _needRedraw = true;
+}
+
+void VirtualKeyboard::show() {
+ switchMode(_initialMode);
+ _displaying = true;
+ runLoop();
+}
+
+void VirtualKeyboard::hide() {
+ _displaying = false;
+}
+
+void VirtualKeyboard::runLoop() {
+ Common::EventManager *eventMan = _system->getEventManager();
+
+ _system->showOverlay();
+ // capture mouse clicks
+ while (_displaying) {
+ if (_needRedraw) redraw();
+
+ Common::Event event;
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseDown = event.mouse;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ if (ABS(_mouseDown.x - event.mouse.x) < 5
+ && ABS(_mouseDown.y - event.mouse.y) < 5)
+ processClick(event.mouse.x, event.mouse.y);
+ break;
+ case Common::EVENT_QUIT:
+ _system->quit();
+ return;
+ }
+ }
+ }
+ // clear keyboard from overlay
+ _system->hideOverlay();
+}
+
+void VirtualKeyboard::redraw() {
+ _needRedraw = false;
+ _system->clearOverlay();
+ _system->copyRectToOverlay((OverlayColor*)_currentMode->image->pixels,
+ _currentMode->image->w, _pos.x, _pos.y,
+ _currentMode->image->w, _currentMode->image->h);
+ _system->updateScreen();
+}
+
+bool VirtualKeyboard::pollEvent(Common::Event &event) {
+ if (_displaying || (_keyQueue.empty() && !_keyDown))
+ return false;
+
+ event.synthetic = false; // ???
+ if (_keyDown) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd = *_keyDown;
+ _keyQueue.remove_at(0);
+ _keyDown = 0;
+ } else {
+ _keyDown = _keyQueue.begin();
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd = *_keyDown;
+ }
+ return true;
+}
+
+} // end of namespace GUI
diff --git a/backends/common/virtualKeyboard.h b/backends/common/virtualKeyboard.h
new file mode 100644
index 0000000000..b44d2cd459
--- /dev/null
+++ b/backends/common/virtualKeyboard.h
@@ -0,0 +1,147 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GUI_VIRTUAL_KEYBOARD_H
+#define GUI_VIRTUAL_KEYBOARD_H
+
+class OSystem;
+
+#include "common/events.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/imagemap.h"
+#include "common/keyboard.h"
+#include "common/str.h"
+#include "graphics/surface.h"
+
+namespace GUI {
+
+class VirtualKeyboardParser;
+
+
+
+class VirtualKeyboard {
+
+ /** Type of key event */
+ enum EventType {
+ kEventKey,
+ kEventSwitchMode,
+ kEventClose,
+
+ kEventMax
+ };
+
+ struct Event {
+ Common::String name;
+ EventType type;
+ void *data;
+ };
+
+ typedef Common::HashMap<Common::String, Event, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> EventMap;
+
+ struct Mode {
+ Common::String name;
+ Common::String resolution;
+ Common::String bitmapName;
+ Graphics::Surface *image;
+ Common::ImageMap imageMap;
+ EventMap events;
+ Mode() : image(0) {}
+ };
+
+ typedef Common::HashMap<Common::String, Mode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ModeMap;
+
+ enum HorizontalAlignment {
+ kAlignLeft,
+ kAlignCentre,
+ kAlignRight
+ };
+
+ enum VerticalAlignment {
+ kAlignTop,
+ kAlignMiddle,
+ kAlignBottom
+ };
+
+public:
+ VirtualKeyboard();
+ virtual ~VirtualKeyboard();
+
+ bool loadKeyboardPack(Common::String packName);
+ void show();
+ void hide();
+ bool isDisplaying() {
+ return _displaying;
+ }
+ bool isLoaded() {
+ return _loaded;
+ }
+
+ /**
+ * Get the next virtual key event in the event queue.
+ * @param event point to an Event struct, which will be filled with the event data.
+ * @return true if an event was retrieved.
+ */
+ bool pollEvent(Common::Event &event);
+
+private:
+ OSystem *_system;
+
+ friend class VirtualKeyboardParser;
+ VirtualKeyboardParser *_parser;
+
+ // TODO : sort order of all this stuff
+ void reset();
+ void reposition();
+ void switchMode(Mode *newMode);
+ void switchMode(const Common::String& newMode);
+ void processClick(int16 x, int16 y);
+ void runLoop();
+ void redraw();
+
+ bool _loaded;
+ bool _displaying;
+ bool _needRedraw;
+
+ ModeMap _modes;
+ Mode *_initialMode;
+ Mode *_currentMode;
+
+ Common::Point _pos;
+ HorizontalAlignment _hAlignment;
+ VerticalAlignment _vAlignment;
+
+ Common::Point _mouseDown;
+
+ Common::Array<Common::KeyState> _keyQueue;
+ Common::KeyState *_keyDown;
+
+};
+
+
+} // End of namespace GUI
+
+
+#endif
diff --git a/backends/common/virtualKeyboardParser.cpp b/backends/common/virtualKeyboardParser.cpp
new file mode 100644
index 0000000000..8475f3e4f6
--- /dev/null
+++ b/backends/common/virtualKeyboardParser.cpp
@@ -0,0 +1,292 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "backends/common/virtualKeyboardParser.h"
+
+#include "common/keyboard.h"
+#include "graphics/imageman.h"
+#include "common/util.h"
+
+namespace GUI {
+
+VirtualKeyboardParser::VirtualKeyboardParser(VirtualKeyboard *kbd) : XMLParser() {
+ _keyboard = kbd;
+
+ _callbacks["keyboard"] = &VirtualKeyboardParser::parserCallback_Keyboard;
+ _callbacks["mode"] = &VirtualKeyboardParser::parserCallback_Mode;
+ _callbacks["event"] = &VirtualKeyboardParser::parserCallback_Event;
+ _callbacks["layout"] = &VirtualKeyboardParser::parserCallback_Layout;
+ _callbacks["map"] = &VirtualKeyboardParser::parserCallback_Map;
+ _callbacks["area"] = &VirtualKeyboardParser::parserCallback_Area;
+}
+
+bool VirtualKeyboardParser::keyCallback(Common::String keyName) {
+ if (!_callbacks.contains(_activeKey.top()->name))
+ return parserError("%s is not a valid key name.", keyName.c_str());
+
+ return (this->*(_callbacks[_activeKey.top()->name]))();
+}
+
+bool VirtualKeyboardParser::parserCallback_Keyboard() {
+ ParserNode *kbdNode = getActiveNode();
+
+ assert(kbdNode->name == "keyboard");
+
+ if (getParentNode(kbdNode) != 0)
+ return parserError("Keyboard element must be root");
+
+ if (_kbdParsed)
+ return parserError("Only a single keyboard element is allowed");
+ _kbdParsed = true;
+
+ if (!kbdNode->values.contains("initial_mode"))
+ return parserError("Keyboard element must contain initial_mode attribute");
+
+ _initialModeName = kbdNode->values["initial_mode"];
+
+ if (kbdNode->values.contains("h_align")) {
+ Common::String h = kbdNode->values["h_align"];
+ if (h == "left")
+ _keyboard->_hAlignment = VirtualKeyboard::kAlignLeft;
+ else if (h == "centre" || h == "center")
+ _keyboard->_hAlignment = VirtualKeyboard::kAlignCentre;
+ else if (h == "right")
+ _keyboard->_hAlignment = VirtualKeyboard::kAlignRight;
+ }
+
+ if (kbdNode->values.contains("v_align")) {
+ Common::String v = kbdNode->values["h_align"];
+ if (v == "top")
+ _keyboard->_vAlignment = VirtualKeyboard::kAlignTop;
+ else if (v == "middle" || v == "center")
+ _keyboard->_vAlignment = VirtualKeyboard::kAlignMiddle;
+ else if (v == "bottom")
+ _keyboard->_vAlignment = VirtualKeyboard::kAlignBottom;
+ }
+
+ return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_Mode() {
+ ParserNode *modeNode = getActiveNode();
+
+ assert(modeNode->name == "mode");
+
+ if (getParentNode(modeNode) == 0 || getParentNode(modeNode)->name != "keyboard")
+ return parserError("Mode element must be child of keyboard element");
+
+ if (!modeNode->values.contains("name") || !modeNode->values.contains("resolutions"))
+ return parserError("Mode element must contain name and resolutions attributes");
+
+ Common::String name = modeNode->values["name"];
+
+ if (_keyboard->_modes.contains(name))
+ return parserError("Mode '%s' has already been defined", name);
+
+ // create new mode
+ VirtualKeyboard::Mode mode;
+ mode.name = name;
+ _keyboard->_modes[name] = mode;
+ _mode = &(_keyboard->_modes[name]);
+
+ // if this is the keyboard's initial mode
+ // then set it to be the current mode
+ if (name == _initialModeName)
+ _keyboard->_initialMode = _mode;
+
+ Common::String resolutions = modeNode->values["resolutions"];
+ Common::StringTokenizer tok(resolutions, " ,");
+
+ uint16 scrX = g_system->getOverlayWidth(), scrY = g_system->getOverlayHeight();
+ uint32 diff = 0xFFFFFFFF;
+
+ for (Common::String res = tok.nextToken(); res.size() > 0; res = tok.nextToken()) {
+ int resX, resY;
+ if (sscanf(res.c_str(), "%dx%d", &resX, &resY) != 2) {
+ parserError("Invalid resolution specification");
+ } else {
+ if (resX == scrX && resY == scrY) {
+ _mode->resolution = res;
+ break;
+ } else {
+ uint16 newDiff = ABS(scrX - resX) + ABS(scrY - resY);
+ if (newDiff < diff) {
+ diff = newDiff;
+ _mode->resolution = res;
+ }
+ }
+ }
+ }
+
+ if (_mode->resolution.empty())
+ return parserError("No acceptable resolution was found");
+
+ return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_Event() {
+ ParserNode *evtNode = getActiveNode();
+
+ assert(evtNode->name == "event");
+
+ if (getParentNode(evtNode) == 0 || getParentNode(evtNode)->name != "mode")
+ return parserError("Event element must be child of mode element");
+
+ if (!evtNode->values.contains("name") || !evtNode->values.contains("type"))
+ return parserError("Event element must contain name and type attributes");
+
+ assert(_mode);
+
+ Common::String name = evtNode->values["name"];
+ if (_mode->events.contains(name))
+ return parserError("Event '%s' has already been defined", name);
+
+ VirtualKeyboard::Event evt;
+ evt.name = name;
+
+ Common::String type = evtNode->values["type"];
+ if (type == "key") {
+ if (!evtNode->values.contains("code") || !evtNode->values.contains("ascii"))
+ return parserError("Key event element must contain code and ascii attributes");
+
+ evt.type = VirtualKeyboard::kEventKey;
+
+ Common::KeyCode code = (Common::KeyCode)atoi(evtNode->values["code"].c_str());
+ uint16 ascii = atoi(evtNode->values["ascii"].c_str());
+
+ byte flags = 0;
+ if (evtNode->values.contains("flags")) {
+ Common::StringTokenizer tok(evtNode->values["flags"], ", ");
+ for (Common::String fl = tok.nextToken(); !fl.empty(); fl = tok.nextToken()) {
+ if (fl == "ctrl" || fl == "control")
+ flags &= Common::KBD_CTRL;
+ else if (fl == "alt")
+ flags &= Common::KBD_ALT;
+ else if (fl == "shift")
+ flags &= Common::KBD_SHIFT;
+ }
+ }
+
+ evt.data = new Common::KeyState(code, ascii, flags);
+
+ } else if (type == "switch_mode") {
+ if (!evtNode->values.contains("mode"))
+ return parserError("Switch mode event element must contain mode attribute");
+
+ evt.type = VirtualKeyboard::kEventSwitchMode;
+ evt.data = new Common::String(evtNode->values["mode"]);
+ } else
+ return parserError("Event type '%s' not known", type);
+
+ _mode->events[name] = evt;
+
+ return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_Layout() {
+ ParserNode *layoutNode = getActiveNode();
+
+ assert(layoutNode->name == "layout");
+
+ if (getParentNode(layoutNode) == 0 || getParentNode(layoutNode)->name != "mode")
+ return parserError("Layout element must be child of mode element");
+
+ if (!layoutNode->values.contains("resolution") || !layoutNode->values.contains("bitmap"))
+ return parserError("Layout element must contain resolution and bitmap attributes");
+
+ assert(!_mode->resolution.empty());
+
+ Common::String res = layoutNode->values["resolution"];
+
+ if (res != _mode->resolution) {
+ layoutNode->ignore = true;
+ return true;
+ }
+
+ _mode->bitmapName = layoutNode->values["bitmap"];
+
+
+ if (!ImageMan.registerSurface(_mode->bitmapName, 0))
+ return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
+
+ _mode->image = ImageMan.getSurface(_mode->bitmapName);
+ if (!_mode->image)
+ return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
+
+ return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_Map() {
+ ParserNode *mapNode = getActiveNode();
+
+ assert(mapNode->name == "map");
+
+ if (getParentNode(mapNode) == 0 || getParentNode(mapNode)->name != "layout")
+ return parserError("Map element must be child of layout element");
+
+ return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_Area() {
+ ParserNode *areaNode = getActiveNode();
+
+ assert(areaNode->name == "area");
+
+ if (getParentNode(areaNode) == 0 || getParentNode(areaNode)->name != "map")
+ return parserError("Area element must be child of map element");
+
+ if (!areaNode->values.contains("shape") || !areaNode->values.contains("coords") || !areaNode->values.contains("target"))
+ return parserError("Area element must contain shape, coords and target attributes");
+
+ Common::String shape = areaNode->values["shape"];
+ if (shape == "rect") {
+ int x1, y1, x2, y2;
+ if (!parseIntegerKey(areaNode->values["coords"].c_str(), 4, &x1, &y1, &x2, &y2))
+ return parserError("Invalid coords for rect area");
+
+ Common::Rect rect(x1, y1, x2, y2);
+ _mode->imageMap.addRectMapArea(rect, areaNode->values["target"]);
+ } else if (shape == "poly") {
+ Common::StringTokenizer tok (areaNode->values["coords"], ", ");
+ Common::Polygon poly;
+ for (Common::String st = tok.nextToken(); !st.empty(); st = tok.nextToken()) {
+ int x, y;
+ if (sscanf(st.c_str(), "%d", &x) != 1)
+ return parserError("Invalid coords for polygon area");
+ st = tok.nextToken();
+ if (sscanf(st.c_str(), "%d", &y) != 1)
+ return parserError("Invalid coords for polygon area");
+ poly.addPoint(x, y);
+ }
+ if (poly.getPointCount() < 3)
+ return parserError("Invalid coords for polygon area");
+ _mode->imageMap.addPolygonMapArea(poly, areaNode->values["target"]);
+ } else
+ return parserError("Area shape '%s' not known", shape);
+
+ return true;
+}
+
+} // end of namespace GUI
diff --git a/backends/common/virtualKeyboardParser.h b/backends/common/virtualKeyboardParser.h
new file mode 100644
index 0000000000..4325d8af31
--- /dev/null
+++ b/backends/common/virtualKeyboardParser.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GUI_VIRTUAL_KEYBOARD_PARSER
+#define GUI_VIRTUAL_KEYBOARD_PARSER
+
+#include "common/xmlparser.h"
+#include "backends/common/virtualKeyboard.h"
+
+namespace GUI {
+
+class VirtualKeyboardParser : public Common::XMLParser {
+
+ typedef bool (VirtualKeyboardParser::*ParserCallback)();
+
+public:
+
+ VirtualKeyboardParser(VirtualKeyboard *kbd);
+
+protected:
+ VirtualKeyboard *_keyboard;
+
+ /** internal state variables of parser */
+ VirtualKeyboard::Mode *_mode; // pointer to mode currently being parsed
+ bool _modeParsed;
+ Common::String _initialModeName; // name of initial keyboard mode
+ bool _kbdParsed;
+
+ bool keyCallback(Common::String keyName);
+ void cleanup() {
+ _mode = 0;
+ _kbdParsed = _modeParsed = false;
+ _initialModeName.clear();
+ }
+
+ bool parserCallback_Keyboard();
+ bool parserCallback_Mode();
+ bool parserCallback_Event();
+ bool parserCallback_Layout();
+ bool parserCallback_Map();
+ bool parserCallback_Area();
+
+ Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks;
+};
+
+} // end of namespace GUI
+
+#endif