aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kodi.xcodeproj/project.pbxproj20
-rw-r--r--addons/resource.language.en_gb/resources/strings.po6
-rw-r--r--project/VS2010Express/XBMC.vcxproj6
-rw-r--r--project/VS2010Express/XBMC.vcxproj.filters14
-rw-r--r--system/keyboardlayouts.xml447
-rw-r--r--system/keyboardlayouts/arabic.xml27
-rw-r--r--system/keyboardlayouts/bulgarian.xml47
-rw-r--r--system/keyboardlayouts/danish.xml27
-rw-r--r--system/keyboardlayouts/english.xml67
-rw-r--r--system/keyboardlayouts/german.xml27
-rw-r--r--system/keyboardlayouts/greek.xml27
-rw-r--r--system/keyboardlayouts/hebrew.xml47
-rw-r--r--system/keyboardlayouts/hungarian.xml27
-rw-r--r--system/keyboardlayouts/norwegian.xml27
-rw-r--r--system/keyboardlayouts/polish.xml27
-rw-r--r--system/keyboardlayouts/portuguese.xml27
-rw-r--r--system/keyboardlayouts/russian.xml47
-rw-r--r--system/keyboardlayouts/spanish.xml27
-rw-r--r--system/keyboardlayouts/swedish.xml27
-rw-r--r--system/keyboardlayouts/turkish.xml27
-rw-r--r--system/keyboardlayouts/ukrainian.xml47
-rw-r--r--xbmc/Application.cpp8
-rw-r--r--xbmc/dialogs/GUIDialogKeyboardGeneric.cpp24
-rw-r--r--xbmc/input/KeyboardLayout.cpp131
-rw-r--r--xbmc/input/KeyboardLayout.h52
-rw-r--r--xbmc/input/KeyboardLayoutConfiguration.cpp279
-rw-r--r--xbmc/input/KeyboardLayoutConfiguration.h75
-rw-r--r--xbmc/input/KeyboardLayoutManager.cpp138
-rw-r--r--xbmc/input/KeyboardLayoutManager.h52
-rw-r--r--xbmc/input/KeyboardStat.cpp2
-rw-r--r--xbmc/input/Makefile2
-rw-r--r--xbmc/settings/Settings.cpp4
32 files changed, 876 insertions, 936 deletions
diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj
index d96fbcc292..80c885578c 100644
--- a/Kodi.xcodeproj/project.pbxproj
+++ b/Kodi.xcodeproj/project.pbxproj
@@ -140,7 +140,6 @@
18B7C8A0129423A7009E7A26 /* MusicInfoTagLoaderSPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C87E129423A7009E7A26 /* MusicInfoTagLoaderSPC.cpp */; };
18B7C8A4129423A7009E7A26 /* MusicInfoTagLoaderYM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C886129423A7009E7A26 /* MusicInfoTagLoaderYM.cpp */; };
18B7C8D712942546009E7A26 /* ButtonTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CB12942546009E7A26 /* ButtonTranslator.cpp */; };
- 18B7C8D812942546009E7A26 /* KeyboardLayoutConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CD12942546009E7A26 /* KeyboardLayoutConfiguration.cpp */; };
18B7C8D912942546009E7A26 /* KeyboardStat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */; };
18B7C8DA12942546009E7A26 /* MouseStat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8D112942546009E7A26 /* MouseStat.cpp */; };
18B7C8DB12942546009E7A26 /* SDLJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8D312942546009E7A26 /* SDLJoystick.cpp */; };
@@ -181,6 +180,9 @@
3802709A13D5A653009493DD /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3802709813D5A653009493DD /* SystemClock.cpp */; };
384718D81325BA04000486D6 /* XBDateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 384718D61325BA04000486D6 /* XBDateTime.cpp */; };
38F4E57013CCCB3B00664821 /* Implementation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F4E56C13CCCB3B00664821 /* Implementation.cpp */; };
+ 395897151AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395897131AAD94F00033D27C /* KeyboardLayoutManager.cpp */; };
+ 395897161AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395897131AAD94F00033D27C /* KeyboardLayoutManager.cpp */; };
+ 395897171AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395897131AAD94F00033D27C /* KeyboardLayoutManager.cpp */; };
395C29BC1A94733100EBC7AD /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C29BA1A94733100EBC7AD /* Key.cpp */; };
395C29BD1A94733100EBC7AD /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C29BA1A94733100EBC7AD /* Key.cpp */; };
395C29BE1A94733100EBC7AD /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C29BA1A94733100EBC7AD /* Key.cpp */; };
@@ -1874,7 +1876,6 @@
DFF0F46E17528350002DA3A4 /* WindowXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1AD1EC15FCE77900E10810 /* WindowXML.cpp */; };
DFF0F46F17528350002DA3A4 /* ButtonTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CB12942546009E7A26 /* ButtonTranslator.cpp */; };
DFF0F47017528350002DA3A4 /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */; };
- DFF0F47117528350002DA3A4 /* KeyboardLayoutConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CD12942546009E7A26 /* KeyboardLayoutConfiguration.cpp */; };
DFF0F47217528350002DA3A4 /* KeyboardStat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */; };
DFF0F47317528350002DA3A4 /* SDLJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8D312942546009E7A26 /* SDLJoystick.cpp */; };
DFF0F47417528350002DA3A4 /* XBMC_keytable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8EC5D0C1369519D00CCC10D /* XBMC_keytable.cpp */; };
@@ -3115,7 +3116,6 @@
E4991569174E656E00741B6D /* WindowXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1AD1EC15FCE77900E10810 /* WindowXML.cpp */; };
E499156A174E65AB00741B6D /* ButtonTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CB12942546009E7A26 /* ButtonTranslator.cpp */; };
E499156B174E65AB00741B6D /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */; };
- E499156C174E65AB00741B6D /* KeyboardLayoutConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CD12942546009E7A26 /* KeyboardLayoutConfiguration.cpp */; };
E499156D174E65AB00741B6D /* KeyboardStat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */; };
E499156E174E65AB00741B6D /* SDLJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C8D312942546009E7A26 /* SDLJoystick.cpp */; };
E499156F174E65AC00741B6D /* XBMC_keytable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8EC5D0C1369519D00CCC10D /* XBMC_keytable.cpp */; };
@@ -3578,8 +3578,6 @@
18B7C887129423A7009E7A26 /* MusicInfoTagLoaderYM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicInfoTagLoaderYM.h; sourceTree = "<group>"; };
18B7C8CB12942546009E7A26 /* ButtonTranslator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ButtonTranslator.cpp; sourceTree = "<group>"; };
18B7C8CC12942546009E7A26 /* ButtonTranslator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButtonTranslator.h; sourceTree = "<group>"; };
- 18B7C8CD12942546009E7A26 /* KeyboardLayoutConfiguration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardLayoutConfiguration.cpp; sourceTree = "<group>"; };
- 18B7C8CE12942546009E7A26 /* KeyboardLayoutConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardLayoutConfiguration.h; sourceTree = "<group>"; };
18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardStat.cpp; sourceTree = "<group>"; };
18B7C8D012942546009E7A26 /* KeyboardStat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardStat.h; sourceTree = "<group>"; };
18B7C8D112942546009E7A26 /* MouseStat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseStat.cpp; sourceTree = "<group>"; };
@@ -3669,6 +3667,8 @@
38F4E56C13CCCB3B00664821 /* Implementation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Implementation.cpp; sourceTree = "<group>"; };
38F4E56D13CCCB3B00664821 /* README.platform */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.platform; sourceTree = "<group>"; };
38F4E56E13CCCB3B00664821 /* ThreadLocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocal.h; sourceTree = "<group>"; };
+ 395897131AAD94F00033D27C /* KeyboardLayoutManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardLayoutManager.cpp; sourceTree = "<group>"; };
+ 395897141AAD94F00033D27C /* KeyboardLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardLayoutManager.h; sourceTree = "<group>"; };
395C29BA1A94733100EBC7AD /* Key.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Key.cpp; sourceTree = "<group>"; };
395C29BB1A94733100EBC7AD /* Key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Key.h; sourceTree = "<group>"; };
395C29BF1A98A0A000EBC7AD /* Webinterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Webinterface.cpp; sourceTree = "<group>"; };
@@ -6423,8 +6423,8 @@
395C29BB1A94733100EBC7AD /* Key.h */,
7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */,
7CF80DC819710DC2003B2B34 /* KeyboardLayout.h */,
- 18B7C8CD12942546009E7A26 /* KeyboardLayoutConfiguration.cpp */,
- 18B7C8CE12942546009E7A26 /* KeyboardLayoutConfiguration.h */,
+ 395897131AAD94F00033D27C /* KeyboardLayoutManager.cpp */,
+ 395897141AAD94F00033D27C /* KeyboardLayoutManager.h */,
18B7C8CF12942546009E7A26 /* KeyboardStat.cpp */,
18B7C8D012942546009E7A26 /* KeyboardStat.h */,
18B7C8D112942546009E7A26 /* MouseStat.cpp */,
@@ -10742,6 +10742,7 @@
E3A4780A0D29029A00F3C3A6 /* GUIDialogCache.cpp in Sources */,
395C29ED1A98A16300EBC7AD /* HTTPPythonInvoker.cpp in Sources */,
E3A4781A0D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp in Sources */,
+ 395897151AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */,
E36578880D3AA7B40033CC1C /* DVDPlayerCodec.cpp in Sources */,
E33206380D5070AA00435CE3 /* DVDDemuxVobsub.cpp in Sources */,
E33979960D62FD48004ECDDA /* DVDInputStreamTV.cpp in Sources */,
@@ -10999,7 +11000,6 @@
18B7C8A0129423A7009E7A26 /* MusicInfoTagLoaderSPC.cpp in Sources */,
18B7C8A4129423A7009E7A26 /* MusicInfoTagLoaderYM.cpp in Sources */,
18B7C8D712942546009E7A26 /* ButtonTranslator.cpp in Sources */,
- 18B7C8D812942546009E7A26 /* KeyboardLayoutConfiguration.cpp in Sources */,
18B7C8D912942546009E7A26 /* KeyboardStat.cpp in Sources */,
18B7C8DA12942546009E7A26 /* MouseStat.cpp in Sources */,
18B7C8DB12942546009E7A26 /* SDLJoystick.cpp in Sources */,
@@ -11825,6 +11825,7 @@
DFF0F24D17528350002DA3A4 /* SpecialProtocol.cpp in Sources */,
DFF0F24E17528350002DA3A4 /* SpecialProtocolDirectory.cpp in Sources */,
DFF0F24F17528350002DA3A4 /* SpecialProtocolFile.cpp in Sources */,
+ 395897171AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */,
DFF0F25017528350002DA3A4 /* StackDirectory.cpp in Sources */,
DFF0F25317528350002DA3A4 /* udf25.cpp in Sources */,
DFF0F25417528350002DA3A4 /* UDFDirectory.cpp in Sources */,
@@ -12367,7 +12368,6 @@
DFF0F46E17528350002DA3A4 /* WindowXML.cpp in Sources */,
DFF0F46F17528350002DA3A4 /* ButtonTranslator.cpp in Sources */,
DFF0F47017528350002DA3A4 /* InertialScrollingHandler.cpp in Sources */,
- DFF0F47117528350002DA3A4 /* KeyboardLayoutConfiguration.cpp in Sources */,
395C29DD1A98A11C00EBC7AD /* WsgiResponse.cpp in Sources */,
DFF0F47217528350002DA3A4 /* KeyboardStat.cpp in Sources */,
DFF0F47317528350002DA3A4 /* SDLJoystick.cpp in Sources */,
@@ -12990,6 +12990,7 @@
E4991309174E5DAD00741B6D /* GUIRadioButtonControl.cpp in Sources */,
E499130A174E5DAD00741B6D /* GUIRenderingControl.cpp in Sources */,
E499130B174E5DAD00741B6D /* GUIResizeControl.cpp in Sources */,
+ 395897161AAD94F00033D27C /* KeyboardLayoutManager.cpp in Sources */,
395C2A251AA4C32100EBC7AD /* AudioDecoder.cpp in Sources */,
E499130C174E5DAD00741B6D /* GUIRSSControl.cpp in Sources */,
E499130D174E5DAD00741B6D /* GUIScrollBarControl.cpp in Sources */,
@@ -13441,7 +13442,6 @@
E4991569174E656E00741B6D /* WindowXML.cpp in Sources */,
E499156A174E65AB00741B6D /* ButtonTranslator.cpp in Sources */,
E499156B174E65AB00741B6D /* InertialScrollingHandler.cpp in Sources */,
- E499156C174E65AB00741B6D /* KeyboardLayoutConfiguration.cpp in Sources */,
E499156D174E65AB00741B6D /* KeyboardStat.cpp in Sources */,
E499156E174E65AB00741B6D /* SDLJoystick.cpp in Sources */,
E499156F174E65AC00741B6D /* XBMC_keytable.cpp in Sources */,
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index ab7a087cc7..607af485eb 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -1319,7 +1319,11 @@ msgctxt "#310"
msgid "Keyboard layouts"
msgstr ""
-#empty string with id 311
+#. Keyboard layout name e.g. "English QWERTY"
+#: xbmc/input/KeyboardLayout.cpp
+msgctxt "#311"
+msgid "%s %s"
+msgstr ""
msgctxt "#312"
msgid "(0=auto)"
diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj
index 62ee9780d9..9d35b9ee62 100644
--- a/project/VS2010Express/XBMC.vcxproj
+++ b/project/VS2010Express/XBMC.vcxproj
@@ -502,7 +502,7 @@
<ClCompile Include="..\..\xbmc\input\InputManager.cpp" />
<ClCompile Include="..\..\xbmc\input\Key.cpp" />
<ClCompile Include="..\..\xbmc\input\KeyboardLayout.cpp" />
- <ClCompile Include="..\..\xbmc\input\KeyboardLayoutConfiguration.cpp" />
+ <ClCompile Include="..\..\xbmc\input\KeyboardLayoutManager.cpp" />
<ClCompile Include="..\..\xbmc\input\KeyboardStat.cpp" />
<ClCompile Include="..\..\xbmc\input\MouseStat.cpp" />
<ClCompile Include="..\..\xbmc\input\touch\generic\GenericTouchActionHandler.cpp" />
@@ -905,6 +905,7 @@
<ClInclude Include="..\..\xbmc\IFileItemListModifier.h" />
<ClInclude Include="..\..\xbmc\input\InputManager.h" />
<ClInclude Include="..\..\xbmc\input\Key.h" />
+ <ClInclude Include="..\..\xbmc\input\KeyboardLayoutManager.h" />
<ClInclude Include="..\..\xbmc\input\touch\generic\GenericTouchActionHandler.h" />
<ClInclude Include="..\..\xbmc\input\touch\generic\GenericTouchSwipeDetector.h" />
<ClInclude Include="..\..\xbmc\input\touch\generic\IGenericTouchGestureDetector.h" />
@@ -1866,7 +1867,6 @@
<ClInclude Include="..\..\xbmc\input\ButtonTranslator.h" />
<ClInclude Include="..\..\xbmc\input\InertialScrollingHandler.h" />
<ClInclude Include="..\..\xbmc\input\KeyboardLayout.h" />
- <ClInclude Include="..\..\xbmc\input\KeyboardLayoutConfiguration.h" />
<ClInclude Include="..\..\xbmc\input\KeyboardStat.h" />
<ClInclude Include="..\..\xbmc\input\MouseStat.h" />
<ClInclude Include="..\..\xbmc\input\windows\IRServerSuite.h" />
@@ -2615,4 +2615,4 @@
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters
index 12cb18fb2e..6173801e46 100644
--- a/project/VS2010Express/XBMC.vcxproj.filters
+++ b/project/VS2010Express/XBMC.vcxproj.filters
@@ -1150,9 +1150,6 @@
<ClCompile Include="..\..\xbmc\input\KeyboardLayout.cpp">
<Filter>input</Filter>
</ClCompile>
- <ClCompile Include="..\..\xbmc\input\KeyboardLayoutConfiguration.cpp">
- <Filter>input</Filter>
- </ClCompile>
<ClCompile Include="..\..\xbmc\input\KeyboardStat.cpp">
<Filter>input</Filter>
</ClCompile>
@@ -3179,6 +3176,9 @@
<ClCompile Include="..\..\xbmc\utils\Speed.cpp">
<Filter>utils</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\input\KeyboardLayoutManager.cpp">
+ <Filter>input</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
@@ -4128,9 +4128,6 @@
<ClInclude Include="..\..\xbmc\input\KeyboardLayout.h">
<Filter>input</Filter>
</ClInclude>
- <ClInclude Include="..\..\xbmc\input\KeyboardLayoutConfiguration.h">
- <Filter>input</Filter>
- </ClInclude>
<ClInclude Include="..\..\xbmc\input\KeyboardStat.h">
<Filter>input</Filter>
</ClInclude>
@@ -6177,6 +6174,9 @@
<ClInclude Include="..\..\xbmc\utils\Speed.h">
<Filter>utils</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\input\KeyboardLayoutManager.h">
+ <Filter>input</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
@@ -6222,4 +6222,4 @@
<Filter>interfaces\swig</Filter>
</CustomBuild>
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/system/keyboardlayouts.xml b/system/keyboardlayouts.xml
deleted file mode 100644
index b1aa50835e..0000000000
--- a/system/keyboardlayouts.xml
+++ /dev/null
@@ -1,447 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-Please use English language names instead.
-Default font lacks support for all characters
--->
-<keyboardlayouts>
- <layout name="Arabic QWERTY">
- <keyboard>
- <row>١٢٣٤٥٦٧٨٩٠</row>
- <row>ضصثقفغعهخحج</row>
- <row>شسيبلاتنمكة</row>
- <row>ءظطذدزروی</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>أإآؤ</row>
- <row>ـئ‘،؛</row>
- <row>ًٌٍََُِّْ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~؟</row>
- </keyboard>
- </layout>
- <layout name="English QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>qwertyuiop</row>
- <row>asdfghjkl</row>
- <row>zxcvbnm</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOP</row>
- <row>ASDFGHJKL</row>
- <row>ZXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="English AZERTY">
- <keyboard>
- <row>1234567890</row>
- <row>azertyuiop</row>
- <row>qsdfghjklm</row>
- <row>wxcvbn</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>AZERTYUIOP</row>
- <row>QSDFGHJKLM</row>
- <row>WXCVBN</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~éèçà</row>
- </keyboard>
- </layout>
- <layout name="English ABC">
- <keyboard>
- <row>0123456789</row>
- <row>abcdefghij</row>
- <row>klmnopqrst</row>
- <row>uvwxyz</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789</row>
- <row>ABCDEFGHIJ</row>
- <row>KLMNOPQRST</row>
- <row>UVWXYZ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Bulgarian ЯВЕРТЪ">
- <keyboard>
- <row>ч1234567890</row>
- <row>явертъуиопшщ</row>
- <row>асдфгхйклю</row>
- <row>зьцжбнм</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>Ч1234567890</row>
- <row>ЯВЕРТЪУИОПШЩ</row>
- <row>АСДФГХЙКЛЮ</row>
- <row>ЗЬЦЖБНМ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Bulgarian АБВ">
- <keyboard>
- <row>0123456789</row>
- <row>абвгдежзий</row>
- <row>клмнопрсту</row>
- <row>фхцчшщъьюя</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789</row>
- <row>АБВГДЕЖЗИЙ</row>
- <row>КЛМНОПРСТУ</row>
- <row>ФХЦЧШЩЪЬЮЯ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="German QWERTZ">
- <keyboard>
- <row>1234567890</row>
- <row>qwertzuiopü</row>
- <row>asdfghjklöä</row>
- <row>yxcvbnm</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTZUIOPÜ</row>
- <row>ASDFGHJKLÖÄ</row>
- <row>YXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Hungarian QWERTZ">
- <keyboard>
- <row>0123456789öüó</row>
- <row>qwertzuiopőú</row>
- <row>asdfghjkléáű</row>
- <row>íyxcvbnm,.-</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789ÖÜÓ</row>
- <row>QWERTZUIOPŐÚ</row>
- <row>ASDFGHJKLÉÁŰ</row>
- <row>ÍYXCVBNM,.-</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>§'"+!/=()~</row>
- <row>^;\|Ä€Í÷×ä</row>
- <row>đĐ[]íłŁ$ߤ</row>
- <row>#@{}&lt;&gt;*?:_</row>
- </keyboard>
- </layout>
- <layout name="Polish QWERTY">
- <keyboard>
- <row>`1234567890-</row>
- <row>qwertyuiopąć</row>
- <row>asdfghjklęłń</row>
- <row>zxcvbnmóśżź</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>~1234567890_</row>
- <row>QWERTYUIOPĄĆ</row>
- <row>ASDFGHJKLĘŁŃ</row>
- <row>ZXCVBNMÓŚŻŹ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>!@#$%^&amp;*()=+</row>
- <row>\|€£§[]{};',</row>
- <row>./:"&lt;&gt;?</row>
- <row></row>
- </keyboard>
- </layout>
- <layout name="Portuguese (Portugal) QWERTY">
- <keyboard>
- <row>\1234567890'</row>
- <row>qwertyuiop+´</row>
- <row>asdfghjklçº~</row>
- <row>&lt;zxcvbnm,.-</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>|1234567890?</row>
- <row>QWERTYUIOP*`</row>
- <row>ASDFGHJKLǪ^</row>
- <row>&gt;ZXCVBNM;:_</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>|!"#$%&amp;/()=?</row>
- <row>@£§{[]}€áãâà</row>
- <row>éêíóõôúÁÃÂÀÉ</row>
- <row>ÊÍÓÕÔÚ«»¨</row>
- </keyboard>
- </layout>
- <layout name="Russian ЙЦУКЕН">
- <keyboard>
- <row>ё1234567890</row>
- <row>йцукенгшщзхъ</row>
- <row>фывапролджэ</row>
- <row>ячсмитьбю</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>Ё1234567890</row>
- <row>ЙЦУКЕНГШЩЗХЪ</row>
- <row>ФЫВАПРОЛДЖЭ</row>
- <row>ЯЧСМИТЬБЮ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Russian АБВ">
- <keyboard>
- <row>0123456789</row>
- <row>абвгдеёжзий</row>
- <row>клмнопрстуф</row>
- <row>хцчшщъыьэюя</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789</row>
- <row>АБВГДЕЁЖЗИЙ</row>
- <row>КЛМНОПРСТУФ</row>
- <row>ХЦЧШЩЪЫЬЭЮЯ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Spanish QWERTY">
- <keyboard>
- <row>1234567890'¡</row>
- <row>qwertyuiop`+</row>
- <row>asdfghjklñ´ç</row>
- <row>&lt;zxcvbnm,.-</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890?¿</row>
- <row>QWERTYUIOP^*</row>
- <row>ASDFGHJKLѨÇ</row>
- <row>&gt;ZXCVBNM;:_</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>!"·$%&amp;/()=?¿</row>
- <row>\|@#€£¥[]{}~</row>
- <row>áéíóúü¹²³ªº±</row>
- <row>ÁÉÍÓÚܼ½¾«»§</row>
- </keyboard>
- </layout>
- <layout name="Hebrew QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>קראטוןםפ</row>
- <row>שדגכעיחלךף</row>
- <row>זסבהנמצתץ</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOP</row>
- <row>ASDFGHJKL</row>
- <row>ZXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Hebrew ABC">
- <keyboard>
- <row>0123456789</row>
- <row>יטחזוהדגבא</row>
- <row>ףפעסןנםמלכ</row>
- <row>תשרקץצ</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789</row>
- <row>ABCDEFGHIJ</row>
- <row>KLMNOPQRST</row>
- <row>UVWXYZ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Norwegian QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>qwertyuiopå</row>
- <row>asdfghjkløæ</row>
- <row>zxcvbnm</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOPÅ</row>
- <row>ASDFGHJKLØÆ</row>
- <row>ZXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Danish QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>qwertyuiopå</row>
- <row>asdfghjklæø</row>
- <row>zxcvbnm</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOPÅ</row>
- <row>ASDFGHJKLÆØ</row>
- <row>ZXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Swedish QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>qwertyuiopå</row>
- <row>asdfghjklöä</row>
- <row>zxcvbnm</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOPÅ</row>
- <row>ASDFGHJKLÖÄ</row>
- <row>ZXCVBNM</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Turkish QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>qwertyuıopğü</row>
- <row>asdfghjklşi</row>
- <row>zxcvbnmöç</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>QWERTYUIOPĞÜ</row>
- <row>ASDFGHJKLŞİ</row>
- <row>ZXCVBNMÖÇ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Ukrainian ЙЦУКЕН">
- <keyboard>
- <row>'1234567890</row>
- <row>йцукенгшщзхї</row>
- <row>фівапролджє</row>
- <row>ґячсмитьбю</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>'1234567890</row>
- <row>ЙЦУКЕНГШЩЗХЇ</row>
- <row>ФІВАПРОЛДЖЄ</row>
- <row>ҐЯЧСМИТЬБЮ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Ukrainian АБВ">
- <keyboard>
- <row>0123456789</row>
- <row>абвгґдеєжзиі</row>
- <row>їйклмнопрст</row>
- <row>уфхцчшцьюя'</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>0123456789</row>
- <row>АБВГҐДЕЄЖЗИІ</row>
- <row>ЇЙКЛМНОПРСТ</row>
- <row>УФХЦЧШЩЬЮЯ'</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(</row>
- <row>[]{}-_=+;:</row>
- <row>'",.&lt;&gt;/?\|</row>
- <row>`~</row>
- </keyboard>
- </layout>
- <layout name="Greek QWERTY">
- <keyboard>
- <row>1234567890</row>
- <row>ςερτυθιοπ</row>
- <row>ασδφγηξκλ</row>
- <row>ζχψωβνμ</row>
- </keyboard>
- <keyboard modifiers="shift">
- <row>1234567890</row>
- <row>ΕΡΤΥΘΙΟΠ</row>
- <row>ΑΣΔΦΓΗΞΚΛ</row>
- <row>ΖΧΨΩΒΝΜ</row>
- </keyboard>
- <keyboard modifiers="symbol,shift+symbol">
- <row>)!@#$%^&amp;*(€</row>
- <row>[]{}-_=+;:~</row>
- <row>'",.&lt;&gt;/?\|`</row>
- <row>έύίόάήώϋϊΰΐ</row>
- </keyboard>
- </layout>
-</keyboardlayouts>
diff --git a/system/keyboardlayouts/arabic.xml b/system/keyboardlayouts/arabic.xml
new file mode 100644
index 0000000000..3b37ff0ad0
--- /dev/null
+++ b/system/keyboardlayouts/arabic.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Arabic" layout="QWERTY">
+ <keyboard>
+ <row>١٢٣٤٥٦٧٨٩٠</row>
+ <row>ضصثقفغعهخحج</row>
+ <row>شسيبلاتنمكة</row>
+ <row>ءظطذدزروی</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>أإآؤ</row>
+ <row>ـئ‘،؛</row>
+ <row>ًٌٍََُِّْ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~؟</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/bulgarian.xml b/system/keyboardlayouts/bulgarian.xml
new file mode 100644
index 0000000000..dee53f554c
--- /dev/null
+++ b/system/keyboardlayouts/bulgarian.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Bulgarian" layout="ЯВЕРТЪ">
+ <keyboard>
+ <row>ч1234567890</row>
+ <row>явертъуиопшщ</row>
+ <row>асдфгхйклю</row>
+ <row>зьцжбнм</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>Ч1234567890</row>
+ <row>ЯВЕРТЪУИОПШЩ</row>
+ <row>АСДФГХЙКЛЮ</row>
+ <row>ЗЬЦЖБНМ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+ <layout language="Bulgarian" layout="АБВ">
+ <keyboard>
+ <row>0123456789</row>
+ <row>абвгдежзий</row>
+ <row>клмнопрсту</row>
+ <row>фхцчшщъьюя</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789</row>
+ <row>АБВГДЕЖЗИЙ</row>
+ <row>КЛМНОПРСТУ</row>
+ <row>ФХЦЧШЩЪЬЮЯ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/danish.xml b/system/keyboardlayouts/danish.xml
new file mode 100644
index 0000000000..2ceffecba0
--- /dev/null
+++ b/system/keyboardlayouts/danish.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Danish" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertyuiopå</row>
+ <row>asdfghjklæø</row>
+ <row>zxcvbnm</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOPÅ</row>
+ <row>ASDFGHJKLÆØ</row>
+ <row>ZXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/english.xml b/system/keyboardlayouts/english.xml
new file mode 100644
index 0000000000..eb4ca6259d
--- /dev/null
+++ b/system/keyboardlayouts/english.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="English" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertyuiop</row>
+ <row>asdfghjkl</row>
+ <row>zxcvbnm</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOP</row>
+ <row>ASDFGHJKL</row>
+ <row>ZXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+ <layout language="English" layout="AZERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>azertyuiop</row>
+ <row>qsdfghjklm</row>
+ <row>wxcvbn</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>AZERTYUIOP</row>
+ <row>QSDFGHJKLM</row>
+ <row>WXCVBN</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~éèçà</row>
+ </keyboard>
+ </layout>
+ <layout language="English" layout="ABC">
+ <keyboard>
+ <row>0123456789</row>
+ <row>abcdefghij</row>
+ <row>klmnopqrst</row>
+ <row>uvwxyz</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789</row>
+ <row>ABCDEFGHIJ</row>
+ <row>KLMNOPQRST</row>
+ <row>UVWXYZ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/german.xml b/system/keyboardlayouts/german.xml
new file mode 100644
index 0000000000..e18a00ffe7
--- /dev/null
+++ b/system/keyboardlayouts/german.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="German" layout="QWERTZ">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertzuiopü</row>
+ <row>asdfghjklöä</row>
+ <row>yxcvbnm</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTZUIOPÜ</row>
+ <row>ASDFGHJKLÖÄ</row>
+ <row>YXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/greek.xml b/system/keyboardlayouts/greek.xml
new file mode 100644
index 0000000000..0c4ee93d6d
--- /dev/null
+++ b/system/keyboardlayouts/greek.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Greek" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>ςερτυθιοπ</row>
+ <row>ασδφγηξκλ</row>
+ <row>ζχψωβνμ</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>ΕΡΤΥΘΙΟΠ</row>
+ <row>ΑΣΔΦΓΗΞΚΛ</row>
+ <row>ΖΧΨΩΒΝΜ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(€</row>
+ <row>[]{}-_=+;:~</row>
+ <row>'",.&lt;&gt;/?\|`</row>
+ <row>έύίόάήώϋϊΰΐ</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/hebrew.xml b/system/keyboardlayouts/hebrew.xml
new file mode 100644
index 0000000000..8cd23abddf
--- /dev/null
+++ b/system/keyboardlayouts/hebrew.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Hebrew" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>קראטוןםפ</row>
+ <row>שדגכעיחלךף</row>
+ <row>זסבהנמצתץ</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOP</row>
+ <row>ASDFGHJKL</row>
+ <row>ZXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+ <layout language="Hebrew" layout="ABC">
+ <keyboard>
+ <row>0123456789</row>
+ <row>יטחזוהדגבא</row>
+ <row>ףפעסןנםמלכ</row>
+ <row>תשרקץצ</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789</row>
+ <row>ABCDEFGHIJ</row>
+ <row>KLMNOPQRST</row>
+ <row>UVWXYZ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/hungarian.xml b/system/keyboardlayouts/hungarian.xml
new file mode 100644
index 0000000000..b1f433aed9
--- /dev/null
+++ b/system/keyboardlayouts/hungarian.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Hungarian" layout="QWERTZ">
+ <keyboard>
+ <row>0123456789öüó</row>
+ <row>qwertzuiopőú</row>
+ <row>asdfghjkléáű</row>
+ <row>íyxcvbnm,.-</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789ÖÜÓ</row>
+ <row>QWERTZUIOPŐÚ</row>
+ <row>ASDFGHJKLÉÁŰ</row>
+ <row>ÍYXCVBNM,.-</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>§'"+!/=()~</row>
+ <row>^;\|Ä€Í÷×ä</row>
+ <row>đĐ[]íłŁ$ߤ</row>
+ <row>#@{}&lt;&gt;*?:_</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/norwegian.xml b/system/keyboardlayouts/norwegian.xml
new file mode 100644
index 0000000000..8db7f78f2b
--- /dev/null
+++ b/system/keyboardlayouts/norwegian.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Norwegian" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertyuiopå</row>
+ <row>asdfghjkløæ</row>
+ <row>zxcvbnm</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOPÅ</row>
+ <row>ASDFGHJKLØÆ</row>
+ <row>ZXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/polish.xml b/system/keyboardlayouts/polish.xml
new file mode 100644
index 0000000000..91e631e2da
--- /dev/null
+++ b/system/keyboardlayouts/polish.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Polish" layout="QWERTY">
+ <keyboard>
+ <row>`1234567890-</row>
+ <row>qwertyuiopąć</row>
+ <row>asdfghjklęłń</row>
+ <row>zxcvbnmóśżź</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>~1234567890_</row>
+ <row>QWERTYUIOPĄĆ</row>
+ <row>ASDFGHJKLĘŁŃ</row>
+ <row>ZXCVBNMÓŚŻŹ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>!@#$%^&amp;*()=+</row>
+ <row>\|€£§[]{};',</row>
+ <row>./:"&lt;&gt;?</row>
+ <row></row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/portuguese.xml b/system/keyboardlayouts/portuguese.xml
new file mode 100644
index 0000000000..6730ed6dad
--- /dev/null
+++ b/system/keyboardlayouts/portuguese.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Portuguese (Portugal)" layout="QWERTY">
+ <keyboard>
+ <row>\1234567890'</row>
+ <row>qwertyuiop+´</row>
+ <row>asdfghjklçº~</row>
+ <row>&lt;zxcvbnm,.-</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>|1234567890?</row>
+ <row>QWERTYUIOP*`</row>
+ <row>ASDFGHJKLǪ^</row>
+ <row>&gt;ZXCVBNM;:_</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>|!"#$%&amp;/()=?</row>
+ <row>@£§{[]}€áãâà</row>
+ <row>éêíóõôúÁÃÂÀÉ</row>
+ <row>ÊÍÓÕÔÚ«»¨</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/russian.xml b/system/keyboardlayouts/russian.xml
new file mode 100644
index 0000000000..d0c9102b31
--- /dev/null
+++ b/system/keyboardlayouts/russian.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Russian" layout="ЙЦУКЕН">
+ <keyboard>
+ <row>ё1234567890</row>
+ <row>йцукенгшщзхъ</row>
+ <row>фывапролджэ</row>
+ <row>ячсмитьбю</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>Ё1234567890</row>
+ <row>ЙЦУКЕНГШЩЗХЪ</row>
+ <row>ФЫВАПРОЛДЖЭ</row>
+ <row>ЯЧСМИТЬБЮ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+ <layout language="Russian" layout="АБВ">
+ <keyboard>
+ <row>0123456789</row>
+ <row>абвгдеёжзий</row>
+ <row>клмнопрстуф</row>
+ <row>хцчшщъыьэюя</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789</row>
+ <row>АБВГДЕЁЖЗИЙ</row>
+ <row>КЛМНОПРСТУФ</row>
+ <row>ХЦЧШЩЪЫЬЭЮЯ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/spanish.xml b/system/keyboardlayouts/spanish.xml
new file mode 100644
index 0000000000..866e9b019e
--- /dev/null
+++ b/system/keyboardlayouts/spanish.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Spanish" layout="QWERTY">
+ <keyboard>
+ <row>1234567890'¡</row>
+ <row>qwertyuiop`+</row>
+ <row>asdfghjklñ´ç</row>
+ <row>&lt;zxcvbnm,.-</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890?¿</row>
+ <row>QWERTYUIOP^*</row>
+ <row>ASDFGHJKLѨÇ</row>
+ <row>&gt;ZXCVBNM;:_</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>!"·$%&amp;/()=?¿</row>
+ <row>\|@#€£¥[]{}~</row>
+ <row>áéíóúü¹²³ªº±</row>
+ <row>ÁÉÍÓÚܼ½¾«»§</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/swedish.xml b/system/keyboardlayouts/swedish.xml
new file mode 100644
index 0000000000..62f920c6df
--- /dev/null
+++ b/system/keyboardlayouts/swedish.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Swedish" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertyuiopå</row>
+ <row>asdfghjklöä</row>
+ <row>zxcvbnm</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOPÅ</row>
+ <row>ASDFGHJKLÖÄ</row>
+ <row>ZXCVBNM</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/turkish.xml b/system/keyboardlayouts/turkish.xml
new file mode 100644
index 0000000000..3a123db4cb
--- /dev/null
+++ b/system/keyboardlayouts/turkish.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Turkish" layout="QWERTY">
+ <keyboard>
+ <row>1234567890</row>
+ <row>qwertyuıopğü</row>
+ <row>asdfghjklşi</row>
+ <row>zxcvbnmöç</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>1234567890</row>
+ <row>QWERTYUIOPĞÜ</row>
+ <row>ASDFGHJKLŞİ</row>
+ <row>ZXCVBNMÖÇ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/system/keyboardlayouts/ukrainian.xml b/system/keyboardlayouts/ukrainian.xml
new file mode 100644
index 0000000000..b187f5a2b3
--- /dev/null
+++ b/system/keyboardlayouts/ukrainian.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Please use English language names instead.
+Default font lacks support for all characters
+-->
+<keyboardlayouts>
+ <layout language="Ukrainian" layout="ЙЦУКЕН">
+ <keyboard>
+ <row>'1234567890</row>
+ <row>йцукенгшщзхї</row>
+ <row>фівапролджє</row>
+ <row>ґячсмитьбю</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>'1234567890</row>
+ <row>ЙЦУКЕНГШЩЗХЇ</row>
+ <row>ФІВАПРОЛДЖЄ</row>
+ <row>ҐЯЧСМИТЬБЮ</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+ <layout language="Ukrainian" layout="АБВ">
+ <keyboard>
+ <row>0123456789</row>
+ <row>абвгґдеєжзиі</row>
+ <row>їйклмнопрст</row>
+ <row>уфхцчшцьюя'</row>
+ </keyboard>
+ <keyboard modifiers="shift">
+ <row>0123456789</row>
+ <row>АБВГҐДЕЄЖЗИІ</row>
+ <row>ЇЙКЛМНОПРСТ</row>
+ <row>УФХЦЧШЩЬЮЯ'</row>
+ </keyboard>
+ <keyboard modifiers="symbol,shift+symbol">
+ <row>)!@#$%^&amp;*(</row>
+ <row>[]{}-_=+;:</row>
+ <row>'",.&lt;&gt;/?\|</row>
+ <row>`~</row>
+ </keyboard>
+ </layout>
+</keyboardlayouts>
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index c974695699..a60c4827aa 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -100,6 +100,7 @@
#include "utils/SeekHandler.h"
#include "view/ViewStateSettings.h"
+#include "input/KeyboardLayoutManager.h"
#include "input/KeyboardStat.h"
#include "input/XBMC_vkeys.h"
#include "input/MouseStat.h"
@@ -704,6 +705,13 @@ bool CApplication::Create()
// Initialize after loading settings to get joystick deadzone setting
CInputManager::Get().InitializeInputs();
+ // load the keyboard layouts
+ if (!CKeyboardLayoutManager::Get().Load())
+ {
+ CLog::Log(LOGFATAL, "CApplication::Create: Unable to load keyboard layouts");
+ return false;
+ }
+
#if defined(TARGET_DARWIN_OSX)
// Configure and possible manually start the helper.
XBMCHelper::GetInstance().Configure();
diff --git a/xbmc/dialogs/GUIDialogKeyboardGeneric.cpp b/xbmc/dialogs/GUIDialogKeyboardGeneric.cpp
index a29cd46024..8c9b94896a 100644
--- a/xbmc/dialogs/GUIDialogKeyboardGeneric.cpp
+++ b/xbmc/dialogs/GUIDialogKeyboardGeneric.cpp
@@ -22,6 +22,7 @@
#include "input/XBMC_vkeys.h"
#include "guilib/GUIEditControl.h"
#include "guilib/GUIWindowManager.h"
+#include "input/KeyboardLayoutManager.h"
#include "input/Key.h"
#include "guilib/LocalizeStrings.h"
#include "GUIUserMessages.h"
@@ -90,15 +91,14 @@ void CGUIDialogKeyboardGeneric::OnInitWindow()
// fill in the keyboard layouts
m_currentLayout = 0;
m_layouts.clear();
- std::vector<CKeyboardLayout> keyLayouts = CKeyboardLayout::LoadLayouts();
- const CSetting *setting = CSettings::Get().GetSetting("locale.keyboardlayouts");
- std::vector<std::string> layouts;
- if (setting)
- layouts = StringUtils::Split(setting->ToString(), '|');
- for (std::vector<CKeyboardLayout>::const_iterator j = keyLayouts.begin(); j != keyLayouts.end(); ++j)
+ const KeyboardLayouts& keyboardLayouts = CKeyboardLayoutManager::Get().GetLayouts();
+ std::vector<CVariant> layoutNames = CSettings::Get().GetList("locale.keyboardlayouts");
+
+ for (std::vector<CVariant>::const_iterator layoutName = layoutNames.begin(); layoutName != layoutNames.end(); ++layoutName)
{
- if (std::find(layouts.begin(), layouts.end(), j->GetName()) != layouts.end())
- m_layouts.push_back(*j);
+ KeyboardLayouts::const_iterator keyboardLayout = keyboardLayouts.find(layoutName->asString());
+ if (keyboardLayout != keyboardLayouts.end())
+ m_layouts.push_back(keyboardLayout->second);
}
// set alphabetic (capitals)
@@ -318,14 +318,14 @@ void CGUIDialogKeyboardGeneric::UpdateButtons()
CKeyboardLayout layout = m_layouts.empty() ? CKeyboardLayout() : m_layouts[m_currentLayout];
SET_CONTROL_LABEL(CTL_BUTTON_LAYOUT, layout.GetName());
- unsigned int modifiers = CKeyboardLayout::MODIFIER_KEY_NONE;
+ unsigned int modifiers = CKeyboardLayout::ModifierKeyNone;
if ((m_keyType == CAPS && !m_bShift) || (m_keyType == LOWER && m_bShift))
- modifiers |= CKeyboardLayout::MODIFIER_KEY_SHIFT;
+ modifiers |= CKeyboardLayout::ModifierKeyShift;
if (m_keyType == SYMBOLS)
{
- modifiers |= CKeyboardLayout::MODIFIER_KEY_SYMBOL;
+ modifiers |= CKeyboardLayout::ModifierKeySymbol;
if (m_bShift)
- modifiers |= CKeyboardLayout::MODIFIER_KEY_SHIFT;
+ modifiers |= CKeyboardLayout::ModifierKeyShift;
}
for (unsigned int row = 0; row < BUTTONS_MAX_ROWS; row++)
diff --git a/xbmc/input/KeyboardLayout.cpp b/xbmc/input/KeyboardLayout.cpp
index 511c676b0e..7a4f344c37 100644
--- a/xbmc/input/KeyboardLayout.cpp
+++ b/xbmc/input/KeyboardLayout.cpp
@@ -18,53 +18,86 @@
*
*/
+#include <algorithm>
+#include <set>
+
#include "KeyboardLayout.h"
+#include "guilib/LocalizeStrings.h"
#include "settings/lib/Setting.h"
#include "utils/CharsetConverter.h"
+#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
-#include <set>
-#include <algorithm>
-#define KEYBOARD_LAYOUTS_XML "special://xbmc/system/keyboardlayouts.xml"
+CKeyboardLayout::CKeyboardLayout()
+{ }
-CKeyboardLayout::CKeyboardLayout() : m_name("")
-{
-}
+CKeyboardLayout::~CKeyboardLayout()
+{ }
-CKeyboardLayout::CKeyboardLayout(const std::string &name, const TiXmlElement &element) : m_name(name)
+bool CKeyboardLayout::Load(const TiXmlElement* element)
{
- const TiXmlElement *keyboard = element.FirstChildElement("keyboard");
- while (keyboard)
+ const char* language = element->Attribute("language");
+ if (language == NULL)
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayout: invalid \"language\" attribute");
+ return false;
+ }
+
+ m_language = language;
+ if (m_language.empty())
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayout: empty \"language\" attribute");
+ return false;
+ }
+
+ const char* layout = element->Attribute("layout");
+ if (layout == NULL)
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayout: invalid \"layout\" attribute");
+ return false;
+ }
+
+ m_layout = layout;
+ if (m_layout.empty())
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayout: empty \"layout\" attribute");
+ return false;
+ }
+
+ const TiXmlElement *keyboard = element->FirstChildElement("keyboard");
+ while (keyboard != NULL)
{
// parse modifiers keys
std::set<unsigned int> modifierKeysSet;
- if (keyboard->Attribute("modifiers"))
+ const char* strModifiers = keyboard->Attribute("modifiers");
+ if (strModifiers != NULL)
{
- std::string modifiers = keyboard->Attribute("modifiers");
+ std::string modifiers = strModifiers;
StringUtils::ToLower(modifiers);
std::vector<std::string> variants = StringUtils::Split(modifiers, ",");
for (std::vector<std::string>::const_iterator itv = variants.begin(); itv != variants.end(); ++itv)
{
- unsigned int iKeys = MODIFIER_KEY_NONE;
+ unsigned int iKeys = ModifierKeyNone;
std::vector<std::string> keys = StringUtils::Split(*itv, "+");
for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
{
std::string strKey = *it;
if (strKey == "shift")
- iKeys |= MODIFIER_KEY_SHIFT;
+ iKeys |= ModifierKeyShift;
else if (strKey == "symbol")
- iKeys |= MODIFIER_KEY_SYMBOL;
+ iKeys |= ModifierKeySymbol;
}
+
modifierKeysSet.insert(iKeys);
}
}
// parse keyboard rows
const TiXmlNode *row = keyboard->FirstChild("row");
- while (row)
+ while (row != NULL)
{
if (!row->NoChildren())
{
@@ -76,27 +109,41 @@ CKeyboardLayout::CKeyboardLayout(const std::string &name, const TiXmlElement &el
m_keyboards[*it].push_back(chars);
}
else
- m_keyboards[MODIFIER_KEY_NONE].push_back(chars);
+ m_keyboards[ModifierKeyNone].push_back(chars);
}
+
row = row->NextSibling();
}
keyboard = keyboard->NextSiblingElement();
}
+
+ if (m_keyboards.empty())
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayout: no keyboard layout found");
+ return false;
+ }
+
+ return true;
}
-CKeyboardLayout::~CKeyboardLayout(void)
+std::string CKeyboardLayout::GetIdentifier() const
{
+ return StringUtils::Format("%s %s", m_language.c_str(), m_layout.c_str());
+}
+std::string CKeyboardLayout::GetName() const
+{
+ return StringUtils::Format(g_localizeStrings.Get(311).c_str(), m_language.c_str(), m_layout.c_str());
}
std::string CKeyboardLayout::GetCharAt(unsigned int row, unsigned int column, unsigned int modifiers) const
{
Keyboards::const_iterator mod = m_keyboards.find(modifiers);
- if (modifiers != MODIFIER_KEY_NONE && mod != m_keyboards.end() && mod->second.empty())
+ if (modifiers != ModifierKeyNone && mod != m_keyboards.end() && mod->second.empty())
{
// fallback to basic keyboard
- mod = m_keyboards.find(MODIFIER_KEY_NONE);
+ mod = m_keyboards.find(ModifierKeyNone);
}
if (mod != m_keyboards.end())
@@ -117,53 +164,11 @@ std::vector<std::string> CKeyboardLayout::BreakCharacters(const std::string &cha
std::vector<std::string> result;
// break into utf8 characters
std::u32string chars32 = g_charsetConverter.utf8ToUtf32(chars);
- for (size_t i = 0; i < chars32.size(); i++)
+ for (std::u32string::const_iterator it = chars32.begin(); it != chars32.end(); ++it)
{
- std::u32string char32(1, chars32[i]);
+ std::u32string char32(1, *it);
result.push_back(g_charsetConverter.utf32ToUtf8(char32));
}
- return result;
-}
-
-CKeyboardLayout CKeyboardLayout::Load(const std::string& layout)
-{
- std::vector<CKeyboardLayout> layouts = LoadLayouts();
- for (std::vector<CKeyboardLayout>::const_iterator it = layouts.begin(); it != layouts.end(); ++it)
- {
- if (it->GetName() == layout)
- return *it;
- }
- return CKeyboardLayout();
-}
-std::vector<CKeyboardLayout> CKeyboardLayout::LoadLayouts()
-{
- std::vector<CKeyboardLayout> result;
- CXBMCTinyXML xmlDoc;
- if (xmlDoc.LoadFile(KEYBOARD_LAYOUTS_XML))
- {
- const TiXmlElement* root = xmlDoc.RootElement();
- if (root && root->ValueStr() == "keyboardlayouts")
- {
- const TiXmlElement* layout = root->FirstChildElement("layout");
- while (layout)
- {
- if (layout->Attribute("name"))
- result.push_back(CKeyboardLayout(layout->Attribute("name"), *layout));
- layout = layout->NextSiblingElement("layout");
- }
- }
- }
return result;
}
-
-void CKeyboardLayout::SettingOptionsKeyboardLayoutsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, void *data)
-{
- std::vector<CKeyboardLayout> layouts = LoadLayouts();
- for (std::vector<CKeyboardLayout>::const_iterator it = layouts.begin(); it != layouts.end(); ++it)
- {
- std::string name = it->GetName();
- list.push_back(make_pair(name, name));
- }
- std::sort(list.begin(), list.end());
-}
diff --git a/xbmc/input/KeyboardLayout.h b/xbmc/input/KeyboardLayout.h
index d540cb3214..0d34dd4986 100644
--- a/xbmc/input/KeyboardLayout.h
+++ b/xbmc/input/KeyboardLayout.h
@@ -1,10 +1,4 @@
-/*!
-\file KeyboardLayout.h
-\brief
-*/
-
#pragma once
-
/*
* Copyright (C) 2005-2013 Team XBMC
* http://xbmc.org
@@ -25,46 +19,33 @@
*
*/
-#include <string>
#include <map>
+#include <string>
#include <vector>
-/*!
- \ingroup keyboardlayouts
- \brief
- */
-
class TiXmlElement;
-class CSetting;
class CKeyboardLayout
{
public:
CKeyboardLayout();
- CKeyboardLayout(const std::string &name, const TiXmlElement& element);
- virtual ~CKeyboardLayout(void);
- const std::string& GetName() const { return m_name; }
- std::string GetCharAt(unsigned int row, unsigned int column, unsigned int modifiers = 0) const;
+ virtual ~CKeyboardLayout();
- enum MODIFIER_KEYS
- {
- MODIFIER_KEY_NONE = 0x00,
- MODIFIER_KEY_SHIFT = 0x01,
- MODIFIER_KEY_SYMBOL = 0x02
- };
+ bool Load(const TiXmlElement* element);
- /*! \brief helper to load a keyboard layout
- \param layout the layout to load.
- \return a CKeyboardLayout.
- */
- static CKeyboardLayout Load(const std::string &layout);
+ std::string GetIdentifier() const;
+ std::string GetName() const;
+ const std::string& GetLanguage() const { return m_language; }
+ const std::string& GetLayout() const { return m_layout; }
- /*! \brief helper to list available keyboard layouts
- \return a vector of CKeyboardLayouts with the layout names.
- */
- static std::vector<CKeyboardLayout> LoadLayouts();
+ enum ModifierKey
+ {
+ ModifierKeyNone = 0x00,
+ ModifierKeyShift = 0x01,
+ ModifierKeySymbol = 0x02
+ };
- static void SettingOptionsKeyboardLayoutsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, void* data);
+ std::string GetCharAt(unsigned int row, unsigned int column, unsigned int modifiers = 0) const;
private:
static std::vector<std::string> BreakCharacters(const std::string &chars);
@@ -72,6 +53,7 @@ private:
typedef std::vector< std::vector<std::string> > KeyboardRows;
typedef std::map<unsigned int, KeyboardRows> Keyboards;
- std::string m_name;
- Keyboards m_keyboards;
+ std::string m_language;
+ std::string m_layout;
+ Keyboards m_keyboards;
};
diff --git a/xbmc/input/KeyboardLayoutConfiguration.cpp b/xbmc/input/KeyboardLayoutConfiguration.cpp
deleted file mode 100644
index 916a2e559d..0000000000
--- a/xbmc/input/KeyboardLayoutConfiguration.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * 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, 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 XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "KeyboardLayoutConfiguration.h"
-#include "utils/CharsetConverter.h"
-#include "utils/XBMCTinyXML.h"
-#include "utils/XMLUtils.h"
-
-using namespace std;
-CKeyboardLayoutConfiguration g_keyboardLayoutConfiguration;
-
-CKeyboardLayoutConfiguration::CKeyboardLayoutConfiguration()
-{
- SetDefaults();
-}
-
-
-CKeyboardLayoutConfiguration::~CKeyboardLayoutConfiguration()
-{
- SetDefaults();
-}
-
-void CKeyboardLayoutConfiguration::SetDefaults()
-{
- m_changeXbmcCharRegardlessModifiers.clear();
- m_changeXbmcCharWithRalt.clear();
- m_deriveXbmcCharFromVkeyRegardlessModifiers.clear();
- m_deriveXbmcCharFromVkeyWithShift.clear();
- m_deriveXbmcCharFromVkeyWithRalt.clear();
-}
-
-bool CKeyboardLayoutConfiguration::Load(const std::string& strFileName)
-{
- SetDefaults();
-
- CXBMCTinyXML xmlDoc;
- if (!xmlDoc.LoadFile(strFileName))
- {
- CLog::Log(LOGINFO, "unable to load %s: %s at line %d", strFileName.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow());
- return false;
- }
-
- TiXmlElement* pRootElement = xmlDoc.RootElement();
- std::string strValue = pRootElement->Value();
- if (strValue != "keyboard_layout")
- {
- CLog::Log(LOGERROR, "%s Doesn't contain <keyboard_layout>", strFileName.c_str());
- return false;
- }
-
- CLog::Log(LOGDEBUG, "reading char2char ");
- const TiXmlElement* pMapChangeXbmcCharRegardlessModifiers = pRootElement->FirstChildElement("char2char");
- readCharMapFromXML(pMapChangeXbmcCharRegardlessModifiers, m_changeXbmcCharRegardlessModifiers, ("char2char"));
-
- CLog::Log(LOGDEBUG, "reading char2char_ralt ");
- const TiXmlElement* pMapChangeXbmcCharWithRalt = pRootElement->FirstChildElement("char2char_ralt");
- readCharMapFromXML(pMapChangeXbmcCharWithRalt, m_changeXbmcCharWithRalt, ("char2char_ralt"));
-
- CLog::Log(LOGDEBUG, "reading vkey2char ");
- const TiXmlElement* pMapDeriveXbmcCharFromVkeyRegardlessModifiers = pRootElement->FirstChildElement("vkey2char");
- readByteMapFromXML(pMapDeriveXbmcCharFromVkeyRegardlessModifiers, m_deriveXbmcCharFromVkeyRegardlessModifiers, ("vkey2char"));
-
- CLog::Log(LOGDEBUG, "reading vkey2char_shift ");
- const TiXmlElement* pMapDeriveXbmcCharFromVkeyWithShift = pRootElement->FirstChildElement("vkey2char_shift");
- readByteMapFromXML(pMapDeriveXbmcCharFromVkeyWithShift, m_deriveXbmcCharFromVkeyWithShift, ("vkey2char_shift"));
-
- CLog::Log(LOGDEBUG, "reading vkey2char_ralt ");
- const TiXmlElement* pMapDeriveXbmcCharFromVkeyWithRalt = pRootElement->FirstChildElement("vkey2char_ralt");
- readByteMapFromXML(pMapDeriveXbmcCharFromVkeyWithRalt, m_deriveXbmcCharFromVkeyWithRalt, ("vkey2char_ralt"));
-
- return true;
-}
-
-void CKeyboardLayoutConfiguration::readCharMapFromXML(const TiXmlElement* pXMLMap, map<WCHAR, WCHAR>& charToCharMap, const char* mapRootElement)
-{
- if (pXMLMap && !pXMLMap->NoChildren())
- { // map keys
- const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
- while (pEntry)
- {
- std::string strInChar = XMLUtils::GetAttribute(pEntry, "inchar");
- std::string strOutChar = XMLUtils::GetAttribute(pEntry, "outchar");
- if (!strInChar.empty() && !strOutChar.empty())
- {
- std::wstring fromStr;
- g_charsetConverter.utf8ToW(strInChar, fromStr);
- std::wstring toStr;
- g_charsetConverter.utf8ToW(strOutChar, toStr);
- if (fromStr.size()==1 && toStr.size()==1)
- {
- charToCharMap.insert(pair<WCHAR, WCHAR>(fromStr[0], toStr[0]));
- CLog::Log(LOGDEBUG, "insert map entry from %c to %c ", fromStr[0], toStr[0]);
- }
- else
- {
- CLog::Log(LOGERROR, "String from %ls or to %ls does not have the expected length of 1", fromStr.c_str(), toStr.c_str());
- }
- }
- else
- {
- CLog::Log(LOGERROR, "map entry misses attribute <inchar> or <outchar> or content of them");
- }
- pEntry = pEntry->NextSiblingElement();
- }
- }
- else
- {
- CLog::Log(LOGDEBUG, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
- }
-}
-
-void CKeyboardLayoutConfiguration::readByteMapFromXML(const TiXmlElement* pXMLMap, map<BYTE, WCHAR>& charToCharMap, const char* mapRootElement)
-{
- if (pXMLMap && !pXMLMap->NoChildren())
- { // map keys
- const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
- while (pEntry)
- {
- std::string strInHex = XMLUtils::GetAttribute(pEntry, "inhex");
- std::string strOutChar = XMLUtils::GetAttribute(pEntry, "outchar");
- if (!strInHex.empty() && !strOutChar.empty())
- {
- std::string hexValue = strInHex;
- std::wstring toStr;
- g_charsetConverter.utf8ToW(strOutChar, toStr);
-
- int from;
- if (sscanf(hexValue.c_str(), "%x", (unsigned int *)&from))
- {
- if (from != 0) // eats nearly any typing error as 0: catch it:
- {
- if (from < 256)
- {
- if (toStr.size()==1)
- {
- charToCharMap.insert(pair<BYTE, WCHAR>(from, toStr[0]));
- CLog::Log(LOGDEBUG, "insert map entry from %d to %c ", from, toStr[0]);
- }
- else
- {
- CLog::Log(LOGERROR, "String to %ls does not have the expected length of >=1", toStr.c_str());
- }
- }
- else
- {
- CLog::Log(LOGERROR, "From value %d was greater than 255! ", from);
- }
- }
- else
- {
- CLog::Log(LOGERROR, "Scanned from-value %d as 0 probably a (typing?) error! ", from);
- }
- }
- else
- {
- CLog::Log(LOGERROR, "Could not scan from-value %s (was no valid hex value) ", hexValue.c_str());
- }
- }
- else
- {
- CLog::Log(LOGERROR, "map entry misses attribute <inhex> or <outchar> or content of them");
- }
- pEntry = pEntry->NextSiblingElement();
- }
- }
- else
- {
- CLog::Log(LOGERROR, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
- }
-}
-
-bool CKeyboardLayoutConfiguration::containsChangeXbmcCharRegardlessModifiers(WCHAR key)
-{
- bool result = m_changeXbmcCharRegardlessModifiers.find(key) != m_changeXbmcCharRegardlessModifiers.end();
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found containsChangeXbmcCharRegardlessModifiers key char %c: bool: %d ", key, result);
-#endif
- return result;
-}
-
-bool CKeyboardLayoutConfiguration::containsChangeXbmcCharWithRalt(WCHAR key)
-{
- bool result = m_changeXbmcCharWithRalt.find(key) != m_changeXbmcCharWithRalt.end();
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found containsChangeXbmcCharWithRalt key char %c: bool: %d ", key, result);
-#endif
- return result;
-}
-
-bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key)
-{
- bool result = m_deriveXbmcCharFromVkeyRegardlessModifiers.find(key) != m_deriveXbmcCharFromVkeyRegardlessModifiers.end();
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyRegardlessModifiers key vkey %d: bool: %d ", key, result);
-#endif
- return result;
-}
-
-bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyWithShift(BYTE key)
-{
- bool result = m_deriveXbmcCharFromVkeyWithShift.find(key) != m_deriveXbmcCharFromVkeyWithShift.end();
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyWithShift key vkey %d: bool: %d ", key, result);
-#endif
- return result;
-}
-
-bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyWithRalt(BYTE key)
-{
- bool result = m_deriveXbmcCharFromVkeyWithRalt.find(key) != m_deriveXbmcCharFromVkeyWithRalt.end();
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyWithRalt key vkey %d: bool: %d ", key, result);
-#endif
- return result;
-}
-
-WCHAR CKeyboardLayoutConfiguration::valueOfChangeXbmcCharRegardlessModifiers(WCHAR key)
-{
- WCHAR result = (m_changeXbmcCharRegardlessModifiers.find(key))->second;
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found valueOfChangeXbmcCharRegardlessModifiers for char key %c: char %c ", key, result);
-#endif
- return result;
-}
-
-WCHAR CKeyboardLayoutConfiguration::valueOfChangeXbmcCharWithRalt(WCHAR key)
-{
- WCHAR result = (m_changeXbmcCharWithRalt.find(key))->second;
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found valueOfChangeXbmcCharWithRalt for char key %c: char %c ", key, result);
-#endif
- return result;
-}
-
-WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key)
-{
- WCHAR result = (m_deriveXbmcCharFromVkeyRegardlessModifiers.find(key))->second;
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyRegardlessModifiers for key vkey %d: char %c ", key, result);
-#endif
- return result;
-}
-
-WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyWithShift(BYTE key)
-{
- WCHAR result = (m_deriveXbmcCharFromVkeyWithShift.find(key))->second;
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyWithShift for key vkey %d: char %c ", key, result);
-#endif
- return result;
-}
-
-WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyWithRalt(BYTE key)
-{
- WCHAR result = (m_deriveXbmcCharFromVkeyWithRalt.find(key))->second;
-#ifdef DEBUG_KEYBOARD_GETCHAR
- CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyWithRalt for key vkey %d: char %c ", key, result);
-#endif
- return result;
-}
-
-
diff --git a/xbmc/input/KeyboardLayoutConfiguration.h b/xbmc/input/KeyboardLayoutConfiguration.h
deleted file mode 100644
index decb0a6692..0000000000
--- a/xbmc/input/KeyboardLayoutConfiguration.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef KEYBOARDLAYOUTCONFIGURATION_H
-#define KEYBOARDLAYOUTCONFIGURATION_H
-
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * 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, 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 XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-// Comment OUT, if not really debugging!!!
-// #define DEBUG_KEYBOARD_GETCHAR
-
-#ifdef TARGET_POSIX
-#include "linux/PlatformDefs.h"
-#elif defined (TARGET_WINDOWS)
-#include "windows.h"
-#else
-#include "xtl.h"
-#endif
-
-#include <map>
-#include <string>
-#include "utils/log.h"
-
-class TiXmlElement;
-
-class CKeyboardLayoutConfiguration
-{
-public:
- CKeyboardLayoutConfiguration();
- ~CKeyboardLayoutConfiguration();
-
- bool Load(const std::string& strFileName);
-
- bool containsChangeXbmcCharRegardlessModifiers(WCHAR key);
- bool containsChangeXbmcCharWithRalt(WCHAR key);
- bool containsDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key);
- bool containsDeriveXbmcCharFromVkeyWithShift(BYTE key);
- bool containsDeriveXbmcCharFromVkeyWithRalt(BYTE key);
-
- WCHAR valueOfChangeXbmcCharRegardlessModifiers(WCHAR key);
- WCHAR valueOfChangeXbmcCharWithRalt(WCHAR key);
- WCHAR valueOfDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key);
- WCHAR valueOfDeriveXbmcCharFromVkeyWithShift(BYTE key);
- WCHAR valueOfDeriveXbmcCharFromVkeyWithRalt(BYTE key);
-
-private:
- std::map<WCHAR, WCHAR> m_changeXbmcCharRegardlessModifiers;
- std::map<WCHAR, WCHAR> m_changeXbmcCharWithRalt;
- std::map<BYTE, WCHAR> m_deriveXbmcCharFromVkeyRegardlessModifiers;
- std::map<BYTE, WCHAR> m_deriveXbmcCharFromVkeyWithShift;
- std::map<BYTE, WCHAR> m_deriveXbmcCharFromVkeyWithRalt;
-
- void SetDefaults();
- void readCharMapFromXML(const TiXmlElement* pXMLMap, std::map<WCHAR, WCHAR>& charToCharMap, const char* mapRootElement);
- void readByteMapFromXML(const TiXmlElement* pXMLMap, std::map<BYTE, WCHAR>& charToCharMap, const char* mapRootElement);
-};
-
-extern CKeyboardLayoutConfiguration g_keyboardLayoutConfiguration;
-
-#endif
diff --git a/xbmc/input/KeyboardLayoutManager.cpp b/xbmc/input/KeyboardLayoutManager.cpp
new file mode 100644
index 0000000000..9ccc19427c
--- /dev/null
+++ b/xbmc/input/KeyboardLayoutManager.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <algorithm>
+
+#include "KeyboardLayoutManager.h"
+#include "FileItem.h"
+#include "URL.h"
+#include "filesystem/Directory.h"
+#include "utils/log.h"
+#include "utils/XBMCTinyXML.h"
+
+#define KEYBOARD_LAYOUTS_PATH "special://xbmc/system/keyboardlayouts"
+
+CKeyboardLayoutManager::~CKeyboardLayoutManager()
+{
+ Unload();
+}
+
+CKeyboardLayoutManager& CKeyboardLayoutManager::Get()
+{
+ static CKeyboardLayoutManager s_instance;
+ return s_instance;
+}
+
+bool CKeyboardLayoutManager::Load(const std::string& path /* = "" */)
+{
+ std::string layoutDirectory = path;
+ if (layoutDirectory.empty())
+ layoutDirectory = KEYBOARD_LAYOUTS_PATH;
+
+ if (!XFILE::CDirectory::Exists(layoutDirectory))
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unable to load keyboard layouts from non-existing directory \"%s\"", layoutDirectory.c_str());
+ return false;
+ }
+
+ CFileItemList layouts;
+ if (!XFILE::CDirectory::GetDirectory(CURL(layoutDirectory), layouts, ".xml") || layouts.IsEmpty())
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: no keyboard layouts found in %s", layoutDirectory.c_str());
+ return false;
+ }
+
+ CLog::Log(LOGINFO, "CKeyboardLayoutManager: loading keyboard layouts from %s...", layoutDirectory.c_str());
+ size_t oldLayoutCount = m_layouts.size();
+ for (int i = 0; i < layouts.Size(); i++)
+ {
+ std::string layoutPath = layouts[i]->GetPath();
+ if (layoutPath.empty())
+ continue;
+
+ CXBMCTinyXML xmlDoc;
+ if (!xmlDoc.LoadFile(layoutPath))
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unable to open %s", layoutPath.c_str());
+ continue;
+ }
+
+ const TiXmlElement* rootElement = xmlDoc.RootElement();
+ if (rootElement == NULL)
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: missing or invalid XML root element in %s", layoutPath.c_str());
+ continue;
+ }
+
+ if (rootElement->ValueStr() != "keyboardlayouts")
+ {
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unexpected XML root element \"%s\" in %s", rootElement->Value(), layoutPath.c_str());
+ continue;
+ }
+
+ const TiXmlElement* layoutElement = rootElement->FirstChildElement("layout");
+ while (layoutElement != NULL)
+ {
+ CKeyboardLayout layout;
+ if (!layout.Load(layoutElement))
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: failed to load %s", layoutPath.c_str());
+ else if (m_layouts.find(layout.GetIdentifier()) != m_layouts.end())
+ CLog::Log(LOGWARNING, "CKeyboardLayoutManager: duplicate layout with identifier \"%s\" in %s", layout.GetIdentifier().c_str(), layoutPath.c_str());
+ else
+ {
+ CLog::Log(LOGDEBUG, "CKeyboardLayoutManager: keyboard layout \"%s\" successfully loaded", layout.GetIdentifier().c_str());
+ m_layouts.insert(std::make_pair(layout.GetIdentifier(), layout));
+ }
+
+ layoutElement = layoutElement->NextSiblingElement();
+ }
+ }
+
+ return m_layouts.size() > oldLayoutCount;
+}
+
+void CKeyboardLayoutManager::Unload()
+{
+ m_layouts.clear();
+}
+
+bool CKeyboardLayoutManager::GetLayout(const std::string& name, CKeyboardLayout& layout) const
+{
+ if (name.empty())
+ return false;
+
+ KeyboardLayouts::const_iterator it = m_layouts.find(name);
+ if (it == m_layouts.end())
+ return false;
+
+ layout = it->second;
+ return true;
+}
+
+void CKeyboardLayoutManager::SettingOptionsKeyboardLayoutsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, void* data)
+{
+ for (KeyboardLayouts::const_iterator it = CKeyboardLayoutManager::Get().m_layouts.begin(); it != CKeyboardLayoutManager::Get().m_layouts.end(); ++it)
+ {
+ std::string name = it->second.GetName();
+ list.push_back(make_pair(name, name));
+ }
+
+ std::sort(list.begin(), list.end());
+}
diff --git a/xbmc/input/KeyboardLayoutManager.h b/xbmc/input/KeyboardLayoutManager.h
new file mode 100644
index 0000000000..497c92a598
--- /dev/null
+++ b/xbmc/input/KeyboardLayoutManager.h
@@ -0,0 +1,52 @@
+#pragma once
+/*
+ * Copyright (C) 2015 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <map>
+#include <string>
+
+#include "input/KeyboardLayout.h"
+
+class CSetting;
+
+typedef std::map<std::string, CKeyboardLayout> KeyboardLayouts;
+
+class CKeyboardLayoutManager
+{
+public:
+ virtual ~CKeyboardLayoutManager();
+
+ static CKeyboardLayoutManager& Get();
+
+ bool Load(const std::string& path = "");
+ void Unload();
+
+ const KeyboardLayouts& GetLayouts() const { return m_layouts; }
+ bool GetLayout(const std::string& name, CKeyboardLayout& layout) const;
+
+ static void SettingOptionsKeyboardLayoutsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, void* data);
+
+private:
+ CKeyboardLayoutManager() { }
+ CKeyboardLayoutManager(const CKeyboardLayoutManager&);
+ CKeyboardLayoutManager const& operator=(CKeyboardLayoutManager const&);
+
+ KeyboardLayouts m_layouts;
+};
diff --git a/xbmc/input/KeyboardStat.cpp b/xbmc/input/KeyboardStat.cpp
index 42bc50ffa6..7a9189c1b5 100644
--- a/xbmc/input/KeyboardStat.cpp
+++ b/xbmc/input/KeyboardStat.cpp
@@ -24,13 +24,13 @@
//#define DEBUG_KEYBOARD_GETCHAR
#include "KeyboardStat.h"
-#include "KeyboardLayoutConfiguration.h"
#include "windowing/XBMC_events.h"
#include "utils/TimeUtils.h"
#include "input/XBMC_keytable.h"
#include "input/XBMC_vkeys.h"
#include "peripherals/Peripherals.h"
#include "peripherals/devices/PeripheralHID.h"
+#include "utils/log.h"
using namespace std;
using namespace PERIPHERALS;
diff --git a/xbmc/input/Makefile b/xbmc/input/Makefile
index 5bf45894e2..fcad66efc6 100644
--- a/xbmc/input/Makefile
+++ b/xbmc/input/Makefile
@@ -1,7 +1,7 @@
SRCS=ButtonTranslator.cpp \
InertialScrollingHandler.cpp \
KeyboardLayout.cpp \
- KeyboardLayoutConfiguration.cpp \
+ KeyboardLayoutManager.cpp \
KeyboardStat.cpp \
MouseStat.cpp \
SDLJoystick.cpp \
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
index 871de64bab..34e02c6c32 100644
--- a/xbmc/settings/Settings.cpp
+++ b/xbmc/settings/Settings.cpp
@@ -36,7 +36,7 @@
#include "guilib/GUIFontManager.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/StereoscopicsManager.h"
-#include "input/KeyboardLayout.h"
+#include "input/KeyboardLayoutManager.h"
#if defined(TARGET_POSIX)
#include "linux/LinuxTimezone.h"
#endif // defined(TARGET_POSIX)
@@ -608,7 +608,7 @@ void CSettings::InitializeOptionFillers()
m_settingsManager->RegisterSettingOptionsFiller("timezones", CLinuxTimezone::SettingOptionsTimezonesFiller);
#endif
m_settingsManager->RegisterSettingOptionsFiller("verticalsyncs", CDisplaySettings::SettingOptionsVerticalSyncsFiller);
- m_settingsManager->RegisterSettingOptionsFiller("keyboardlayouts", CKeyboardLayout::SettingOptionsKeyboardLayoutsFiller);
+ m_settingsManager->RegisterSettingOptionsFiller("keyboardlayouts", CKeyboardLayoutManager::SettingOptionsKeyboardLayoutsFiller);
m_settingsManager->RegisterSettingOptionsFiller("loggingcomponents", CAdvancedSettings::SettingOptionsLoggingComponentsFiller);
}