* added vkeybd, not tested

This commit is contained in:
Pawel Kolodziejski 2009-10-04 10:31:37 +00:00
parent 657272f7ba
commit ba58b9033d
22 changed files with 3564 additions and 0 deletions

View file

@ -0,0 +1,74 @@
/* 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$
*
*/
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/image-map.h"
#include "backends/vkeybd/polygon.h"
namespace Common {
ImageMap::~ImageMap() {
removeAllAreas();
}
Polygon *ImageMap::createArea(const String& id) {
if (_areas.contains(id)) {
warning("Image map already contains an area with target of '%s'", id.c_str());
return 0;
}
Polygon *p = new Polygon();
_areas[id] = p;
return p;
}
void ImageMap::removeArea(const String& id) {
if (!_areas.contains(id))
return;
delete _areas[id];
_areas.erase(id);
}
void ImageMap::removeAllAreas() {
HashMap<String, Polygon*>::iterator it;
for (it = _areas.begin(); it != _areas.end(); it++) {
delete it->_value;
}
_areas.clear();
}
String ImageMap::findMapArea(int16 x, int16 y) {
HashMap<String, Polygon*>::iterator it;
for (it = _areas.begin(); it != _areas.end(); it++) {
if (it->_value->contains(x, y))
return it->_key;
}
return String();
}
} // End of namespace Common
#endif // #ifdef ENABLE_VKEYBD

View file

@ -0,0 +1,59 @@
/* 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 COMMON_IMAGEMAP_H
#define COMMON_IMAGEMAP_H
#ifdef ENABLE_VKEYBD
#include "common/scummsys.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
namespace Common {
struct Polygon;
class ImageMap {
public:
~ImageMap();
Polygon *createArea(const String& id);
void removeArea(const String& id);
void removeAllAreas();
String findMapArea(int16 x, int16 y);
protected:
HashMap<String, Polygon *> _areas;
};
} // End of namespace Common
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef COMMON_IMAGEMAP_H

View file

@ -0,0 +1,335 @@
#ifndef KEYCODE_DESCRIPTIONS_H
#define KEYCODE_DESCRIPTIONS_H
#ifdef ENABLE_VKEYBD
static const char *keycodeDescTable[] = {
"",
"",
"",
"",
"",
"",
"",
"",
"Backspace",
"Tab",
"",
"",
"Clear",
"Return",
"",
"",
"",
"",
"",
"Pause",
"",
"",
"",
"",
"",
"",
"",
"Escape",
"",
"",
"",
"",
" ",
"!",
"\"",
"#",
"$",
"%",
"&",
"'",
"(",
")",
"*",
"+",
",",
"-",
".",
"/",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
":",
";",
"<",
"=",
">",
"?",
"@",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"[",
"\\",
"]",
"^",
"_",
"`",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"{",
"|",
"}",
"~",
"Delete",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
".",
"/",
"*",
"-",
"+",
"Enter",
"=",
"Up",
"Down",
"Right",
"Left",
"Ins",
"Home",
"End",
"Page Up",
"Page Down",
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"F13",
"F14",
"F15",
"",
"",
"",
"Num Lock",
"Caps Lock",
"Scroll Lock",
"Shift",
"Shift",
"Ctrl",
"Ctrl",
"Alt",
"Alt",
"Meta",
"Meta",
"Super",
"Super",
"Mode",
"Compose",
"Help",
"Print",
"SysReq",
"Break",
"Menu",
"Power",
"",
"Undo"
};
static const int keycodeDescTableSize = 322;
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef KEYCODE_DESCRIPTIONS_H

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

View file

@ -0,0 +1,920 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<keyboard initial_mode="lowercase" v_align="bottom" h_align="centre">
<!-- Lowercase -->
<mode name="lowercase" resolutions="320x240,640x480">
<layout resolution="320x240" bitmap="lowercase320x240.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="13,8,306,20" target="display_area" />
<area shape="rect" coords="9,26,25,42" target="esc" />
<area shape="rect" coords="50,25,67,43" target="f2" />
<area shape="rect" coords="29,24,46,43" target="f1" />
<area shape="rect" coords="71,26,88,44" target="f3" />
<area shape="rect" coords="90,25,107,43" target="f4" />
<area shape="rect" coords="111,26,128,44" target="f5" />
<area shape="rect" coords="132,26,149,44" target="f6" />
<area shape="rect" coords="153,25,170,44" target="f7" />
<area shape="rect" coords="173,26,190,44" target="f8" />
<area shape="rect" coords="194,24,211,43" target="f9" />
<area shape="rect" coords="215,26,231,44" target="f10" />
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
<area shape="rect" coords="276,47,308,64" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="q" />
<area shape="rect" coords="57,68,75,86" target="w" />
<area shape="rect" coords="78,67,94,85" target="e" />
<area shape="rect" coords="98,67,115,85" target="r" />
<area shape="rect" coords="119,67,136,85" target="t" />
<area shape="rect" coords="141,68,158,86" target="y" />
<area shape="rect" coords="161,67,179,86" target="u" />
<area shape="rect" coords="182,67,199,86" target="i" />
<area shape="rect" coords="202,67,220,85" target="o" />
<area shape="rect" coords="223,68,240,86" target="p" />
<area shape="rect" coords="44,88,63,107" target="a" />
<area shape="rect" coords="65,88,84,106" target="s" />
<area shape="rect" coords="86,89,104,107" target="d" />
<area shape="rect" coords="107,89,124,107" target="f" />
<area shape="rect" coords="128,89,145,107" target="g" />
<area shape="rect" coords="149,88,165,107" target="h" />
<area shape="rect" coords="169,89,186,107" target="j" />
<area shape="rect" coords="189,89,207,107" target="k" />
<area shape="rect" coords="210,89,228,107" target="l" />
<area shape="rect" coords="273,89,311,106" target="enter" />
<area shape="rect" coords="9,110,50,127" target="shift" />
<area shape="rect" coords="8,89,41,106" target="caps" />
<area shape="rect" coords="58,110,75,128" target="z" />
<area shape="rect" coords="79,110,96,128" target="x" />
<area shape="rect" coords="99,109,116,127" target="c" />
<area shape="rect" coords="120,110,138,128" target="v" />
<area shape="rect" coords="141,109,157,127" target="b" />
<area shape="rect" coords="162,110,179,128" target="n" />
<area shape="rect" coords="182,110,199,128" target="m" />
<area shape="rect" coords="271,109,311,128" target="symbols" />
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
<area shape="rect" coords="8,47,26,64" target="|" />
<area shape="rect" coords="28,47,45,64" target="1" />
<area shape="rect" coords="50,47,67,65" target="2" />
<area shape="rect" coords="70,46,87,65" target="3" />
<area shape="rect" coords="91,46,108,64" target="4" />
<area shape="rect" coords="111,46,129,65" target="5" />
<area shape="rect" coords="132,47,149,65" target="6" />
<area shape="rect" coords="152,47,170,64" target="7" />
<area shape="rect" coords="174,46,191,63" target="8" />
<area shape="rect" coords="194,47,211,65" target="9" />
<area shape="rect" coords="215,46,232,64" target="0" />
<area shape="rect" coords="235,47,252,65" target="-" />
<area shape="rect" coords="255,46,272,65" target="=" />
<area shape="rect" coords="244,68,261,86" target="[" />
<area shape="rect" coords="264,67,282,86" target="]" />
<area shape="rect" coords="284,68,309,86" target="#" />
<area shape="rect" coords="231,88,249,106" target=";" />
<area shape="rect" coords="251,89,269,107" target="" />
<area shape="rect" coords="202,110,219,128" target="," />
<area shape="rect" coords="223,110,241,128" target="." />
<area shape="rect" coords="243,110,261,128" target="/" />
<area shape="rect" coords="277,133,292,148" target="ok" />
<area shape="rect" coords="292,133,309,148" target="cancel" />
</map>
</layout>
<layout resolution="640x480" bitmap="lowercase640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="26,23,613,37" target="display_area" />
<area shape="rect" coords="18,52,51,85" target="esc" />
<area shape="rect" coords="100,51,135,88" target="f2" />
<area shape="rect" coords="59,49,94,88" target="f1" />
<area shape="rect" coords="142,53,176,89" target="f3" />
<area shape="rect" coords="181,51,216,87" target="f4" />
<area shape="rect" coords="223,52,258,88" target="f5" />
<area shape="rect" coords="265,52,299,89" target="f6" />
<area shape="rect" coords="306,51,341,90" target="f7" />
<area shape="rect" coords="347,53,382,89" target="f8" />
<area shape="rect" coords="389,49,424,88" target="f9" />
<area shape="rect" coords="431,52,464,89" target="f10" />
<area shape="rect" coords="470,53,506,88" target="f11" />
<area shape="rect" coords="511,52,546,90" target="f12" />
<area shape="rect" coords="552,55,620,87" target="del" />
<area shape="rect" coords="553,94,618,129" target="backspace" />
<area shape="rect" coords="17,136,66,171" target="tab" />
<area shape="rect" coords="73,137,108,171" target="q" />
<area shape="rect" coords="114,136,150,172" target="w" />
<area shape="rect" coords="157,134,189,171" target="e" />
<area shape="rect" coords="197,135,232,171" target="r" />
<area shape="rect" coords="239,135,274,172" target="t" />
<area shape="rect" coords="282,136,317,173" target="y" />
<area shape="rect" coords="322,135,359,173" target="u" />
<area shape="rect" coords="364,134,399,172" target="i" />
<area shape="rect" coords="404,135,440,171" target="o" />
<area shape="rect" coords="446,136,480,172" target="p" />
<area shape="rect" coords="89,177,127,216" target="a" />
<area shape="rect" coords="131,177,169,214" target="s" />
<area shape="rect" coords="173,178,209,215" target="d" />
<area shape="rect" coords="215,178,250,214" target="f" />
<area shape="rect" coords="256,178,291,214" target="g" />
<area shape="rect" coords="299,176,332,214" target="h" />
<area shape="rect" coords="339,178,374,215" target="j" />
<area shape="rect" coords="379,178,415,215" target="k" />
<area shape="rect" coords="421,178,457,215" target="l" />
<area shape="rect" coords="546,179,622,214" target="enter" />
<area shape="rect" coords="19,221,101,256" target="shift" />
<area shape="rect" coords="17,179,84,213" target="caps" />
<area shape="rect" coords="117,220,152,256" target="z" />
<area shape="rect" coords="158,220,192,256" target="x" />
<area shape="rect" coords="198,219,233,256" target="c" />
<area shape="rect" coords="240,220,276,257" target="v" />
<area shape="rect" coords="283,219,316,255" target="b" />
<area shape="rect" coords="324,220,359,256" target="n" />
<area shape="rect" coords="365,220,399,257" target="m" />
<area shape="rect" coords="542,219,623,257" target="symbols" />
<area shape="rect" coords="19,260,68,296" target="ctrl" />
<area shape="rect" coords="76,261,123,295" target="alt" />
<area shape="rect" coords="135,261,525,297" target="space" />
<area shape="rect" coords="16,95,53,129" target="|" />
<area shape="rect" coords="57,95,92,129" target="1" />
<area shape="rect" coords="100,94,134,130" target="2" />
<area shape="rect" coords="140,93,174,131" target="3" />
<area shape="rect" coords="182,93,217,130" target="4" />
<area shape="rect" coords="222,93,258,132" target="5" />
<area shape="rect" coords="265,94,299,131" target="6" />
<area shape="rect" coords="305,94,341,129" target="7" />
<area shape="rect" coords="348,93,382,128" target="8" />
<area shape="rect" coords="389,94,423,130" target="9" />
<area shape="rect" coords="431,93,465,130" target="0" />
<area shape="rect" coords="471,94,505,131" target="-" />
<area shape="rect" coords="511,93,546,131" target="=" />
<area shape="rect" coords="488,136,522,172" target="[" />
<area shape="rect" coords="529,135,565,173" target="]" />
<area shape="rect" coords="569,136,620,172" target="#" />
<area shape="rect" coords="462,177,498,214" target=";" />
<area shape="rect" coords="503,178,539,214" target="" />
<area shape="rect" coords="405,220,440,256" target="," />
<area shape="rect" coords="447,220,483,256" target="." />
<area shape="rect" coords="487,220,524,256" target="/" />
<area shape="rect" coords="555,266,585,298" target="ok" />
<area shape="rect" coords="585,266,619,298" target="cancel" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
<event name="f1" type="key" code="282" ascii="315" modifiers="" />
<event name="f2" type="key" code="283" ascii="316" modifiers="" />
<event name="f3" type="key" code="284" ascii="317" modifiers="" />
<event name="f4" type="key" code="285" ascii="318" modifiers="" />
<event name="f5" type="key" code="286" ascii="319" modifiers="" />
<event name="f6" type="key" code="287" ascii="320" modifiers="" />
<event name="f7" type="key" code="288" ascii="321" modifiers="" />
<event name="f8" type="key" code="289" ascii="322" modifiers="" />
<event name="f9" type="key" code="290" ascii="323" modifiers="" />
<event name="f10" type="key" code="291" ascii="324" modifiers="" />
<event name="f11" type="key" code="292" ascii="325" modifiers="" />
<event name="f12" type="key" code="293" ascii="326" modifiers="" />
<event name="del" type="key" code="127" ascii="0" modifiers="" />
<event name="ctrl" type="modifier" modifiers="ctrl" />
<event name="alt" type="modifier" modifiers="alt" />
<event name="shift" type="modifier" modifiers="shift" />
<event name="caps" type="switch_mode" mode="uppercase" />
<event name="symbols" type="switch_mode" mode="lowercasesymbols" />
<event name="backspace" type="key" code="8" ascii="8" modifiers="" />
<event name="enter" type="key" code="13" ascii="13" modifiers="" />
<event name="|" type="key" code="124" ascii="124" modifiers="" />
<event name="-" type="key" code="45" ascii="45" modifiers="" />
<event name="=" type="key" code="61" ascii="61" modifiers="" />
<event name="[" type="key" code="91" ascii="91" modifiers="" />
<event name="]" type="key" code="93" ascii="93" modifiers="" />
<event name="#" type="key" code="35" ascii="35" modifiers="" />
<event name=";" type="key" code="59" ascii="59" modifiers="" />
<event name="'" type="key" code="39" ascii="39" modifiers="" />
<event name="," type="key" code="44" ascii="44" modifiers="" />
<event name="." type="key" code="46" ascii="46" modifiers="" />
<event name="/" type="key" code="47" ascii="47" modifiers="" />
<event name="space" type="key" code="32" ascii="32" modifiers="" />
<event name="tab" type="key" code="9" ascii="9" modifiers="" />
<event name="a" type="key" code="97" ascii="97" modifiers="" />
<event name="b" type="key" code="98" ascii="98" modifiers="" />
<event name="c" type="key" code="99" ascii="99" modifiers="" />
<event name="d" type="key" code="100" ascii="100" modifiers="" />
<event name="e" type="key" code="101" ascii="101" modifiers="" />
<event name="f" type="key" code="102" ascii="102" modifiers="" />
<event name="g" type="key" code="103" ascii="103" modifiers="" />
<event name="h" type="key" code="104" ascii="104" modifiers="" />
<event name="i" type="key" code="105" ascii="105" modifiers="" />
<event name="j" type="key" code="106" ascii="106" modifiers="" />
<event name="k" type="key" code="107" ascii="107" modifiers="" />
<event name="l" type="key" code="108" ascii="108" modifiers="" />
<event name="m" type="key" code="109" ascii="109" modifiers="" />
<event name="n" type="key" code="110" ascii="110" modifiers="" />
<event name="o" type="key" code="111" ascii="111" modifiers="" />
<event name="p" type="key" code="112" ascii="112" modifiers="" />
<event name="q" type="key" code="113" ascii="113" modifiers="" />
<event name="r" type="key" code="114" ascii="114" modifiers="" />
<event name="s" type="key" code="115" ascii="115" modifiers="" />
<event name="t" type="key" code="116" ascii="116" modifiers="" />
<event name="u" type="key" code="117" ascii="117" modifiers="" />
<event name="v" type="key" code="118" ascii="118" modifiers="" />
<event name="w" type="key" code="119" ascii="119" modifiers="" />
<event name="x" type="key" code="120" ascii="120" modifiers="" />
<event name="y" type="key" code="121" ascii="121" modifiers="" />
<event name="z" type="key" code="122" ascii="122" modifiers="" />
<event name="0" type="key" code="48" ascii="48" modifiers="" />
<event name="1" type="key" code="49" ascii="49" modifiers="" />
<event name="2" type="key" code="50" ascii="50" modifiers="" />
<event name="3" type="key" code="51" ascii="51" modifiers="" />
<event name="4" type="key" code="52" ascii="52" modifiers="" />
<event name="5" type="key" code="53" ascii="53" modifiers="" />
<event name="6" type="key" code="54" ascii="54" modifiers="" />
<event name="7" type="key" code="55" ascii="55" modifiers="" />
<event name="8" type="key" code="56" ascii="56" modifiers="" />
<event name="9" type="key" code="57" ascii="57" modifiers="" />
<event name="ok" type="submit" />
<event name="cancel" type="cancel" />
<event name="quit" type="submit" />
</mode>
<!-- Uppercase -->
<mode name="uppercase" resolutions="320x240,640x480">
<layout resolution="320x240" bitmap="uppercase320x240.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="13,8,306,20" target="display_area" />
<area shape="rect" coords="9,26,25,42" target="esc" />
<area shape="rect" coords="50,25,67,43" target="f2" />
<area shape="rect" coords="29,24,46,43" target="f1" />
<area shape="rect" coords="71,26,88,44" target="f3" />
<area shape="rect" coords="90,25,107,43" target="f4" />
<area shape="rect" coords="111,26,128,44" target="f5" />
<area shape="rect" coords="132,26,149,44" target="f6" />
<area shape="rect" coords="153,25,170,44" target="f7" />
<area shape="rect" coords="173,26,190,44" target="f8" />
<area shape="rect" coords="194,24,211,43" target="f9" />
<area shape="rect" coords="215,26,231,44" target="f10" />
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
<area shape="rect" coords="276,47,308,64" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="Q" />
<area shape="rect" coords="57,68,75,86" target="W" />
<area shape="rect" coords="78,67,94,85" target="E" />
<area shape="rect" coords="98,67,115,85" target="R" />
<area shape="rect" coords="119,67,136,85" target="T" />
<area shape="rect" coords="141,68,158,86" target="Y" />
<area shape="rect" coords="161,67,179,86" target="U" />
<area shape="rect" coords="182,67,199,86" target="I" />
<area shape="rect" coords="202,67,220,85" target="O" />
<area shape="rect" coords="223,68,240,86" target="P" />
<area shape="rect" coords="44,88,63,107" target="A" />
<area shape="rect" coords="65,88,84,106" target="S" />
<area shape="rect" coords="86,89,104,107" target="D" />
<area shape="rect" coords="107,89,124,107" target="F" />
<area shape="rect" coords="128,89,145,107" target="G" />
<area shape="rect" coords="149,88,165,107" target="H" />
<area shape="rect" coords="169,89,186,107" target="J" />
<area shape="rect" coords="189,89,207,107" target="K" />
<area shape="rect" coords="210,89,228,107" target="L" />
<area shape="rect" coords="273,89,311,106" target="enter" />
<area shape="rect" coords="9,110,50,127" target="shift" />
<area shape="rect" coords="8,89,41,106" target="caps" />
<area shape="rect" coords="58,110,75,128" target="Z" />
<area shape="rect" coords="79,110,96,128" target="X" />
<area shape="rect" coords="99,109,116,127" target="C" />
<area shape="rect" coords="120,110,138,128" target="V" />
<area shape="rect" coords="141,109,157,127" target="B" />
<area shape="rect" coords="162,110,179,128" target="N" />
<area shape="rect" coords="182,110,199,128" target="M" />
<area shape="rect" coords="271,109,311,128" target="symbols" />
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
<area shape="rect" coords="8,47,26,64" target="|" />
<area shape="rect" coords="28,47,45,64" target="1" />
<area shape="rect" coords="50,47,67,65" target="2" />
<area shape="rect" coords="70,46,87,65" target="3" />
<area shape="rect" coords="91,46,108,64" target="4" />
<area shape="rect" coords="111,46,129,65" target="5" />
<area shape="rect" coords="132,47,149,65" target="6" />
<area shape="rect" coords="152,47,170,64" target="7" />
<area shape="rect" coords="174,46,191,63" target="8" />
<area shape="rect" coords="194,47,211,65" target="9" />
<area shape="rect" coords="215,46,232,64" target="0" />
<area shape="rect" coords="235,47,252,65" target="-" />
<area shape="rect" coords="255,46,272,65" target="=" />
<area shape="rect" coords="244,68,261,86" target="[" />
<area shape="rect" coords="264,67,282,86" target="]" />
<area shape="rect" coords="284,68,309,86" target="#" />
<area shape="rect" coords="231,88,249,106" target=";" />
<area shape="rect" coords="251,89,269,107" target="" />
<area shape="rect" coords="202,110,219,128" target="," />
<area shape="rect" coords="223,110,241,128" target="." />
<area shape="rect" coords="243,110,261,128" target="/" />
</map>
</layout>
<layout resolution="640x480" bitmap="uppercase640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="26,23,613,37" target="display_area" />
<area shape="rect" coords="18,52,51,85" target="esc" />
<area shape="rect" coords="100,51,135,88" target="f2" />
<area shape="rect" coords="59,49,94,88" target="f1" />
<area shape="rect" coords="142,53,176,89" target="f3" />
<area shape="rect" coords="181,51,216,87" target="f4" />
<area shape="rect" coords="223,52,258,88" target="f5" />
<area shape="rect" coords="265,52,299,89" target="f6" />
<area shape="rect" coords="306,51,341,90" target="f7" />
<area shape="rect" coords="347,53,382,89" target="f8" />
<area shape="rect" coords="389,49,424,88" target="f9" />
<area shape="rect" coords="431,52,464,89" target="f10" />
<area shape="rect" coords="470,53,506,88" target="f11" />
<area shape="rect" coords="511,52,546,90" target="f12" />
<area shape="rect" coords="552,55,620,87" target="del" />
<area shape="rect" coords="553,94,618,129" target="backspace" />
<area shape="rect" coords="17,136,66,171" target="tab" />
<area shape="rect" coords="73,137,108,171" target="Q" />
<area shape="rect" coords="114,136,150,172" target="W" />
<area shape="rect" coords="157,134,189,171" target="E" />
<area shape="rect" coords="197,135,232,171" target="R" />
<area shape="rect" coords="239,135,274,172" target="T" />
<area shape="rect" coords="282,136,317,173" target="Y" />
<area shape="rect" coords="322,135,359,173" target="U" />
<area shape="rect" coords="364,134,399,172" target="I" />
<area shape="rect" coords="404,135,440,171" target="O" />
<area shape="rect" coords="446,136,480,172" target="P" />
<area shape="rect" coords="89,177,127,216" target="A" />
<area shape="rect" coords="131,177,169,214" target="S" />
<area shape="rect" coords="173,178,209,215" target="D" />
<area shape="rect" coords="215,178,250,214" target="F" />
<area shape="rect" coords="256,178,291,214" target="G" />
<area shape="rect" coords="299,176,332,214" target="H" />
<area shape="rect" coords="339,178,374,215" target="J" />
<area shape="rect" coords="379,178,415,215" target="K" />
<area shape="rect" coords="421,178,457,215" target="L" />
<area shape="rect" coords="546,179,622,214" target="enter" />
<area shape="rect" coords="19,221,101,256" target="shift" />
<area shape="rect" coords="17,179,84,213" target="caps" />
<area shape="rect" coords="117,220,152,256" target="Z" />
<area shape="rect" coords="158,220,192,256" target="X" />
<area shape="rect" coords="198,219,233,256" target="C" />
<area shape="rect" coords="240,220,276,257" target="V" />
<area shape="rect" coords="283,219,316,255" target="B" />
<area shape="rect" coords="324,220,359,256" target="N" />
<area shape="rect" coords="365,220,399,257" target="M" />
<area shape="rect" coords="542,219,623,257" target="symbols" />
<area shape="rect" coords="19,260,68,296" target="ctrl" />
<area shape="rect" coords="76,261,123,295" target="alt" />
<area shape="rect" coords="135,261,525,297" target="space" />
<area shape="rect" coords="16,95,53,129" target="|" />
<area shape="rect" coords="57,95,92,129" target="1" />
<area shape="rect" coords="100,94,134,130" target="2" />
<area shape="rect" coords="140,93,174,131" target="3" />
<area shape="rect" coords="182,93,217,130" target="4" />
<area shape="rect" coords="222,93,258,132" target="5" />
<area shape="rect" coords="265,94,299,131" target="6" />
<area shape="rect" coords="305,94,341,129" target="7" />
<area shape="rect" coords="348,93,382,128" target="8" />
<area shape="rect" coords="389,94,423,130" target="9" />
<area shape="rect" coords="431,93,465,130" target="0" />
<area shape="rect" coords="471,94,505,131" target="-" />
<area shape="rect" coords="511,93,546,131" target="=" />
<area shape="rect" coords="488,136,522,172" target="[" />
<area shape="rect" coords="529,135,565,173" target="]" />
<area shape="rect" coords="569,136,620,172" target="#" />
<area shape="rect" coords="462,177,498,214" target=";" />
<area shape="rect" coords="503,178,539,214" target="" />
<area shape="rect" coords="405,220,440,256" target="," />
<area shape="rect" coords="447,220,483,256" target="." />
<area shape="rect" coords="487,220,524,256" target="/" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
<event name="f1" type="key" code="282" ascii="315" modifiers="" />
<event name="f2" type="key" code="283" ascii="316" modifiers="" />
<event name="f3" type="key" code="284" ascii="317" modifiers="" />
<event name="f4" type="key" code="285" ascii="318" modifiers="" />
<event name="f5" type="key" code="286" ascii="319" modifiers="" />
<event name="f6" type="key" code="287" ascii="320" modifiers="" />
<event name="f7" type="key" code="288" ascii="321" modifiers="" />
<event name="f8" type="key" code="289" ascii="322" modifiers="" />
<event name="f9" type="key" code="290" ascii="323" modifiers="" />
<event name="f10" type="key" code="291" ascii="324" modifiers="" />
<event name="f11" type="key" code="292" ascii="325" modifiers="" />
<event name="f12" type="key" code="293" ascii="326" modifiers="" />
<event name="del" type="key" code="127" ascii="0" modifiers="" />
<event name="ctrl" type="modifier" modifiers="ctrl" />
<event name="alt" type="modifier" modifiers="alt" />
<event name="shift" type="modifier" modifiers="shift" />
<event name="caps" type="switch_mode" mode="lowercase" />
<event name="symbols" type="switch_mode" mode="uppercasesymbols" />
<event name="backspace" type="key" code="8" ascii="8" modifiers="" />
<event name="enter" type="key" code="13" ascii="13" modifiers="" />
<event name="|" type="key" code="124" ascii="124" modifiers="" />
<event name="-" type="key" code="45" ascii="45" modifiers="" />
<event name="=" type="key" code="61" ascii="61" modifiers="" />
<event name="[" type="key" code="91" ascii="91" modifiers="" />
<event name="]" type="key" code="93" ascii="93" modifiers="" />
<event name="#" type="key" code="35" ascii="35" modifiers="" />
<event name=";" type="key" code="59" ascii="59" modifiers="" />
<event name="'" type="key" code="39" ascii="39" modifiers="" />
<event name="," type="key" code="44" ascii="44" modifiers="" />
<event name="." type="key" code="46" ascii="46" modifiers="" />
<event name="/" type="key" code="47" ascii="47" modifiers="" />
<event name="space" type="key" code="32" ascii="32" modifiers="" />
<event name="tab" type="key" code="9" ascii="9" modifiers="" />
<event name="A" type="key" code="97" ascii="65" modifiers="shift" />
<event name="B" type="key" code="98" ascii="66" modifiers="shift" />
<event name="C" type="key" code="99" ascii="67" modifiers="shift" />
<event name="D" type="key" code="100" ascii="68" modifiers="shift" />
<event name="E" type="key" code="101" ascii="69" modifiers="shift" />
<event name="F" type="key" code="102" ascii="70" modifiers="shift" />
<event name="G" type="key" code="103" ascii="71" modifiers="shift" />
<event name="H" type="key" code="104" ascii="72" modifiers="shift" />
<event name="I" type="key" code="105" ascii="73" modifiers="shift" />
<event name="J" type="key" code="106" ascii="74" modifiers="shift" />
<event name="K" type="key" code="107" ascii="75" modifiers="shift" />
<event name="L" type="key" code="108" ascii="76" modifiers="shift" />
<event name="M" type="key" code="109" ascii="77" modifiers="shift" />
<event name="N" type="key" code="110" ascii="78" modifiers="shift" />
<event name="O" type="key" code="111" ascii="79" modifiers="shift" />
<event name="P" type="key" code="112" ascii="80" modifiers="shift" />
<event name="Q" type="key" code="113" ascii="81" modifiers="shift" />
<event name="R" type="key" code="114" ascii="82" modifiers="shift" />
<event name="S" type="key" code="115" ascii="83" modifiers="shift" />
<event name="T" type="key" code="116" ascii="84" modifiers="shift" />
<event name="U" type="key" code="117" ascii="85" modifiers="shift" />
<event name="V" type="key" code="118" ascii="86" modifiers="shift" />
<event name="W" type="key" code="119" ascii="87" modifiers="shift" />
<event name="X" type="key" code="120" ascii="88" modifiers="shift" />
<event name="Y" type="key" code="121" ascii="89" modifiers="shift" />
<event name="Z" type="key" code="122" ascii="90" modifiers="shift" />
<event name="0" type="key" code="48" ascii="48" modifiers="" />
<event name="1" type="key" code="49" ascii="49" modifiers="" />
<event name="2" type="key" code="50" ascii="50" modifiers="" />
<event name="3" type="key" code="51" ascii="51" modifiers="" />
<event name="4" type="key" code="52" ascii="52" modifiers="" />
<event name="5" type="key" code="53" ascii="53" modifiers="" />
<event name="6" type="key" code="54" ascii="54" modifiers="" />
<event name="7" type="key" code="55" ascii="55" modifiers="" />
<event name="8" type="key" code="56" ascii="56" modifiers="" />
<event name="9" type="key" code="57" ascii="57" modifiers="" />
<event name="quit" type="submit" />
</mode>
<!-- Lowercase Symbols -->
<mode name="lowercasesymbols" resolutions="320x240,640x480">
<layout resolution="320x240" bitmap="lowercase-symbols320x240.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="13,8,306,20" target="display_area" />
<area shape="rect" coords="9,26,25,42" target="esc" />
<area shape="rect" coords="50,25,67,43" target="f2" />
<area shape="rect" coords="29,24,46,43" target="f1" />
<area shape="rect" coords="71,26,88,44" target="f3" />
<area shape="rect" coords="90,25,107,43" target="f4" />
<area shape="rect" coords="111,26,128,44" target="f5" />
<area shape="rect" coords="132,26,149,44" target="f6" />
<area shape="rect" coords="153,25,170,44" target="f7" />
<area shape="rect" coords="173,26,190,44" target="f8" />
<area shape="rect" coords="194,24,211,43" target="f9" />
<area shape="rect" coords="215,26,231,44" target="f10" />
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
<area shape="rect" coords="8,47,26,64" target="¬" />
<area shape="rect" coords="28,47,45,64" target="!" />
<area shape="rect" coords="50,47,67,65" target="quote" />
<area shape="rect" coords="70,46,87,65" target="£" />
<area shape="rect" coords="91,46,108,64" target="$" />
<area shape="rect" coords="111,46,129,65" target="%" />
<area shape="rect" coords="132,47,149,65" target="^" />
<area shape="rect" coords="152,47,170,64" target="&amp;" />
<area shape="rect" coords="174,46,191,63" target="*" />
<area shape="rect" coords="194,47,211,65" target="(" />
<area shape="rect" coords="215,46,232,64" target=")" />
<area shape="rect" coords="235,47,252,65" target="_" />
<area shape="rect" coords="255,46,272,65" target="+" />
<area shape="rect" coords="276,47,308,64" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="q" />
<area shape="rect" coords="57,68,75,86" target="w" />
<area shape="rect" coords="78,67,94,85" target="e" />
<area shape="rect" coords="98,67,115,85" target="r" />
<area shape="rect" coords="119,67,136,85" target="t" />
<area shape="rect" coords="141,68,158,86" target="y" />
<area shape="rect" coords="161,67,179,86" target="u" />
<area shape="rect" coords="182,67,199,86" target="i" />
<area shape="rect" coords="202,67,220,85" target="o" />
<area shape="rect" coords="223,68,240,86" target="p" />
<area shape="rect" coords="244,68,261,86" target="{" />
<area shape="rect" coords="264,67,282,86" target="}" />
<area shape="rect" coords="284,68,309,86" target="~" />
<area shape="rect" coords="8,89,41,106" target="caps" />
<area shape="rect" coords="44,88,63,107" target="a" />
<area shape="rect" coords="65,88,84,106" target="s" />
<area shape="rect" coords="86,89,104,107" target="d" />
<area shape="rect" coords="107,89,124,107" target="f" />
<area shape="rect" coords="128,89,145,107" target="g" />
<area shape="rect" coords="149,88,165,107" target="h" />
<area shape="rect" coords="169,89,186,107" target="j" />
<area shape="rect" coords="189,89,207,107" target="k" />
<area shape="rect" coords="210,89,228,107" target="l" />
<area shape="rect" coords="231,88,249,106" target=":" />
<area shape="rect" coords="251,89,269,107" target="@" />
<area shape="rect" coords="273,89,311,106" target="enter" />
<area shape="rect" coords="9,110,50,127" target="shift" />
<area shape="rect" coords="58,110,75,128" target="z" />
<area shape="rect" coords="79,110,96,128" target="x" />
<area shape="rect" coords="99,109,116,127" target="c" />
<area shape="rect" coords="120,110,138,128" target="v" />
<area shape="rect" coords="141,109,157,127" target="b" />
<area shape="rect" coords="162,110,179,128" target="n" />
<area shape="rect" coords="182,110,199,128" target="m" />
<area shape="rect" coords="202,110,219,128" target="&lt;" />
<area shape="rect" coords="223,110,241,128" target="&gt;" />
<area shape="rect" coords="243,110,261,128" target="?" />
<area shape="rect" coords="271,109,311,128" target="symbols" />
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
</map>
</layout>
<layout resolution="640x480" bitmap="lowercase-symbols640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="26,23,613,37" target="display_area" />
<area shape="rect" coords="18,52,51,85" target="esc" />
<area shape="rect" coords="100,51,135,88" target="f2" />
<area shape="rect" coords="59,49,94,88" target="f1" />
<area shape="rect" coords="142,53,176,89" target="f3" />
<area shape="rect" coords="181,51,216,87" target="f4" />
<area shape="rect" coords="223,52,258,88" target="f5" />
<area shape="rect" coords="265,52,299,89" target="f6" />
<area shape="rect" coords="306,51,341,90" target="f7" />
<area shape="rect" coords="347,53,382,89" target="f8" />
<area shape="rect" coords="389,49,424,88" target="f9" />
<area shape="rect" coords="431,52,464,89" target="f10" />
<area shape="rect" coords="470,53,506,88" target="f11" />
<area shape="rect" coords="511,52,546,90" target="f12" />
<area shape="rect" coords="552,55,620,87" target="del" />
<area shape="rect" coords="16,95,53,129" target="¬" />
<area shape="rect" coords="57,95,92,129" target="!" />
<area shape="rect" coords="100,94,134,130" target="quote" />
<area shape="rect" coords="140,93,174,131" target="£" />
<area shape="rect" coords="182,93,217,130" target="$" />
<area shape="rect" coords="222,93,258,132" target="%" />
<area shape="rect" coords="265,94,299,131" target="^" />
<area shape="rect" coords="305,94,341,129" target="&amp;" />
<area shape="rect" coords="348,93,382,128" target="*" />
<area shape="rect" coords="389,94,423,130" target="(" />
<area shape="rect" coords="431,93,465,130" target=")" />
<area shape="rect" coords="471,94,505,131" target="_" />
<area shape="rect" coords="511,93,546,131" target="+" />
<area shape="rect" coords="553,94,618,129" target="backspace" />
<area shape="rect" coords="17,136,66,171" target="tab" />
<area shape="rect" coords="73,137,108,171" target="q" />
<area shape="rect" coords="114,136,150,172" target="w" />
<area shape="rect" coords="157,134,189,171" target="e" />
<area shape="rect" coords="197,135,232,171" target="r" />
<area shape="rect" coords="239,135,274,172" target="t" />
<area shape="rect" coords="282,136,317,173" target="y" />
<area shape="rect" coords="322,135,359,173" target="u" />
<area shape="rect" coords="364,134,399,172" target="i" />
<area shape="rect" coords="404,135,440,171" target="o" />
<area shape="rect" coords="446,136,480,172" target="p" />
<area shape="rect" coords="488,136,522,172" target="{" />
<area shape="rect" coords="529,135,565,173" target="}" />
<area shape="rect" coords="569,136,620,172" target="~" />
<area shape="rect" coords="17,179,84,213" target="caps" />
<area shape="rect" coords="89,177,127,216" target="a" />
<area shape="rect" coords="131,177,169,214" target="s" />
<area shape="rect" coords="173,178,209,215" target="d" />
<area shape="rect" coords="215,178,250,214" target="f" />
<area shape="rect" coords="256,178,291,214" target="g" />
<area shape="rect" coords="299,176,332,214" target="h" />
<area shape="rect" coords="339,178,374,215" target="j" />
<area shape="rect" coords="379,178,415,215" target="k" />
<area shape="rect" coords="421,178,457,215" target="l" />
<area shape="rect" coords="462,177,498,214" target=":" />
<area shape="rect" coords="503,178,539,214" target="@" />
<area shape="rect" coords="546,179,622,214" target="enter" />
<area shape="rect" coords="19,221,101,256" target="shift" />
<area shape="rect" coords="117,220,152,256" target="z" />
<area shape="rect" coords="158,220,192,256" target="x" />
<area shape="rect" coords="198,219,233,256" target="c" />
<area shape="rect" coords="240,220,276,257" target="v" />
<area shape="rect" coords="283,219,316,255" target="b" />
<area shape="rect" coords="324,220,359,256" target="n" />
<area shape="rect" coords="365,220,399,257" target="m" />
<area shape="rect" coords="405,220,440,256" target="&lt;" />
<area shape="rect" coords="447,220,483,256" target="&gt;" />
<area shape="rect" coords="487,220,524,256" target="?" />
<area shape="rect" coords="542,219,623,257" target="symbols" />
<area shape="rect" coords="19,260,68,296" target="ctrl" />
<area shape="rect" coords="76,261,123,295" target="alt" />
<area shape="rect" coords="135,261,525,297" target="space" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
<event name="f1" type="key" code="282" ascii="315" modifiers="" />
<event name="f2" type="key" code="283" ascii="316" modifiers="" />
<event name="f3" type="key" code="284" ascii="317" modifiers="" />
<event name="f4" type="key" code="285" ascii="318" modifiers="" />
<event name="f5" type="key" code="286" ascii="319" modifiers="" />
<event name="f6" type="key" code="287" ascii="320" modifiers="" />
<event name="f7" type="key" code="288" ascii="321" modifiers="" />
<event name="f8" type="key" code="289" ascii="322" modifiers="" />
<event name="f9" type="key" code="290" ascii="323" modifiers="" />
<event name="f10" type="key" code="291" ascii="324" modifiers="" />
<event name="f11" type="key" code="292" ascii="325" modifiers="" />
<event name="f12" type="key" code="293" ascii="326" modifiers="" />
<event name="del" type="key" code="127" ascii="0" modifiers="" />
<event name="ctrl" type="modifier" modifiers="ctrl" />
<event name="alt" type="modifier" modifiers="alt" />
<event name="shift" type="modifier" modifiers="shift" />
<event name="symbols" type="switch_mode" mode="lowercase" />
<event name="caps" type="switch_mode" mode="uppercasesymbols" />
<event name="backspace" type="key" code="8" ascii="8" modifiers="" />
<event name="enter" type="key" code="13" ascii="13" modifiers="" />
<event name="quote" type="key" code="34" ascii="34" modifiers="" />
<event name="£" type="key" code="163" ascii="163" modifiers="" />
<event name="$" type="key" code="36" ascii="36" modifiers="" />
<event name="%" type="key" code="37" ascii="37" modifiers="" />
<event name="^" type="key" code="94" ascii="94" modifiers="" />
<event name="&amp;" type="key" code="38" ascii="38" modifiers="" />
<event name="*" type="key" code="42" ascii="42" modifiers="" />
<event name="(" type="key" code="40" ascii="40" modifiers="" />
<event name=")" type="key" code="41" ascii="41" modifiers="" />
<event name="_" type="key" code="95" ascii="95" modifiers="" />
<event name="+" type="key" code="43" ascii="43" modifiers="" />
<event name="¬" type="key" code="172" ascii="172" modifiers="" />
<event name="!" type="key" code="33" ascii="33" modifiers="" />
<event name="{" type="key" code="123" ascii="123" modifiers="" />
<event name="}" type="key" code="125" ascii="125" modifiers="" />
<event name="~" type="key" code="126" ascii="126" modifiers="" />
<event name=":" type="key" code="58" ascii="58" modifiers="" />
<event name="@" type="key" code="64" ascii="64" modifiers="" />
<event name="&lt;" type="key" code="60" ascii="60" modifiers="" />
<event name="&gt;" type="key" code="62" ascii="62" modifiers="" />
<event name="?" type="key" code="63" ascii="63" modifiers="" />
<event name="space" type="key" code="32" ascii="32" modifiers="" />
<event name="tab" type="key" code="9" ascii="9" modifiers="" />
<event name="a" type="key" code="97" ascii="97" modifiers="" />
<event name="b" type="key" code="98" ascii="98" modifiers="" />
<event name="c" type="key" code="99" ascii="99" modifiers="" />
<event name="d" type="key" code="100" ascii="100" modifiers="" />
<event name="e" type="key" code="101" ascii="101" modifiers="" />
<event name="f" type="key" code="102" ascii="102" modifiers="" />
<event name="g" type="key" code="103" ascii="103" modifiers="" />
<event name="h" type="key" code="104" ascii="104" modifiers="" />
<event name="i" type="key" code="105" ascii="105" modifiers="" />
<event name="j" type="key" code="106" ascii="106" modifiers="" />
<event name="k" type="key" code="107" ascii="107" modifiers="" />
<event name="l" type="key" code="108" ascii="108" modifiers="" />
<event name="m" type="key" code="109" ascii="109" modifiers="" />
<event name="n" type="key" code="110" ascii="110" modifiers="" />
<event name="o" type="key" code="111" ascii="111" modifiers="" />
<event name="p" type="key" code="112" ascii="112" modifiers="" />
<event name="q" type="key" code="113" ascii="113" modifiers="" />
<event name="r" type="key" code="114" ascii="114" modifiers="" />
<event name="s" type="key" code="115" ascii="115" modifiers="" />
<event name="t" type="key" code="116" ascii="116" modifiers="" />
<event name="u" type="key" code="117" ascii="117" modifiers="" />
<event name="v" type="key" code="118" ascii="118" modifiers="" />
<event name="w" type="key" code="119" ascii="119" modifiers="" />
<event name="x" type="key" code="120" ascii="120" modifiers="" />
<event name="y" type="key" code="121" ascii="121" modifiers="" />
<event name="z" type="key" code="122" ascii="122" modifiers="" />
<event name="quit" type="submit" />
</mode>
<!-- Uppercase Symbols -->
<mode name="uppercasesymbols" resolutions="320x240,640x480">
<layout resolution="320x240" bitmap="uppercase-symbols320x240.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="13,8,306,20" target="display_area" />
<area shape="rect" coords="9,26,25,42" target="esc" />
<area shape="rect" coords="50,25,67,43" target="f2" />
<area shape="rect" coords="29,24,46,43" target="f1" />
<area shape="rect" coords="71,26,88,44" target="f3" />
<area shape="rect" coords="90,25,107,43" target="f4" />
<area shape="rect" coords="111,26,128,44" target="f5" />
<area shape="rect" coords="132,26,149,44" target="f6" />
<area shape="rect" coords="153,25,170,44" target="f7" />
<area shape="rect" coords="173,26,190,44" target="f8" />
<area shape="rect" coords="194,24,211,43" target="f9" />
<area shape="rect" coords="215,26,231,44" target="f10" />
<area shape="rect" coords="235,26,253,43" target="f11" />
<area shape="rect" coords="255,26,272,45" target="f12" />
<area shape="rect" coords="276,27,310,43" target="del" />
<area shape="rect" coords="8,47,26,64" target="¬" />
<area shape="rect" coords="28,47,45,64" target="!" />
<area shape="rect" coords="50,47,67,65" target="quote" />
<area shape="rect" coords="70,46,87,65" target="£" />
<area shape="rect" coords="91,46,108,64" target="$" />
<area shape="rect" coords="111,46,129,65" target="%" />
<area shape="rect" coords="132,47,149,65" target="^" />
<area shape="rect" coords="152,47,170,64" target="&amp;" />
<area shape="rect" coords="174,46,191,63" target="*" />
<area shape="rect" coords="194,47,211,65" target="(" />
<area shape="rect" coords="215,46,232,64" target=")" />
<area shape="rect" coords="235,47,252,65" target="_" />
<area shape="rect" coords="255,46,272,65" target="+" />
<area shape="rect" coords="276,47,308,64" target="backspace" />
<area shape="rect" coords="8,68,32,85" target="tab" />
<area shape="rect" coords="36,68,53,85" target="Q" />
<area shape="rect" coords="57,68,75,86" target="W" />
<area shape="rect" coords="78,67,94,85" target="E" />
<area shape="rect" coords="98,67,115,85" target="R" />
<area shape="rect" coords="119,67,136,85" target="T" />
<area shape="rect" coords="141,68,158,86" target="Y" />
<area shape="rect" coords="161,67,179,86" target="U" />
<area shape="rect" coords="182,67,199,86" target="I" />
<area shape="rect" coords="202,67,220,85" target="O" />
<area shape="rect" coords="223,68,240,86" target="P" />
<area shape="rect" coords="244,68,261,86" target="{" />
<area shape="rect" coords="264,67,282,86" target="}" />
<area shape="rect" coords="284,68,309,86" target="~" />
<area shape="rect" coords="8,89,41,106" target="caps" />
<area shape="rect" coords="44,88,63,107" target="A" />
<area shape="rect" coords="65,88,84,106" target="S" />
<area shape="rect" coords="86,89,104,107" target="D" />
<area shape="rect" coords="107,89,124,107" target="F" />
<area shape="rect" coords="128,89,145,107" target="G" />
<area shape="rect" coords="149,88,165,107" target="H" />
<area shape="rect" coords="169,89,186,107" target="J" />
<area shape="rect" coords="189,89,207,107" target="K" />
<area shape="rect" coords="210,89,228,107" target="L" />
<area shape="rect" coords="231,88,249,106" target=":" />
<area shape="rect" coords="251,89,269,107" target="@" />
<area shape="rect" coords="273,89,311,106" target="enter" />
<area shape="rect" coords="9,110,50,127" target="shift" />
<area shape="rect" coords="58,110,75,128" target="z" />
<area shape="rect" coords="79,110,96,128" target="x" />
<area shape="rect" coords="99,109,116,127" target="c" />
<area shape="rect" coords="120,110,138,128" target="v" />
<area shape="rect" coords="141,109,157,127" target="b" />
<area shape="rect" coords="162,110,179,128" target="n" />
<area shape="rect" coords="182,110,199,128" target="m" />
<area shape="rect" coords="202,110,219,128" target="&lt;" />
<area shape="rect" coords="223,110,241,128" target="&gt;" />
<area shape="rect" coords="243,110,261,128" target="?" />
<area shape="rect" coords="271,109,311,128" target="symbols" />
<area shape="rect" coords="9,130,33,148" target="ctrl" />
<area shape="rect" coords="38,130,61,147" target="alt" />
<area shape="rect" coords="67,130,262,148" target="space" />
</map>
</layout>
<layout resolution="640x480" bitmap="uppercase-symbols640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="rect" coords="26,23,613,37" target="display_area" />
<area shape="rect" coords="18,52,51,85" target="esc" />
<area shape="rect" coords="100,51,135,88" target="f2" />
<area shape="rect" coords="59,49,94,88" target="f1" />
<area shape="rect" coords="142,53,176,89" target="f3" />
<area shape="rect" coords="181,51,216,87" target="f4" />
<area shape="rect" coords="223,52,258,88" target="f5" />
<area shape="rect" coords="265,52,299,89" target="f6" />
<area shape="rect" coords="306,51,341,90" target="f7" />
<area shape="rect" coords="347,53,382,89" target="f8" />
<area shape="rect" coords="389,49,424,88" target="f9" />
<area shape="rect" coords="431,52,464,89" target="f10" />
<area shape="rect" coords="470,53,506,88" target="f11" />
<area shape="rect" coords="511,52,546,90" target="f12" />
<area shape="rect" coords="552,55,620,87" target="del" />
<area shape="rect" coords="16,95,53,129" target="¬" />
<area shape="rect" coords="57,95,92,129" target="!" />
<area shape="rect" coords="100,94,134,130" target="quote" />
<area shape="rect" coords="140,93,174,131" target="£" />
<area shape="rect" coords="182,93,217,130" target="$" />
<area shape="rect" coords="222,93,258,132" target="%" />
<area shape="rect" coords="265,94,299,131" target="^" />
<area shape="rect" coords="305,94,341,129" target="&amp;" />
<area shape="rect" coords="348,93,382,128" target="*" />
<area shape="rect" coords="389,94,423,130" target="(" />
<area shape="rect" coords="431,93,465,130" target=")" />
<area shape="rect" coords="471,94,505,131" target="_" />
<area shape="rect" coords="511,93,546,131" target="+" />
<area shape="rect" coords="553,94,618,129" target="backspace" />
<area shape="rect" coords="17,136,66,171" target="tab" />
<area shape="rect" coords="73,137,108,171" target="Q" />
<area shape="rect" coords="114,136,150,172" target="W" />
<area shape="rect" coords="157,134,189,171" target="E" />
<area shape="rect" coords="197,135,232,171" target="R" />
<area shape="rect" coords="239,135,274,172" target="T" />
<area shape="rect" coords="282,136,317,173" target="Y" />
<area shape="rect" coords="322,135,359,173" target="U" />
<area shape="rect" coords="364,134,399,172" target="I" />
<area shape="rect" coords="404,135,440,171" target="O" />
<area shape="rect" coords="446,136,480,172" target="P" />
<area shape="rect" coords="488,136,522,172" target="{" />
<area shape="rect" coords="529,135,565,173" target="}" />
<area shape="rect" coords="569,136,620,172" target="~" />
<area shape="rect" coords="17,179,84,213" target="caps" />
<area shape="rect" coords="89,177,127,216" target="A" />
<area shape="rect" coords="131,177,169,214" target="S" />
<area shape="rect" coords="173,178,209,215" target="D" />
<area shape="rect" coords="215,178,250,214" target="F" />
<area shape="rect" coords="256,178,291,214" target="G" />
<area shape="rect" coords="299,176,332,214" target="H" />
<area shape="rect" coords="339,178,374,215" target="J" />
<area shape="rect" coords="379,178,415,215" target="K" />
<area shape="rect" coords="421,178,457,215" target="L" />
<area shape="rect" coords="462,177,498,214" target=":" />
<area shape="rect" coords="503,178,539,214" target="@" />
<area shape="rect" coords="546,179,622,214" target="enter" />
<area shape="rect" coords="19,221,101,256" target="shift" />
<area shape="rect" coords="117,220,152,256" target="z" />
<area shape="rect" coords="158,220,192,256" target="x" />
<area shape="rect" coords="198,219,233,256" target="c" />
<area shape="rect" coords="240,220,276,257" target="v" />
<area shape="rect" coords="283,219,316,255" target="b" />
<area shape="rect" coords="324,220,359,256" target="n" />
<area shape="rect" coords="365,220,399,257" target="m" />
<area shape="rect" coords="405,220,440,256" target="&lt;" />
<area shape="rect" coords="447,220,483,256" target="&gt;" />
<area shape="rect" coords="487,220,524,256" target="?" />
<area shape="rect" coords="542,219,623,257" target="symbols" />
<area shape="rect" coords="19,260,68,296" target="ctrl" />
<area shape="rect" coords="76,261,123,295" target="alt" />
<area shape="rect" coords="135,261,525,297" target="space" />
</map>
</layout>
<event name="esc" type="key" code="27" ascii="27" modifiers="" />
<event name="f1" type="key" code="282" ascii="315" modifiers="" />
<event name="f2" type="key" code="283" ascii="316" modifiers="" />
<event name="f3" type="key" code="284" ascii="317" modifiers="" />
<event name="f4" type="key" code="285" ascii="318" modifiers="" />
<event name="f5" type="key" code="286" ascii="319" modifiers="" />
<event name="f6" type="key" code="287" ascii="320" modifiers="" />
<event name="f7" type="key" code="288" ascii="321" modifiers="" />
<event name="f8" type="key" code="289" ascii="322" modifiers="" />
<event name="f9" type="key" code="290" ascii="323" modifiers="" />
<event name="f10" type="key" code="291" ascii="324" modifiers="" />
<event name="f11" type="key" code="292" ascii="325" modifiers="" />
<event name="f12" type="key" code="293" ascii="326" modifiers="" />
<event name="del" type="key" code="127" ascii="0" modifiers="" />
<event name="ctrl" type="modifier" modifiers="ctrl" />
<event name="alt" type="modifier" modifiers="alt" />
<event name="shift" type="switch_mode" mode="shiftlowercase" />
<event name="caps" type="switch_mode" mode="lowercasesymbols" />
<event name="symbols" type="switch_mode" mode="uppercase" />
<event name="backspace" type="key" code="8" ascii="8" modifiers="" />
<event name="enter" type="key" code="13" ascii="13" modifiers="" />
<event name="quote" type="key" code="34" ascii="34" modifiers="" />
<event name="£" type="key" code="163" ascii="163" modifiers="" />
<event name="$" type="key" code="36" ascii="36" modifiers="" />
<event name="%" type="key" code="37" ascii="37" modifiers="" />
<event name="^" type="key" code="94" ascii="94" modifiers="" />
<event name="&amp;" type="key" code="38" ascii="38" modifiers="" />
<event name="*" type="key" code="42" ascii="42" modifiers="" />
<event name="(" type="key" code="40" ascii="40" modifiers="" />
<event name=")" type="key" code="41" ascii="41" modifiers="" />
<event name="_" type="key" code="95" ascii="95" modifiers="" />
<event name="+" type="key" code="43" ascii="43" modifiers="" />
<event name="¬" type="key" code="172" ascii="172" modifiers="" />
<event name="!" type="key" code="33" ascii="33" modifiers="" />
<event name="{" type="key" code="123" ascii="123" modifiers="" />
<event name="}" type="key" code="125" ascii="125" modifiers="" />
<event name="~" type="key" code="126" ascii="126" modifiers="" />
<event name=":" type="key" code="58" ascii="58" modifiers="" />
<event name="@" type="key" code="64" ascii="64" modifiers="" />
<event name="&lt;" type="key" code="60" ascii="60" modifiers="" />
<event name="&gt;" type="key" code="62" ascii="62" modifiers="" />
<event name="?" type="key" code="63" ascii="63" modifiers="" />
<event name="space" type="key" code="32" ascii="32" modifiers="" />
<event name="tab" type="key" code="9" ascii="9" modifiers="" />
<event name="A" type="key" code="97" ascii="65" modifiers="shift" />
<event name="B" type="key" code="98" ascii="66" modifiers="shift" />
<event name="C" type="key" code="99" ascii="67" modifiers="shift" />
<event name="D" type="key" code="100" ascii="68" modifiers="shift" />
<event name="E" type="key" code="101" ascii="69" modifiers="shift" />
<event name="F" type="key" code="102" ascii="70" modifiers="shift" />
<event name="G" type="key" code="103" ascii="71" modifiers="shift" />
<event name="H" type="key" code="104" ascii="72" modifiers="shift" />
<event name="I" type="key" code="105" ascii="73" modifiers="shift" />
<event name="J" type="key" code="106" ascii="74" modifiers="shift" />
<event name="K" type="key" code="107" ascii="75" modifiers="shift" />
<event name="L" type="key" code="108" ascii="76" modifiers="shift" />
<event name="M" type="key" code="109" ascii="77" modifiers="shift" />
<event name="N" type="key" code="110" ascii="78" modifiers="shift" />
<event name="O" type="key" code="111" ascii="79" modifiers="shift" />
<event name="P" type="key" code="112" ascii="80" modifiers="shift" />
<event name="Q" type="key" code="113" ascii="81" modifiers="shift" />
<event name="R" type="key" code="114" ascii="82" modifiers="shift" />
<event name="S" type="key" code="115" ascii="83" modifiers="shift" />
<event name="T" type="key" code="116" ascii="84" modifiers="shift" />
<event name="U" type="key" code="117" ascii="85" modifiers="shift" />
<event name="V" type="key" code="118" ascii="86" modifiers="shift" />
<event name="W" type="key" code="119" ascii="87" modifiers="shift" />
<event name="X" type="key" code="120" ascii="88" modifiers="shift" />
<event name="Y" type="key" code="121" ascii="89" modifiers="shift" />
<event name="Z" type="key" code="122" ascii="90" modifiers="shift" />
<event name="0" type="key" code="48" ascii="48" modifiers="" />
<event name="1" type="key" code="49" ascii="49" modifiers="" />
<event name="2" type="key" code="50" ascii="50" modifiers="" />
<event name="3" type="key" code="51" ascii="51" modifiers="" />
<event name="4" type="key" code="52" ascii="52" modifiers="" />
<event name="5" type="key" code="53" ascii="53" modifiers="" />
<event name="6" type="key" code="54" ascii="54" modifiers="" />
<event name="7" type="key" code="55" ascii="55" modifiers="" />
<event name="8" type="key" code="56" ascii="56" modifiers="" />
<event name="9" type="key" code="57" ascii="57" modifiers="" />
<event name="quit" type="submit" />
</mode>
</keyboard>

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python
# encoding: utf-8
import sys
import re
import os
import zipfile
try:
import zlib
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
PACK_FILE_EXTENSIONS = ('.xml', '.bmp')
def buildPack(packName):
if not os.path.isdir(packName):
print ("Invalid pack name: " + packName)
return
zf = zipfile.ZipFile(packName + ".zip", 'w')
zf.compress_type = zipfile.ZIP_DEFLATED
print ("Building '" + packName + "' pack:")
os.chdir(packName)
for filename in os.listdir('.'):
if os.path.isfile(filename) and not filename[0] == '.' and filename.endswith(PACK_FILE_EXTENSIONS):
zf.write(filename, './' + filename, compress_type=compression)
print (" Adding file: " + filename)
os.chdir('../')
zf.close()
def buildAllPacks():
for f in os.listdir('.'):
if os.path.isdir(os.path.join('.', f)) and not f[0] == '.':
buildPack(f)
def printUsage():
print ("===============================================")
print ("ScummVM Virtual Keyboard Pack Generation Script")
print ("===============================================")
print ("Usage:")
print ("vkeybdpack.py makeall")
print (" Builds all the available pack.\n")
print ("vkeybdpack.py make [packname]")
print (" Builds the pack called 'packname'.\n")
def main():
if len(sys.argv) == 2 and sys.argv[1] == "makeall":
buildAllPacks()
elif len(sys.argv) == 3 and sys.argv[1] == "make":
buildPack(sys.argv[2])
else:
printUsage()
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,59 @@
/* 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$
*
*/
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/polygon.h"
namespace Common {
bool Polygon::contains(int16 x, int16 y) const {
int yflag0;
int yflag1;
bool inside_flag = false;
unsigned int pt;
const Point *vtx0 = &_points[_points.size() - 1];
const Point *vtx1 = &_points[0];
yflag0 = (vtx0->y >= y);
for (pt = 0; pt < _points.size(); pt++, vtx1++) {
yflag1 = (vtx1->y >= y);
if (yflag0 != yflag1) {
if (((vtx1->y - y) * (vtx0->x - vtx1->x) >=
(vtx1->x - x) * (vtx0->y - vtx1->y)) == yflag1) {
inside_flag = !inside_flag;
}
}
yflag0 = yflag1;
vtx0 = vtx1;
}
return inside_flag;
}
} // end of namespace Common
#endif // #ifdef ENABLE_VKEYBD

114
backends/vkeybd/polygon.h Normal file
View file

@ -0,0 +1,114 @@
/* 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 COMMON_POLYGON_H
#define COMMON_POLYGON_H
#ifdef ENABLE_VKEYBD
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
namespace Common {
struct Polygon {
Polygon() {}
Polygon(Array<Point> p) : _points(p) {
for (uint i = 0; i < p.size(); i++) {
_bound.extend(Rect(p[i].x, p[i].y, p[i].x, p[i].y));
}
}
Polygon(Point *p, int n) {
for (int i = 0; i < n; i++) {
addPoint(p[i]);
}
}
void addPoint(const Point& p) {
_points.push_back(p);
_bound.extend(Rect(p.x, p.y, p.x, p.y));
}
void addPoint(int16 x, int16 y) {
addPoint(Point(x,y));
}
uint getPointCount() {
return _points.size();
}
/**
* Check if given position is inside this polygon.
*
* @param x the horizontal position to check
* @param y the vertical position to check
* @return true if the given position is inside this polygon, false otherwise
*/
bool contains(int16 x, int16 y) const;
/**
* Check if given point is inside this polygon.
*
* @param p the point to check
* @return true if the given point is inside this polygon, false otherwise
*/
bool contains(const Point &p) const {
return contains(p.x, p.y);
}
void moveTo(int16 x, int16 y) {
int16 dx = x - ((_bound.right + _bound.left) / 2);
int16 dy = y - ((_bound.bottom + _bound.top) / 2);
translate(dx, dy);
}
void moveTo(const Point &p) {
moveTo(p.x, p.y);
}
void translate(int16 dx, int16 dy) {
Array<Point>::iterator it;
for (it = _points.begin(); it != _points.end(); it++) {
it->x += dx;
it->y += dy;
}
}
Rect getBoundingRect() const {
return _bound;
}
private:
Array<Point> _points;
Rect _bound;
};
} // end of namespace Common
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef COMMON_POLYGON_H

View file

@ -0,0 +1,474 @@
/* 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$
*
*/
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/virtual-keyboard-gui.h"
#include "graphics/cursorman.h"
#include "gui/GuiManager.h"
namespace Common {
static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, OverlayColor transparent) {
if (surf_dst->bytesPerPixel != sizeof(OverlayColor) || surf_src->bytesPerPixel != sizeof(OverlayColor))
return;
const OverlayColor *src = (const OverlayColor *)surf_src->pixels;
int blitW = surf_src->w;
int blitH = surf_src->h;
// clip co-ordinates
if (x < 0) {
blitW += x;
src -= x;
x = 0;
}
if (y < 0) {
blitH += y;
src -= y * surf_src->w;
y = 0;
}
if (blitW > surf_dst->w - x)
blitW = surf_dst->w - x;
if (blitH > surf_dst->h - y)
blitH = surf_dst->h - y;
if (blitW <= 0 || blitH <= 0)
return;
OverlayColor *dst = (OverlayColor *)surf_dst->getBasePtr(x, y);
int dstAdd = surf_dst->w - blitW;
int srcAdd = surf_src->w - blitW;
for (int i = 0; i < blitH; ++i) {
for (int j = 0; j < blitW; ++j, ++dst, ++src) {
OverlayColor col = *src;
if (col != transparent)
*dst = col;
}
dst += dstAdd;
src += srcAdd;
}
}
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
: _kbd(kbd), _displaying(false), _drag(false),
_drawCaret(false), _displayEnabled(false), _firstRun(true),
_cursorAnimateTimer(0), _cursorAnimateCounter(0) {
assert(_kbd);
assert(g_system);
_system = g_system;
_lastScreenChanged = _system->getScreenChangeID();
_screenW = _system->getOverlayWidth();
_screenH = _system->getOverlayHeight();
memset(_cursor, 0xFF, sizeof(_cursor));
}
VirtualKeyboardGUI::~VirtualKeyboardGUI() {
_overlayBackup.free();
_dispSurface.free();
}
void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
assert(mode->image);
_kbdSurface = mode->image;
_kbdTransparentColor = mode->transparentColor;
_kbdBound.setWidth(_kbdSurface->w);
_kbdBound.setHeight(_kbdSurface->h);
setupDisplayArea(mode->displayArea, mode->displayFontColor);
if (_displaying) {
extendDirtyRect(_kbdBound);
redraw();
}
}
void VirtualKeyboardGUI::setupDisplayArea(Rect& r, OverlayColor forecolor) {
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
if (!fontIsSuitable(_dispFont, r)) {
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
if (!fontIsSuitable(_dispFont, r)) {
/* FIXME: We 'ab'use the kConsoleFont to get a font that fits in a small display_area on 320*240 keyboard images */
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont);
if (!fontIsSuitable(_dispFont, r)) {
_displayEnabled = false;
return;
}
}
}
_dispX = _kbdBound.left + r.left;
_dispY = _kbdBound.top + r.top + (r.height() - _dispFont->getFontHeight()) / 2;
_dispI = 0;
_dispForeColor = forecolor;
_dispBackColor = _dispForeColor + 0xFF;
_dispSurface.create(r.width(), _dispFont->getFontHeight(), sizeof(OverlayColor));
_dispSurface.fillRect(Rect(_dispSurface.w, _dispSurface.h), _dispBackColor);
_displayEnabled = true;
}
bool VirtualKeyboardGUI::fontIsSuitable(const Graphics::Font *font, const Rect& rect) {
return (font->getMaxCharWidth() < rect.width() &&
font->getFontHeight() < rect.height());
}
void VirtualKeyboardGUI::checkScreenChanged() {
if (_lastScreenChanged != _system->getScreenChangeID())
screenChanged();
}
void VirtualKeyboardGUI::initSize(int16 w, int16 h) {
_screenW = w;
_screenH = h;
}
void VirtualKeyboardGUI::run() {
if (_firstRun) {
_firstRun = false;
moveToDefaultPosition();
}
if (!g_gui.isActive()) {
_system->showOverlay();
_system->clearOverlay();
}
_overlayBackup.create(_screenW, _screenH, sizeof(OverlayColor));
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
setupCursor();
forceRedraw();
_displaying = true;
mainLoop();
removeCursor();
_system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h);
if (!g_gui.isActive()) _system->hideOverlay();
_overlayBackup.free();
_dispSurface.free();
}
void VirtualKeyboardGUI::close() {
_displaying = false;
}
void VirtualKeyboardGUI::reset() {
_kbdBound.left = _kbdBound.top
= _kbdBound.right = _kbdBound.bottom = 0;
_displaying = _drag = false;
_firstRun = true;
_lastScreenChanged = _system->getScreenChangeID();
_kbdSurface = 0;
}
void VirtualKeyboardGUI::moveToDefaultPosition()
{
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
int16 x = 0, y = 0;
if (_screenW != kbdW) {
switch (_kbd->_hAlignment) {
case VirtualKeyboard::kAlignLeft:
x = 0;
break;
case VirtualKeyboard::kAlignCentre:
x = (_screenW - kbdW) / 2;
break;
case VirtualKeyboard::kAlignRight:
x = _screenW - kbdW;
break;
}
}
if (_screenH != kbdH) {
switch (_kbd->_vAlignment) {
case VirtualKeyboard::kAlignTop:
y = 0;
break;
case VirtualKeyboard::kAlignMiddle:
y = (_screenH - kbdH) / 2;
break;
case VirtualKeyboard::kAlignBottom:
y = _screenH - kbdH;
break;
}
}
move(x, y);
}
void VirtualKeyboardGUI::move(int16 x, int16 y) {
// add old position to dirty area
if (_displaying) extendDirtyRect(_kbdBound);
// snap to edge of screen
if (ABS(x) < SNAP_WIDTH)
x = 0;
int16 x2 = _screenW - _kbdBound.width();
if (ABS(x - x2) < SNAP_WIDTH)
x = x2;
if (ABS(y) < SNAP_WIDTH)
y = 0;
int16 y2 = _screenH - _kbdBound.height();
if (ABS(y - y2) < SNAP_WIDTH)
y = y2;
_dispX += x - _kbdBound.left;
_dispY += y - _kbdBound.top;
_kbdBound.moveTo(x, y);
if (_displaying) {
// add new position to dirty area
extendDirtyRect(_kbdBound);
redraw();
}
}
void VirtualKeyboardGUI::screenChanged() {
g_gui.checkScreenChange();
_lastScreenChanged = _system->getScreenChangeID();
int16 newScreenW = _system->getOverlayWidth();
int16 newScreenH = _system->getOverlayHeight();
if (_screenW != newScreenW || _screenH != newScreenH) {
_screenW = newScreenW;
_screenH = newScreenH;
_overlayBackup.create(_screenW, _screenH, sizeof(OverlayColor));
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
if (!_kbd->checkModeResolutions()) {
_displaying = false;
return;
}
moveToDefaultPosition();
}
}
void VirtualKeyboardGUI::mainLoop() {
Common::EventManager *eventMan = _system->getEventManager();
while (_displaying) {
if (_kbd->_keyQueue.hasStringChanged())
updateDisplay();
animateCaret();
animateCursor();
redraw();
_system->updateScreen();
Common::Event event;
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
if (_kbdBound.contains(event.mouse)) {
_kbd->handleMouseDown(event.mouse.x - _kbdBound.left,
event.mouse.y - _kbdBound.top);
}
break;
case Common::EVENT_LBUTTONUP:
if (_kbdBound.contains(event.mouse)) {
_kbd->handleMouseUp(event.mouse.x - _kbdBound.left,
event.mouse.y - _kbdBound.top);
}
break;
case Common::EVENT_MOUSEMOVE:
if (_drag)
move(event.mouse.x - _dragPoint.x,
event.mouse.y - _dragPoint.y);
break;
case Common::EVENT_SCREEN_CHANGED:
screenChanged();
break;
case Common::EVENT_QUIT:
_system->quit();
return;
default:
break;
}
}
// Delay for a moment
_system->delayMillis(10);
}
}
void VirtualKeyboardGUI::startDrag(int16 x, int16 y) {
_drag = true;
_dragPoint.x = x;
_dragPoint.y = y;
}
void VirtualKeyboardGUI::endDrag() {
_drag = false;
}
void VirtualKeyboardGUI::extendDirtyRect(const Rect &r) {
if (_dirtyRect.isValidRect()) {
_dirtyRect.extend(r);
} else {
_dirtyRect = r;
}
_dirtyRect.clip(Rect(_overlayBackup.w, _overlayBackup.h));
}
void VirtualKeyboardGUI::resetDirtyRect() {
_dirtyRect.setWidth(-1);
}
void VirtualKeyboardGUI::forceRedraw() {
updateDisplay();
extendDirtyRect(Rect(_overlayBackup.w, _overlayBackup.h));
redraw();
}
void VirtualKeyboardGUI::redraw() {
assert(_kbdSurface);
int16 w = _dirtyRect.width();
int16 h = _dirtyRect.height();
if (w <= 0 || h <= 0) return;
Graphics::Surface surf;
surf.create(w, h, sizeof(OverlayColor));
OverlayColor *dst = (OverlayColor *)surf.pixels;
const OverlayColor *src = (OverlayColor *) _overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
while (h--) {
memcpy(dst, src, surf.w * sizeof(OverlayColor));
dst += surf.w;
src += _overlayBackup.w;
}
blit(&surf, _kbdSurface, _kbdBound.left - _dirtyRect.left,
_kbdBound.top - _dirtyRect.top, _kbdTransparentColor);
if (_displayEnabled) {
blit(&surf, &_dispSurface, _dispX - _dirtyRect.left,
_dispY - _dirtyRect.top, _dispBackColor);
}
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w,
_dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
surf.free();
resetDirtyRect();
}
uint VirtualKeyboardGUI::calculateEndIndex(const String& str, uint startIndex) {
int16 w = 0;
while (w <= _dispSurface.w && startIndex < str.size()) {
w += _dispFont->getCharWidth(str[startIndex++]);
}
if (w > _dispSurface.w) startIndex--;
return startIndex;
}
void VirtualKeyboardGUI::animateCaret() {
if (!_displayEnabled) return;
if (_system->getMillis() % kCaretBlinkTime < kCaretBlinkTime / 2) {
if (!_drawCaret) {
_drawCaret = true;
_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
}
} else {
if (_drawCaret) {
_drawCaret = false;
_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispBackColor);
extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
}
}
}
void VirtualKeyboardGUI::updateDisplay() {
if (!_displayEnabled) return;
// calculate the text to display
uint cursorPos = _kbd->_keyQueue.getInsertIndex();
String wholeText = _kbd->_keyQueue.getString();
uint dispTextEnd;
if (_dispI > cursorPos)
_dispI = cursorPos;
dispTextEnd = calculateEndIndex(wholeText, _dispI);
while (cursorPos > dispTextEnd)
dispTextEnd = calculateEndIndex(wholeText, ++_dispI);
String dispText = String(wholeText.c_str() + _dispI, wholeText.c_str() + dispTextEnd);
// draw to display surface
_dispSurface.fillRect(Rect(_dispSurface.w, _dispSurface.h), _dispBackColor);
_dispFont->drawString(&_dispSurface, dispText, 0, 0, _dispSurface.w, _dispForeColor);
String beforeCaret(wholeText.c_str() + _dispI, wholeText.c_str() + cursorPos);
_caretX = _dispFont->getStringWidth(beforeCaret);
if (_drawCaret) _dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
extendDirtyRect(Rect(_dispX, _dispY, _dispX + _dispSurface.w, _dispY + _dispSurface.h));
}
void VirtualKeyboardGUI::setupCursor() {
const byte palette[] = {
255, 255, 255, 0,
255, 255, 255, 0,
171, 171, 171, 0,
87, 87, 87, 0
};
CursorMan.pushCursorPalette(palette, 0, 4);
CursorMan.pushCursor(NULL, 0, 0, 0, 0);
CursorMan.showMouse(true);
}
void VirtualKeyboardGUI::animateCursor() {
int time = _system->getMillis();
if (time > _cursorAnimateTimer + kCursorAnimateDelay) {
for (int i = 0; i < 15; i++) {
if ((i < 6) || (i > 8)) {
_cursor[16 * 7 + i] = _cursorAnimateCounter;
_cursor[16 * i + 7] = _cursorAnimateCounter;
}
}
CursorMan.replaceCursor(_cursor, 16, 16, 7, 7);
_cursorAnimateTimer = time;
_cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4;
}
}
void VirtualKeyboardGUI::removeCursor() {
CursorMan.popCursor();
CursorMan.popCursorPalette();
}
} // end of namespace Common
#endif // #ifdef ENABLE_VKEYBD

View file

@ -0,0 +1,158 @@
/* 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 COMMON_VIRTUAL_KEYBOARD_GUI_H
#define COMMON_VIRTUAL_KEYBOARD_GUI_H
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/virtual-keyboard.h"
#include "common/scummsys.h"
#include "common/rect.h"
#include "common/system.h"
#include "graphics/fontman.h"
#include "graphics/surface.h"
namespace Common {
/**
* Class to handle the drawing of the virtual keyboard to the overlay, and the
* execution of the keyboard's main loop.
* This includes the blitting of the appropriate bitmap in the correct location,
* as well as the drawing of the virtual keyboard display.
*/
class VirtualKeyboardGUI {
public:
VirtualKeyboardGUI(VirtualKeyboard *kbd);
~VirtualKeyboardGUI();
/**
* Updates the GUI when the Mode of the keyboard is changes
*/
void initMode(VirtualKeyboard::Mode *mode);
/**
* Starts the drawing of the keyboard, and runs the main event loop.
*/
void run();
/**
* Interrupts the event loop and resets the overlay to its initial state.
*/
void close();
bool isDisplaying() { return _displaying; }
/**
* Reset the class to an initial state
*/
void reset();
/**
* Activates drag mode. Takes the keyboard-relative coordinates of the
* cursor as an argument.
*/
void startDrag(int16 x, int16 y);
/**
* Deactivates drag mode
* */
void endDrag();
/**
* Checks for a screen change in the backend and re-inits the virtual
* keyboard if it has.
*/
void checkScreenChanged();
/**
* Sets the GUI's internal screen size variables
*/
void initSize(int16 w, int16 h);
private:
OSystem *_system;
VirtualKeyboard *_kbd;
Rect _kbdBound;
Graphics::Surface *_kbdSurface;
OverlayColor _kbdTransparentColor;
Point _dragPoint;
bool _drag;
static const int SNAP_WIDTH = 10;
Graphics::Surface _overlayBackup;
Rect _dirtyRect;
bool _displayEnabled;
Graphics::Surface _dispSurface;
const Graphics::Font *_dispFont;
int16 _dispX, _dispY;
uint _dispI;
OverlayColor _dispForeColor, _dispBackColor;
int _lastScreenChanged;
int16 _screenW, _screenH;
bool _displaying;
bool _firstRun;
void setupDisplayArea(Rect& r, OverlayColor forecolor);
void move(int16 x, int16 y);
void moveToDefaultPosition();
void screenChanged();
void mainLoop();
void extendDirtyRect(const Rect &r);
void resetDirtyRect();
void redraw();
void forceRedraw();
void updateDisplay();
bool fontIsSuitable(const Graphics::Font *font, const Rect& rect);
uint calculateEndIndex(const String& str, uint startIndex);
bool _drawCaret;
int16 _caretX;
static const int kCaretBlinkTime = 500;
void animateCaret();
static const int kCursorAnimateDelay = 250;
int _cursorAnimateCounter;
int _cursorAnimateTimer;
byte _cursor[2048];
void setupCursor();
void removeCursor();
void animateCursor();
};
} // end of namespace Common
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef COMMON_VIRTUAL_KEYBOARD_GUI_H

View file

@ -0,0 +1,376 @@
/* 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$
*
*/
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/virtual-keyboard-parser.h"
#include "backends/vkeybd/polygon.h"
#include "common/keyboard.h"
#include "common/util.h"
#include "common/system.h"
#include "common/archive.h"
#include "graphics/imagedec.h"
namespace Common {
VirtualKeyboardParser::VirtualKeyboardParser(VirtualKeyboard *kbd)
: XMLParser(), _keyboard(kbd) {
}
void VirtualKeyboardParser::cleanup() {
_mode = 0;
_kbdParsed = false;
_initialModeName.clear();
if (_parseMode == kParseFull) {
// reset keyboard to remove existing config
_keyboard->reset();
}
}
bool VirtualKeyboardParser::closedKeyCallback(ParserNode *node) {
if (node->name.equalsIgnoreCase("keyboard")) {
_kbdParsed = true;
if (!_keyboard->_initialMode)
return parserError("Initial mode of keyboard pack not defined");
} else if (node->name.equalsIgnoreCase("mode")) {
if (!_layoutParsed) {
return parserError("'%s' layout missing from '%s' mode",
_mode->resolution.c_str(), _mode->name.c_str());
}
}
return true;
}
bool VirtualKeyboardParser::parserCallback_keyboard(ParserNode *node) {
if (_kbdParsed)
return parserError("Only a single keyboard element is allowed");
// if not full parse then we're done
if (_parseMode == kParseCheckResolutions)
return true;
_initialModeName = node->values["initial_mode"];
if (node->values.contains("h_align")) {
String h = node->values["h_align"];
if (h.equalsIgnoreCase("left"))
_keyboard->_hAlignment = VirtualKeyboard::kAlignLeft;
else if (h.equalsIgnoreCase("centre") || h.equalsIgnoreCase("center"))
_keyboard->_hAlignment = VirtualKeyboard::kAlignCentre;
else if (h.equalsIgnoreCase("right"))
_keyboard->_hAlignment = VirtualKeyboard::kAlignRight;
}
if (node->values.contains("v_align")) {
String v = node->values["v_align"];
if (v.equalsIgnoreCase("top"))
_keyboard->_vAlignment = VirtualKeyboard::kAlignTop;
else if (v.equalsIgnoreCase("middle") || v.equalsIgnoreCase("center"))
_keyboard->_vAlignment = VirtualKeyboard::kAlignMiddle;
else if (v.equalsIgnoreCase("bottom"))
_keyboard->_vAlignment = VirtualKeyboard::kAlignBottom;
}
return true;
}
bool VirtualKeyboardParser::parserCallback_mode(ParserNode *node) {
String name = node->values["name"];
if (_parseMode == kParseFull) {
// if full parse then add new mode to keyboard
if (_keyboard->_modes.contains(name))
return parserError("Mode '%s' has already been defined", name.c_str());
VirtualKeyboard::Mode mode;
mode.name = name;
_keyboard->_modes[name] = mode;
}
_mode = &(_keyboard->_modes[name]);
if (name == _initialModeName)
_keyboard->_initialMode = _mode;
String resolutions = node->values["resolutions"];
StringTokenizer tok (resolutions, " ,");
// select best resolution simply by minimising the difference between the
// overlay size and the resolution dimensions.
// TODO: improve this by giving preference to a resolution that is smaller
// than the overlay res (so the keyboard can't be too big for the screen)
uint16 scrW = g_system->getOverlayWidth(), scrH = g_system->getOverlayHeight();
uint32 diff = 0xFFFFFFFF;
String newResolution;
for (String res = tok.nextToken(); res.size() > 0; res = tok.nextToken()) {
int resW, resH;
if (sscanf(res.c_str(), "%dx%d", &resW, &resH) != 2) {
return parserError("Invalid resolution specification");
} else {
if (resW == scrW && resH == scrH) {
newResolution = res;
break;
} else {
uint32 newDiff = ABS(scrW - resW) + ABS(scrH - resH);
if (newDiff < diff) {
diff = newDiff;
newResolution = res;
}
}
}
}
if (newResolution.empty())
return parserError("No acceptable resolution was found");
if (_parseMode == kParseCheckResolutions) {
if (_mode->resolution == newResolution) {
node->ignore = true;
return true;
} else {
// remove data relating to old resolution
_mode->bitmapName.clear();
delete _mode->image;
_mode->image = 0;
_mode->imageMap.removeAllAreas();
_mode->displayArea = Rect();
}
}
_mode->resolution = newResolution;
_layoutParsed = false;
return true;
}
bool VirtualKeyboardParser::parserCallback_event(ParserNode *node) {
// if just checking resolutions we're done
if (_parseMode == kParseCheckResolutions)
return true;
String name = node->values["name"];
if (_mode->events.contains(name))
return parserError("Event '%s' has already been defined", name.c_str());
VirtualKeyboard::VKEvent *evt = new VirtualKeyboard::VKEvent();
evt->name = name;
String type = node->values["type"];
if (type.equalsIgnoreCase("key")) {
if (!node->values.contains("code") || !node->values.contains("ascii")) {
delete evt;
return parserError("Key event element must contain code and ascii attributes");
}
evt->type = VirtualKeyboard::kVKEventKey;
KeyState *ks = (KeyState*) malloc(sizeof(KeyState));
ks->keycode = (KeyCode)atoi(node->values["code"].c_str());
ks->ascii = atoi(node->values["ascii"].c_str());
ks->flags = 0;
if (node->values.contains("modifiers"))
ks->flags = parseFlags(node->values["modifiers"]);
evt->data = ks;
} else if (type.equalsIgnoreCase("modifier")) {
if (!node->values.contains("modifiers")) {
delete evt;
return parserError("Key modifier element must contain modifier attributes");
}
evt->type = VirtualKeyboard::kVKEventModifier;
byte *flags = (byte*) malloc(sizeof(byte));
*(flags) = parseFlags(node->values["modifiers"]);
evt->data = flags;
} else if (type.equalsIgnoreCase("switch_mode")) {
if (!node->values.contains("mode")) {
delete evt;
return parserError("Switch mode event element must contain mode attribute");
}
evt->type = VirtualKeyboard::kVKEventSwitchMode;
String& mode = node->values["mode"];
char *str = (char*) malloc(sizeof(char) * mode.size() + 1);
memcpy(str, mode.c_str(), sizeof(char) * mode.size());
str[mode.size()] = 0;
evt->data = str;
} else if (type.equalsIgnoreCase("submit")) {
evt->type = VirtualKeyboard::kVKEventSubmit;
} else if (type.equalsIgnoreCase("cancel")) {
evt->type = VirtualKeyboard::kVKEventCancel;
} else if (type.equalsIgnoreCase("clear")) {
evt->type = VirtualKeyboard::kVKEventClear;
} else if (type.equalsIgnoreCase("delete")) {
evt->type = VirtualKeyboard::kVKEventDelete;
} else if (type.equalsIgnoreCase("move_left")) {
evt->type = VirtualKeyboard::kVKEventMoveLeft;
} else if (type.equalsIgnoreCase("move_right")) {
evt->type = VirtualKeyboard::kVKEventMoveRight;
} else {
delete evt;
return parserError("Event type '%s' not known", type.c_str());
}
_mode->events[name] = evt;
return true;
}
bool VirtualKeyboardParser::parserCallback_layout(ParserNode *node) {
assert(!_mode->resolution.empty());
String res = node->values["resolution"];
if (res != _mode->resolution) {
node->ignore = true;
return true;
}
_mode->bitmapName = node->values["bitmap"];
SeekableReadStream *file = _keyboard->_fileArchive->createReadStreamForMember(_mode->bitmapName);
if (!file)
return parserError("Bitmap '%s' not found", _mode->bitmapName.c_str());
const Graphics::PixelFormat format = g_system->getOverlayFormat();
_mode->image = Graphics::ImageDecoder::loadFile(*file, format);
delete file;
if (!_mode->image)
return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
int r, g, b;
if (node->values.contains("transparent_color")) {
if (!parseIntegerKey(node->values["transparent_color"].c_str(), 3, &r, &g, &b))
return parserError("Could not parse color value");
} else {
// default to purple
r = 255;
g = 0;
b = 255;
}
_mode->transparentColor = format.RGBToColor(r, g, b);
if (node->values.contains("display_font_color")) {
if (!parseIntegerKey(node->values["display_font_color"].c_str(), 3, &r, &g, &b))
return parserError("Could not parse color value");
} else {
r = g = b = 0; // default to black
}
_mode->displayFontColor = format.RGBToColor(r, g, b);
_layoutParsed = true;
return true;
}
bool VirtualKeyboardParser::parserCallback_map(ParserNode *node) {
return true;
}
bool VirtualKeyboardParser::parserCallback_area(ParserNode *node) {
String& shape = node->values["shape"];
String& target = node->values["target"];
String& coords = node->values["coords"];
if (target.equalsIgnoreCase("display_area")) {
if (!shape.equalsIgnoreCase("rect"))
return parserError("display_area must be a rect area");
_mode->displayArea = Rect();
return parseRect(_mode->displayArea, coords);
} else if (shape.equalsIgnoreCase("rect")) {
Polygon *poly = _mode->imageMap.createArea(target);
return parseRectAsPolygon(*poly, coords);
} else if (shape.equalsIgnoreCase("poly")) {
Polygon *poly = _mode->imageMap.createArea(target);
return parsePolygon(*poly, coords);
}
return parserError("Area shape '%s' not known", shape.c_str());
}
byte VirtualKeyboardParser::parseFlags(const String& flags) {
if (flags.empty())
return 0;
StringTokenizer tok(flags, ", ");
byte val = 0;
for (String fl = tok.nextToken(); !fl.empty(); fl = tok.nextToken()) {
if (fl == "ctrl" || fl == "control")
val |= KBD_CTRL;
else if (fl == "alt")
val |= KBD_ALT;
else if (fl == "shift")
val |= KBD_SHIFT;
}
return val;
}
bool VirtualKeyboardParser::parseRect(Rect &rect, const String& coords) {
int x1, y1, x2, y2;
if (!parseIntegerKey(coords.c_str(), 4, &x1, &y1, &x2, &y2))
return parserError("Invalid coords for rect area");
rect.left = x1;
rect.top = y1;
rect.right = x2;
rect.bottom = y2;
if (!rect.isValidRect())
return parserError("Rect area is not a valid rectangle");
return true;
}
bool VirtualKeyboardParser::parsePolygon(Polygon &poly, const String& coords) {
StringTokenizer tok(coords, ", ");
for (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");
return true;
}
bool VirtualKeyboardParser::parseRectAsPolygon(Polygon &poly, const String& coords) {
Rect rect;
if (!parseRect(rect, coords))
return false;
poly.addPoint(rect.left, rect.top);
poly.addPoint(rect.right, rect.top);
poly.addPoint(rect.right, rect.bottom);
poly.addPoint(rect.left, rect.bottom);
return true;
}
} // end of namespace GUI
#endif // #ifdef ENABLE_VKEYBD

View file

@ -0,0 +1,272 @@
/* 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 COMMON_VIRTUAL_KEYBOARD_PARSER_H
#define COMMON_VIRTUAL_KEYBOARD_PARSER_H
#ifdef ENABLE_VKEYBD
#include "common/scummsys.h"
#include "common/xmlparser.h"
#include "backends/vkeybd/virtual-keyboard.h"
/**
***************************************
** Virtual Keyboard Pack File Format **
***************************************
The new virtual keyboard for ScummVM is implemented in the same way as a HTML
ImageMap. It uses a single bitmap of the entire keyboard layout and then a
image map description allows certain areas of the bitmap to be given special
actions. Most of these actions will be a virtual key press event, but there
will also be special keys that will change the keyboard layout or close the
keyboard. The HTML image map description is contained in a larger XML file that
can describe all the different modes of the keyboard, and also different
keyboard layouts for different screen resolutions.
********************************************
** Example keyboard pack description file **
********************************************
<keyboard modes="normal,caps" initial_mode="normal" v_align="bottom" h_align="centre">
<mode name="normal" resolutions="640x400,320x200">
<layout resolution="640x400" bitmap="normal_640x400.bmp" transparent_color="255,0,255">
<map>
<area shape="poly" coords="65,50,67,48,94,48,96,50,96,77,94,79,67,79,65,77" target="q" />
<area shape="poly" coords="105,50,107,48,134,48,136,50,136,77,134,79,107,79,105,77" target="w" />
<area shape="poly" coords="146,50,148,48,174,48,176,50,176,77,174,79,148,79,146,77" target="e" />
...
<area shape="poly" coords="11,89,12,88,69,88,70,89,70,116,69,117,12,117,11,116" target="caps" />
</map>
</layout>
<layout resolution="320x200" bitmap="normal_320x200.bmp" transparent_color="255,0,255">
...
</layout>
<event name="a" type="key" code="97" ascii="97" modifiers="" />
<event name="b" type="key" code="98" ascii="98" modifiers="" />
<event name="c" type="key" code="99" ascii="99" modifiers="" />
...
<event name="caps" type="switch_mode" mode="caps" />
</mode>
<mode name="caps" resolutions="640x400">
<layout resolution="640x400" bitmap="caps_640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="poly" coords="65,50,67,48,94,48,96,50,96,77,94,79,67,79,65,77" target="Q" />
...
</map>
</layout>
<event name="A" type="key" code="97" ascii="65" modifiers="shift" />
<event name="B" type="key" code="98" ascii="66" modifiers="shift" />
<event name="C" type="key" code="99" ascii="67" modifiers="shift" />
...
</mode>
</keyboard>
*************************
** Description of tags **
*************************
<keyboard>
This is the required, root element of the file format.
required attributes:
- initial_mode: name of the mode the keyboard will show initially
optional attributes:
- v_align/h_align: where on the screen should the keyboard appear initially
(defaults to bottom/center).
child tags:
- mode
-------------------------------------------------------------------------------
<mode>
This tag encapsulates a single mode of the keyboard. Within are a number of
layouts, which provide the specific implementation at different resolutions.
required attributes:
- name: the name of the mode
- resolutions: list of the different layout resolutions
child tags:
- layout
- event
-------------------------------------------------------------------------------
<event>
These tags describe a particular event that will be triggered by a mouse click
on a particular area. The target attribute of each image map area should be the
same as an event's name.
required attributes:
- name: name of the event
- type: key | modifier | switch_mode | submit | cancel | clear | delete |
move_left | move_right - see VirtualKeyboard::EventType for explanation
for key events
- code / ascii: describe a key press in ScummVM KeyState format
for key and modifier events
- modifiers: modifier keystate as comma-separated list of shift, ctrl and/or
alt.
for switch_mode events
- mode: name of the mode that should be switched to
-------------------------------------------------------------------------------
<layout>
These tags encapsulate an implementation of a mode at a particular resolution.
required attributes:
- resolution: the screen resolution that this layout is designed for
- bitmap: filename of the 24-bit bitmap that will be used for this layout
optional attributes:
- transparent_color: color in r,g,b format that will be used for keycolor
transparency (defaults to (255,0,255).
- display_font_color: color in r,g,b format that will be used for the text of
the keyboard display (defaults to (0,0,0).
child nodes:
- map: this describes the image map using the same format as html image maps
-------------------------------------------------------------------------------
<map>
These tags describe the image map for a particular layout. It uses the same
format as HTML image maps. The only area shapes that are supported are
rectangles and polygons. The target attribute of each area should be the name
of an event for this mode (see <event> tag). They will usually be generated by
an external tool such as GIMP's Image Map plugin, and so will not be written
by hand, but for more information on HTML image map format see
- http://www.w3schools.com/TAGS/tag_map.asp
- http://www.w3schools.com/TAGS/tag_area.asp
*/
namespace Common {
/**
* Subclass of Common::XMLParser that parses the virtual keyboard pack
* description file
*/
class VirtualKeyboardParser : public XMLParser {
public:
/**
* Enum dictating how extensive a parse will be
*/
enum ParseMode {
/**
* Full parse - when loading keyboard pack for first time
*/
kParseFull,
/**
* Just check resolutions and reload layouts if needed - following a
* change in screen size
*/
kParseCheckResolutions
};
VirtualKeyboardParser(VirtualKeyboard *kbd);
void setParseMode(ParseMode m) {
_parseMode = m;
}
protected:
CUSTOM_XML_PARSER(VirtualKeyboardParser) {
XML_KEY(keyboard)
XML_PROP(initial_mode, true)
XML_PROP(v_align, false)
XML_PROP(h_align, false)
XML_KEY(mode)
XML_PROP(name, true)
XML_PROP(resolutions, true)
XML_KEY(layout)
XML_PROP(resolution, true)
XML_PROP(bitmap, true)
XML_PROP(transparent_color, false)
XML_PROP(display_font_color, false)
XML_KEY(map)
XML_KEY(area)
XML_PROP(shape, true)
XML_PROP(coords, true)
XML_PROP(target, true)
KEY_END()
KEY_END()
KEY_END()
XML_KEY(event)
XML_PROP(name, true)
XML_PROP(type, true)
XML_PROP(code, false)
XML_PROP(ascii, false)
XML_PROP(modifiers, false)
XML_PROP(mode, false)
KEY_END()
KEY_END()
KEY_END()
} PARSER_END()
protected:
VirtualKeyboard *_keyboard;
/** internal state variables of parser */
ParseMode _parseMode;
VirtualKeyboard::Mode *_mode;
String _initialModeName;
bool _kbdParsed;
bool _layoutParsed;
/** Cleanup internal state before parse */
virtual void cleanup();
/** Parser callback function */
bool parserCallback_keyboard(ParserNode *node);
bool parserCallback_mode(ParserNode *node);
bool parserCallback_event(ParserNode *node);
bool parserCallback_layout(ParserNode *node);
bool parserCallback_map(ParserNode *node);
bool parserCallback_area(ParserNode *node);
virtual bool closedKeyCallback(ParserNode *node);
/** Parse helper functions */
byte parseFlags(const String& flags);
bool parseRect(Rect &rect, const String& coords);
bool parsePolygon(Polygon &poly, const String& coords);
bool parseRectAsPolygon(Polygon &poly, const String& coords);
};
} // end of namespace GUI
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef COMMON_VIRTUAL_KEYBOARD_PARSER_H

View file

@ -0,0 +1,397 @@
/* 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$
*
*/
#ifdef ENABLE_VKEYBD
#include "backends/vkeybd/virtual-keyboard.h"
#include "backends/vkeybd/virtual-keyboard-gui.h"
#include "backends/vkeybd/virtual-keyboard-parser.h"
#include "backends/vkeybd/keycode-descriptions.h"
#include "common/config-manager.h"
#include "common/fs.h"
#include "common/unzip.h"
#define KEY_START_CHAR ('[')
#define KEY_END_CHAR (']')
namespace Common {
VirtualKeyboard::VirtualKeyboard() : _currentMode(0) {
assert(g_system);
_system = g_system;
_parser = new VirtualKeyboardParser(this);
_kbdGUI = new VirtualKeyboardGUI(this);
_submitKeys = _loaded = false;
_fileArchive = 0;
}
VirtualKeyboard::~VirtualKeyboard() {
deleteEvents();
delete _kbdGUI;
delete _parser;
delete _fileArchive;
}
void VirtualKeyboard::deleteEvents() {
ModeMap::iterator it_m;
VKEventMap::iterator it_e;
for (it_m = _modes.begin(); it_m != _modes.end(); it_m++) {
VKEventMap *evt = &(it_m->_value.events);
for (it_e = evt->begin(); it_e != evt->end(); it_e++)
delete it_e->_value;
}
}
void VirtualKeyboard::reset() {
deleteEvents();
_modes.clear();
_initialMode = _currentMode = 0;
_hAlignment = kAlignCentre;
_vAlignment = kAlignBottom;
_keyQueue.clear();
_loaded = false;
_kbdGUI->reset();
}
bool VirtualKeyboard::loadKeyboardPack(String packName) {
_kbdGUI->initSize(_system->getOverlayWidth(), _system->getOverlayHeight());
delete _fileArchive;
_fileArchive = 0;
FSNode vkDir;
if (ConfMan.hasKey("vkeybdpath"))
vkDir = FSNode(ConfMan.get("vkeybdpath"));
else if (ConfMan.hasKey("extrapath"))
vkDir = FSNode(ConfMan.get("extrapath"));
else // use current directory
vkDir = FSNode(".");
if (vkDir.getChild(packName + ".xml").exists()) {
_fileArchive = new FSDirectory(vkDir, 1);
// uncompressed keyboard pack
if (!_parser->loadFile(vkDir.getChild(packName + ".xml")))
return false;
} else if (vkDir.getChild(packName + ".zip").exists()) {
// compressed keyboard pack
#ifdef USE_ZLIB
_fileArchive = new ZipArchive(vkDir.getChild(packName + ".zip"));
if (_fileArchive->hasFile(packName + ".xml")) {
if (!_parser->loadStream(_fileArchive->createReadStreamForMember(packName + ".xml")))
return false;
} else {
warning("Could not find %s.xml file in %s.zip keyboard pack", packName.c_str(), packName.c_str());
return false;
}
#else
return false;
#endif
} else {
warning("Keyboard pack not found");
return false;
}
_parser->setParseMode(VirtualKeyboardParser::kParseFull);
_loaded = _parser->parse();
if (_loaded)
printf("Keyboard pack '%s' loaded successfully!\n", packName.c_str());
return _loaded;
}
bool VirtualKeyboard::checkModeResolutions() {
_parser->setParseMode(VirtualKeyboardParser::kParseCheckResolutions);
_loaded = _parser->parse();
if (_currentMode)
_kbdGUI->initMode(_currentMode);
return _loaded;
}
String VirtualKeyboard::findArea(int16 x, int16 y) {
return _currentMode->imageMap.findMapArea(x, y);
}
void VirtualKeyboard::processAreaClick(const String& area) {
if (!_currentMode->events.contains(area))
return;
VKEvent *evt = _currentMode->events[area];
switch (evt->type) {
case kVKEventKey:
// add virtual keypress to queue
_keyQueue.insertKey(*(KeyState*)evt->data);
break;
case kVKEventModifier:
_keyQueue.toggleFlags(*(byte*)(evt->data));
break;
case kVKEventSwitchMode:
// switch to new mode
switchMode((char *)evt->data);
_keyQueue.clearFlags();
break;
case kVKEventSubmit:
close(true);
break;
case kVKEventCancel:
close(false);
break;
case kVKEventClear:
_keyQueue.clear();
break;
case kVKEventDelete:
_keyQueue.deleteKey();
break;
case kVKEventMoveLeft:
_keyQueue.moveLeft();
break;
case kVKEventMoveRight:
_keyQueue.moveRight();
break;
}
}
void VirtualKeyboard::switchMode(Mode *newMode) {
_kbdGUI->initMode(newMode);
_currentMode = newMode;
}
void VirtualKeyboard::switchMode(const String& newMode) {
if (!_modes.contains(newMode)) {
warning("Keyboard mode '%s' unknown", newMode.c_str());
} else {
switchMode(&_modes[newMode]);
}
}
void VirtualKeyboard::handleMouseDown(int16 x, int16 y) {
_areaDown = findArea(x, y);
if (_areaDown.empty())
_kbdGUI->startDrag(x, y);
}
void VirtualKeyboard::handleMouseUp(int16 x, int16 y) {
if (!_areaDown.empty() && _areaDown == findArea(x, y)) {
processAreaClick(_areaDown);
_areaDown.clear();
}
_kbdGUI->endDrag();
}
void VirtualKeyboard::show() {
if (!_loaded) {
warning("Virtual keyboard not loaded");
return;
} else {
_kbdGUI->checkScreenChanged();
}
switchMode(_initialMode);
_kbdGUI->run();
if (_submitKeys) {
EventManager *eventMan = _system->getEventManager();
assert(eventMan);
// push keydown & keyup events into the event manager
Event evt;
evt.synthetic = false;
while (!_keyQueue.empty()) {
evt.kbd = _keyQueue.pop();
evt.type = EVENT_KEYDOWN;
eventMan->pushEvent(evt);
evt.type = EVENT_KEYUP;
eventMan->pushEvent(evt);
}
} else {
_keyQueue.clear();
}
}
void VirtualKeyboard::close(bool submit) {
_submitKeys = submit;
_kbdGUI->close();
}
bool VirtualKeyboard::isDisplaying() {
return _kbdGUI->isDisplaying();
}
VirtualKeyboard::KeyPressQueue::KeyPressQueue() {
_keyPos = _keys.end();
_strPos = 0;
_strChanged = false;
_flags = 0;
}
void VirtualKeyboard::KeyPressQueue::toggleFlags(byte fl) {
_flags ^= fl;
_flagsStr.clear();
if (_flags) {
_flagsStr = KEY_START_CHAR;
if (_flags & KBD_CTRL)
_flagsStr += "Ctrl+";
if (_flags & KBD_ALT)
_flagsStr += "Alt+";
if (_flags & KBD_SHIFT)
_flagsStr += "Shift+";
}
_strChanged = true;
}
void VirtualKeyboard::KeyPressQueue::clearFlags() {
_flags = 0;
_flagsStr.clear();
_strChanged = true;
}
void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) {
_strChanged = true;
key.flags ^= _flags;
if ((key.keycode >= KEYCODE_a) && (key.keycode <= KEYCODE_z))
key.ascii = (key.flags & KBD_SHIFT) ? key.keycode - 32 : key.keycode;
clearFlags();
String keyStr;
if (key.flags & KBD_CTRL) keyStr += "Ctrl+";
if (key.flags & KBD_ALT) keyStr += "Alt+";
if (key.ascii >= 32 && key.ascii <= 255) {
if (key.flags & KBD_SHIFT && (key.ascii < 65 || key.ascii > 90))
keyStr += "Shift+";
keyStr += (char)key.ascii;
} else {
if (key.flags & KBD_SHIFT) keyStr += "Shift+";
if (key.keycode >= 0 && key.keycode < keycodeDescTableSize)
keyStr += keycodeDescTable[key.keycode];
}
if (keyStr.empty()) keyStr += "???";
_keysStr.insertChar(KEY_START_CHAR, _strPos++);
const char *k = keyStr.c_str();
while (char ch = *k++)
_keysStr.insertChar(ch, _strPos++);
_keysStr.insertChar(KEY_END_CHAR, _strPos++);
VirtualKeyPress kp;
kp.key = key;
kp.strLen = keyStr.size() + 2;
_keys.insert(_keyPos, kp);
}
void VirtualKeyboard::KeyPressQueue::deleteKey() {
if (_keyPos == _keys.begin())
return;
List<VirtualKeyPress>::iterator it = _keyPos;
it--;
_strPos -= it->strLen;
while((it->strLen)-- > 0)
_keysStr.deleteChar(_strPos);
_keys.erase(it);
_strChanged = true;
}
void VirtualKeyboard::KeyPressQueue::moveLeft() {
if (_keyPos == _keys.begin())
return;
_keyPos--;
_strPos -= _keyPos->strLen;
_strChanged = true;
}
void VirtualKeyboard::KeyPressQueue::moveRight() {
if (_keyPos == _keys.end())
return;
_strPos += _keyPos->strLen;
_keyPos++;
_strChanged = true;
}
KeyState VirtualKeyboard::KeyPressQueue::pop() {
bool front = (_keyPos == _keys.begin());
VirtualKeyPress kp = *(_keys.begin());
_keys.pop_front();
if (front)
_keyPos = _keys.begin();
else
_strPos -= kp.strLen;
while (kp.strLen-- > 0)
_keysStr.deleteChar(0);
return kp.key;
}
void VirtualKeyboard::KeyPressQueue::clear() {
_keys.clear();
_keyPos = _keys.end();
_keysStr.clear();
_strPos = 0;
clearFlags();
_strChanged = true;
}
bool VirtualKeyboard::KeyPressQueue::empty() {
return _keys.empty();
}
String VirtualKeyboard::KeyPressQueue::getString() {
if (_keysStr.empty())
return _flagsStr;
if (_flagsStr.empty())
return _keysStr;
if (_strPos == _keysStr.size())
return _keysStr + _flagsStr;
uint len = _keysStr.size() + _flagsStr.size();
char *str = new char[len];
memcpy(str, _keysStr.c_str(), _strPos);
memcpy(str + _strPos, _flagsStr.c_str(), _flagsStr.size());
memcpy(str + _strPos + _flagsStr.size(), _keysStr.c_str() + _strPos, _keysStr.size() - _strPos);
String ret(str, len);
delete[] str;
return ret;
}
uint VirtualKeyboard::KeyPressQueue::getInsertIndex() {
return _strPos + _flagsStr.size();
}
bool VirtualKeyboard::KeyPressQueue::hasStringChanged() {
bool ret = _strChanged;
_strChanged = false;
return ret;
}
} // end of namespace Common
#endif // #ifdef ENABLE_VKEYBD

View file

@ -0,0 +1,263 @@
/* 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 COMMON_VIRTUAL_KEYBOARD_H
#define COMMON_VIRTUAL_KEYBOARD_H
#ifdef ENABLE_VKEYBD
class OSystem;
#include "common/scummsys.h"
#include "common/events.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/keyboard.h"
#include "common/list.h"
#include "common/str.h"
#include "backends/vkeybd/image-map.h"
#include "graphics/surface.h"
namespace Common {
class Archive;
class VirtualKeyboardGUI;
class VirtualKeyboardParser;
/**
* Class that handles the functionality of the virtual keyboard.
* This includes storage of the virtual key press events when the user clicks
* a key and delivery of them when the keyboard is closed, as well as managing
* the internal state of the keyboard, such as its active mode.
*/
class VirtualKeyboard {
protected:
/**
* Enum to describe the different types of events that can be associated
* with an area of the virtual keyboard bitmap.
*/
enum VKEventType {
/** Standard key press event */
kVKEventKey,
/** Modifier key press event */
kVKEventModifier,
/** Switch the mode of the keyboard */
kVKEventSwitchMode,
/** Close the keyboard, submitting all keypresses */
kVKEventSubmit,
/** Close the keyboard, without submitting keypresses */
kVKEventCancel,
/** Clear the virtual keypress queue */
kVKEventClear,
/** Move the keypress queue insert position backwards */
kVKEventMoveLeft,
/** Move the keypress queue insert position forwards */
kVKEventMoveRight,
/** Delete keypress from queue at the current insert position */
kVKEventDelete
};
/** VKEvent struct encapsulates data on a virtual keyboard event */
struct VKEvent {
String name;
VKEventType type;
/**
* Void pointer that will point to different types of data depending
* on the type of the event, these are:
* - KeyState struct for kVKEventKey events
* - a flags byte for kVKEventModifier events
* - c-string stating the name of the new mode for kSwitchMode events
*/
void *data;
VKEvent() : data(0) {}
~VKEvent() {
if (data)
free(data);
}
};
typedef HashMap<String, VKEvent*> VKEventMap;
/**
* Mode struct encapsulates all the data for each mode of the keyboard
*/
struct Mode {
String name;
String resolution;
String bitmapName;
Graphics::Surface *image;
OverlayColor transparentColor;
ImageMap imageMap;
VKEventMap events;
Rect displayArea;
OverlayColor displayFontColor;
Mode() : image(0) {}
~Mode() { delete image; }
};
typedef HashMap<String, Mode, IgnoreCase_Hash, IgnoreCase_EqualTo> ModeMap;
enum HorizontalAlignment {
kAlignLeft,
kAlignCentre,
kAlignRight
};
enum VerticalAlignment {
kAlignTop,
kAlignMiddle,
kAlignBottom
};
struct VirtualKeyPress {
KeyState key;
/** length of the key presses description string */
uint strLen;
};
/**
* Class that stores the queue of virtual key presses, as well as
* maintaining a string that represents a preview of the queue
*/
class KeyPressQueue {
public:
KeyPressQueue();
void toggleFlags(byte fl);
void clearFlags();
void insertKey(KeyState key);
void deleteKey();
void moveLeft();
void moveRight();
KeyState pop();
void clear();
bool empty();
String getString();
uint getInsertIndex();
bool hasStringChanged();
private:
byte _flags;
String _flagsStr;
List<VirtualKeyPress> _keys;
String _keysStr;
bool _strChanged;
List<VirtualKeyPress>::iterator _keyPos;
uint _strPos;
};
public:
VirtualKeyboard();
virtual ~VirtualKeyboard();
/**
* Loads the keyboard pack with the given name.
* The system first looks for an uncompressed keyboard pack by searching
* for packName.xml in the filesystem, if this does not exist then it
* searches for a compressed keyboard pack by looking for packName.zip.
* @param packName name of the keyboard pack
*/
bool loadKeyboardPack(String packName);
/**
* Shows the keyboard, starting an event loop that will intercept all
* user input (like a modal GUI dialog).
* It is assumed that the game has been paused, before this is called
*/
void show();
/**
* Hides the keyboard, ending the event loop.
* @param submit if true all accumulated key presses are submitted to
* the event manager
*/
void close(bool submit);
/**
* Returns true if the keyboard is currently being shown
*/
bool isDisplaying();
/**
* Returns true if the keyboard is loaded and ready to be shown
*/
bool isLoaded() {
return _loaded;
}
protected:
OSystem *_system;
Archive *_fileArchive;
friend class VirtualKeyboardGUI;
VirtualKeyboardGUI *_kbdGUI;
KeyPressQueue _keyQueue;
friend class VirtualKeyboardParser;
VirtualKeyboardParser *_parser;
void reset();
void deleteEvents();
bool checkModeResolutions();
void switchMode(Mode *newMode);
void switchMode(const String& newMode);
void handleMouseDown(int16 x, int16 y);
void handleMouseUp(int16 x, int16 y);
String findArea(int16 x, int16 y);
void processAreaClick(const String &area);
bool _loaded;
ModeMap _modes;
Mode *_initialMode;
Mode *_currentMode;
HorizontalAlignment _hAlignment;
VerticalAlignment _vAlignment;
String _areaDown;
bool _submitKeys;
};
} // End of namespace Common
#endif // #ifdef ENABLE_VKEYBD
#endif // #ifndef COMMON_VIRTUAL_KEYBOARD_H