diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/VBox/Frontends/Common | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Frontends/Common')
-rw-r--r-- | src/VBox/Frontends/Common/Makefile.kmk | 39 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/PasswordInput.cpp | 182 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/PasswordInput.h | 44 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/.scm-settings | 31 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/COPYING.LIB | 504 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/Makefile | 34 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk | 100 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h | 2076 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h | 268 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h | 250 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h | 138 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c | 669 | ||||
-rw-r--r-- | src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h | 299 |
13 files changed, 4634 insertions, 0 deletions
diff --git a/src/VBox/Frontends/Common/Makefile.kmk b/src/VBox/Frontends/Common/Makefile.kmk new file mode 100644 index 00000000..35b88cf6 --- /dev/null +++ b/src/VBox/Frontends/Common/Makefile.kmk @@ -0,0 +1,39 @@ +# $Id: Makefile.kmk $ +## @file +# Top-level makefile for VBox frontends shared bits +# + +# +# Copyright (C) 2010-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.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, in version 3 of the +# License. +# +# 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, see <https://www.gnu.org/licenses>. +# +# SPDX-License-Identifier: GPL-3.0-only +# + +SUB_DEPTH = ../../../.. +include $(KBUILD_PATH)/subheader.kmk + +# Include Sub-Makefiles +ifneq ($(VBOX_WITH_QTGUI)$(VBOX_WITH_VBOXSDL),) + ifeq ($(filter-out freebsd linux openbsd netbsd solaris,$(KBUILD_TARGET)),) # X11 + include $(PATH_SUB_CURRENT)/VBoxKeyboard/Makefile.kmk + endif +endif + +include $(FILE_KBUILD_SUB_FOOTER) + diff --git a/src/VBox/Frontends/Common/PasswordInput.cpp b/src/VBox/Frontends/Common/PasswordInput.cpp new file mode 100644 index 00000000..c868fa70 --- /dev/null +++ b/src/VBox/Frontends/Common/PasswordInput.cpp @@ -0,0 +1,182 @@ +/* $Id: PasswordInput.cpp $ */ +/** @file + * Frontend shared bits - Password file and console input helpers. + */ + +/* + * Copyright (C) 2012-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.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, in version 3 of the + * License. + * + * 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, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "PasswordInput.h" + +#include <iprt/ctype.h> +#include <iprt/errcore.h> +#include <iprt/message.h> +#include <iprt/stream.h> + +#include <VBox/com/errorprint.h> + + +/** + * Reads a password from the password file. + * + * Only first line is used. The passwords length must be less than 512 bytes + * + * @param pszFilename The path to file containing the password + * @param pPasswd The string where password will be returned + * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg. + */ +RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd) +{ + size_t cbFile; + char szPasswd[512] = { 0 }; + int vrc = VINF_SUCCESS; + RTEXITCODE rcExit = RTEXITCODE_SUCCESS; + bool fStdIn = !strcmp(pszFilename, "stdin"); + PRTSTREAM pStrm; + if (!fStdIn) + vrc = RTStrmOpen(pszFilename, "r", &pStrm); + else + pStrm = g_pStdIn; + if (RT_SUCCESS(vrc)) + { + vrc = RTStrmReadEx(pStrm, szPasswd, sizeof(szPasswd)-1, &cbFile); + if (RT_SUCCESS(vrc)) + { + size_t cbSize = RT_MIN(sizeof(szPasswd)-1, cbFile); + unsigned i; + for (i = 0; i < cbSize && !RTLocCIsCntrl(szPasswd[i]); i++) + ; + szPasswd[i] = '\0'; + /* If the line containing password doesn't fit into buffer */ + if (i >= sizeof(szPasswd)-1 && cbFile >= sizeof(szPasswd)) + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Provided password in file '%s' is too long", pszFilename); + else + *pPasswd = szPasswd; + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot read password from file '%s': %Rrc", pszFilename, vrc); + if (!fStdIn) + RTStrmClose(pStrm); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot open password file '%s' (%Rrc)", pszFilename, vrc); + + return rcExit; +} + + +/** + * Sets password for settings from password file + * + * Only first line is used. The passwords length must be less than 512 bytes + * + * @param virtualBox The IVirtualBox interface the settings password will be set for + * @param pszFilename The path to file containing the password + * @return RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg. + */ +RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename) +{ + com::Utf8Str passwd; + RTEXITCODE rcExit = readPasswordFile(pszFilename, &passwd); + if (rcExit == RTEXITCODE_SUCCESS) + { + HRESULT hrc; + CHECK_ERROR(virtualBox, SetSettingsSecret(com::Bstr(passwd).raw())); + if (FAILED(hrc)) + rcExit = RTEXITCODE_FAILURE; + } + + return rcExit; +} + + +/** + * Gets the password from the user input + * * + * @param pPassword The string where password will be returned + * @param pszPrompt The prompt string for user + * @return RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg. + */ +RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...) +{ + RTEXITCODE rcExit = RTEXITCODE_SUCCESS; + char aszPwdInput[_1K] = { 0 }; + va_list vaArgs; + + va_start(vaArgs, pszPrompt); + int vrc = RTStrmPrintfV(g_pStdOut, pszPrompt, vaArgs); + if (RT_SUCCESS(vrc)) + { + bool fEchoOld = false; + vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld); + if (RT_SUCCESS(vrc)) + { + vrc = RTStrmInputSetEchoChars(g_pStdIn, false); + if (RT_SUCCESS(vrc)) + { + vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput)); + if (RT_SUCCESS(vrc)) + { +#ifdef RT_OS_WINDOWS + /* + * Returned string encoded in console code page (e.g. Win-125X or CP-XXX). + * Convert it to Utf-8 + */ + char *pszPassword = NULL; + vrc = RTStrConsoleCPToUtf8(&pszPassword, aszPwdInput); + if (RT_SUCCESS(vrc) && pszPassword) + { + *pPassword = pszPassword; + RTMemFree(pszPassword); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, + "Failed to convert password from windows console codepage to Utf-8 (%Rrc)", + vrc); +#else + *pPassword = aszPwdInput; +#endif + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed read password from command line (%Rrc)", vrc); + + int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld); + AssertRC(vrc2); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to disable echoing typed characters (%Rrc)", vrc); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to retrieve echo setting (%Rrc)", vrc); + + RTStrmPutStr(g_pStdOut, "\n"); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to print prompt (%Rrc)", vrc); + va_end(vaArgs); + + return rcExit; +} diff --git a/src/VBox/Frontends/Common/PasswordInput.h b/src/VBox/Frontends/Common/PasswordInput.h new file mode 100644 index 00000000..a7e306e1 --- /dev/null +++ b/src/VBox/Frontends/Common/PasswordInput.h @@ -0,0 +1,44 @@ +/* $Id: PasswordInput.h $ */ +/** @file + * Frontend shared bits - Password file and console input helpers. + */ + +/* + * Copyright (C) 2012-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.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, in version 3 of the + * License. + * + * 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, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#ifndef VBOX_INCLUDED_SRC_Common_PasswordInput_h +#define VBOX_INCLUDED_SRC_Common_PasswordInput_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <VBox/com/com.h> +#include <VBox/com/ptr.h> +#include <VBox/com/string.h> +#include <VBox/com/VirtualBox.h> + + +RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd); +RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...); +RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename); + +#endif /* !VBOX_INCLUDED_SRC_Common_PasswordInput_h */ diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/.scm-settings b/src/VBox/Frontends/Common/VBoxKeyboard/.scm-settings new file mode 100644 index 00000000..5184e0fb --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/.scm-settings @@ -0,0 +1,31 @@ +# $Id: .scm-settings $ +## @file +# Source code massager settings for VBoxKeyboard. +# + +# +# Copyright (C) 2010-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.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, in version 3 of the +# License. +# +# 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, see <https://www.gnu.org/licenses>. +# +# SPDX-License-Identifier: GPL-3.0-only +# + + +# These are LGPL and generally external. +/keyboard*|/xkbtoscan.h: --external-copyright --no-fix-header-guards + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/COPYING.LIB b/src/VBox/Frontends/Common/VBoxKeyboard/COPYING.LIB new file mode 100644 index 00000000..5ab7695a --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/COPYING.LIB @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/Makefile b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile new file mode 100644 index 00000000..762f556d --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile @@ -0,0 +1,34 @@ +# $Id: Makefile $ +## @file +# Makefile for building the VirtualBox keyboard handler library. +# + +# Note that for reasons of convenience, VirtualBox builds this library +# from inside its own build system rather than using this file. + +# +# Copyright (C) 2007-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.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, in version 3 of the +# License. +# +# 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, see <https://www.gnu.org/licenses>. +# +# SPDX-License-Identifier: GPL-3.0-only +# + +CFLAGS = -I. -fPIC + +VBoxKeyboard.so : keyboard.o + gcc -shared -o VBoxKeyboard.so keyboard.o -lX11 diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk new file mode 100644 index 00000000..be1759df --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/Makefile.kmk @@ -0,0 +1,100 @@ +# $Id: Makefile.kmk $ +## @file +# Makefile for the VirtualBox X11 keyboard library +# + +# +# Copyright (C) 2006-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.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, in version 3 of the +# License. +# +# 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, see <https://www.gnu.org/licenses>. +# +# SPDX-License-Identifier: GPL-3.0-only +# + +SUB_DEPTH = ../../../../.. +include $(KBUILD_PATH)/subheader.kmk + +if1of ($(KBUILD_TARGET), freebsd linux openbsd netbsd solaris) # X11 + DLLS += VBoxKeyboard + OTHERS += $(PATH_STAGE_BIN)/vboxkeyboard.tar.bz2 + OTHER_CLEAN += $(PATH_STAGE_BIN)/vboxkeyboard.tar.bz2 +endif + + +# +# VBoxKeyboard - keyboard library for X11. +# +VBoxKeyboard_TEMPLATE = VBOXR3 +VBoxKeyboard_SOURCES = \ + keyboard.c +VBoxKeyboard_LIBS = X11 +VBoxKeyboard_LIBPATH = $(VBOX_LIBPATH_X11) + + +# +# vboxkeyboard.tar.gz - the LGPLed keyboard library must always be +# redistributed with usable sources. +# +# This rule will link create a temporary symlink to src/X11/ and tar +# up the selected files into a tarball that is installed into the +# bin directory (probably belongs in /usr/shared/somewhere really, +# but wtf, it's not like we're even trying to be FHS compliant). +# +VBOX_KEYBOARD_STAGE_DIR = $(PATH_TARGET)/VBoxKeyboard/install +VBOX_KEYBOARD_DEST_DIR = $(VBOX_KEYBOARD_STAGE_DIR)/VBoxKeyboard/ + +## @todo kBuild need support for copying files into _1_OUTDIR. +INSTALLS += VBoxKeyboard-Files +VBoxKeyboard-Files_INSTTYPE = stage +VBoxKeyboard-Files_INST = misc-staging/VBoxKeyboard/ +VBoxKeyboard-Files_MODE = a+r,u+w +VBoxKeyboard-Files_SOURCES = \ + COPYING.LIB \ + keyboard.c \ + keyboard-layouts.h \ + keyboard-list.h \ + keyboard-tables.h \ + keyboard-types.h \ + Makefile \ + ../../../../../include/VBox/VBoxKeyboard.h=>VBox/VBoxKeyboard.h + +INSTALLS += VBoxKeyboard-Tarball +VBoxKeyboard-Tarball_INST = $(INST_BIN) +VBoxKeyboard-Tarball_MODE = a+r,u+w +VBoxKeyboard-Tarball_SOURCES = $(VBoxKeyboard-Tarball_0_OUTDIR)/vboxkeyboard.tar.bz2 +VBoxKeyboard-Tarball_CLEAN = $(VBoxKeyboard-Tarball_0_OUTDIR)/vboxkeyboard.tar.bz2 + +$$(VBoxKeyboard-Tarball_0_OUTDIR)/vboxkeyboard.tar.bz2: \ + $$(VBoxKeyboard-Files_2_STAGE_TARGETS) \ + $(MAKEFILE_CURRENT) \ + | $$(dir $$@) + $(call MSG_L1,Packing $@) + $(QUIET)$(RM) -f -- $@ $(patsubst %.bz2,%,$@) +ifdef VBOX_GTAR + $(QUIET)$(VBOX_GTAR) --dereference --owner 0 --group 0 --ignore-failed-read \ + -cjRf $@ \ + -C $(PATH_STAGE)/$(VBoxKeyboard-Files_INST).. VBoxKeyboard +else + $(QUIET)tar -cjf $@ \ + -C $(PATH_STAGE)/$(VBoxKeyboard-Files_INST).. VBoxKeyboard +endif + $(QUIET)$(CHMOD) 0644 $@ + + + +include $(FILE_KBUILD_SUB_FOOTER) + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h new file mode 100644 index 00000000..a833bcb8 --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-layouts.h @@ -0,0 +1,2076 @@ +/* $Id: keyboard-layouts.h $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard driver translation tables (keyboard layouts). + * + * This file was generated by successively loading each of the keyboard + * layouts listed in the file keyboard-list.h into the X server and + * reading and dumping the values associated with each key. The format + * of the dumped data is chosen to be compatible with the keyboard code + * in keyboard-new.c, which is based on code from the Wine project. + */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +#ifndef ___VBox_keyboard_tables_h +# error This file must be included from within keyboard-tables.h +#endif /* !___VBox_keyboard_tables_h */ + +/* This file contains a more or less complete dump of all keyboard + layouts known to my version of X.org. Duplicate layouts have + been removed to save space and lookup time, and the Japanese + layout has been manually corrected, due to differences in handling + between 105 and 106-key keyboards. + + Note that contrary to the original tables in the Wine source code, + these tables simply contain the X keysym values truncated to the + least significant byte. In fact, there is no need to do any + additional translation of the values (the original code translated + them to whatever character set was deemed appropriate, rather + inconsistently) as long as we use the same algorithm for creating + the tables and doing the lookups. + + The last three entries in the tables are respectively the 102nd + key on 102/105/106 key keyboards, the extra key on Brazilian and + Japanese keyboards and the Yen key on Japanese keyboards. + The layout-switching keys on Japanese and Korean keyboards are + dealt with elsewhere. */ + +/* U.S. English */ +static const char main_key_us[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, International (with dead keys) */ +static const char main_key_us_intl[MAIN_LEN][2] = +{ +"PS","1!","2@","3#","4$","5%","6R","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","QW","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, International, alternative 102nd key */ +static const char main_key_us_intl_alt102[MAIN_LEN][2] = +{ +"PS","1!","2@","3#","4$","5%","6R","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","QW","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\\|","\x0\x0","\x0\x0" +}; + +/* U.S. English, Dvorak */ +static const char main_key_us_dvorak[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","[{","]}", +"'\"",",<",".>","pP","yY","fF","gG","cC","rR","lL","/?","=+", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","\\|", +";:","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, Left handed Dvorak */ +static const char main_key_us_dvorak_l[MAIN_LEN][2] = +{ +"`~","[{","]}","/?","pP","fF","mM","lL","jJ","4$","3#","2@","1!", +";:","qQ","bB","yY","uU","rR","sS","oO",".>","6^","5%","=+", +"-_","kK","cC","dD","tT","hH","eE","aA","zZ","8*","7&","\\|", +"'\"","xX","gG","vV","wW","nN","iI",",<","0)","9(","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, Right handed Dvorak */ +static const char main_key_us_dvorak_r[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","jJ","lL","mM","fF","pP","/?","[{","]}", +"5%","6^","qQ",".>","oO","rR","sS","uU","yY","bB",";:","=+", +"7&","8*","zZ","aA","eE","hH","tT","dD","cC","kK","-_","\\|", +"9(","0)","xX",",<","iI","nN","wW","vV","gG","'\"","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, Classic Dvorak */ +static const char main_key_us_dvorak_classic[MAIN_LEN][2] = +{ +"`~","[{","7&","5%","3#","1!","9(","0)","2@","4$","6^","8*","]}", +"/?",",<",".>","pP","yY","fF","gG","cC","rR","lL","'\"","=+", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","\\|", +";:","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, Russian phonetic */ +static const char main_key_us_rus[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","\xdf\xff", +"\xd1\xf1","\xd7\xf7","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xd9\xf9","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xdd\xfd", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xca\xea","\xcb\xeb","\xcc\xec","\xde\xfe","\xc0\xe0","\xdc\xfc", +"\xda\xfa","\xd8\xf8","\xc3\xe3","\xd6\xf6","\xc2\xe2","\xce\xee","\xcd\xed",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* U.S. English, Colemak */ +static const char main_key_us_col[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","fF","pP","gG","jJ","lL","uU","yY",";:","[{","]}", +"aA","rR","sS","tT","dD","hH","nN","eE","iI","oO","'\"","\\|", +"zZ","xX","cC","vV","bB","kK","mM",",<",".>","/?","-_","\x0\x0","\x0\x0" +}; + +/* Afghanistan */ +static const char main_key_af[MAIN_LEN][2] = +{ +"\xd\xf7","\xf1!","\xf2l","\xf3k","\xf4\xb","\xf5j","\xf6\xd7","\xf7\xac","\xf8*","\xf9)","\xf0(","-\xe0","+=", +"\xd6\xf2","\xd5\xec","\xcb\xed","\xe2\xeb","\xe1\xef","\xda\xf0","\xd9\xee","\xe7\xf1","\xce]","\xcd[","\xcc}","\x86{", +"\xd4\xc4","\xd3\xc6","\xcc\xea","\xc8\xc5","\xe4\xc3","\xc7\xc2","\xca\xc9","\xe6\xbb","\xe5\xab","\xa9:","\xaf\xbb","\\|", +"\xd8\xe3","\xd7S","\xd2\x98","\xd1p","\xd0\xc","\xcfT","~\xc1","\xe8>",".<","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Afghanistan, Pashto */ +static const char main_key_af_ps[MAIN_LEN][2] = +{ +"\xd\xf7","\xf1!","\xf2l","\xf3k","\xf4\xb","\xf5j","\xf6\xd7","\xf7\xbb","\xf8\xab","\xf9)","\xf0(","-\xe0","+=", +"\xd6\xf2","\xd5\xec","\xcb\xed","\xe2\xeb","\xe1\xef","\xda\xf0","\xd9\xee","\xe7\xf1","\xce\x81","\xcd\x85","\xcc]","\x86[", +"\xd4\x9a","\xd3\xc6","\xcc\xea","\xc8~","\xe4\xc3","\xc7\xc2","\xca|","\xe6\xbc","\xe5)","\xa9:","\xab\xbb","\\*", +"\xcd""8","\xd0""7","\xd2\x98","\xd1!","\xd0\xc","\xcf\x89","\x93$","\xe8\xc","\x96.","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Afghanistan, Southern Uzbek */ +static const char main_key_af_uz[MAIN_LEN][2] = +{ +"\xd\xf7","\xf1!","\xf2l","\xf3k","\xf4\xb","\xf5j","\xf6\xd7","\xf7\xac","\xf8*","\xf9)","\xf0(","-\xe0","+=", +"\xd6\xf2","\xd5\xec","\xcb\xed","\xe2\xeb","\xe1\xef","\xda\xf0","\xd9\xee","\xe7\xf1","\xce]","\xcd[","\xcc}","\x86{", +"\xd4\xc4","\xd3\xc6","\xcc\xea","\xc8\xd0","\xe4\xc3","\xc7\xc2","\xca\xc9","\xe6\xbb","\xe5\xab","\xa9:","\xaf\xbb","\\|", +"\xd8\xc9","\xd7\xc7","\xd2\x98","\xd1%","\xd0\xc","\xcfT","~\xc1","\xe8>",".<","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Arabic */ +static const char main_key_ara[MAIN_LEN][2] = +{ +"\xd0\xf1","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\xd6\xee","\xd5\xeb","\xcb\xef","\xe2\xec","\xe1\xf9","\xda\xc5","\xd9`","\xe7\xf7","\xce\xd7","\xcd\xbb","\xcc{","\xcf}", +"\xd4\\","\xd3S","\xea[","\xc8]","\xe4\xf7","\xc7\xc3","\xca\xe0","\xe6\xac","\xe5/","\xe3:","\xd7\"","<>", +"\xc6~","\xc1\xf2","\xc4\xf0","\xd1\xed","\xfb\xf5","\xe9\xc2","\xc9'","\xe8,","\xd2.","\xd8\xbf","|\xa6","\x0\x0","\x0\x0" +}; + +/* Arabic, azerty */ +static const char main_key_ara_azerty[MAIN_LEN][2] = +{ +"\xd0\xf1","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"\xd6\xee","\xd5\xeb","\xcb\xef","\xe2\xec","\xe1\xf9","\xda\xc5","\xd9`","\xe7\xf7","\xce\xd7","\xcd\xbb","\xcc{","\xcf}", +"\xd4\\","\xd3S","\xea[","\xc8]","\xe4\xf7","\xc7\xc3","\xca\xe0","\xe6\xac","\xe5/","\xe3:","\xd7\"","<>", +"\xc6~","\xc1\xf2","\xc4\xf0","\xd1\xed","\xfb\xf5","\xe9\xc2","\xc9'","\xe8,","\xd2.","\xd8\xbf","|\xa6","\x0\x0","\x0\x0" +}; + +/* Arabic, azerty/digits */ +static const char main_key_ara_azerty_digits[MAIN_LEN][2] = +{ +"\xd0\xf1","&a","\xe9""b","\"c","'d","(e","-f","\xe8g","_h","\xe7i","\xe0`",")\xb0","=+", +"\xd6\xee","\xd5\xeb","\xcb\xef","\xe2\xec","\xe1\xf9","\xda\xc5","\xd9`","\xe7\xf7","\xce\xd7","\xcd\xbb","\xcc{","\xcf}", +"\xd4\\","\xd3S","\xea[","\xc8]","\xe4\xf7","\xc7\xc3","\xca\xe0","\xe6\xac","\xe5/","\xe3:","\xd7\"","<>", +"\xc6~","\xc1\xf2","\xc4\xf0","\xd1\xed","\xfb\xf5","\xe9\xc2","\xc9'","\xe8,","\xd2.","\xd8\xbf","|\xa6","\x0\x0","\x0\x0" +}; + +/* Arabic, digits */ +static const char main_key_ara_digits[MAIN_LEN][2] = +{ +"\xd0\xf1","a!","b@","c#","d$","e%","f^","g&","h*","i(","`)","-_","=+", +"\xd6\xee","\xd5\xeb","\xcb\xef","\xe2\xec","\xe1\xf9","\xda\xc5","\xd9`","\xe7\xf7","\xce\xd7","\xcd\xbb","\xcc{","\xcf}", +"\xd4\\","\xd3S","\xea[","\xc8]","\xe4\xf7","\xc7\xc3","\xca\xe0","\xe6\xac","\xe5/","\xe3:","\xd7\"","<>", +"\xc6~","\xc1\xf2","\xc4\xf0","\xd1\xed","\xfb\xf5","\xe9\xc2","\xc9'","\xe8,","\xd2.","\xd8\xbf","|\xa6","\x0\x0","\x0\x0" +}; + +/* Arabic, Buckwalter */ +static const char main_key_ara_buckwalter[MAIN_LEN][2] = +{ +"p\xf1","a\xff","b\xff","c\xff","d\xd4","ej","f\xff","g\xc4","h\xd0","i>","`?","-\xe0","=+", +"\xe2\xff","\xe8\xc4","\xff\xd9","\xd1\xff","\xca\xd7","\xea\xe9","\xef\xff","\xf0\xc5","\xf2\xc3","\xc9\xff","\xffq","\xff\xc6", +"\xee\xc7","\xd3\xd5","\xcf\xd6","\xe1\xeb","\xda\xff","\xe7\xcd","\xcc\xff","\xe3\xed","\xe4\xff","\xbb\xff","\xc1\xff","\xff\xc2", +"\xd2\xd8","\xce\xff","\xff\xff","\xcb\xff","\xc8\xff","\xe6\xec","\xe5\xff","\xac\xc5","\xd4\xc3","\xff\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Albania */ +static const char main_key_al[MAIN_LEN][2] = +{ +"\\|","1!","2\"","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xe7\xc7","@'", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xeb\xcb","[{","]}", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","/?","<>","\x0\x0","\x0\x0" +}; + +/* Armenia */ +static const char main_key_am[MAIN_LEN][2] = +{ +"]\\","\x86V","qA","\x13\x14",",$","\x89&","^%","$\x87","[\xbc",")(","\x85U","g7","rB", +"sC","\x83S","b2","}M","tD","xH","\x82R","o?","h8","i9","n>","\x81Q", +"{K","~N","c3","e5","a1","vF","k;","\x7fO","p@","zJ","\x80P","\xbb\xab", +"j:","d4","yI","uE","f6","l<","\x84T","m=","wG","|L","?\x8a","\x0\x0","\x0\x0" +}; + +/* Armenia, Phonetic */ +static const char main_key_am_phonetic[MAIN_LEN][2] = +{ +"]\\","g7","i9","\x83S","qA","{K","\x82R","\x87\x87","\x80P","yI","sC","-\x15","j:", +"\x84T","xH","e5","|L","\x7fO","h8","\x82R","k;","\x85U","zJ","m=","n>", +"a1","}M","d4","\x86V","c3","p@","uE","o?","l<",";\x89","[\"","wG", +"f6","rB","\x81Q","~N","b2","vF","tD",",\xab","$\xbb","/^","?\x8a","\x0\x0","\x0\x0" +}; + +/* Armenia, Eastern */ +static const char main_key_am_eastern[MAIN_LEN][2] = +{ +"]\\","\x89\xb1","qA","uE","[\xb3",",\xb4","-\xb9",".\x87","\xab(","\xbb)","\x85U","|L","j:", +"m=","\x82R","g7","\x80P","\x7fO","e5","h8","k;","xH","zJ","yI","{K", +"a1","}M","d4","\x86V","c3","p@","sC","o?","l<","i9","\x83S","'^", +"f6","\x81Q","\x84T","~N","b2","vF","tD","wG","rB","n>","<>","\x0\x0","\x0\x0" +}; + +/* Armenia, Western */ +static const char main_key_am_western[MAIN_LEN][2] = +{ +"]\\","\x89\xb1","qA","uE","[\xb3",",\xb4","-\xb9",".\x87","\xab(","\xbb)","\x85U","|L","j:", +"m=","~N","g7","\x80P","d4","e5","h8","k;","xH","b2","yI","{K", +"a1","}M","\x7fO","\x86V","o?","p@","sC","\x84T","l<","i9","\x83S","'^", +"f6","\x81Q","c3","\x82R","zJ","vF","tD","wG","rB","n>","<>","\x0\x0","\x0\x0" +}; + +/* Armenia, Alternative Eastern */ +static const char main_key_am_eastern_alt[MAIN_LEN][2] = +{ +"]\\","\x89\xb1","qA","uE","[\xb3",",\xb4","-\xb9",".\x87","\xab(","\xbb)","\x85U","|L","j:", +"m=","\x82R","g7","\x80P","\x7fO","e5","h8","k;","xH","zJ","yI","{K", +"a1","}M","d4","\x86V","\x84T","p@","sC","o?","l<","i9","\x83S","'^", +"f6","\x81Q","c3","~N","b2","vF","tD","wG","rB","n>","<>","\x0\x0","\x0\x0" +}; + +/* Azerbaijan */ +static const char main_key_az[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6:","7?","8*","9(","0)","-_","=+", +"qQ","\xfc\xdc","eE","rR","tT","yY","uU","i\xa9","oO","pP","\xf6\xd6","\xbb\xab", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xb9I","Y\x8f","\\|", +"zZ","xX","cC","vV","bB","nN","mM","\xe7\xc7","\xba\xaa",".,","<>","\x0\x0","\x0\x0" +}; + +/* Azerbaijan, Cyrillic */ +static const char main_key_az_cyrillic[MAIN_LEN][2] = +{ +"\x0\x0","\x0\x0","2\"","3#","4;","\x0\x0","6:","7?","8*","9(","0)","-_","\x0\x0", +"\xa8\xb8","\xaf\xae","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xbb\xba","\xda\xfa","\xc8\xe8","\xb9\xb8", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\x9d\x9c","\\|", +"\xd9\xd8","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\x93\x92","\xc2\xe2","\xe9\xe8",".,","<>","\x0\x0","\x0\x0" +}; + +/* Belarus */ +static const char main_key_by[MAIN_LEN][2] = +{ +"\xa3\xb3","\x0\x0","2\"","\x0\x0","4;","5%","6:","7?","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xae\xbe","\xda\xfa","\xc8\xe8","''", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","/|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xa6\xb6","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","|\xa6","\x0\x0","\x0\x0" +}; + +/* Belarus, Winkeys */ +static const char main_key_by_winkeys[MAIN_LEN][2] = +{ +"\xa3\xb3","\x0\x0","2\"","3#","4;","5%","6:","7?","8*","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xae\xbe","\xda\xfa","\xc8\xe8","''", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","/|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xa6\xb6","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","|\xa6","\x0\x0","\x0\x0" +}; + +/* Belgium */ +static const char main_key_be[MAIN_LEN][2] = +{ +"\xb2\xb3","&1","\xe9""2","\"3","'4","(5","\xa7""6","\xe8""7","!8","\xe7""9","\xe0""0",")\xb0","-_", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","RW","$*", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","\xb5\xa3", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","=+","<>","\x0\x0","\x0\x0" +}; + +/* Belgium, Eliminate dead keys */ +static const char main_key_be_nodeadkeys[MAIN_LEN][2] = +{ +"\xb2\xb3","&1","\xe9""2","\"3","'4","(5","\xa7""6","\xe8""7","!8","\xe7""9","\xe0""0",")\xb0","-_", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","^\xa8","$*", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","\xb5\xa3", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","=+","<>","\x0\x0","\x0\x0" +}; + +/* Belgium, Sun dead keys */ +static const char main_key_be_sundeadkeys[MAIN_LEN][2] = +{ +"\xb2\xb3","&1","\xe9""2","\"3","'4","(5","\xa7""6","\xe8""7","!8","\xe7""9","\xe0""0",")\xb0","-_", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","\x1\x4","$*", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","\xb5\xa3", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","=+","<>","\x0\x0","\x0\x0" +}; + +/* Bangladesh */ +static const char main_key_bd[MAIN_LEN][2] = +{ +"`~","\xe7!","\xe8@","\xe9#","\xea$","\xeb%","\xec^","\xed&","\xee*","\xef(","\xe6)","-_","=+", +"\x99\x82","\xaf\xdf","\xa1\xa2","\xaa\xab","\x9f\xa0","\x9a\x9b","\x9c\x9d","\xb9\x9e","\x97\x98","\xdc\xdd","[{","]}", +"\xc3\xd7","\xc1\xc2","\xbf\xc0","\xac\xad","\xcd""d","\xbe\x85","\x95\x96","\xa4\xa5","\xa6\xa7",";:","'\"","\\|", +"\x81\x83","\xcb\xcc","\xc7\xc8","\xb0\xb2","\xa8\xa3","\xb8\xb7","\xae\xb6",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Bangladesh, Probhat */ +static const char main_key_bd_probhat[MAIN_LEN][2] = +{ +"`~","\xe7!","\xe8@","\xe9#","\xea\xf3","\xeb%","\xec^","\xed\x9e","\xee\xce","\xef(","\xe6)","\xc_","=\xd", +"\xa6\xa7","\xc2\x8a","\xc0\x88","\xb0\xdc","\x9f\xa0","\x8f\x90","\xc1\x89","\xbf\x87","\x93\x94","\xaa\xab","\xc7\xc8","\xcb\xcc", +"\xbe\x85","\xb8\xb7","\xa1\xa2","\xa4\xa5","\x97\x98","\xb9\x83","\x9c\x9d","\x95\x96","\xb2\x82",";:","'\"","\\e", +"\xdf\xaf","\xb6\xdd","\x9a\x9b","\x86\x8b","\xac\xad","\xa8\xa3","\xae\x99",",\xc3","d\x81","\xcd?","<>","\x0\x0","\x0\x0" +}; + +/* India */ +static const char main_key_in[MAIN_LEN][2] = +{ +"J\x12","g\xd","hE","ii","jj","kk","ll","mm","nn","o(","f)","\x3\x3","C\xb", +"L\x14","H\x10",">\x6","@\x8","B\xa",",-","9\x19","\x17\x18","&'","\x1c\x1d","!\"","<\x1e", +"K\x13","G\xf","M\x5","?\x7","A\x9","*+","01","\x15\x16","$%","\x1a\x1b","\x1f\x20","I\x11", +"F\xe","\x2\x1",".#","()","54","23","86",",7",".d","/?","<>","\x0\x0","\x0\x0" +}; + +/* India, Bengali */ +static const char main_key_in_ben[MAIN_LEN][2] = +{ +"\x0\x0","\xe7\xe7","\xe8\xe8","\xe9\xe9","\xea\xea","\xeb\xeb","\xec\xec","\xed\xed","\xee\xee","\xef(","\xe6)","-\x83","\x8b\xc3", +"\xcc\x94","\xc8\x90","\xbe\x86","\xc0\x88","\xc2\x8a","\xac\xad","\xb9\x99","\x97\x98","\xa6\xa7","\x9c\x9d","\xa1\xa2","\xbc\x9e", +"\xcb\x93","\xc7\x8f","\xcd\x85","\xbf\x87","\xc1\x89","\xaa\xab","\xb0\xdd","\x95\x96","\xa4\xa5","\x9a\x9b","\x9f\xa0","\\|", +"zZ","\x82\x81","\xae\xa3","\xa8\xa8","\xac\xac","\xb2\xb2","\xb8\xb6",",\xb7",".d","\xdf\xaf","<>","\x0\x0","\x0\x0" +}; + +/* India, Gujarati */ +static const char main_key_in_guj[MAIN_LEN][2] = +{ +"\x0\x0","\xe7\x8d","\xe8\xc5","\xe9\xe9","\xea\xea","\xeb\xeb","\xec\xec","\xed\xed","\xee\xee","\xef(","\xe6)","-\x83","\x8b\xc3", +"\xcc\x94","\xc8\x90","\xbe\x86","\xc0\x88","\xc2\x8a","\xac\xad","\xb9\x99","\x97\x98","\xa6\xa7","\x9c\x9d","\xa1\xa2","\xbc\x9e", +"\xcb\x93","\xc7\x8f","\xcd\x85","\xbf\x87","\xc1\x89","\xaa\xab","\xb0\xb0","\x95\x96","\xa4\xa5","\x9a\x9b","\x9f\xa0","\xc9\x91", +"zZ","\x82\x81","\xae\xa3","\xa8\xa8","\xb5\xb5","\xb2\xb3","\xb8\xb6",",\xb7",".d","\xaf?","<>","\x0\x0","\x0\x0" +}; + +/* India, Gurmukhi */ +static const char main_key_in_guru[MAIN_LEN][2] = +{ +"\x0\x0","gg","hh","ii","jj","kk","ll","mm","nn","o(","f)","\x0\x0","\x0\x0", +"L\x14","H\x10",">\x6","@\x8","B\xa",",-","9\x19","\x17\x18","&'","\x1c\x1d","!\"","<\x1e", +"K\x13","G\xf","M\x5","?\x7","A\x9","*+","00","\x15\x16","$%","\x1a\x1b","\x1f\x20","\\|", +"zZ","\x2p",".#","((","55","23","86",",<",".d","/?","<>","\x0\x0","\x0\x0" +}; + +/* India, Kannada */ +static const char main_key_in_kan[MAIN_LEN][2] = +{ +"\xca\x92","\xe7\xe7","\xe8\xe8","\xe9\xe9","\xea\xea","\xeb\xeb","\xec\xec","\xed\xed","\xee\xee","\xef\xef","\xe6\xe6","\x83\x83","\xc3\x8b", +"\xcc\x94","\xc8\x90","\xbe\x86","\xc0\x88","\xc2\x8a","\xac\xad","\xb9\x99","\x97\x98","\xa6\xa7","\x9c\x9d","\xa1\xa2","\xbc\x9e", +"\xcb\x93","\xc7\x8f","\xcd\x85","\xbf\x87","\xc1\x89","\xaa\xab","\xb0\xb1","\x95\x96","\xa4\xa5","\x9a\x9b","\x9f\xa0","\\|", +"\xc6\x8e","\x82\x82","\xae\xa3","\xa8\xa8","\xb5\xb4","\xb2\xb3","\xb8\xb6",",\xb7","..","\xaf@","<>","\x0\x0","\x0\x0" +}; + +/* India, Malayalam */ +static const char main_key_in_mal[MAIN_LEN][2] = +{ +"J\x12","g!","h@","i#","j$","k%","l^","m&","n*","o(","f)","-\x3","C\xb", +"L\x14","H\x10",">\x6","@\x8","B\xa",",-","9\x19","\x17\x18","&'","\x1c\x1d","!\"","\xd\x1e", +"K\x13","G\xf","M\x5","?\x7","A\x9","*+","01","\x15\x16","$%","\x1a\x1b","\x1f\x20","\\|", +"F\xe","\x2\x2",".#","((","54","23","86",",7","..","/?","<>","\x0\x0","\x0\x0" +}; + +/* India, Oriya */ +static const char main_key_in_ori[MAIN_LEN][2] = +{ +"\x0\x0","gg","hh","ii","jj","kk","ll","mm","nn","oo","ff","\x3\x3","C\xb", +"L\x14","H\x10",">\x6","@\x8","B\xa",",-","9\x19","\x17\x18","&'","\x1c\x1d","!\"","<\x1e", +"K\x13","G\xf","M\x5","?\x7","A\x9","*+","00","\x15\x16","$%","\x1a\x1b","\x1f\x20","\\|", +"\x0\x0","\x2\x1",".#","((","55","23","86",",7","..","/@","<>","\x0\x0","\x0\x0" +}; + +/* India, Tamil Unicode */ +static const char main_key_in_tam_unicode[MAIN_LEN][2] = +{ +"\x0\x0","\x83\x83","\x0\x0","\x9c\x9c","\xb7\xb7","\xb8\xb8","\xb9\xb9","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\x9e\x9e","\xb1\xb1","\xa8\xa8","\x9a\x9a","\xb5\xb5","\xb2\xb2","\xb0\xb0","\xc8\x90","\xca\xcb","\xbf\xc0","\xc1\xc2","\x0\x0", +"\xaf\xaf","\xb3\xb3","\xa9\xa9","\x95\x95","\xaa\xaa","\xbe\xb4","\xa4\xa4","\xae\xae","\x9f\x9f","\xcd\xcd","\x99\x99","\\|", +"\xa3\xa3","\x92\x93","\x89\x8a","\x8e\x8f","\xc6\xc7","\x94\xcc","\x85\x86","\x87\x88","\x0\x0","\x0\x0","<>","\x0\x0","\x0\x0" +}; + +/* India, Tamil TAB Typewriter */ +static const char main_key_in_tam_TAB[MAIN_LEN][2] = +{ +"\x0\x0","\xe7\xa7","\xfa\xa8","\xfb\xfb","\xfc\xfc","\xfd\xfd","\xfe\xfe","\xff\xff","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\xeb\xb3","\xf8\xc1","\xef\xb8","\xea\xb2","\xf5\xbe","\xf4\xbd","\xf3\xbc","\xac\xe4","\xae\xaf","\xa4\xa6","R\xa6","\x0\x0", +"\xf2\xbb","\xf7\xc0","\xf9\xc2","\xe8\xb0","\xf0\xb9","\xa2\xa3","\xee\xb6","\xf1\xba","\xec\xb4","\xf6\xbf","\xe9\xb1","\\|", +"\xed\xb5","\xe5\xe6","\xe0\xe1","\xe2\xe3","\xaa\xab","\xac\xa3","\xdc\xdd","\xde\xdf","\x0\x0","\x0\x0","<>","\x0\x0","\x0\x0" +}; + +/* India, Tamil TSCII Typewriter */ +static const char main_key_in_tam_TSCII[MAIN_LEN][2] = +{ +"\x0\x0","\xb7\xa4","\x82\xa5","\x83\x88","\x84\x89","\x85\x8a","\x86\x8b","\x87\x8c","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\xbb\x9a","\xc8\xda","\xbf\xd1","\xba\xcd","\xc5\xd7","\xc4\xd6","\xc3\xd5","\xa8\xb3","\xca\xcb","\xa2\xa3","Q\xa3","\x0\x0", +"\xc2\xd4","\xc7\xd9","\xc9\xdb","\xb8\xcc","\xc0\xd2","P\xa1","\xbe\xd0","\xc1\xd3","\xbc\xce","\xc6\xd8","\xb9\x99","\\|", +"\xbd\xcf","\xb4\xb5","\xaf\xb0","\xb1\xb2","\xa6\xa7","\xb6\xaa","\xab\xac","\xfe\xae","\x0\x0","\x0\x0","<>","\x0\x0","\x0\x0" +}; + +/* India, Tamil */ +static const char main_key_in_tam[MAIN_LEN][2] = +{ +"\xca\x92","\xe7\xe7","\xe8\xe8","\xe9\xe9","\xea\xea","\xeb\xeb","\xec\xec","\xed\xed","\xee\xee","\xef(","\xf0)","\xf1\x83","\xf2+", +"\xcc\x94","\xc8\x90","\xbe\x86","\xc0\x88","\xc2\x8a","\x0\x0","\xb9\x99","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x9e\x9e", +"\xcb\x93","\xc7\x8f","\xcd\x85","\xbf\x87","\xc1\x89","\xaa\xaa","\xb0\xb1","\x95\x95","\xa4\xa4","\x9a\x9a","\x9f\x9f","\\|", +"\xc6\x8e","\x82\x82","\xae\xa3","\xa8\xa9","\xb5\xb4","\xb2\xb3","\xb8\xb8",",\xb7",".d","\xaf?","<>","\x0\x0","\x0\x0" +}; + +/* India, Telugu */ +static const char main_key_in_tel[MAIN_LEN][2] = +{ +"J\x12","gg","hh","i#","j$","k%","l^","m&","n*","o(","f)","\x3_","C\xb", +"L\x14","H\x10",">\x6","@\x8","B\xa",",-","9\x19","\x17\x18","&'","\x1c\x1d","!\"","\x1e\x1e", +"K\x13","G\xf","M\x5","?\x7","A\x9","*+","01","\x15\x16","$%","\x1a\x1b","\x1f\x20","\\|", +"F\xe","\x2\x1",".#","((","55","23","86",",7","..","/@","<>","\x0\x0","\x0\x0" +}; + +/* India, Urdu */ +static const char main_key_in_urd[MAIN_LEN][2] = +{ +"\xd4\xd4","a!","b@","c#","\xf4$","\xf5%","f^","g&","h*","i(","`)","-_","=+", +"\xe2\xe1","H\xf9","9\xf7","1\x91","\xcay","\xd2|","!L","\xccV","G)","~O","[{","]}", +"'\"","\xd3""5","/\x88","Ap","\xaf:","\xbe-",",6","\xa9.","D\x12","\x1b:","''","\\|", +"\xd2\xd0","4\x98","\x86+","78","((","F\xba","EE","\xcN","\xd4P","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Bosnia and Herzegovina */ +static const char main_key_ba[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xb9\xa9","\xf0\xd0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe8\xc8","\xe6\xc6","\xbe\xae", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Bosnia and Herzegovina, Use Bosnian digraphs */ +static const char main_key_ba_unicode[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"\xc9\xc8","\xcc\xcb","eE","rR","tT","zZ","uU","iI","oO","pP","\xb9\xa9","\xf0\xd0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe8\xc8","\xe6\xc6","\xbe\xae", +"\xbe\xae","\xc6\xc5","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Bosnia and Herzegovina, US keyboard with Bosnian digraphs */ +static const char main_key_ba_unicodeus[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"\xc9\xc8","\xcc\xcb","eE","rR","tT","\xbe\xae","uU","iI","oO","pP","\xb9\xa9","\xf0\xd0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe8\xc8","\xe6\xc6","\xbe\xae", +"zZ","\xc6\xc5","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Bosnia and Herzegovina, US keyboard with Bosnian letters */ +static const char main_key_ba_us[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xb9\xa9","\xf0\xd0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe8\xc8","\xe6\xc6","\xbe\xae", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Brazil */ +static const char main_key_br[MAIN_LEN][2] = +{ +"'\"","1!","2@","3#","4$","5%","6W","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","QP","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","SR","]}", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>",";:","\\|","/?","\x0\x0" +}; + +/* Brazil, Eliminate dead keys */ +static const char main_key_br_nodeadkeys[MAIN_LEN][2] = +{ +"'\"","1!","2@","3#","4$","5%","6\xa8","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","'`","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","~^","]}", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>",";:","\\|","/?","\x0\x0" +}; + +/* Brazil with alternative 102 */ +static const char main_key_br_alt_102[MAIN_LEN][2] = +{ +"'\"","1!","2@","3#","4$","5%","6W","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","QP","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","SR","]}", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>",";:","<>","/?","\x0\x0" +}; + +/* Brazil with alternative 102, Eliminate dead keys */ +static const char main_key_br_alt_102_nodeadkeys[MAIN_LEN][2] = +{ +"'\"","1!","2@","3#","4$","5%","6\xa8","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","'`","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","~^","]}", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>",";:","<>","/?","\x0\x0" +}; + +/* Bulgaria */ +static const char main_key_bg[MAIN_LEN][2] = +{ +"()","1!","2?","3+","4\"","5%","6=","7:","8/","9\xa9","0\xb0","-I",".V", +",\xd9","\xd5\xf5","\xc5\xe5","\xc9\xe9","\xdb\xfb","\xdd\xfd","\xcb\xeb","\xd3\xf3","\xc4\xe4","\xda\xfa","\xc3\xe3",";\xa7", +"\xd8\xf8","\xd1\xf1","\xc1\xe1","\xcf\xef","\xd6\xf6","\xc7\xe7","\xd4\xf4","\xce\xee","\xd7\xf7","\xcd\xed","\xde\xfe","'\xf9", +"\xc0\xe0","\xca\xea","\xdf\xff","\xdc\xfc","\xc6\xe6","\xc8\xe8","\xd0\xf0","\xd2\xf2","\xcc\xec","\xc2\xe2","<>","\x0\x0","\x0\x0" +}; + +/* Bulgaria, Phonetic */ +static const char main_key_bg_phonetic[MAIN_LEN][2] = +{ +"\xde\xfe","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\xd1\xf1","\xd7\xf7","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xdf\xff","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xdd\xfd", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xca\xea","\xcb\xeb","\xcc\xec",";:","'\"","\xc0\xe0", +"\xda\xfa","\xd8\xf8","\xc3\xe3","\xd6\xf6","\xc2\xe2","\xce\xee","\xcd\xed",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Myanmar */ +static const char main_key_mm[MAIN_LEN][2] = +{ +"\x0\x0","A!","BB","CC","DD","EE","FF","GG","HH","I(","@)","-8","RV", +"**","22",",!",".$","0&","\x17\x18","\x1f\x4","\x2\x3","\x12\x13","\x7\x8","\xd\xe","\xa\x9", +"))","''","9!","-#","/%","\x15\x16","\x1b\x1b","\x0\x1","\x10\x11","\x5\x6","\xb\xc","NO", +"LM","76","\x19\xf","\x14\x14","\x17\x17","\x1c\x1c","\x1eP",",Q",".J","/\x1a","<>","\x0\x0","\x0\x0" +}; + +/* Canada */ +static const char main_key_ca[MAIN_LEN][2] = +{ +"#|","1!","2\"","3/","4$","5%","6?","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","RR","[W", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","PP","<>", +"zZ","xX","cC","vV","bB","nN","mM",",'","..","\xe9\xc9","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Canada, French Dvorak */ +static const char main_key_ca_fr_dvorak[MAIN_LEN][2] = +{ +"#|","1!","2\"","3/","4$","5%","6?","7&","8*","9(","0)","RR","[W", +"PP",",'","..","pP","yY","fF","gG","cC","rR","lL","\xe9\xc9","=+", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","<>", +";:","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Canada, French (legacy) */ +static const char main_key_ca_fr_legacy[MAIN_LEN][2] = +{ +"\xb0\xb0","1!","2\"","3#","4$","5%","6?","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","RR","\xe7\xc7", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","\xe8\xc8","\xe0\xc0", +"zZ","xX","cC","vV","bB","nN","mM",",'","..","\xe9\xc9","\xf9\xd9","\x0\x0","\x0\x0" +}; + +/* Canada, Multilingual */ +static const char main_key_ca_multix[MAIN_LEN][2] = +{ +"/\\","1!","2@","3#","4$","5%","6?","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","RW","\xe7\xc7", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","\xe8\xc8","\xe0\xc0", +"zZ","xX","cC","vV","bB","nN","mM",",'",".\"","\xe9\xc9","\xf9\xd9","\x0\x0","\x0\x0" +}; + +/* Canada, Multilingual, second part */ +static const char main_key_ca_multi_2gr[MAIN_LEN][2] = +{ +"\x0\xad","\xb9\xa1","\xb2\xb2","\xb3\xa3","\xbc\xa4","\xbd\xc4","\xbe\xc5","\x0\xc6","\x0\xc9","\x0\xb1","\x0\x0","\x0\xbf","[\\", +"\x0\xd9","\xb3\xa3","\xbd\xbc","\xb6\xae","\xbc\xac","\xfb\xa5","\xfe\xfc","\xfd\xb9","\xf8\xd8","\xfe\xde","\x0X","ST", +"\xe6\xc6","\xdf\xa7","\xf0\xd0","\x0\xaa","\xbf\xbd","\xb1\xa1","32","\xa2\xa2","@?","QY","\x0Z","\\U", +"\x0\x0","\x0\x0","\xa2\xa9","\xd2\xd0","\xd3\xd1","Ij","\xb5\xba","\xaf\xd7","\xb7\xf7","\x0V","<\xa6","\x0\x0","\x0\x0" +}; + +/* Canada, Inuktitut */ +static const char main_key_ca_ike[MAIN_LEN][2] = +{ +"{u","\x95""1","I2","P3","\x83""4","f5","\x85""6","\xbb""7","\xd0""8","\xea""9",">0","-_","]=", +"\x8f\x8b","\x3""1","\x7f""F","m\x96","Nq","\xefs","\xa5u","\xc2\xa4","\xd5\xa0","(\xa6","\xa1\x5","V\x1e", +"\x91\x8d","\x5""3","\x81H","oU","P(","\xf1)","\xa7*","\xc4W","\xd7\xa2",";:","'\"","\\|", +"\x93\x90","\xa""8","\x83K","r?","U|","\xf4\xc7","\xaa\xda",",<",".>","-Y","yw","\x0\x0","\x0\x0" +}; + +/* Congo, Democratic Republic of the */ +static const char main_key_cd[MAIN_LEN][2] = +{ +"`~","&1","\x1""2","\x0""3","(4","{5","}6",")7","\x2""8","\xc""9","\x8""0","-_","=+", +"aA","wW","eE","rR","tT","yY","uU","iI","oO","pP","[\x90","*^", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","T\x86","\"\\", +"zZ","xX","cC","vV","bB","nN",",.",";:","!?","'/","\\|","\x0\x0","\x0\x0" +}; + +/* Czechia */ +static const char main_key_cz[MAIN_LEN][2] = +{ +";X","+1","\xec""2","\xb9""3","\xe8""4","\xf8""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfa/",")(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf9\"","\xa7!","W'", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Czechia, With <|> key */ +static const char main_key_cz_bksl[MAIN_LEN][2] = +{ +";X","+1","\xec""2","\xb9""3","\xe8""4","\xf8""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfa/",")(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf9\"","\xa7!","\\|", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Czechia, qwerty */ +static const char main_key_cz_qwerty[MAIN_LEN][2] = +{ +";X","+1","\xec""2","\xb9""3","\xe8""4","\xf8""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfa/",")(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf9\"","\xa7!","W'", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Czechia, qwerty, extended Backslash */ +static const char main_key_cz_qwerty_bksl[MAIN_LEN][2] = +{ +";X","+1","\xec""2","\xb9""3","\xe8""4","\xf8""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfa/",")(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf9\"","\xa7!","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Denmark */ +static const char main_key_dk[MAIN_LEN][2] = +{ +"\xbd\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","QP", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","WR", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe6\xc6","\xf8\xd8","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Denmark, Eliminate dead keys */ +static const char main_key_dk_nodeadkeys[MAIN_LEN][2] = +{ +"\xbd\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\xb4`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe6\xc6","\xf8\xd8","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Netherlands */ +static const char main_key_nl[MAIN_LEN][2] = +{ +"@\xa7","1!","2\"","3#","4$","5%","6&","7_","8(","9)","0'","/?","\xb0S", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","WR","*|", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","+\xb1","'`","<>", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-=","][","\x0\x0","\x0\x0" +}; + +/* Bhutan */ +static const char main_key_bt[MAIN_LEN][2] = +{ +"\x9\xa","!\x4","\"\x5","#\x6","$H","%p","&\x8","'8","(4",")<","\x20=","\x14\x7f","\xd\x11", +"@\x90","A\x91","B\x92","D\x94","r\x80","t\x84","z{","|}","E\x95","F\x96","G\x97","I\x99", +"O\x9f","P\xa0","Q\xa1","S\xa3","T\xa4","U\xa5","V\xa6","X\xa8","Y\xa9","Z\xaa","[\xab","]\xad", +"^\xae","_\xaf","`q","a\xb1","b\xb2","c\xb3","d\xb4","f\xb6","g\xb7","h\xb8","\xd\x11","\x0\x0","\x0\x0" +}; + +/* Estonia */ +static const char main_key_ee[MAIN_LEN][2] = +{ +"ZS","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","QP", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfc\xdc","\xf5\xd5", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Estonia, Eliminate dead keys */ +static const char main_key_ee_nodeadkeys[MAIN_LEN][2] = +{ +"^~","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","'`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfc\xdc","\xf5\xd5", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Iran */ +static const char main_key_ir[MAIN_LEN][2] = +{ +"\xd\xf7","\xf1!","\xf2l","\xf3k","\xf4\xfc","\xf5j","\xf6\xd7","\xf7\xac","\xf8*","\xf9)","\xf0(","-\xe0","=+", +"\xd6\xf2","\xd5\xec","\xcb\xed","\xe2\xeb","\xe1\xef","\xda\xf0","\xd9\xee","\xe7\xf1","\xce]","\xcd[","\xcc}","\x86{", +"\xd4\xc4","\xd3\xc6","\xcc\xea","\xc8\xc5","\xe4\xc3","\xc7\xc2","\xca\xc9","\xe6\xbb","\xe5\xab","\xa9:","\xaf\xbb","\\|", +"\xd8\xe3","\xd7S","\xd2\x98","\xd1p","\xd0\xc","\xcfT","~\xc1","\xe8>",".<","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Iran, Kurdish, Latin Q */ +static const char main_key_ir_ku[MAIN_LEN][2] = +{ +"\"\\","1!","2'","3^","4+","5%","6&","7/","8(","9)","0=","*?","-_", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","xX","\xfb\xdb", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xba\xaa","\xee\xce",",;", +"zZ","xX","cC","vV","bB","nN","mM","\xea\xca","\xe7\xc7",".:","<>","\x0\x0","\x0\x0" +}; + +/* Iran, Kurdish, (F) */ +static const char main_key_ir_ku_f[MAIN_LEN][2] = +{ +"+*","1!","2\"","3^","4$","5%","6&","7'","8(","9)","0=","/?","-_", +"fF","gG","xX","iI","oO","dD","rR","nN","hH","pP","qQ","wW", +"\xfb\xdb","\xee\xce","eE","aA","uU","tT","kK","mM","lL","yY","\xba\xaa","xX", +"jJ","\xea\xca","vV","cC","\xe7\xc7","zZ","sS","bB",".:",",;","<>","\x0\x0","\x0\x0" +}; + +/* Iran, Kurdish, Arabic-Latin */ +static const char main_key_ir_ku_ara[MAIN_LEN][2] = +{ +"\xd\xf7","1!","2@","3#","4$","5%","6^","7&","8*","9)","0(","-\xe0","=+", +"\xe2X","\xe8X","\xd5\xe7","\xd1\x95","\xca\xd7","\xcc\xce","\xc6\xc1","\xcd\xd9","\xc6\xc4","~\xcb","]}","[{", +"\xc7\xc2","\xd3\xd4","\xcf\xd0","\xe1\xc5","\xaf\xda","\xe7\xc","\x98\xc3","\xa9\xe3","\xe4\xb5","\xbb:","'\"","\\|", +"\xd2\xd6","\xce\xd5","\xcc\x86","\xa4\xd8","\xc8I","\xe6\xc9","\xe5\xe0","\xac>",".<","/\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Faroe Islands */ +static const char main_key_fo[MAIN_LEN][2] = +{ +"\xbd\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","QP", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xf0\xd0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe6\xc6","\xf8\xd8","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Finland */ +static const char main_key_fi[MAIN_LEN][2] = +{ +"\xa7\xbd","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","QP", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","WR", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Finland, Eliminate dead keys */ +static const char main_key_fi_nodeadkeys[MAIN_LEN][2] = +{ +"\xa7\xbd","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\xb4`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Finland, Northern Saami */ +static const char main_key_fi_smi[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","+?","\\`", +"\xe1\xc1","\xb9\xa9","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xbf\xbd", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","\xf0\xd0", +"zZ","\xe8\xc8","cC","vV","bB","nN","mM",",;",".:","-_","\xbe\xae","\x0\x0","\x0\x0" +}; + +/* Finland, Macintosh */ +static const char main_key_fi_mac[MAIN_LEN][2] = +{ +"\xa7\xb0","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\xb4`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* France */ +static const char main_key_fr[MAIN_LEN][2] = +{ +"\xb2~","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","RW","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Eliminate dead keys */ +static const char main_key_fr_nodeadkeys[MAIN_LEN][2] = +{ +"\xb2~","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","^\xa8","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Sun dead keys */ +static const char main_key_fr_sundeadkeys[MAIN_LEN][2] = +{ +"\xb2~","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","\x1\x4","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Alternative */ +static const char main_key_fr_oss[MAIN_LEN][2] = +{ +"\xf8\xd8","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","RW","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Alternative, eliminate dead keys */ +static const char main_key_fr_oss_nodeadkeys[MAIN_LEN][2] = +{ +"\xf8\xd8","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","^\xa8","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Alternative, Sun dead keys */ +static const char main_key_fr_oss_sundeadkeys[MAIN_LEN][2] = +{ +"\xf8\xd8","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","\x1\x4","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, (Legacy) Alternative */ +static const char main_key_fr_latin9[MAIN_LEN][2] = +{ +"\xbd\xbc","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","RW","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, (Legacy) Alternative, eliminate dead keys */ +static const char main_key_fr_latin9_nodeadkeys[MAIN_LEN][2] = +{ +"\xbd\xbc","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","^\xa8","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, (Legacy) Alternative, Sun dead keys */ +static const char main_key_fr_latin9_sundeadkeys[MAIN_LEN][2] = +{ +"\xbd\xbc","&1","\xe9""2","\"3","'4","(5","-6","\xe8""7","_8","\xe7""9","\xe0""0",")\xb0","=+", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","\x1\x4","$\xa3", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","*\xb5", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","!\xa7","<>","\x0\x0","\x0\x0" +}; + +/* France, Dvorak */ +static const char main_key_fr_dvorak[MAIN_LEN][2] = +{ +"\xbd\xbc","/1","+2","-3","*4","=5","\\6","(7","`8",")9","\"0","[{","]}", +":?","\xe0\xc0","\xe9\xc9","gG",".!","hH","vV","cC","mM","kK","\xe8\xc8","zZ", +"oO","aA","uU","eE","bB","fF","sS","tT","nN","dD","wW","\xf9\xd9", +"'_","qQ",",;","iI","yY","xX","rR","lL","pP","jJ","\xe7\xc7","\x0\x0","\x0\x0" +}; + +/* France, Macintosh */ +static const char main_key_fr_mac[MAIN_LEN][2] = +{ +"@#","&1","\xe9""2","\"3","'4","(5","\xa7""6","\xe8""7","!8","\xe7""9","\xe0""0",")\xb0","-_", +"aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","RW","$*", +"qQ","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","P\xa3", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","=+","<>","\x0\x0","\x0\x0" +}; + +/* Ghana */ +static const char main_key_gh[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xb5","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Ghana, Akan */ +static const char main_key_gh_akan[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xb5","5%","6^","7&","8*","9(","0)","-_","=+", +"[\x90","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","T\x86","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Ghana, Ewe */ +static const char main_key_gh_ewe[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xb5","5%","6^","7&","8*","9(","0)","-_","=+", +"[\x90","wW","eE","rR","tT","yY","uU","iI","oO","pP","T\x86","\x8b\xb2", +"aA","sS","dD","fF","gG","hH","\x92\x91","kK","lL",";:","'\"","\\|", +"zZ","xX","KJ","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Ghana, Fula */ +static const char main_key_gh_fula[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xb5","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","\xfc\xdc","eE","rR","tT","yY","uU","iI","oO","pP","\xb4\xb3","\xe7\xe6", +"aA","sS","W\x8a","fF","gG","hH","jJ","kK","lL","10","\xdd\x8e","\\|", +"r\x9d","xX","cC","vV","bB","nN","\xf1\xd1",",<","\xe7\xc7","\xba\xaa","<>","\x0\x0","\x0\x0" +}; + +/* Ghana, Ga */ +static const char main_key_gh_ga[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xb5","5%","6^","7&","8*","9(","0)","-_","=+", +"[\x90","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","T\x86","KJ","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Georgia */ +static const char main_key_ge[MAIN_LEN][2] = +{ +"\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\xe5q","\xec\xed","\xd4""e","\xe0\xe6","\xe2\xd7","\xe7y","\xe3u","\xd8i","\xddo","\xdep","[{","]}", +"\xd0""a","\xe1\xe8","\xd3""d","\xe4""f","\xd2g","\xf0h","\xef\xdf","\xd9k","\xdal",";:","'\"","\\|", +"\xd6\xeb","\xeex","\xea\xe9","\xd5v","\xd1""b","\xdcn","\xdbm",",<",".>","/?","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Georgia, Russian */ +static const char main_key_ge_ru[MAIN_LEN][2] = +{ +"^~","1!","2@","3#","4;","5:","6,","7.","8*","9(","0)","-_","#|", +"\xe6q","\xeaw","\xe3""e","\xd9r","\xd4t","\xdcy","\xd2u","\xe8i","\xeco","\xd6p","\xee[","\xef]", +"\xe4""a","\xd7s","\xd5""d","\xd0""f","\xdeg","\xe0h","\xddj","\xdak","\xd3l","\xdf;","\xeb%","\\|", +"\xedz","\xe9x","\xe1""c","\xdbv","\xd8""b","\xe2n","\xe5m","\xd1<","\xe7>","\xf0?","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Germany */ +static const char main_key_de[MAIN_LEN][2] = +{ +"R\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","QP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dead acute */ +static const char main_key_de_deadacute[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","Q`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dead grave acute */ +static const char main_key_de_deadgraveacute[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","QP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Eliminate dead keys */ +static const char main_key_de_nodeadkeys[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","\xb4`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Eliminate dead keys, acute replaced by apostrophe */ +static const char main_key_de_nodeadkeys_noacute[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","\x27`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dvorak */ +static const char main_key_de_dvorak[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","+*","<>", +"\xfc\xdc",",;",".:","pP","yY","fF","gG","cC","tT","zZ","?\xdf","/\\", +"aA","oO","eE","iI","uU","hH","dD","rR","nN","sS","lL","-_", +"\xf6\xd6","qQ","jJ","kK","xX","bB","mM","wW","vV","#'","\xe4\xc4","\x0\x0","\x0\x0" +}; + +/* Germany, Neostyle */ +static const char main_key_de_neo[MAIN_LEN][2] = +{ +"R\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","-_","QP", +"qQ","vV","lL","cC","wW","kK","hH","gG","fF","jJ","\xdf?","+*", +"uU","iI","aA","eE","oO","sS","nN","rR","tT","dD","yY","#'", +"\xf6\xd6","\xfc\xdc","\xe4\xc4","pP","zZ","bB","mM",",;",".:","xX","<>","\x0\x0","\x0\x0" +}; + +/* Germany, paragraph */ +static const char main_key_de_para[MAIN_LEN][2] = +{ +"R\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","\xdf?","QP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dead acute, paragraph */ +static const char main_key_de_deadacute_para[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","\xdf?","Q`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dead grave acute, paragraph */ +static const char main_key_de_deadgraveacute_para[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","\xdf?","QP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Eliminate dead keys, paragraph */ +static const char main_key_de_nodeadkeys_para[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","\xdf?","\xb4`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Eliminate dead keys, acute replaced by apostrophe, paragraph */ +static const char main_key_de_nodeadkeys_noacute_para[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","\xdf?","\x27`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Germany, Dvorak, paragraph */ +static const char main_key_de_dvorak_para[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xb6","4$","5%","6&","7/","8(","9)","0=","+*","<>", +"\xfc\xdc",",;",".:","pP","yY","fF","gG","cC","tT","zZ","?\xdf","/\\", +"aA","oO","eE","iI","uU","hH","dD","rR","nN","sS","lL","-_", +"\xf6\xd6","qQ","jJ","kK","xX","bB","mM","wW","vV","#'","\xe4\xc4","\x0\x0","\x0\x0" +}; + +/* Germany, Sun dead keys */ +static const char main_key_de_sun[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3\xa7","4$","5%","6&","7/","8(","9)","0=","\xdf?","\x3\x0", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#'", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Greece */ +static const char main_key_gr[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +";:","\xf3\xd2","\xe5\xc5","\xf1\xd1","\xf4\xd4","\xf5\xd5","\xe8\xc8","\xe9\xc9","\xef\xcf","\xf0\xd0","[{","]}", +"\xe1\xc1","\xf2\xd2","\xe4\xc4","\xf6\xd6","\xe3\xc3","\xe7\xc7","\xee\xce","\xea\xca","\xeb\xcb","QW","'\"","\\|", +"\xe6\xc6","\xf7\xd7","\xf8\xd8","\xf9\xd9","\xe2\xc2","\xed\xcd","\xec\xcc",",<",".>","/?","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Greece, Eliminate dead keys */ +static const char main_key_gr_nodeadkeys[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +";:","\xf3\xd2","\xe5\xc5","\xf1\xd1","\xf4\xd4","\xf5\xd5","\xe8\xc8","\xe9\xc9","\xef\xcf","\xf0\xd0","[{","]}", +"\xe1\xc1","\xf2\xd2","\xe4\xc4","\xf6\xd6","\xe3\xc3","\xe7\xc7","\xee\xce","\xea\xca","\xeb\xcb",";:","'\"","\\|", +"\xe6\xc6","\xf7\xd7","\xf8\xd8","\xf9\xd9","\xe2\xc2","\xed\xcd","\xec\xcc",",<",".>","/?","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Greece, Polytonic */ +static const char main_key_gr_polytonic[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +";:","\xf3\xd2","\xe5\xc5","\xf1\xd1","\xf4\xd4","\xf5\xd5","\xe8\xc8","\xe9\xc9","\xef\xcf","\xf0\xd0","SW","]\xff", +"\xe1\xc1","\xf2\xd2","\xe4\xc4","\xf6\xd6","\xe3\xc3","\xe7\xc7","\xee\xce","\xea\xca","\xeb\xcb","Q\x13","P\x14","\\|", +"\xe6\xc6","\xf7\xd7","\xf8\xd8","\xf9\xd9","\xe2\xc2","\xed\xcd","\xec\xcc",",<",".>","/?","\xab\xbb","\x0\x0","\x0\x0" +}; + +/* Hungary */ +static const char main_key_hu[MAIN_LEN][2] = +{ +"0\xa7","1'","2\"","3+","4!","5%","6/","7=","8(","9)","\xf6\xd6","\xfc\xdc","\xf3\xd3", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xf5\xd5","\xfa\xda", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xc9","\xe1\xc1","\xfb\xdb", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","\xed\xcd","\x0\x0","\x0\x0" +}; + +/* Hungary, qwerty */ +static const char main_key_hu_qwerty[MAIN_LEN][2] = +{ +"\xed\xcd","1'","2\"","3+","4!","5%","6/","7=","8(","9)","\xf6\xd6","\xfc\xdc","\xf3\xd3", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf5\xd5","\xfa\xda", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xc9","\xe1\xc1","\xfb\xdb", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Hungary, 101/qwertz/comma/Dead keys */ +static const char main_key_hu_101_qwertz_comma_dead[MAIN_LEN][2] = +{ +"\xed\xcd","1'","2\"","3+","4!","5%","6/","7=","8(","9)","\xf6\xd6","\xfc\xdc","\xf3\xd3", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xf5\xd5","\xfa\xda", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xc9","\xe1\xc1","\xfb\xdb", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Hungary, 102/qwerty/comma/Dead keys */ +static const char main_key_hu_102_qwerty_comma_dead[MAIN_LEN][2] = +{ +"0\xa7","1'","2\"","3+","4!","5%","6/","7=","8(","9)","\xf6\xd6","\xfc\xdc","\xf3\xd3", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf5\xd5","\xfa\xda", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xc9","\xe1\xc1","\xfb\xdb", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","\xed\xcd","\x0\x0","\x0\x0" +}; + +/* Iceland */ +static const char main_key_is[MAIN_LEN][2] = +{ +"\xb0\xa8","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","\xf6\xd6","-_", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf0\xd0","'?", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe6\xc6","Q\xc4","+*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","\xfe\xde","<>","\x0\x0","\x0\x0" +}; + +/* Iceland, Sun dead keys */ +static const char main_key_is_Sundeadkeys[MAIN_LEN][2] = +{ +"\x1\xb0","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","\xf6\xd6","\x3\x0", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#\xb4", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","\xfe\xde","<>","\x0\x0","\x0\x0" +}; + +/* Iceland, Eliminate dead keys */ +static const char main_key_is_nodeadkeys[MAIN_LEN][2] = +{ +"^\xb0","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","\xf6\xd6","'`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfc\xdc","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xd6","\xe4\xc4","#\xb4", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","\xfe\xde","<>","\x0\x0","\x0\x0" +}; + +/* Iceland, Macintosh */ +static const char main_key_is_mac[MAIN_LEN][2] = +{ +"\xa3\xa7","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","\xf6\xd6","-_", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf0\xd0","'?", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe6\xc6","QW","+*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","\xfe\xde","<>","\x0\x0","\x0\x0" +}; + +/* Israel */ +static const char main_key_il[MAIN_LEN][2] = +{ +";~","1!","2@","3#","4$","5%","6^","7&","8*","9)","0(","-_","=+", +"/Q","'W","\xf7""E","\xf8R","\xe0T","\xe8Y","\xe5U","\xefI","\xedO","\xf4P","]}","[{", +"\xf9""A","\xe3S","\xe2""D","\xeb""F","\xf2G","\xe9H","\xe7J","\xecK","\xeaL","\xf3:",",\"","\\\\", +"\xe6Z","\xf1X","\xe1""C","\xe4V","\xf0""B","\xeeN","\xf6M","\xfa>","\xf5<",".?","<>","\x0\x0","\x0\x0" +}; + +/* Israel, lyx */ +static const char main_key_il_lyx[MAIN_LEN][2] = +{ +";~","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","9)","0(","-\xbe","\x0\x0", +"//","''","\xf7\xb8","\xf8\xbc","\xe0\xe","\xe8\xf","\xe5\xb9","\xef\xef","\xed\xed","\xf4\xb7","]}","[{", +"\xf9\xb0","\xe3\xbc","\xe2\xe2","\xeb\xeb","\xf2\xc2","\xe9\xc1","\xe7\xb4","\xec\xaa","\xea\xea","\xf3:",",\"","\\|", +"\xe6\xe6","\xf1\xb6","\xe1\xbb","\xe4\xb1","\xf0\xb2","\xee\xb3","\xf6\xb5","\xfa>","\xf5<",".?","<>","\x0\x0","\x0\x0" +}; + +/* Israel, Phonetic */ +static const char main_key_il_phonetic[MAIN_LEN][2] = +{ +"\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","=+", +"\xf7\xf7","\xe5\xe5","\xe0\xe0","\xf8\xf8","\xfa\xe8","\xf2\xf2","\xe5\xe5","\xe9\xe9","\xf1\xf1","\xf4\xf3","\x0\x0","\x0\x0", +"\xe0\xe0","\xf9\xf9","\xe3\xe3","\xf4\xf3","\xe2\xe2","\xe4\xe4","\xe9\xe9","\xeb\xea","\xec\xec","\x0\x0","\x0\x0","\\|", +"\xe6\xe6","\xe7\xe7","\xf6\xf5","\xe5\xe5","\xe1\xe1","\xf0\xef","\xee\xed","\x0\x0","\x0\x0","\x0\x0","<>","\x0\x0","\x0\x0" +}; + +/* Italy */ +static const char main_key_it[MAIN_LEN][2] = +{ +"\\|","1!","2\"","3\xa3","4$","5%","6&","7/","8(","9)","0=","'?","\xec^", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe8\xe9","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf2\xe7","\xe0\xb0","\xf9\xa7", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Italy, Macintosh */ +static const char main_key_it_mac[MAIN_LEN][2] = +{ +"@#","&1","\"2","'3","(4","\xe7""5","\xe8""6",")7","\xa3""8","\xe0""9","\xe9""0","-_","=+", +"qQ","zZ","eE","rR","tT","yY","uU","iI","oO","pP","\xec^","$*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","mM","\xf9%","\xa7\xb0", +"wW","xX","cC","vV","bB","nN",",?",";.",":/","\xf2!","<>","\x0\x0","\x0\x0" +}; + +/* Japan */ +static const char main_key_jp[MAIN_LEN][2] = +{ +"\x0\x0","1!","2\"","3#","4$","5%","6&","7'","8(","9)","0~","-=","^~", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","@`","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";+",":*","]}", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\\_","\\|" +}; + +/* Kyrgyzstan */ +static const char main_key_kg[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\/", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","/|","\x0\x0","\x0\x0" +}; + +/* Cambodia */ +static const char main_key_kh[MAIN_LEN][2] = +{ +"\xab\xbb","\xe1!","\xe2\xd7","\xe3\"","\xe4\xdb","\xe5%","\xe6\xcd","\xe7\xd0","\xe8\xcf","\xe9(","\xe0)","\xa5\xcc","\xb2=", +"\x86\x88","\xb9\xba","\xc1\xc2","\x9a\xac","\x8f\x91","\x99\xbd","\xbb\xbc","\xb7\xb8","\xc4\xc5","\x95\x97","\xc0\xbf","\xaa\xa7", +"\xb6\xff","\x9f\xc3","\x8a\x8c","\x90\x92","\x84\xa2","\xa0\xc7","\xd2\x89","\x80\x82","\x9b\xa1","\xbe\xfe","\xcb\xc9","\xae\xad", +"\x8b\x8d","\x81\x83","\x85\x87","\x9c\xfd","\x94\x96","\x93\x8e","\x98\xc6","\xfc\xfb","\xd4\xd5","\xca?","<>","\x0\x0","\x0\x0" +}; + +/* Kazakhstan */ +static const char main_key_kz[MAIN_LEN][2] = +{ +"()","\xfe!","\xd9\xd8","\xa6\xb6","\xa3\xa2","\x93\x92",",;",".:","\xaf\xae","\xb1\xb0","\x9b\x9a","\xe9\xe8","\xbb\xba", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\/", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","\xb0?","<>","\x0\x0","\x0\x0" +}; + +/* Kazakhstan, Russian with Kazakh */ +static const char main_key_kz_ruskaz[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\/", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","<>","\x0\x0","\x0\x0" +}; + +/* Kazakhstan, Kazakh with Russian */ +static const char main_key_kz_kazrus[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xa3\xa2","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\x93\x92","\xda\xfa","\xc8\xe8","\xb1\xb0", +"\xe9\xe8","\xd9\xf9","\x9b\x9a","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xd9\xd8","\\/", +"\xd1\xf1","\xa6\xb6","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xaf\xae","\xc2\xe2","\xc0\xe0",".,","<>","\x0\x0","\x0\x0" +}; + +/* Laos */ +static const char main_key_la[MAIN_LEN][2] = +{ +"\xd\xd","\xa2\xd1","\x9f\xd2","\xc2\xd3","\x96\xd4","\xb8\xcc","\xb9\xbc","\x84\xd5","\x95\xd6","\x88\xd7","\x82\xd8","\x8a\xd9","\xcd\xcd", +"\xbb\xbb","\xc4\xd0","\xb3\xb3","\x9e_","\xb0+","\xb4\xb4","\xb5\xb5","\xa3\xae","\x99\x99","\x8d\xbd","\x9a-","\xa5}", +"\xb1\xb1","\xab;","\x81.","\x94,","\xc0:","\xc9\xca","\xc8\xcb","\xb2!","\xaa?","\xa7%","\x87=","\xdc\xdd", +"\x9c\xad","\x9b(","\xc1\xaf","\xad\xad","\xb6\xb6","\xb7\xb7","\x97\xc6","\xa1`","\xc3$","\x9d)","<>","\x0\x0","\x0\x0" +}; + +/* Latin American */ +static const char main_key_latam[MAIN_LEN][2] = +{ +"|\xb0","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xbf\xa1", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","QW","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","{[","}]", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Latin American, Eliminate dead keys */ +static const char main_key_latam_nodeadkeys[MAIN_LEN][2] = +{ +"|\xb0","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xbf\xa1", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","`^","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","\xb4\xa8","\xe7\xc7", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Latin American, Sun dead keys */ +static const char main_key_latam_sundeadkeys[MAIN_LEN][2] = +{ +"|\xb0","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xbf\xa1", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\x0\x1","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","\x3\x4","}]", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Lithuania */ +static const char main_key_lt[MAIN_LEN][2] = +{ +"`~","\xb1\xa1","\xe8\xc8","\xea\xca","\xec\xcc","\xe7\xc7","\xb9\xa9","\xf9\xd9","\xfe\xde","\xfe(","\xd2)","-_","\xbe\xae", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\xaa\xac","\x0\x0","\x0\x0" +}; + +/* Lithuania, Standard */ +static const char main_key_lt_std[MAIN_LEN][2] = +{ +"`~","!1","-2","/3",";4",":5",",6",".7","=8","(9",")0","?+","xX", +"\xb1\xa1","\xbe\xae","eE","rR","tT","yY","uU","iI","oO","pP","\xe7\xc7","wW", +"aA","sS","dD","\xb9\xa9","gG","hH","jJ","kK","lL","\xf9\xd9","\xec\xcc","qQ", +"zZ","\xfe\xde","cC","vV","bB","nN","mM","\xe8\xc8","fF","\xea\xca","<>","\x0\x0","\x0\x0" +}; + +/* Lithuania, US keyboard with Lithuanian letters */ +static const char main_key_lt_us[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\xaa\xac","\x0\x0","\x0\x0" +}; + +/* Lithuania, IBM (LST 1205-92) */ +static const char main_key_lt_ibm[MAIN_LEN][2] = +{ +"`~","!1","\"2","/3",";4",":5",",6",".7","?8","(9",")0","_-","+=", +"\xb1\xa1","\xbe\xae","eE","rR","tT","yY","uU","iI","oO","pP","\xe7\xc7","\xfe\xd2", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf9\xd9","\xec\xcc","\\|", +"zZ","\xfe\xde","cC","vV","bB","nN","mM","\xe8\xc8","\xb9\xa9","\xea\xca","<>","\x0\x0","\x0\x0" +}; + +/* Latvia, Apostrophe (') variant */ +static const char main_key_lv_apostrophe[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","\x4\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Latvia, Tilde (~) variant */ +static const char main_key_lv_tilde[MAIN_LEN][2] = +{ +"\x4~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Latvia, F-letter (F) variant */ +static const char main_key_lv_fkey[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","\x4\x4","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Macedonia */ +static const char main_key_mk[MAIN_LEN][2] = +{ +"P~","1!","2\xfe","3\xd2","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\xa9\xb9","\xaa\xba","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xa5\xb5","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xa2\xb2", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xa8\xb8","\xcb\xeb","\xcc\xec","\xde\xfe","\xac\xbc","\xd6\xf6", +"\xda\xfa","\xaf\xbf","\xc3\xe3","\xd7\xf7","\xc2\xe2","\xce\xee","\xcd\xed",",;",".:","/?","<>","\x0\x0","\x0\x0" +}; + +/* Macedonia, Eliminate dead keys */ +static const char main_key_mk_nodeadkeys[MAIN_LEN][2] = +{ +"`~","1!","2\xfe","3\xd2","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\xa9\xb9","\xaa\xba","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xa5\xb5","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xa2\xb2", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xa8\xb8","\xcb\xeb","\xcc\xec","\xde\xfe","\xac\xbc","\xd6\xf6", +"\xda\xfa","\xaf\xbf","\xc3\xe3","\xd7\xf7","\xc2\xe2","\xce\xee","\xcd\xed",",;",".:","/?","<>","\x0\x0","\x0\x0" +}; + +/* Malta */ +static const char main_key_mt[MAIN_LEN][2] = +{ +"\xe5\xc5","1!","2@","3\xac","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf5\xd5","\xb1\xa1", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\xbf\xaf","\x0\x0","\x0\x0" +}; + +/* Malta, Maltese keyboard with US layout */ +static const char main_key_mt_us[MAIN_LEN][2] = +{ +"\xe5\xc5","1!","2@","3\xac","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xf5\xd5","\xb1\xa1", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\xbf\xaf", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\xbf\xaf","\x0\x0","\x0\x0" +}; + +/* Mongolia */ +static const char main_key_mn[MAIN_LEN][2] = +{ +"=+","1\xb0","2-","3\"","4\xae","5:","6.","7_","8,","9%","0?","\xc5\xe5","\xdd\xfd", +"\xc6\xe6","\xc3\xe3","\xd5\xf5","\xd6\xf6","\xdc\xfc","\xce\xee","\xc7\xe7","\xdb\xfb","\xaf\xae","\xda\xfa","\xcb\xeb","\xdf\xff", +"\xca\xea","\xd9\xf9","\xc2\xe2","\xe9\xe8","\xc1\xe1","\xc8\xe8","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd0\xf0","!|", +"\xd1\xf1","\xde\xfe","\xa3\xb3","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xd7\xf7","\xc0\xe0","()","\x0\x0","\x0\x0" +}; + +/* Norway */ +static const char main_key_no[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\\P", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","WR", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf8\xd8","\xe6\xc6","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Norway, Eliminate dead keys */ +static const char main_key_no_nodeadkeys[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\\`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf8\xd8","\xe6\xc6","'*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Norway, Dvorak */ +static const char main_key_no_dvorak[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","+?","\\`", +"\xe5\xc5",",;",".:","pP","yY","fF","gG","cC","rR","lL","'*","~^", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","<>", +"\xe6\xc6","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","\xf8\xd8","\x0\x0","\x0\x0" +}; + +/* Norway, Northern Saami */ +static const char main_key_no_smi[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","+?","\\`", +"\xe1\xc1","\xb9\xa9","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xbf\xbd", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf8\xd8","\xe6\xc6","\xf0\xd0", +"zZ","\xe8\xc8","cC","vV","bB","nN","mM",",;",".:","-_","\xbe\xae","\x0\x0","\x0\x0" +}; + +/* Norway, Macintosh */ +static const char main_key_no_mac[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","PQ", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf8\xd8","\xe6\xc6","@*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Norway, Macintosh, eliminate dead keys */ +static const char main_key_no_mac_nodeadkeys[MAIN_LEN][2] = +{ +"|\xa7","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","`\xb4", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe5\xc5","\xa8^", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf8\xd8","\xe6\xc6","@*", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Poland, qwertz */ +static const char main_key_pl_qwertz[MAIN_LEN][2] = +{ +"\xff\\","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","+?","'*", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xbf\xf1","\xb6\xe6", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xb3\xa3","\xb1\xea","\xf3\xbc", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal */ +static const char main_key_pt[MAIN_LEN][2] = +{ +"\\|","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xab\xbb", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","+*","QP", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","\xba\xaa","SR", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal, Eliminate dead keys */ +static const char main_key_pt_nodeadkeys[MAIN_LEN][2] = +{ +"\\|","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xab\xbb", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","+*","\xb4`", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","\xba\xaa","~^", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal, Sun dead keys */ +static const char main_key_pt_sundeadkeys[MAIN_LEN][2] = +{ +"\\|","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","\xab\xbb", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","+*","\x3\x0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","\xba\xaa","\x2\x1", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal, Macintosh */ +static const char main_key_pt_mac[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xba\xaa","QP", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","SR","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal, Macintosh, eliminate dead keys */ +static const char main_key_pt_mac_nodeadkeys[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xba\xaa","\xb4`", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","~^","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Portugal, Macintosh, Sun dead keys */ +static const char main_key_pt_mac_sundeadkeys[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xba\xaa","\x3\x0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe7\xc7","\x2\x1","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Romania */ +static const char main_key_ro[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\\|","\x0\x0","\x0\x0" +}; + +/* Romania, Standard */ +static const char main_key_ro_std[MAIN_LEN][2] = +{ +"\xfe\xd3","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe3\xc3","\xee\xce", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xba\xaa","\xfe\xde","\xe2\xc2", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","/?","\\|","\x0\x0","\x0\x0" +}; + +/* Romania, Standard (Commabelow) */ +static const char main_key_ro_academic[MAIN_LEN][2] = +{ +"\xfe\xd3","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xe3\xc3","\xee\xce", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\x19\x18","\x1b\x1a","\xe2\xc2", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","/?","\\|","\x0\x0","\x0\x0" +}; + +/* Romania, Winkeys */ +static const char main_key_ro_winkeys[MAIN_LEN][2] = +{ +"][","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","'*", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xe3\xc3","\xee\xce", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xba\xaa","\xfe\xde","\xe2\xc2", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Russia */ +static const char main_key_ru[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3#","4*","5:","6,","7.","8;","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","/?","/|","\x0\x0","\x0\x0" +}; + +/* Russia, Phonetic */ +static const char main_key_ru_phonetic[MAIN_LEN][2] = +{ +"\xc0\xe0","1!","2@","3\xa3","4\xb3","5\xdf","6\xff","7&","8*","9(","0)","\x0\x0","\xde\xfe", +"\xd1\xf1","\xd7\xf7","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xd9\xf9","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xdd\xfd", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xca\xea","\xcb\xeb","\xcc\xec",";:","'\"","\xdc\xfc", +"\xda\xfa","\xd8\xf8","\xc3\xe3","\xd6\xf6","\xc2\xe2","\xce\xee","\xcd\xed",",<",".>","/?","|\xa6","\x0\x0","\x0\x0" +}; + +/* Russia, Typewriter */ +static const char main_key_ru_typewriter[MAIN_LEN][2] = +{ +"'\"","!1","\xb0""2","/3",";4",":5",",6",".7","_8","?9","%0","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","()", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","\xa3\xb3","/|","\x0\x0","\x0\x0" +}; + +/* Russia, Tatar */ +static const char main_key_ru_tt[MAIN_LEN][2] = +{ +"\xbb\xba","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xe9\xe8","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xd9\xd8","\xda\xfa","\xc8\xe8","\xaf\xae", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xa3\xa2","\xdc\xfc","\\/", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\x97\x96","\xc2\xe2","\xc0\xe0",".,","/|","\x0\x0","\x0\x0" +}; + +/* Russia, Ossetian */ +static const char main_key_ru_os[MAIN_LEN][2] = +{ +"\xdc\xfc","1!","2\"","3#","4*","5:","6,","7.","8;","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xd5\xd4","\\|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","/?","/|","\x0\x0","\x0\x0" +}; + +/* Russia, Ossetian, Winkeys */ +static const char main_key_ru_os_winkeys[MAIN_LEN][2] = +{ +"\xdc\xfc","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xd5\xd4","\\/", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","/|","\x0\x0","\x0\x0" +}; + +/* Serbia and Montenegro */ +static const char main_key_cs[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"\xa9\xb9","\xaa\xba","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xda\xfa","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xa1\xb1", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xa8\xb8","\xcb\xeb","\xcc\xec","\xde\xfe","\xab\xbb","\xd6\xf6", +"\xd6\xf6","\xaf\xbf","\xc3\xe3","\xd7\xf7","\xc2\xe2","\xce\xee","\xcd\xed",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Serbia and Montenegro, Z and ZHE swapped */ +static const char main_key_cs_yz[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?","+*", +"\xa9\xb9","\xaa\xba","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xd6\xf6","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdb\xfb","\xa1\xb1", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xa8\xb8","\xcb\xeb","\xcc\xec","\xde\xfe","\xab\xbb","\xd6\xf6", +"\xda\xfa","\xaf\xbf","\xc3\xe3","\xd7\xf7","\xc2\xe2","\xce\xee","\xcd\xed",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Slovakia */ +static const char main_key_sk[MAIN_LEN][2] = +{ +";X","+1","\xb5""2","\xb9""3","\xe8""4","\xbb""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfa/","\xe4(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf4\"","\xa7!","\xf2)", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Slovakia, Extended Backslash */ +static const char main_key_sk_bksl[MAIN_LEN][2] = +{ +";X","+1","\xb5""2","\xb9""3","\xe8""4","\xbb""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfa/","\xe4(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf4\"","\xa7!","\\|", +"yY","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Slovakia, qwerty */ +static const char main_key_sk_qwerty[MAIN_LEN][2] = +{ +";X","+1","\xb5""2","\xb9""3","\xe8""4","\xbb""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfa/","\xe4(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf4\"","\xa7!","\xf2)", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Slovakia, qwerty, extended Backslash */ +static const char main_key_sk_qwerty_bksl[MAIN_LEN][2] = +{ +";X","+1","\xb5""2","\xb9""3","\xe8""4","\xbb""5","\xbe""6","\xfd""7","\xe1""8","\xed""9","\xe9""0","=%","QZ", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xfa/","\xe4(", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf4\"","\xa7!","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",?",".:","-_","\\|","\x0\x0","\x0\x0" +}; + +/* Spain */ +static const char main_key_es[MAIN_LEN][2] = +{ +"\xba\xaa","1!","2\"","3\xb7","4$","5%","6&","7/","8(","9)","0=","'?","\xa1\xbf", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","PR","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","QW","\xe7\xc7", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Spain, Eliminate dead keys */ +static const char main_key_es_nodeadkeys[MAIN_LEN][2] = +{ +"\xba\xaa","1!","2\"","3\xb7","4$","5%","6&","7/","8(","9)","0=","'?","\xa1\xbf", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","`^","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","\xb4\xa8","\xe7\xc7", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Spain, Sun dead keys */ +static const char main_key_es_sundeadkeys[MAIN_LEN][2] = +{ +"\xba\xaa","1!","2\"","3\xb7","4$","5%","6&","7/","8(","9)","0=","'?","\xa1\xbf", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\x0\x1","+*", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf1\xd1","\x3\x4","\xe7\xc7", +"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Spain, Dvorak */ +static const char main_key_es_dvorak[MAIN_LEN][2] = +{ +"\xba\xaa","1!","2\"","3\xb7","4$","5%","6&","7/","8(","9)","0=","'?","\xa1\xbf", +".:",",;","\xf1\xd1","pP","yY","fF","gG","cC","hH","lL","PR","+*", +"aA","oO","eE","uU","iI","dD","rR","tT","nN","sS","QW","\xe7\xc7", +"-_","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","<>","\x0\x0","\x0\x0" +}; + +/* Sweden, Dvorak */ +static const char main_key_se_dvorak[MAIN_LEN][2] = +{ +"\xa7\xbd","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","QP", +"\xe5\xc5","\xe4\xc4","\xf6\xd6","pP","yY","fF","gG","cC","rR","lL",",;","WR", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","'*", +".:","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","<>","\x0\x0","\x0\x0" +}; + +/* Sweden, Russian phonetic */ +static const char main_key_se_rus[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3#","4\xa4","5%","6&","7/","8(","9)","0=","+?","\xdf\xff", +"\xd1\xf1","\xd7\xf7","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xd9\xf9","\xd5\xf5","\xc9\xe9","\xcf\xef","\xd0\xf0","\xdc\xfc","WR", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xca\xea","\xcb\xeb","\xcc\xec","\xdb\xfb","\xdd\xfd","\xc0\xe0", +"\xda\xfa","\xd8\xf8","\xc3\xe3","\xd6\xf6","\xc2\xe2","\xce\xee","\xcd\xed",",;",".:","-_","\xde\xfe","\x0\x0","\x0\x0" +}; + +/* Switzerland */ +static const char main_key_ch[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","RP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xe8","W!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xe9","\xe4\xe0","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Switzerland, German, eliminate dead keys */ +static const char main_key_ch_de_nodeadkeys[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","^`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xe8","\xa8!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xe9","\xe4\xe0","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Switzerland, German, Sun dead keys */ +static const char main_key_ch_de_sundeadkeys[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","\x1\x0", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xfc\xe8","\x4!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xf6\xe9","\xe4\xe0","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Switzerland, French */ +static const char main_key_ch_fr[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","RP", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xe8\xfc","W!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xf6","\xe0\xe4","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Switzerland, French, eliminate dead keys */ +static const char main_key_ch_fr_nodeadkeys[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","^`", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xe8\xfc","\xa8!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xf6","\xe0\xe4","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Switzerland, French, Sun dead keys */ +static const char main_key_ch_fr_sundeadkeys[MAIN_LEN][2] = +{ +"\xa7\xb0","1+","2\"","3*","4\xe7","5%","6&","7/","8(","9)","0=","'?","\x1\x0", +"qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","\xe8\xfc","\x4!", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe9\xf6","\xe0\xe4","$\xa3", +"yY","xX","cC","vV","bB","nN","mM",",;",".:","-_","<>","\x0\x0","\x0\x0" +}; + +/* Syria, Syriac */ +static const char main_key_sy_syc[MAIN_LEN][2] = +{ +"\xf.","1!","2\xa","3%","4I","5p","6q","7\xa","8\xbb","9)","0(","-\xab","=+", +"\x14""0","(3","\x16""6","):","&=","\x1c@","%A","\x17\x8","\x1e\x4","\x1a\x7","\x13\x3","\x15J", +"+1","#4","\x1d""7","\x12;","\x20>","\x10\x11",",\xe0","\"$","!1","\x1f#","\x1b""0","\x6:", +"]2","[5","$8","*<","'?","\x0""9",".B","\x18\xac","\x19\xbb","\x7\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Syria, Syriac phonetic */ +static const char main_key_sy_syc_phonetic[MAIN_LEN][2] = +{ +"\xf.","1!","2\xa","3%","4I","5p","6q","7\xa","8\xbb","9)","0(","-\xab","=+", +")0","\x18""3","\x16""6","*:",",=","\x1d@","\x1c""A","%\x8","'\x4","&\x7","]\x3","[J", +"\x10""1","#4","\x15""7","\x14;","\x13>","\x17\x11","\x1b\xe0","\x1f$","\x20""1","\x1a#","\x1e""0","\x6:", +"\x19""2","(5","$8","+<","\x12?","\"9","!B","\x0\xac",".\xbb","\x7\xbf","<>","\x0\x0","\x0\x0" +}; + +/* Tajikistan */ +static const char main_key_tj[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3'","4*","5:","6,","7.","8;","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","[T","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","/?","|\xa6","\x0\x0","\x0\x0" +}; + +/* Sri Lanka */ +static const char main_key_lk[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\x8d\x8e","\x87\x88","\x91\x92","\xbb\xca","\xa7\xa8","\xba\xca","\x8b\x8c","\x89\x8a","\x94\x95","\xb4\xb5","[{","]}", +"\x85\x86","\xc3\xc2","\xa9\xaa","\xc6""F","\x9c\x9d","\xc4\x83","\xa2\xa3","\x9a\x9b","\xbd\xc5",";:","'\"","\\|", +"\xa4\xa5","\xac\xb3","\xa0\xa1","\xc0V","\xb6\xb7","\xb1\xab","\xb8\xb9",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Thailand */ +static const char main_key_th[MAIN_LEN][2] = +{ +"_%","\xe5+","/\xf1","-\xf2","\xc0\xf3","\xb6\xf4","\xd8\xd9","\xd6\xdf","\xa4\xf5","\xb5\xf6","\xa8\xf7","\xa2\xf8","\xaa\xf9", +"\xe6\xf0","\xe4\"","\xd3\xae","\xbe\xb1","\xd0\xb8","\xd1\xed","\xd5\xea","\xc3\xb3","\xb9\xcf","\xc2\xad","\xba\xb0","\xc5,", +"\xbf\xc4","\xcb\xa6","\xa1\xaf","\xb4\xe2","\xe0\xac","\xe9\xe7","\xe8\xeb","\xd2\xc9","\xca\xc8","\xc7\xab","\xa7.","\xa3\xa5", +"\xbc(","\xbb)","\xe1\xa9","\xcd\xce","\xd4\xda","\xd7\xec","\xb7?","\xc1\xb2","\xe3\xcc","\xbd\xc6","<>","\x0\x0","\x0\x0" +}; + +/* Thailand, TIS-820.2538 */ +static const char main_key_th_tis[MAIN_LEN][2] = +{ +"O[","\xdf\xe5","/\xf1","-\xf2","\xc0\xf3","\xb6\xf4","\xd8\xd9","\xd6N","\xa4\xf5","\xb5\xf6","\xa8\xf7","\xa2\xf8","\xaa\xf9", +"\xe6\xf0","\xe4\"","\xd3\xae","\xbe\xb1","\xd0\xb8","\xd1\xed","\xd5\xea","\xc3\xb3","\xb9\xcf","\xc2\xad","\xba\xb0","\xc5,", +"\xbf\xc4","\xcb\xa6","\xa1\xaf","\xb4\xe2","\xe0\xac","\xe9\xe7","\xe8\xeb","\xd2\xc9","\xca\xc8","\xc7\xab","\xa7.","\xa5\xa3", +"\xbc(","\xbb)","\xe1\xa9","\xcd\xce","\xd4\xda","\xd7\xec","\xb7?","\xc1\xb2","\xe3\xcc","\xbd\xc6","<>","\x0\x0","\x0\x0" +}; + +/* Thailand, Pattachote */ +static const char main_key_th_pat[MAIN_LEN][2] = +{ +"_\xdf","=+","\xf2\"","\xf3/","\xf4,","\xf5?","\xd9\xd8","\xf7_","\xf8.","\xf9(","\xf0)","\xf1-","\xf6%", +"\xe7\xea","\xb5\xc4","\xc2\xe6","\xcd\xad","\xc3\xc9","\xe8\xd6","\xb4\xbd","\xc1\xab","\xc7\xb6","\xe1\xb2","\xe3\xcf","\xac\xc6", +"\xe9\xeb","\xb7\xb8","\xa7\xd3","\xa1\xb3","\xd1\xec","\xd5\xd7","\xd2\xbc","\xb9\xaa","\xe0\xe2","\xe4\xa6","\xa2\xb1","\xe5\xed", +"\xba\xae","\xbb\xaf","\xc5\xb0","\xcb\xc0","\xd4\xda","\xa4\xc8","\xca\xce","\xd0\xbf","\xa8\xa9","\xbe\xcc","<>","\x0\x0","\x0\x0" +}; + +/* Turkey */ +static const char main_key_tr[MAIN_LEN][2] = +{ +"\"\\","1!","2'","3^","4+","5%","6&","7/","8(","9)","0=","*?","-_", +"qQ","wW","eE","rR","tT","yY","uU","\xb9I","oO","pP","\xbb\xab","\xfc\xdc", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xba\xaa","i\xa9",",;", +"zZ","xX","cC","vV","bB","nN","mM","\xf6\xd6","\xe7\xc7",".:","<>","\x0\x0","\x0\x0" +}; + +/* Turkey, (F) */ +static const char main_key_tr_f[MAIN_LEN][2] = +{ +"+*","1!","2\"","3^","4$","5%","6&","7'","8(","9)","0=","/?","-_", +"fF","gG","\xbb\xab","\xb9I","oO","dD","rR","nN","hH","pP","qQ","wW", +"uU","i\xa9","eE","aA","\xfc\xdc","tT","kK","mM","lL","yY","\xba\xaa","xX", +"jJ","\xf6\xd6","vV","cC","\xe7\xc7","zZ","sS","bB",".:",",;","<>","\x0\x0","\x0\x0" +}; + +/* Ukraine */ +static const char main_key_ua[MAIN_LEN][2] = +{ +"'~","1!","2\"","3#","4*","5:","6,","7.","8;","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xa7\xb7", +"\xc6\xe6","\xa6\xb6","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xa4\xb4","\xad\xbd", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","/?","/|","\x0\x0","\x0\x0" +}; + +/* Ukraine, Phonetic */ +static const char main_key_ua_phonetic[MAIN_LEN][2] = +{ +"'~","1!","2\"","3#","4*","5:","6,","7.","8;","9(","0)","-_","=+", +"\xd1\xf1","\xd7\xf7","\xc5\xe5","\xd2\xf2","\xd4\xf4","\xc9\xc9","\xd5\xf5","\xa6\xb6","\xcf\xef","\xd0\xf0","\xdb\xfb","\xdd\xfd", +"\xc1\xe1","\xd3\xf3","\xc4\xe4","\xc6\xe6","\xc7\xe7","\xc8\xe8","\xca\xea","\xcb\xeb","\xcc\xec","\xad\xbd","\xde\xfe","\xc0\xe0", +"\xda\xfa","\xd8\xf8","\xc3\xe3","\xd6\xf6","\xc2\xe2","\xce\xee","\xcd\xed","\xa7\xb7","\xa4\xb4","/?","/|","\x0\x0","\x0\x0" +}; + +/* Ukraine, Typewriter */ +static const char main_key_ua_typewriter[MAIN_LEN][2] = +{ +"'\"","!1","\xb0""2","/3",";4",":5",",6",".7","_8","?9","%0","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xad\xbd", +"\xc6\xe6","\xc9\xe9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xa4\xb4","()", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xa6\xb6","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","\xa7\xb7","/|","\x0\x0","\x0\x0" +}; + +/* Ukraine, Winkeys */ +static const char main_key_ua_winkeys[MAIN_LEN][2] = +{ +"'~","1!","2\"","3\xb0","4;","5%","6:","7?","8*","9(","0)","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xa7\xb7", +"\xc6\xe6","\xa6\xb6","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xa4\xb4","\xad\xbd", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","/|","\x0\x0","\x0\x0" +}; + +/* Ukraine, Standard RSTU */ +static const char main_key_ua_rstu[MAIN_LEN][2] = +{ +"'?","!1","\"2","#3",";4",":5",",6",".7","*8","(9",")0","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xad\xbd", +"\xc6\xe6","\xc9\xe9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xa4\xb4","/%", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xa6\xb6","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","\xa7\xb7","/|","\x0\x0","\x0\x0" +}; + +/* Ukraine, Standard RSTU on Russian layout */ +static const char main_key_ua_rstu_ru[MAIN_LEN][2] = +{ +"'?","!1","\"2","#3",";4",":5",",6",".7","*8","(9",")0","-_","=+", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xdd\xfd","\xda\xfa","\xc8\xe8","\xdf\xff", +"\xc6\xe6","\xd9\xf9","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","/%", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0","\xa3\xb3","/|","\x0\x0","\x0\x0" +}; + +/* United Kingdom */ +static const char main_key_gb[MAIN_LEN][2] = +{ +"`\xac","1!","2\"","3\xa3","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'@","#~", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\\|","\x0\x0","\x0\x0" +}; + +/* United Kingdom, International (with dead keys) */ +static const char main_key_gb_intl[MAIN_LEN][2] = +{ +"P\xac","1!","2W","3\xa3","4$","5%","6R","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","Q@","#S", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\\|","\x0\x0","\x0\x0" +}; + +/* United Kingdom, Dvorak */ +static const char main_key_gb_dvorak[MAIN_LEN][2] = +{ +"`~","1!","2\"","3\xa3","4$","5%","6^","7&","8*","9(","0)","[{","]}", +"'@",",<",".>","pP","yY","fF","gG","cC","rR","lL","/?","=+", +"aA","oO","eE","uU","iI","dD","hH","tT","nN","sS","-_","#~", +";:","qQ","jJ","kK","xX","bB","mM","wW","vV","zZ","\\|","\x0\x0","\x0\x0" +}; + +/* United Kingdom, Macintosh */ +static const char main_key_gb_mac[MAIN_LEN][2] = +{ +"`~","1!","2@","3\xa3","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Uzbekistan */ +static const char main_key_uz[MAIN_LEN][2] = +{ +"\xa3\xb3","1!","2\"","3#","4;","5%","6:","7?","8*","9(","0)","\xae\xbe","\x9b\x9a", +"\xca\xea","\xc3\xe3","\xd5\xf5","\xcb\xeb","\xc5\xe5","\xce\xee","\xc7\xe7","\xdb\xfb","\xc8\xe8","\xdf\xff","\x93\x92","\xb3\xb2", +"\xc6\xe6","\xda\xfa","\xd7\xf7","\xc1\xe1","\xd0\xf0","\xd2\xf2","\xcf\xef","\xcc\xec","\xc4\xe4","\xd6\xf6","\xdc\xfc","\\|", +"\xd1\xf1","\xde\xfe","\xd3\xf3","\xcd\xed","\xc9\xe9","\xd4\xf4","\xd8\xf8","\xc2\xe2","\xc0\xe0",".,","/|","\x0\x0","\x0\x0" +}; + +/* Vietnam */ +static const char main_key_vn[MAIN_LEN][2] = +{ +"`~","\xe3\xc3","\xe2\xc2","\xea\xca","\xf4\xd4","P%","a^","S&","Q*","`(","\xf0\xd0","-_","\xab+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xb0\xaf","\xa1\xa0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Japan (PC-98xx Series) */ +static const char main_key_nec_vndr_jp[MAIN_LEN][2] = +{ +"\x0\x0","1!","2\"","3#","4$","5%","6&","7'","8(","9)","00","-=","^`", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","@~","[{", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";+",":*","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0_","\x0\x0" +}; + +/* Ireland, Ogham */ +static const char main_key_ie_ogam[MAIN_LEN][2] = +{ +"\x9c\x9c","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0","\x0\x0", +"\x8a\x8a","\x95\x95","\x93\x93","\x8f\x8f","\x88\x88","\x98\x98","\x92\x92","\x94\x94","\x91\x91","\x9a\x9a","\x0\x0","\x0\x0", +"\x90\x90","\x84\x84","\x87\x87","\x83\x83","\x8c\x8c","\x86\x86","\x97\x97","\x96\x96","\x82\x82","\x0\x0","\x0\x0","\x80\x80", +"\x8e\x8e","\x99\x99","\x89\x89","\x8d\x8d","\x81\x81","\x85\x85","\x8b\x8b","\x9c\x9c","\x9b\x9b","\x80\x80","\x9b\x9c","\x0\x0","\x0\x0" +}; + +/* Ireland, Ogham IS434 */ +static const char main_key_ie_ogam_is434[MAIN_LEN][2] = +{ +"`\xac","1!","2\"","3\xa3","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","\x0\x0","\x0\x0", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\x0\x0","\x0\x0","#~", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","\\|","\x0\x0","\x0\x0" +}; + +/* Maldives */ +static const char main_key_mv[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", +"\xb0\xa4","\x87\xa2","\xac\xad","\x83\x9c","\x8c\x93","\x94\xa0","\xaa\xab","\xa8\xa9","\xae\xaf","\x95\xf7","[{","]}", +"\xa6\xa7","\x90\x81","\x8b\x91","\x8a\xf2","\x8e\xa3","\x80\x99","\x96\x9b","\x86\x9a","\x8d\x85",";:","'\"","\\|", +"\x92\xa1","\xd7\x98","\x97\x9d","\x88\xa5","\x84\x9e","\x82\x8f","\x89\x9f","\xac<",".>","/\xbf","|\xa6","\x0\x0","\x0\x0" +}; + +/* Esperanto */ +static const char main_key_epo[MAIN_LEN][2] = +{ +"`~","1!","2\"","3#","4$","5%","6'","7&","8*","9(","0)","-_","=+", +"\xfe\xde","\xbc\xac","eE","rR","tT","\xf8\xd8","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xfd\xdd","\xb6\xa6","\\|", +"zZ","\xe6\xc6","cC","vV","bB","nN","mM",",;",".:","/?","<>","\x0\x0","\x0\x0" +}; + +/* Nepal */ +static const char main_key_np[MAIN_LEN][2] = +{ +"=<","gg","hh","ii","jj","kk","ll","mm","nn","oo","fp","-R","=\xc", +"\x1f\x20","L\x14","GH","0C","$%","/\x1e","AB","?@","K\x13","*+","\x7\x8","\xf\x10", +">\x6","86","&'","\x9\xa","\x17\x18","9\x5","\x1c\x1d","\x15\x16","23",";:","'\"","P\x3", +"7\xb","!\"","\x1b\x1a","5\x1",",-","(#",".\x2",",\x19","de","M?","<>","\x0\x0","\x0\x0" +}; + +/* Nigeria */ +static const char main_key_ng[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xa6","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Nigeria, Igbo */ +static const char main_key_ng_igbo[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xa6","5%","6^","7&","8*","9(","0)","-_","=+", +"\xcb\xca","wW","eE","rR","tT","yY","uU","iI","oO","pP","\xcd\xcc","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL","\xe5\xe4","'\"","\\|", +"zZ","ED","cC","vV","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Nigeria, Yoruba */ +static const char main_key_ng_yoruba[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xa6","5%","6^","7&","8*","9(","0)","-_","=+", +"\xb9\xb8","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", +"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", +"zZ","\xcd\xcc","cC","cb","bB","nN","mM",",<",".>","/?","<>","\x0\x0","\x0\x0" +}; + +/* Nigeria, Hausa */ +static const char main_key_ng_hausa[MAIN_LEN][2] = +{ +"`~","1!","2@","3#","4\xa6","5%","6^","7&","8*","9(","0)","-_","=+", +"qQ","\xfc\xdc","eE","rR","tT","yY","uU","iI","oO","pP","\xb4\xb3","\xe7\xe6", +"aA","sS","W\x8a","fF","gG","hH","jJ","kK","lL","10","\xdd\x8e","\\|", +"r\x9d","xX","cC","vV","bB","nN","\xf1\xd1",",<","\xe7\xc7","\xba\xaa","<>","\x0\x0","\x0\x0" +}; + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h new file mode 100644 index 00000000..88858c0d --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-list.h @@ -0,0 +1,268 @@ +/* $Id: keyboard-list.h $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard driver translation tables (keyboard layouts) + * + * This file was originally generated from the X.org file + * /etc/X11/xkb/rules/xorg.xml, in an attempt to support all + * keyboard layouts known to X.org. + */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +#ifndef ___VBox_keyboard_tables_h +# error This file must be included from within keyboard-tables.h +#endif /* !___VBox_keyboard_tables_h */ + +/* This file contains a list of the keyboard layouts in + keyboard-layouts.h, along with the name of the layout, for the + library to run through when it is trying to guess the current + layout. */ + + {"U.S. English", &main_key_us}, + {"U.S. English, International (with dead keys)", &main_key_us_intl}, + {"U.S. English, International, alternative 102nd key", &main_key_us_intl_alt102}, + {"U.S. English, Dvorak", &main_key_us_dvorak}, + {"U.S. English, Left handed Dvorak", &main_key_us_dvorak_l}, + {"U.S. English, Right handed Dvorak", &main_key_us_dvorak_r}, + {"U.S. English, Classic Dvorak", &main_key_us_dvorak_classic}, + {"U.S. English, Russian phonetic", &main_key_us_rus}, + {"U.S. English, Colemak", &main_key_us_col}, + {"Afghanistan", &main_key_af}, + {"Afghanistan, Pashto", &main_key_af_ps}, + {"Afghanistan, Southern Uzbek", &main_key_af_uz}, + {"Arabic", &main_key_ara}, + {"Arabic, azerty", &main_key_ara_azerty}, + {"Arabic, azerty/digits", &main_key_ara_azerty_digits}, + {"Arabic, digits", &main_key_ara_digits}, + {"Arabic, Buckwalter", &main_key_ara_buckwalter}, + {"Albania", &main_key_al}, + {"Armenia", &main_key_am}, + {"Armenia, Phonetic", &main_key_am_phonetic}, + {"Armenia, Eastern", &main_key_am_eastern}, + {"Armenia, Western", &main_key_am_western}, + {"Armenia, Alternative Eastern", &main_key_am_eastern_alt}, + {"Azerbaijan", &main_key_az}, + {"Azerbaijan, Cyrillic", &main_key_az_cyrillic}, + {"Belarus", &main_key_by}, + {"Belarus, Winkeys", &main_key_by_winkeys}, + {"Belgium", &main_key_be}, + {"Belgium, Eliminate dead keys", &main_key_be_nodeadkeys}, + {"Belgium, Sun dead keys", &main_key_be_sundeadkeys}, + {"Bangladesh", &main_key_bd}, + {"Bangladesh, Probhat", &main_key_bd_probhat}, + {"India", &main_key_in}, + {"India, Bengali", &main_key_in_ben}, + {"India, Gujarati", &main_key_in_guj}, + {"India, Gurmukhi", &main_key_in_guru}, + {"India, Kannada", &main_key_in_kan}, + {"India, Malayalam", &main_key_in_mal}, + {"India, Oriya", &main_key_in_ori}, + {"India, Tamil Unicode", &main_key_in_tam_unicode}, + {"India, Tamil TAB Typewriter", &main_key_in_tam_TAB}, + {"India, Tamil TSCII Typewriter", &main_key_in_tam_TSCII}, + {"India, Tamil", &main_key_in_tam}, + {"India, Telugu", &main_key_in_tel}, + {"India, Urdu", &main_key_in_urd}, + {"Bosnia and Herzegovina", &main_key_ba}, + {"Bosnia and Herzegovina, Use Bosnian digraphs", &main_key_ba_unicode}, + {"Bosnia and Herzegovina, US keyboard with Bosnian digraphs", &main_key_ba_unicodeus}, + {"Bosnia and Herzegovina, US keyboard with Bosnian letters", &main_key_ba_us}, + {"Brazil", &main_key_br}, + {"Brazil, Eliminate dead keys", &main_key_br_nodeadkeys}, + {"Brazil, Alternative 102", &main_key_br_alt_102}, + {"Brazil, Alternative 102, Eliminate dead keys", &main_key_br_alt_102_nodeadkeys}, + {"Bulgaria", &main_key_bg}, + {"Bulgaria, Phonetic", &main_key_bg_phonetic}, + {"Myanmar", &main_key_mm}, + {"Canada", &main_key_ca}, + {"Canada, French Dvorak", &main_key_ca_fr_dvorak}, + {"Canada, French (legacy)", &main_key_ca_fr_legacy}, + {"Canada, Multilingual", &main_key_ca_multix}, + {"Canada, Multilingual, second part", &main_key_ca_multi_2gr}, + {"Canada, Inuktitut", &main_key_ca_ike}, + {"Congo, Democratic Republic of the", &main_key_cd}, + {"Czechia", &main_key_cz}, + {"Czechia, With <|> key", &main_key_cz_bksl}, + {"Czechia, qwerty", &main_key_cz_qwerty}, + {"Czechia, qwerty, extended Backslash", &main_key_cz_qwerty_bksl}, + {"Denmark", &main_key_dk}, + {"Denmark, Eliminate dead keys", &main_key_dk_nodeadkeys}, + {"Netherlands", &main_key_nl}, + {"Bhutan", &main_key_bt}, + {"Estonia", &main_key_ee}, + {"Estonia, Eliminate dead keys", &main_key_ee_nodeadkeys}, + {"Iran", &main_key_ir}, + {"Iran, Kurdish, Latin Q", &main_key_ir_ku}, + {"Iran, Kurdish, (F)", &main_key_ir_ku_f}, + {"Iran, Kurdish, Arabic-Latin", &main_key_ir_ku_ara}, + {"Faroe Islands", &main_key_fo}, + {"Finland", &main_key_fi}, + {"Finland, Eliminate dead keys", &main_key_fi_nodeadkeys}, + {"Finland, Northern Saami", &main_key_fi_smi}, + {"Finland, Macintosh", &main_key_fi_mac}, + {"France", &main_key_fr}, + {"France, Eliminate dead keys", &main_key_fr_nodeadkeys}, + {"France, Sun dead keys", &main_key_fr_sundeadkeys}, + {"France, Alternative", &main_key_fr_oss}, + {"France, Alternative, eliminate dead keys", &main_key_fr_oss_nodeadkeys}, + {"France, Alternative, Sun dead keys", &main_key_fr_oss_sundeadkeys}, + {"France, (Legacy) Alternative", &main_key_fr_latin9}, + {"France, (Legacy) Alternative, eliminate dead keys", &main_key_fr_latin9_nodeadkeys}, + {"France, (Legacy) Alternative, Sun dead keys", &main_key_fr_latin9_sundeadkeys}, + {"France, Dvorak", &main_key_fr_dvorak}, + {"France, Macintosh", &main_key_fr_mac}, + {"Ghana", &main_key_gh}, + {"Ghana, Akan", &main_key_gh_akan}, + {"Ghana, Ewe", &main_key_gh_ewe}, + {"Ghana, Fula", &main_key_gh_fula}, + {"Ghana, Ga", &main_key_gh_ga}, + {"Georgia", &main_key_ge}, + {"Georgia, Russian", &main_key_ge_ru}, + {"Germany", &main_key_de}, + {"Germany, Dead acute", &main_key_de_deadacute}, + {"Germany, Dead grave acute", &main_key_de_deadgraveacute}, + {"Germany, Eliminate dead keys", &main_key_de_nodeadkeys}, + {"Germany, Eliminate dead keys, acute replaced by apostrophe", &main_key_de_nodeadkeys_noacute}, + {"Germany, Dvorak", &main_key_de_dvorak}, + {"Germany, Neostyle", &main_key_de_neo}, + {"Germany, paragraph", &main_key_de_para}, + {"Germany, Dead acute, paragraph", &main_key_de_deadacute_para}, + {"Germany, Dead grave acute, paragraph", &main_key_de_deadgraveacute_para}, + {"Germany, Eliminate dead keys, paragraph", &main_key_de_nodeadkeys_para}, + {"Germany, Eliminate dead keys, acute replaced by apostrophe, paragraph", &main_key_de_nodeadkeys_noacute_para}, + {"Germany, Dvorak, paragraph", &main_key_de_dvorak_para}, + {"Germany, Sun dead keys", &main_key_de_sun}, + {"Greece", &main_key_gr}, + {"Greece, Eliminate dead keys", &main_key_gr_nodeadkeys}, + {"Greece, Polytonic", &main_key_gr_polytonic}, + {"Hungary", &main_key_hu}, + {"Hungary, qwerty", &main_key_hu_qwerty}, + {"Hungary, 101/qwertz/comma/Dead keys", &main_key_hu_101_qwertz_comma_dead}, + {"Hungary, 102/qwerty/comma/Dead keys", &main_key_hu_102_qwerty_comma_dead}, + {"Iceland", &main_key_is}, + {"Iceland, Sun dead keys", &main_key_is_Sundeadkeys}, + {"Iceland, Eliminate dead keys", &main_key_is_nodeadkeys}, + {"Iceland, Macintosh", &main_key_is_mac}, + {"Israel", &main_key_il}, + {"Israel, lyx", &main_key_il_lyx}, + {"Israel, Phonetic", &main_key_il_phonetic}, + {"Italy", &main_key_it}, + {"Italy, Macintosh", &main_key_it_mac}, + {"Japan", &main_key_jp}, + {"Kyrgyzstan", &main_key_kg}, + {"Cambodia", &main_key_kh}, + {"Kazakhstan", &main_key_kz}, + {"Kazakhstan, Russian with Kazakh", &main_key_kz_ruskaz}, + {"Kazakhstan, Kazakh with Russian", &main_key_kz_kazrus}, + {"Laos", &main_key_la}, + {"Latin American", &main_key_latam}, + {"Latin American, Eliminate dead keys", &main_key_latam_nodeadkeys}, + {"Latin American, Sun dead keys", &main_key_latam_sundeadkeys}, + {"Lithuania", &main_key_lt}, + {"Lithuania, Standard", &main_key_lt_std}, + {"Lithuania, US keyboard with Lithuanian letters", &main_key_lt_us}, + {"Lithuania, IBM (LST 1205-92)", &main_key_lt_ibm}, + {"Latvia, Apostrophe (') variant", &main_key_lv_apostrophe}, + {"Latvia, Tilde (~) variant", &main_key_lv_tilde}, + {"Latvia, F-letter (F) variant", &main_key_lv_fkey}, + {"Macedonia", &main_key_mk}, + {"Macedonia, Eliminate dead keys", &main_key_mk_nodeadkeys}, + {"Malta", &main_key_mt}, + {"Malta, Maltese keyboard with US layout", &main_key_mt_us}, + {"Mongolia", &main_key_mn}, + {"Norway", &main_key_no}, + {"Norway, Eliminate dead keys", &main_key_no_nodeadkeys}, + {"Norway, Dvorak", &main_key_no_dvorak}, + {"Norway, Northern Saami", &main_key_no_smi}, + {"Norway, Macintosh", &main_key_no_mac}, + {"Norway, Macintosh, eliminate dead keys", &main_key_no_mac_nodeadkeys}, + {"Poland, qwertz", &main_key_pl_qwertz}, + {"Portugal", &main_key_pt}, + {"Portugal, Eliminate dead keys", &main_key_pt_nodeadkeys}, + {"Portugal, Sun dead keys", &main_key_pt_sundeadkeys}, + {"Portugal, Macintosh", &main_key_pt_mac}, + {"Portugal, Macintosh, eliminate dead keys", &main_key_pt_mac_nodeadkeys}, + {"Portugal, Macintosh, Sun dead keys", &main_key_pt_mac_sundeadkeys}, + {"Romania", &main_key_ro}, + {"Romania, Standard", &main_key_ro_std}, + {"Romania, Standard (Commabelow)", &main_key_ro_academic}, + {"Romania, Winkeys", &main_key_ro_winkeys}, + {"Russia", &main_key_ru}, + {"Russia, Phonetic", &main_key_ru_phonetic}, + {"Russia, Typewriter", &main_key_ru_typewriter}, + {"Russia, Tatar", &main_key_ru_tt}, + {"Russia, Ossetian", &main_key_ru_os}, + {"Russia, Ossetian, Winkeys", &main_key_ru_os_winkeys}, + {"Serbia and Montenegro", &main_key_cs}, + {"Serbia and Montenegro, Z and ZHE swapped", &main_key_cs_yz}, + {"Slovakia", &main_key_sk}, + {"Slovakia, Extended Backslash", &main_key_sk_bksl}, + {"Slovakia, qwerty", &main_key_sk_qwerty}, + {"Slovakia, qwerty, extended Backslash", &main_key_sk_qwerty_bksl}, + {"Spain", &main_key_es}, + {"Spain, Eliminate dead keys", &main_key_es_nodeadkeys}, + {"Spain, Sun dead keys", &main_key_es_sundeadkeys}, + {"Spain, Dvorak", &main_key_es_dvorak}, + {"Sweden, Dvorak", &main_key_se_dvorak}, + {"Sweden, Russian phonetic", &main_key_se_rus}, + {"Switzerland", &main_key_ch}, + {"Switzerland, German, eliminate dead keys", &main_key_ch_de_nodeadkeys}, + {"Switzerland, German, Sun dead keys", &main_key_ch_de_sundeadkeys}, + {"Switzerland, French", &main_key_ch_fr}, + {"Switzerland, French, eliminate dead keys", &main_key_ch_fr_nodeadkeys}, + {"Switzerland, French, Sun dead keys", &main_key_ch_fr_sundeadkeys}, + {"Syria, Syriac", &main_key_sy_syc}, + {"Syria, Syriac phonetic", &main_key_sy_syc_phonetic}, + {"Tajikistan", &main_key_tj}, + {"Sri Lanka", &main_key_lk}, + {"Thailand", &main_key_th}, + {"Thailand, TIS-820.2538", &main_key_th_tis}, + {"Thailand, Pattachote", &main_key_th_pat}, + {"Turkey", &main_key_tr}, + {"Turkey, (F)", &main_key_tr_f}, + {"Ukraine", &main_key_ua}, + {"Ukraine, Phonetic", &main_key_ua_phonetic}, + {"Ukraine, Typewriter", &main_key_ua_typewriter}, + {"Ukraine, Winkeys", &main_key_ua_winkeys}, + {"Ukraine, Standard RSTU", &main_key_ua_rstu}, + {"Ukraine, Standard RSTU on Russian layout", &main_key_ua_rstu_ru}, + {"United Kingdom", &main_key_gb}, + {"United Kingdom, International (with dead keys)", &main_key_gb_intl}, + {"United Kingdom, Dvorak", &main_key_gb_dvorak}, + {"United Kingdom, Macintosh", &main_key_gb_mac}, + {"Uzbekistan", &main_key_uz}, + {"Vietnam", &main_key_vn}, + {"Japan (PC-98xx Series)", &main_key_nec_vndr_jp}, + {"Ireland, Ogham", &main_key_ie_ogam}, + {"Ireland, Ogham IS434", &main_key_ie_ogam_is434}, + {"Maldives", &main_key_mv}, + {"Esperanto", &main_key_epo}, + {"Nepal", &main_key_np}, + {"Nigeria", &main_key_ng}, + {"Nigeria, Igbo", &main_key_ng_igbo}, + {"Nigeria, Yoruba", &main_key_ng_yoruba}, + {"Nigeria, Hausa", &main_key_ng_hausa}, + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h new file mode 100644 index 00000000..72ad3356 --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h @@ -0,0 +1,250 @@ +/* $Id: keyboard-tables.h $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard driver translation tables. + */ + +/* This code is originally from the Wine project. It was split off from + keyboard-new.c. (See the copyrights in that file). */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +#ifndef ___VBox_keyboard_tables_h +# define ___VBox_keyboard_tables_h + +#define MAIN_LEN 50 +static const unsigned main_key_scan[MAIN_LEN] = +{ + /* ` 1 2 3 4 5 6 7 8 9 0 - = */ + 0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D, + /* q w e r t y u i o p [ ] */ + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B, + /* a s d f g h j k l ; ' \ */ + 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B, + /* z x c v b n m , . / */ + 0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, + /* 102nd key Brazilian key Yen */ + 0x56, 0x73, 0x7d +}; + +/*** DEFINE YOUR NEW LANGUAGE-SPECIFIC MAPPINGS BELOW, SEE EXISTING TABLES */ + +/* order: Normal, Shift */ +/* We recommend you write just what is guaranteed to be correct (i.e. what's + written on the keycaps), not the bunch of special characters behind AltGr + and Shift-AltGr if it can vary among different X servers */ +/* Remember to also add your new table to the layout index table below! */ + +#include "keyboard-layouts.h" + +/*** Layout table. Add your keyboard mappings to this list */ +static const struct { + const char *comment; + const char (*key)[MAIN_LEN][2]; +} main_key_tab[]={ +#include "keyboard-list.h" + {NULL, NULL} /* sentinel */ +}; + +/** @note On the whole we use Microsoft's "USB HID to PS/2 Scan Code + * Translation Table" and + * http://www.win.tue.nl/~aeb/linux/kbd/scancodes-6.html + * as a reference for scan code numbers. + * Sun keyboards have eleven additional keys on the left-hand side. + * These keys never had PC scan codes assigned to them. We map all X11 + * keycodes which can correspond to these keys to the PC scan codes for + * F13 to F23 (as per Microsoft's translation table) and the USB keyboard + * code translates them back to the correct usage codes. */ + +/* Scan code table for non-character keys */ +static const unsigned nonchar_key_scan[256] = +{ + /* unused */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF00 */ + /* special keys */ + 0x0E, 0x0F, 0x00, /*?*/ 0, 0x00, 0x1C, 0x00, 0x00, /* FF08 */ + 0x00, 0x00, 0x00, 0x145, 0x46, 0x00, 0x00, 0x00, /* FF10 */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* FF18 */ + /* Sun Menu, additional Japanese keys */ +#ifdef sun + 0x15D, 0x79, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, /* FF20 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, /* FF28 */ +#else + 0x15D, 0x00, 0x7B, 0x79, 0x00, 0x00, 0x00, 0x70, /* FF20 */ + 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF28 */ +#endif /* sun */ + /* additional Korean keys */ + 0x00, 0xF2, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, /* FF30 */ + /* unused */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF38 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF40 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF48 */ + /* cursor keys */ + 0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F, /* FF50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF58 */ + /* misc keys */ + /* Print Open Insert Undo Again Menu */ + /* ->F17 ->F14 ->F22 */ + 0x00, 0x137, 0x68, 0x152, 0x00, 0x65, 0x6d, 0x15D, /* FF60 */ + /* Find Stop Help Break */ + /* ->F19 ->F21 ->F23 */ + 0x6a, 0x6c, 0x6e, 0x146, 0x00, 0x00, 0x00, 0x00, /* FF68 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF70 */ + /* keypad keys */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x138, 0x45, /* FF78 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF80 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11C, 0x00, 0x00, /* FF88 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4B, 0x48, /* FF90 */ + 0x4D, 0x50, 0x49, 0x51, 0x4F, 0x4C, 0x52, 0x53, /* FF98 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFA0 */ + 0x00, 0x00, 0x37, 0x4E, 0x53, 0x4A, 0x7e, 0x135, /* FFA8 */ + 0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47, /* FFB0 */ + 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, /* FFB8 */ + /* function keys (F1 to F12) */ + 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */ +#ifdef sun + /* Stop Again F13 F14 F15 F16 F17 F18 */ + /* ->F21 ->F22 */ + 0x6c, 0x6d, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* FFC8 */ +#else + /* F11 F12 */ + 0x57, 0x58, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* FFC8 */ +#endif + /* F19 F20 F21 F22 F23 F24 */ + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x76, 0x00, 0x00, /* FFD0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD8 */ + /* modifier keys */ + 0x00, 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0x00, 0x15B, /* FFE0 */ + 0x15C, 0x38, 0x138, 0x15B, 0x15C, 0x00, 0x00, 0x00, /* FFE8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFF0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x153 /* FFF8 */ +}; + +/* This list was put together using /usr/include/X11/XF86keysym.h and + the documents referenced above for scan code numbers. It has not yet + been extensively tested. The scancodes are those used by MicroSoft + keyboards. */ +static const unsigned xfree86_vendor_key_scan[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF00 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF08 */ + /* Vol- Mute Vol+ Play Stop Track- Track+ */ + 0, 0x12e, 0x120, 0x130, 0x122, 0x124, 0x110, 0x119, /* 1008FF10 */ + /* Home E-mail Search */ + 0x132, 0x16c, 0, 0x165, 0, 0, 0, 0, /* 1008FF18 */ + /* Calndr PwrDown Back Forward */ + 0x115, 0x15e, 0, 0, 0, 0, 0x16a, 0x169, /* 1008FF20 */ + /* Stop Refresh Power Wake Sleep */ + 0x168, 0x167, 0x15e, 0x163, 0, 0, 0, 0x15f, /* 1008FF28 */ + /* Favrts Pause Media MyComp */ + 0x166, 0x122, 0x16d, 0x16b, 0, 0, 0, 0, /* 1008FF30 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF48 */ + /* AppL AppR Calc Close Copy */ + /* ->F16 */ + 0x109, 0x11e, 0, 0, 0x121, 0, 0x140, 0x67, /* 1008FF50 */ + /* Cut Docmnts Excel */ + /* ->F20 */ + 0x6b, 0, 0, 0x105, 0x114, 0, 0, 0, /* 1008FF58 */ + /* LogOff */ + 0, 0x116, 0, 0, 0, 0, 0, 0, /* 1008FF60 */ + /* OffcHm Open Paste */ + /* ->F17 ->F18 */ + 0, 0, 0x13c, 0x68, 0, 0x69, 0, 0, /* 1008FF68 */ + /* Reply Refresh Save */ + 0, 0, 0x141, 0x167, 0, 0, 0, 0x157, /* 1008FF70 */ + /* ScrlUp ScrlDn Send Spell TaskPane */ + 0x10b, 0x18b, 0, 0x143, 0x123, 0, 0, 0x13d, /* 1008FF78 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF80 */ + /* Word */ + 0, 0x113, 0, 0, 0, 0, 0, 0, /* 1008FF88 */ + /* MailFwd MyPics MyMusic*/ + 0x142, 0x164, 0x13c, 0, 0, 0, 0, 0, /* 1008FF90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFA0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFA8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFB0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFB8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFC0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFC8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFD0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFD8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFE0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFE8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1008FFF0 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 1008FFF8 */ +}; + +/* This list was put together using /usr/include/X11/Sunkeysym.h and + comparing the scancodes produced by a Sun type 7 USB keyboard. Note that + Sun call F11 and F12 F36 and F37 respectively. */ +static const unsigned sun_key_scan[256] = +{ + /* FAGrav, FACirc, FATild, FAAcut, FADiae, FACed */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF00 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF08 */ + /* SunF36, SunF37 */ + 0x57, 0x58, 0, 0, 0, 0, 0, 0, /* 1005FF10 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF18 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF20 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF28 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF30 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF48 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF50 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF58 */ + /* SysReq */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF60 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF68 */ + /* Props Front Copy Paste Cut Power Vol- Mute */ + /* ->F13 ->F15 ->F16 ->F18 ->F20 */ + 0x64, 0x66, 0x67, 0x69, 0x6b, 0x15e, 0x12e, 0x120, /* 1005FF70 */ + /* Vol+ */ + 0x130, 0, 0, 0, 0, 0, 0, 0, /* 1005FF78 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF80 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFA0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFA8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFB0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFB8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFC0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFC8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFD0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFD8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFE0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFE8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 1005FFF0 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 1005FFF8 */ +}; + +#include "xkbtoscan.h" + +#endif /* !___VBox_keyboard_tables_h */ + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h new file mode 100644 index 00000000..f4f48e64 --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-types.h @@ -0,0 +1,138 @@ +/* $Id: keyboard-types.h $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard driver translation tables (PC scan code + * mappings for known keyboard maps). + */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +/* This file contains two tables - one which contains entries identifying + * the keyboard maps, each of which contains a name along with the mappings + * of certain fixed keys, and the other of which contains the complete set + * of mappings for each of the entries in the first table. These tables will + * be completed when relevant user feedback is received, based on entries + * autogenerated by VirtualBox in its release log file. */ + +#ifndef ___VBox_keyboard_tables_h +# error This file must be included from within keyboard-tables.h +#endif /* ___VBox_keyboard_tables_h */ + +/** + * This table contains a set of known keycode mappings for a set of known + * keyboard types. The most important type will be the almost ubiquitous PC + * keyboard, but as far as I know some VNC servers and some Sunrays for + * example use different mappings. I only used a minimal set of key mappings + * in this table (perhaps slightly too minimal...) because I wanted to be sure + * that the keys chosen will be present on all keyboards, even very reduced + * laptop keyboards. + */ +typedef struct { + const char *comment; + unsigned lctrl; + unsigned lshift; + unsigned capslock; + unsigned tab; + unsigned esc; + unsigned enter; + unsigned up; + unsigned down; + unsigned left; + unsigned right; + unsigned f1; + unsigned f2; + unsigned f3; + unsigned f4; + unsigned f5; + unsigned f6; + unsigned f7; + unsigned f8; +} keyboard_type; + +static keyboard_type main_keyboard_type_list[] = { + { "XFree86", 0x25, 0x32, 0x42, 0x17, 0x9, 0x24, 0x62, 0x68, + 0x64, 0x66, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a }, + { "evdev", 0x25, 0x32, 0x42, 0x17, 0x9, 0x24, 0x6f, 0x74, + 0x71, 0x72, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a }, + { "XQuartz", 0x43, 0x40, 0x41, 0x38, 0x3d, 0x2c, 0x86, 0x85, + 0x83, 0x84, 0x82, 0x80, 0x6b, 0x7e, 0x68, 0x69, 0x6a, 0x6c }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Sentinel */ +}; + +unsigned main_keyboard_type_scans[][256] = { + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x145, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x0, 0x138, 0x56, 0x57, + 0x58, 0x147, 0x148, 0x149, 0x14b, 0x0, 0x14d, 0x14f, 0x150, 0x151, 0x152, 0x153, 0x11c, 0x11d, 0x45, 0x137, + 0x135, 0x138, 0x0, 0x15b, 0x15c, 0x15d, 0x13c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x138, 0x0, 0x0, 0x0, + 0x0, 0x79, 0x0, 0x7b, 0x0, 0x7d, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x110, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x119, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x120, 0x0, 0x122, 0x0, 0x124, 0x15f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12e, 0x0, + 0x130, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x70, 0x0, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16a, 0x16b, 0x16c, 0x16d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }, + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x145, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x138, 0x29, 0x56, 0x57, + 0x58, 0x73, 0x0, 0x0, 0x79, 0x70, 0x7b, 0x0, 0x11c, 0x11d, 0x135, 0x137, 0x138, 0x0, 0x147, 0x148, + 0x149, 0x14b, 0x14d, 0x14f, 0x150, 0x151, 0x152, 0x153, 0x0, 0x120, 0x12e, 0x130, 0x15e, 0x0, 0x0, 0x45, + 0x0, 0x7e, 0xf2, 0xf1, 0x7d, 0x15b, 0x15c, 0x15d, 0x168, 0x105, 0x106, 0x107, 0x10c, 0x118, 0x65, 0x10a, + 0x110, 0x117, 0x175, 0x0, 0x0, 0x0, 0x15f, 0x163, 0x0, 0x119, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x120, 0x0, 0x122, 0x16c, 0x124, 0x15f, 0x16a, 0x169, 0x0, 0x0, 0x0, 0x119, 0x122, 0x110, 0x12e, 0x0, + 0x130, 0x0, 0x0, 0x0, 0x132, 0x167, 0x140, 0x0, 0x0, 0x10b, 0x18b, 0x0, 0x0, 0x0, 0x105, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x138, 0x0, 0x0, 0x0, 0x0, + 0x122, 0x122, 0x0, 0x0, 0x0, 0x0, 0x140, 0x122, 0x169, 0x0, 0x137, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x165, 0x0, 0x0, 0x0, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16a, 0x16b, 0x16c, 0x16d, 0x0, 0x143, + 0x141, 0x0, 0x157, 0x105, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }, + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x20, 0x21, 0x23, 0x22, 0x2c, 0x2d, + 0x2e, 0x2f, 0x29, 0x30, 0x10, 0x11, 0x12, 0x13, 0x15, 0x14, 0x2, 0x3, 0x4, 0x5, 0x7, 0x6, + 0xd, 0xa, 0x8, 0xc, 0x9, 0xb, 0x1b, 0x18, 0x16, 0x1a, 0x17, 0x19, 0x1c, 0x26, 0x24, 0x28, + 0x25, 0x27, 0x2b, 0x33, 0x35, 0x31, 0x32, 0x34, 0xf, 0x39, 0x56, 0xe, 0x0, 0x1, 0x0, 0x15b, + 0x2a, 0x3a, 0x38, 0x1d, 0x36, 0x138, 0x11d, 0x15c, 0x0, 0x0, 0x0, 0x37, 0x0, 0x4e, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x135, 0x11c, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x52, 0x4f, 0x50, 0x51, 0x4b, 0x4c, + 0x4d, 0x47, 0x0, 0x48, 0x49, 0x0, 0x0, 0x0, 0x3f, 0x40, 0x41, 0x3d, 0x42, 0x43, 0x0, 0x57, + 0x0, 0x64, 0x0, 0x65, 0x0, 0x44, 0x0, 0x58, 0x0, 0x66, 0x6e, 0x147, 0x149, 0x153, 0x3e, 0x14f, + 0x3c, 0x151, 0x3b, 0x14b, 0x14d, 0x150, 0x148, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }, + { 0 } /* Sentinel */ +}; + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c new file mode 100644 index 00000000..7d0d33f6 --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard.c @@ -0,0 +1,669 @@ +/* $Id: keyboard.c $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard handler library. + */ + +/* This code is originally from the Wine project. */ + +/* + * X11 keyboard driver + * + * Copyright 1993 Bob Amstadt + * Copyright 1996 Albrecht Kleine + * Copyright 1997 David Faure + * Copyright 1998 Morten Welinder + * Copyright 1998 Ulrich Weigand + * Copyright 1999 Ove K�ven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> +#include <X11/Xlib.h> +#include <X11/Xresource.h> +#include <X11/Xutil.h> + +#include <ctype.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <VBox/VBoxKeyboard.h> + +/* VBoxKeyboard uses the deprecated XKeycodeToKeysym(3) API, but uses it safely. + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#define KEYC2SCAN_SIZE 256 + +/** + * Array containing the current mapping of keycodes to scan codes, detected + * using the keyboard layout algorithm in X11DRV_InitKeyboardByLayout. + */ +static unsigned keyc2scan[KEYC2SCAN_SIZE]; +/** Whether to output basic debugging information to standard output */ +static int log_kb_1 = 0; +/** Whether to output verbose debugging information to standard output */ +static int log_kb_2 = 0; + +/** Output basic debugging information if wished */ +#define LOG_KB_1(a) \ +do { \ + if (log_kb_1) { \ + printf a; \ + } \ +} while (0) + +/** Output verbose debugging information if wished */ +#define LOG_KB_2(a) \ +do { \ + if (log_kb_2) { \ + printf a; \ + } \ +} while (0) + +/** Keyboard layout tables for guessing the current keyboard layout. */ +#include "keyboard-tables.h" + +/** Tables of keycode to scan code mappings for well-known keyboard types. */ +#include "keyboard-types.h" + +/** + * Translate a keycode in a key event to a scan code. If the keycode maps + * to a key symbol which is in the same place on all PC keyboards, look it + * up by symbol in one of our hard-coded translation tables. It it maps to + * a symbol which can be in a different place on different PC keyboards, look + * it up by keycode using either the lookup table which we constructed + * earlier, or using a hard-coded table if we know what type of keyboard is + * in use. + * + * @returns the scan code number, with 0x100 added for extended scan codes + * @param code the X11 key code to be looked up + */ + +unsigned X11DRV_KeyEvent(Display *display, KeyCode code) +{ + unsigned scan; + KeySym keysym = XKeycodeToKeysym(display, code, 0); + scan = 0; + if (keyc2scan[code] == 0 && keysym != 0) + { + if ((keysym >> 8) == 0xFF) /* non-character key */ + scan = nonchar_key_scan[keysym & 0xff]; + else if ((keysym >> 8) == 0x1008FF) /* XFree86 vendor keys */ + scan = xfree86_vendor_key_scan[keysym & 0xff]; + else if ((keysym >> 8) == 0x1005FF) /* Sun keys */ + scan = sun_key_scan[keysym & 0xff]; + else if (keysym == 0x20) /* Spacebar */ + scan = 0x39; + else if (keysym == 0xFE03) /* ISO level3 shift, aka AltGr */ + scan = 0x138; + else if (keysym == 0xFE11) /* ISO level5 shift, R-Ctrl on */ + scan = 0x11d; /* Canadian multilingual layout */ + } + if (keyc2scan[code]) + scan = keyc2scan[code]; + + return scan; +} + +/** + * Called from X11DRV_InitKeyboardByLayout + * See the comments for that function for a description what this function + * does. + * + * @returns an index into the table of keyboard layouts, or 0 if absolutely + * nothing fits + * @param display pointer to the X11 display handle + * @param min_keycode the lowest value in use as a keycode on this server + * @param max_keycode the highest value in use as a keycode on this server + */ +static int +X11DRV_KEYBOARD_DetectLayout (Display *display, unsigned min_keycode, + unsigned max_keycode) +{ + /** Counter variable for iterating through the keyboard layout tables. */ + unsigned current; + /** The best candidate so far for the layout. */ + unsigned kbd_layout = 0; + /** The number of matching keys in the current best candidate layout. */ + unsigned max_score = 0; + /** The number of changes of scan-code direction in the current + best candidate. */ + unsigned max_seq = 0; + /** Table for the current keycode to keysym mapping. */ + char ckey[256][2]; + /** Counter variable representing a keycode */ + unsigned keyc; + + /* Fill in our keycode to keysym mapping table. */ + memset( ckey, 0, sizeof(ckey) ); + for (keyc = min_keycode; keyc <= max_keycode; keyc++) { + /* get data for keycodes from X server */ + KeySym keysym = XKeycodeToKeysym (display, keyc, 0); + /* We leave keycodes which will definitely not be in the lookup tables + marked with 0 so that we know that we know not to look them up when + we scan the tables. */ + if ( (0xFF != (keysym >> 8)) /* Non-character key */ + && (0x1008FF != (keysym >> 8)) /* XFree86 vendor keys */ + && (0x1005FF != (keysym >> 8)) /* Sun keys */ + && (0x20 != keysym) /* Spacebar */ + && (0xFE03 != keysym) /* ISO level3 shift, aka AltGr */ + ) { + ckey[keyc][0] = keysym & 0xFF; + ckey[keyc][1] = XKeycodeToKeysym(display, keyc, 1) & 0xFF; + } + } + + /* Now scan the lookup tables, looking for one that is as close as + possible to our current keycode to keysym mapping. */ + for (current = 0; main_key_tab[current].comment; current++) { + /** How many keys have matched so far in this layout? */ + unsigned match = 0; + /** How many keys have not changed the direction? */ + unsigned seq = 0; + /** Pointer to the layout we are currently comparing against. */ + const char (*lkey)[MAIN_LEN][2] = main_key_tab[current].key; + /** For detecting dvorak layouts - in which direction do the server's + keycodes seem to be running? We count the number of times that + this direction changes as an additional hint as to how likely this + layout is to be the right one. */ + int direction = 1; + /** The keycode of the last key that we matched. This is used to + determine the direction that the keycodes are running in. */ + int pkey = -1; + LOG_KB_2(("Attempting to match against \"%s\"\n", main_key_tab[current].comment)); + for (keyc = min_keycode; keyc <= max_keycode; keyc++) { + if (0 != ckey[keyc][0]) { + /** The candidate key in the current layout for this keycode. */ + int key; + /** Does this key match? */ + int ok = 0; + /* search for a match in layout table */ + for (key = 0; (key < MAIN_LEN) && (0 == ok); key++) { + if ( ((*lkey)[key][0] == ckey[keyc][0]) + && ((*lkey)[key][1] == ckey[keyc][1]) + ) { + ok = 1; + } + } + /* count the matches and mismatches */ + if (0 != ok) { + match++; + /* How well in sequence are the keys? For dvorak layouts. */ + if (key > pkey) { + if (1 == direction) { + ++seq; + } else { + direction = -1; + } + } + if (key < pkey) { + if (1 != direction) { + ++seq; + } else { + direction = 1; + } + } + pkey = key; + } else { +#ifdef DEBUG + /* print spaces instead of \0's */ + char str[3] = " "; + if ((ckey[keyc][0] > 32) && (ckey[keyc][0] < 127)) { + str[0] = ckey[keyc][0]; + } + if ((ckey[keyc][0] > 32) && (ckey[keyc][0] < 127)) { + str[0] = ckey[keyc][0]; + } + LOG_KB_2(("Mismatch for keycode %u, keysym \"%s\" (0x%.2hx 0x%.2hx)\n", + keyc, str, ckey[keyc][0], ckey[keyc][1])); +#endif /* DEBUG defined */ + } + } + } + LOG_KB_2(("Matches=%u, seq=%u\n", match, seq)); + if ( (match > max_score) + || ((match == max_score) && (seq > max_seq)) + ) { + /* best match so far */ + kbd_layout = current; + max_score = match; + max_seq = seq; + } + } + /* we're done, report results if necessary */ + LOG_KB_1(("Detected layout is \"%s\", matches=%u, seq=%u\n", + main_key_tab[kbd_layout].comment, max_score, max_seq)); + return kbd_layout; +} + +/** + * Initialise the X11 keyboard driver by building up a table to convert X11 + * keycodes to scan codes using a heuristic based on comparing the current + * keyboard map to known international keyboard layouts. + * The basic idea is to examine each key in the current layout to see which + * characters it produces in its normal and its "shifted" state, and to look + * for known keyboard layouts which it could belong to. We then guess the + * current layout based on the number of matches we find. + * One difficulty with this approach is so-called Dvorak layouts, which are + * identical to non-Dvorak layouts, but with the keys in a different order. + * To deal with this, we compare the different candidate layouts to see in + * which one the X11 keycodes would be most sequential and hope that they + * really are arranged more or less sequentially. + * + * The actual detection of the current layout is done in the sub-function + * X11DRV_KEYBOARD_DetectLayout. Once we have determined the layout, since we + * know which PC scan code corresponds to each key in the layout, we can use + * this information to associate the scan code with an X11 keycode, which is + * what the rest of this function does. + * + * @warning not re-entrant + * @returns 1 if the layout found was optimal, 0 if it was not. This is + * for diagnostic purposes + * @param display a pointer to the X11 display + */ +static unsigned +X11DRV_InitKeyboardByLayout(Display *display) +{ + KeySym keysym; + unsigned scan; + int keyc, keyn; + const char (*lkey)[MAIN_LEN][2]; + int min_keycode, max_keycode; + int kbd_layout; + unsigned matches = 0, entries = 0; + + /* Should we log to standard output? */ + if (NULL != getenv("LOG_KB_PRIMARY")) { + log_kb_1 = 1; + } + if (NULL != getenv("LOG_KB_SECONDARY")) { + log_kb_1 = 1; + log_kb_2 = 1; + } + XDisplayKeycodes(display, &min_keycode, &max_keycode); + + /* according to the space this function is guaranteed to never return + * values for min_keycode < 8 and values for max_keycode > 255 */ + if (min_keycode < 0) + min_keycode = 0; + if (max_keycode > 255) + max_keycode = 255; + + /* Detect the keyboard layout */ + kbd_layout = X11DRV_KEYBOARD_DetectLayout(display, min_keycode, + max_keycode); + lkey = main_key_tab[kbd_layout].key; + + /* Now build a conversion array : + * keycode -> scancode + extended */ + + for (keyc = min_keycode; keyc <= max_keycode; keyc++) + { + keysym = XKeycodeToKeysym(display, keyc, 0); + scan = 0; + if (keysym) /* otherwise, keycode not used */ + { + /* Skip over keysyms which we look up on the fly */ + if ( (0xFF != (keysym >> 8)) /* Non-character key */ + && (0x1008FF != (keysym >> 8)) /* XFree86 vendor keys */ + && (0x1005FF != (keysym >> 8)) /* Sun keys */ + && (0x20 != keysym) /* Spacebar */ + && (0xFE03 != keysym) /* ISO level3 shift, aka AltGr */ + ) { + unsigned found = 0; + + /* we seem to need to search the layout-dependent scancodes */ + char unshifted = keysym & 0xFF; + char shifted = XKeycodeToKeysym(display, keyc, 1) & 0xFF; + /* find a key which matches */ + for (keyn = 0; (0 == found) && (keyn<MAIN_LEN); keyn++) { + if ( ((*lkey)[keyn][0] == unshifted) + && ((*lkey)[keyn][1] == shifted) + ) { + found = 1; + } + } + if (0 != found) { + /* got it */ + scan = main_key_scan[keyn - 1]; + /* We keep track of the number of keys that we found a + * match for to see if the layout is optimal or not. + * We ignore the 102nd key though (key number 48), since + * not all keyboards have it. */ + if (keyn != 48) + ++matches; + } + if (0 == scan) { + /* print spaces instead of \0's */ + char str[3] = " "; + if ((unshifted > 32) && (unshifted < 127)) { + str[0] = unshifted; + } + if ((shifted > 32) && (shifted < 127)) { + str[1] = shifted; + } + LOG_KB_1(("No match found for keycode %d, keysym \"%s\" (0x%x 0x%x)\n", + keyc, str, unshifted, shifted)); + } else if ((keyc > 8) && (keyc < 97) && (keyc - scan != 8)) { + /* print spaces instead of \0's */ + char str[3] = " "; + if ((unshifted > 32) && (unshifted < 127)) { + str[0] = unshifted; + } + if ((shifted > 32) && (shifted < 127)) { + str[1] = shifted; + } + LOG_KB_1(("Warning - keycode %d, keysym \"%s\" (0x%x 0x%x) was matched to scancode %u\n", + keyc, str, unshifted, shifted, scan)); + } + } + } + keyc2scan[keyc] = scan; + } /* for */ + /* Did we find a match for all keys in the layout? Count them first. + * Note that we skip the 102nd key, so that owners of 101 key keyboards + * don't get bogus messages about bad matches. */ + for (entries = 0, keyn = 0; keyn < MAIN_LEN; ++keyn) { + if ( (0 != (*lkey)[keyn][0]) + && (0 != (*lkey)[keyn][1]) + && (keyn != 47) /* don't count the 102nd key */ + ) { + ++entries; + } + } + LOG_KB_1(("Finished mapping keyboard, matches=%u, entries=%u (excluding 102nd key)\n", matches, entries)); + if (matches != entries) + { + return 0; + } + return 1; +} + +static int checkHostKeycode(unsigned hostCode, unsigned targetCode) +{ + if (!targetCode) + return 0; + if (hostCode && hostCode != targetCode) + return 0; + return 1; +} + +static int compKBMaps(const keyboard_type *pHost, const keyboard_type *pTarget) +{ + if ( !pHost->lctrl && !pHost->capslock && !pHost->lshift && !pHost->tab + && !pHost->esc && !pHost->enter && !pHost->up && !pHost->down + && !pHost->left && !pHost->right && !pHost->f1 && !pHost->f2 + && !pHost->f3 && !pHost->f4 && !pHost->f5 && !pHost->f6 && !pHost->f7 + && !pHost->f8) + return 0; + /* This test is for the people who like to swap control and caps lock */ + if ( ( !checkHostKeycode(pHost->lctrl, pTarget->lctrl) + || !checkHostKeycode(pHost->capslock, pTarget->capslock)) + && ( !checkHostKeycode(pHost->lctrl, pTarget->capslock) + || !checkHostKeycode(pHost->capslock, pTarget->lctrl))) + return 0; + if ( !checkHostKeycode(pHost->lshift, pTarget->lshift) + || !checkHostKeycode(pHost->tab, pTarget->tab) + || !checkHostKeycode(pHost->esc, pTarget->esc) + || !checkHostKeycode(pHost->enter, pTarget->enter) + || !checkHostKeycode(pHost->up, pTarget->up) + || !checkHostKeycode(pHost->down, pTarget->down) + || !checkHostKeycode(pHost->left, pTarget->left) + || !checkHostKeycode(pHost->right, pTarget->right) + || !checkHostKeycode(pHost->f1, pTarget->f1) + || !checkHostKeycode(pHost->f2, pTarget->f2) + || !checkHostKeycode(pHost->f3, pTarget->f3) + || !checkHostKeycode(pHost->f4, pTarget->f4) + || !checkHostKeycode(pHost->f5, pTarget->f5) + || !checkHostKeycode(pHost->f6, pTarget->f6) + || !checkHostKeycode(pHost->f7, pTarget->f7) + || !checkHostKeycode(pHost->f8, pTarget->f8)) + return 0; + return 1; +} + +static int findHostKBInList(const keyboard_type *pHost, + const keyboard_type *pList, int cList) +{ + int i = 0; + for (; i < cList; ++i) + if (compKBMaps(pHost, &pList[i])) + return i; + return -1; +} + +#ifdef DEBUG +static void testFindHostKB(void) +{ + keyboard_type hostBasic = + { NULL, 1 /* lctrl */, 2, 3, 4, 5, 6, 7 /* up */, 8, 9, 10, 11 /* F1 */, + 12, 13, 14, 15, 16, 17, 18 }; + keyboard_type hostSwapCtrlCaps = + { NULL, 3 /* lctrl */, 2, 1, 4, 5, 6, 7 /* up */, 8, 9, 10, 11 /* F1 */, + 12, 13, 14, 15, 16, 17, 18 }; + keyboard_type hostEmpty = + { NULL, 0 /* lctrl */, 0, 0, 0, 0, 0, 0 /* up */, 0, 0, 0, 0 /* F1 */, + 0, 0, 0, 0, 0, 0, 0 }; + keyboard_type hostNearlyEmpty = + { NULL, 1 /* lctrl */, 0, 0, 0, 0, 0, 0 /* up */, 0, 0, 0, 0 /* F1 */, + 0, 0, 0, 0, 0, 0, 18 }; + keyboard_type hostNearlyRight = + { NULL, 20 /* lctrl */, 2, 3, 4, 5, 6, 7 /* up */, 8, 9, 10, 11 /* F1 */, + 12, 13, 14, 15, 16, 17, 18 }; + keyboard_type targetList[] = { + { NULL, 18 /* lctrl */, 17, 16, 15, 14, 13, 12 /* up */, 11, 10, 9, + 8 /* F1 */, 7, 6, 5, 4, 3, 2, 1 }, + { NULL, 1 /* lctrl */, 2, 3, 4, 5, 6, 7 /* up */, 8, 9, 10, + 11 /* F1 */, 12, 13, 14, 15, 16, 17, 18 } + }; + + /* As we don't have assertions here, just printf. This should *really* + * never happen. */ + if ( hostBasic.f8 != 18 || hostSwapCtrlCaps.f8 != 18 + || hostNearlyEmpty.f8 != 18 || hostNearlyRight.f8 != 18 + || targetList[0].f8 != 1 || targetList[1].f8 != 18) + printf("ERROR: testFindHostKB: bad structures\n"); + if (findHostKBInList(&hostBasic, targetList, 2) != 1) + printf("ERROR: findHostKBInList failed to find a target in a list\n"); + if (findHostKBInList(&hostSwapCtrlCaps, targetList, 2) != 1) + printf("ERROR: findHostKBInList failed on a ctrl-caps swapped map\n"); + if (findHostKBInList(&hostEmpty, targetList, 2) != -1) + printf("ERROR: findHostKBInList accepted an empty host map\n"); + if (findHostKBInList(&hostNearlyEmpty, targetList, 2) != 1) + printf("ERROR: findHostKBInList failed on a partly empty host map\n"); + if (findHostKBInList(&hostNearlyRight, targetList, 2) != -1) + printf("ERROR: findHostKBInList failed to fail a wrong host map\n"); +} +#endif + +static unsigned +X11DRV_InitKeyboardByType(Display *display) +{ + keyboard_type hostKB; + int cMap; + + hostKB.lctrl = XKeysymToKeycode(display, XK_Control_L); + hostKB.capslock = XKeysymToKeycode(display, XK_Caps_Lock); + hostKB.lshift = XKeysymToKeycode(display, XK_Shift_L); + hostKB.tab = XKeysymToKeycode(display, XK_Tab); + hostKB.esc = XKeysymToKeycode(display, XK_Escape); + hostKB.enter = XKeysymToKeycode(display, XK_Return); + hostKB.up = XKeysymToKeycode(display, XK_Up); + hostKB.down = XKeysymToKeycode(display, XK_Down); + hostKB.left = XKeysymToKeycode(display, XK_Left); + hostKB.right = XKeysymToKeycode(display, XK_Right); + hostKB.f1 = XKeysymToKeycode(display, XK_F1); + hostKB.f2 = XKeysymToKeycode(display, XK_F2); + hostKB.f3 = XKeysymToKeycode(display, XK_F3); + hostKB.f4 = XKeysymToKeycode(display, XK_F4); + hostKB.f5 = XKeysymToKeycode(display, XK_F5); + hostKB.f6 = XKeysymToKeycode(display, XK_F6); + hostKB.f7 = XKeysymToKeycode(display, XK_F7); + hostKB.f8 = XKeysymToKeycode(display, XK_F8); + +#ifdef DEBUG + testFindHostKB(); +#endif + cMap = findHostKBInList(&hostKB, main_keyboard_type_list, + sizeof(main_keyboard_type_list) + / sizeof(main_keyboard_type_list[0])); +#ifdef DEBUG + /* Assertion */ + if (sizeof(keyc2scan) != sizeof(main_keyboard_type_scans[cMap])) + { + printf("ERROR: keyc2scan array size doesn't match main_keyboard_type_scans[]!\n"); + return 0; + } +#endif + if (cMap >= 0) + { + memcpy(keyc2scan, main_keyboard_type_scans[cMap], sizeof(keyc2scan)); + return 1; + } + return 0; +} + +/** + * Checks for the XKB extension, and if it is found initialises the X11 keycode + * to XT scan code mapping by looking at the XKB names for each keycode. As it + * turns out that XKB can return an empty list we make sure that the list holds + * enough data to be useful to us. + */ +static unsigned +X11DRV_InitKeyboardByXkb(Display *pDisplay) +{ + int major = XkbMajorVersion, minor = XkbMinorVersion; + XkbDescPtr pKBDesc; + unsigned cFound = 0; + + if (!XkbLibraryVersion(&major, &minor)) + return 0; + if (!XkbQueryExtension(pDisplay, NULL, NULL, &major, &minor, NULL)) + return 0; + pKBDesc = XkbGetKeyboard(pDisplay, XkbAllComponentsMask, XkbUseCoreKbd); + if (!pKBDesc) + return 0; + if (XkbGetNames(pDisplay, XkbKeyNamesMask, pKBDesc) != Success) + return 0; + { + unsigned i, j; + + memset(keyc2scan, 0, sizeof(keyc2scan)); + for (i = pKBDesc->min_key_code; i < pKBDesc->max_key_code; ++i) + for (j = 0; j < sizeof(xkbMap) / sizeof(xkbMap[0]); ++j) + if (!memcmp(xkbMap[j].cszName, + &pKBDesc->names->keys->name[i * XKB_NAME_SIZE], + XKB_NAME_SIZE)) + { + keyc2scan[i] = xkbMap[j].uScan; + ++cFound; + break; + } + } + XkbFreeNames(pKBDesc, XkbKeyNamesMask, True); + XkbFreeKeyboard(pKBDesc, XkbAllComponentsMask, True); + return cFound >= 45 ? 1 : 0; +} + +/** + * Initialise the X11 keyboard driver by finding which X11 keycodes correspond + * to which PC scan codes. If the keyboard being used is not a PC keyboard, + * the X11 keycodes will be mapped to the scan codes which the equivalent keys + * on a PC keyboard would use. + * + * We use two algorithms to try to determine the mapping. See the comments + * attached to the two algorithm functions (X11DRV_InitKeyboardByLayout and + * X11DRV_InitKeyboardByType) for descriptions of the algorithms used. Both + * functions tell us on return whether they think that they have correctly + * determined the mapping. If both functions claim to have determined the + * mapping correctly, we prefer the second (ByType). However, if neither does + * then we prefer the first (ByLayout), as it produces a fuzzy result which is + * still likely to be partially correct. + * + * @warning not re-entrant + * @returns 1 if the layout found was optimal, 0 if it was not. This is + * for diagnostic purposes + * @param display a pointer to the X11 display + * @param byLayoutOK diagnostic - set to one if detection by layout + * succeeded, and to 0 otherwise + * @param byTypeOK diagnostic - set to one if detection by type + * succeeded, and to 0 otherwise + * @param byXkbOK diagnostic - set to one if detection using XKB + * succeeded, and to 0 otherwise + * @param remapScancode array of tuples that remap the keycode (first + * part) to a scancode (second part) + * @note Xkb takes precedence over byType takes precedence over byLayout, + * for anyone who wants to log information about which method is in + * use. byLayout is the fallback, as it is likely to be partly usable + * even if it doesn't initialise correctly. + */ +unsigned X11DRV_InitKeyboard(Display *display, unsigned *byLayoutOK, + unsigned *byTypeOK, unsigned *byXkbOK, + int (*remapScancodes)[2]) +{ + unsigned byLayout, byType, byXkb; + + byLayout = X11DRV_InitKeyboardByLayout(display); + if (byLayoutOK) + *byLayoutOK = byLayout; + + byType = X11DRV_InitKeyboardByType(display); + if (byTypeOK) + *byTypeOK = byType; + + byXkb = X11DRV_InitKeyboardByXkb(display); + if (byXkbOK) + *byXkbOK = byXkb; + + /* Fall back to the one which did work. */ + if (!byXkb) + { + if (byType) + X11DRV_InitKeyboardByType(display); + else + X11DRV_InitKeyboardByLayout(display); + } + + /* Remap keycodes after initialization. Remapping stops after an + identity mapping is seen */ + if (remapScancodes != NULL) + for (; (*remapScancodes)[0] != (*remapScancodes)[1]; remapScancodes++) + keyc2scan[(*remapScancodes)[0]] = (*remapScancodes)[1]; + + return (byLayout || byType || byXkb) ? 1 : 0; +} + +/** + * Returns the keycode to scancode array + */ +unsigned *X11DRV_getKeyc2scan(void) +{ + return keyc2scan; +} + diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h b/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h new file mode 100644 index 00000000..7702c712 --- /dev/null +++ b/src/VBox/Frontends/Common/VBoxKeyboard/xkbtoscan.h @@ -0,0 +1,299 @@ +/* $Id: xkbtoscan.h $ */ +/** @file + * VBox/Frontends/Common - X11 keyboard driver translation tables (XT scan + * code mappings for XKB key names). + */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice + * other than GPL or LGPL is available it will apply instead, Oracle elects to use only + * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where + * a choice of LGPL license versions is made available with the language indicating + * that LGPLv2 or any later version may be used, or where a choice of which version + * of the LGPL is applied is otherwise unspecified. + */ + +#ifndef ___VBox_keyboard_tables_h +# error This file must be included from within keyboard-tables.h +#endif /* ___VBox_keyboard_tables_h */ + +enum { XKB_NAME_SIZE = 4 }; + +/** + * This table contains a list of mappings of XKB key names to XT scan codes. + */ +struct +{ + const char cszName[XKB_NAME_SIZE]; + unsigned uScan; +} xkbMap[] = +{ + { "ESC", 0x1 }, + { "AE01", 0x2 }, + { "AE02", 0x3 }, + { "AE03", 0x4 }, + { "AE04", 0x5 }, + { "AE05", 0x6 }, + { "AE06", 0x7 }, + { "AE07", 0x8 }, + { "AE08", 0x9 }, + { "AE09", 0xa }, + { "AE10", 0xb }, + { "AE11", 0xc }, + { "AE12", 0xd }, + { "BKSP", 0xe }, + { "TAB", 0xf }, + { "AD01", 0x10 }, + { "AD02", 0x11 }, + { "AD03", 0x12 }, + { "AD04", 0x13 }, + { "AD05", 0x14 }, + { "AD06", 0x15 }, + { "AD07", 0x16 }, + { "AD08", 0x17 }, + { "AD09", 0x18 }, + { "AD10", 0x19 }, + { "AD11", 0x1a }, + { "AD12", 0x1b }, + { "RTRN", 0x1c }, + { "LCTL", 0x1d }, + { "AC01", 0x1e }, + { "AC02", 0x1f }, + { "AC03", 0x20 }, + { "AC04", 0x21 }, + { "AC05", 0x22 }, + { "AC06", 0x23 }, + { "AC07", 0x24 }, + { "AC08", 0x25 }, + { "AC09", 0x26 }, + { "AC10", 0x27 }, + { "AC11", 0x28 }, + { "AC12", 0x2b }, + { "TLDE", 0x29 }, + { "LFSH", 0x2a }, + { "BKSL", 0x2b }, + { "AB01", 0x2c }, + { "AB02", 0x2d }, + { "AB03", 0x2e }, + { "AB04", 0x2f }, + { "AB05", 0x30 }, + { "AB06", 0x31 }, + { "AB07", 0x32 }, + { "AB08", 0x33 }, + { "AB09", 0x34 }, + { "AB10", 0x35 }, + { "RTSH", 0x36 }, + { "KPMU", 0x37 }, + { "LALT", 0x38 }, + { "SPCE", 0x39 }, + { "CAPS", 0x3a }, + { "FK01", 0x3b }, + { "FK02", 0x3c }, + { "FK03", 0x3d }, + { "FK04", 0x3e }, + { "FK05", 0x3f }, + { "FK06", 0x40 }, + { "FK07", 0x41 }, + { "FK08", 0x42 }, + { "FK09", 0x43 }, + { "FK10", 0x44 }, + { "NMLK", 0x145 }, + { "SCLK", 0x46 }, + { "KP7", 0x47 }, + { "KP8", 0x48 }, + { "KP9", 0x49 }, + { "KPSU", 0x4a }, + { "KP4", 0x4b }, + { "KP5", 0x4c }, + { "KP6", 0x4d }, + { "KPAD", 0x4e }, + { "KP1", 0x4f }, + { "KP2", 0x50 }, + { "KP3", 0x51 }, + { "KP0", 0x52 }, + { "KPDL", 0x53 }, + { "KPPT", 0x7e }, + { "LVL3", 0x138 }, + { "LSGT", 0x56 }, + { "FK11", 0x57 }, + { "FK12", 0x58 }, + { "AB11", 0x73 }, + { "KATA", 0x0 }, + { "HIRA", 0x0 }, + { "HENK", 0x79 }, + { "HKTG", 0x70 }, + { "MUHE", 0x7b }, + { "HZTG", 0x29 }, + { "JPCM", 0x0 }, + { "KPEN", 0x11c }, + { "RCTL", 0x11d }, + { "KPDV", 0x135 }, + { "PRSC", 0x137 }, + { "RALT", 0x138 }, + { "ALGR", 0x138 }, + { "LNFD", 0x0 }, + { "HOME", 0x147 }, + { "UP", 0x148 }, + { "PGUP", 0x149 }, + { "LEFT", 0x14b }, + { "RGHT", 0x14d }, + { "END", 0x14f }, + { "DOWN", 0x150 }, + { "PGDN", 0x151 }, + { "INS", 0x152 }, + { "DELE", 0x153 }, + { "I120", 0x0 }, + { "MUTE", 0x120 }, + { "VOL-", 0x12e }, + { "VOL+", 0x130 }, + { "POWR", 0x15e }, + { "KPEQ", 0x0 }, + { "I126", 0x0 }, + { "PAUS", 0x45 }, + { "I128", 0x0 }, + { "I129", 0x7e }, + { "KPPT", 0x7e }, + { "HNGL", 0xf2 }, + { "HJCV", 0xf1 }, + { "AE13", 0x7d }, + { "LWIN", 0x15b }, + { "LMTA", 0x15b }, + { "RWIN", 0x15c }, + { "RMTA", 0x15c }, + { "COMP", 0x15d }, + { "MENU", 0x15d }, + { "STOP", 0x168 }, + { "AGAI", 0x105 }, + { "PROP", 0x106 }, + { "UNDO", 0x107 }, + { "FRNT", 0x10c }, + { "COPY", 0x118 }, + { "OPEN", 0x65 }, + { "PAST", 0x10a }, + { "FIND", 0x110 }, + { "CUT", 0x117 }, + { "HELP", 0x175 }, + { "I147", 0x0 }, + { "I148", 0x0 }, + { "I149", 0x0 }, + { "I150", 0x15f }, + { "I151", 0x163 }, + { "I152", 0x0 }, + { "I153", 0x119 }, + { "I154", 0x0 }, + { "I155", 0x0 }, + { "I156", 0x0 }, + { "I157", 0x0 }, + { "I158", 0x0 }, + { "I159", 0x0 }, + { "I160", 0x120 }, + { "I161", 0x0 }, + { "I162", 0x122 }, + { "I163", 0x16c }, + { "I164", 0x124 }, + { "I165", 0x15f }, + { "I166", 0x16a }, + { "I167", 0x169 }, + { "I168", 0x0 }, + { "I169", 0x0 }, + { "I170", 0x0 }, + { "I171", 0x119 }, + { "I172", 0x122 }, + { "I173", 0x110 }, + { "I174", 0x12e }, + { "I175", 0x0 }, + { "I176", 0x130 }, + { "I177", 0x0 }, + { "I178", 0x0 }, + { "I179", 0x0 }, + { "I180", 0x132 }, + { "I181", 0x167 }, + { "I182", 0x140 }, + { "I183", 0x0 }, + { "I184", 0x0 }, + { "I185", 0x10b }, + { "I186", 0x18b }, + { "I187", 0x0 }, + { "I188", 0x0 }, + { "I189", 0x0 }, + { "I190", 0x105 }, + { "FK13", 0x0 }, + { "FK14", 0x0 }, + { "FK15", 0x0 }, + { "FK16", 0x0 }, + { "FK17", 0x0 }, + { "FK18", 0x0 }, + { "FK19", 0x0 }, + { "FK20", 0x0 }, + { "FK21", 0x0 }, + { "FK22", 0x0 }, + { "FK23", 0x0 }, + { "FK24", 0x0 }, + { "MDSW", 0x138 }, + { "ALT", 0x0 }, + { "META", 0x0 }, + { "SUPR", 0x0 }, + { "HYPR", 0x0 }, + { "I208", 0x122 }, + { "I209", 0x122 }, + { "I210", 0x0 }, + { "I211", 0x0 }, + { "I212", 0x0 }, + { "I213", 0x0 }, + { "I214", 0x140 }, + { "I215", 0x122 }, + { "I216", 0x169 }, + { "I217", 0x0 }, + { "I218", 0x137 }, + { "I219", 0x0 }, + { "I220", 0x0 }, + { "I221", 0x0 }, + { "I222", 0x0 }, + { "I223", 0x0 }, + { "I224", 0x0 }, + { "I225", 0x165 }, + { "I226", 0x0 }, + { "I227", 0x0 }, + { "I228", 0x0 }, + { "I229", 0x165 }, + { "I230", 0x166 }, + { "I231", 0x167 }, + { "I232", 0x168 }, + { "I233", 0x169 }, + { "I234", 0x16a }, + { "I235", 0x16b }, + { "I236", 0x16c }, + { "I237", 0x16d }, + { "I238", 0x0 }, + { "I239", 0x143 }, + { "I240", 0x141 }, + { "I241", 0x0 }, + { "I242", 0x157 }, + { "I243", 0x105 }, + { "I244", 0x0 }, + { "I245", 0x0 }, + { "I246", 0x0 }, + { "I247", 0x0 }, + { "I248", 0x0 }, + { "I249", 0x0 }, + { "I250", 0x0 }, + { "I251", 0x0 }, + { "I252", 0x0 }, + { "I253", 0x0 } +}; |