493 lines
18 KiB
C++
493 lines
18 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the utils of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
#include <QtCore>
|
|
#include <QtXml>
|
|
|
|
class XKBLayout
|
|
{
|
|
public:
|
|
QString name;
|
|
QString description;
|
|
QStringList variants;
|
|
};
|
|
|
|
QDomElement find(const QString &tagName, const QDomElement &e)
|
|
{
|
|
QDomNodeList children = e.childNodes();
|
|
for (int i = 0; i < children.size(); ++i) {
|
|
const QDomNode &n = children.at(i);
|
|
if (n.isElement()) {
|
|
QDomElement c = n.toElement();
|
|
if (c.tagName() == tagName)
|
|
return c;
|
|
}
|
|
}
|
|
return QDomElement();
|
|
}
|
|
|
|
QString parseVariant(const QDomElement &e)
|
|
{
|
|
QDomElement configItem = find("configItem", e);
|
|
return find("name", configItem).text();
|
|
}
|
|
|
|
QStringList findVariants(const QDomElement &e)
|
|
{
|
|
QStringList variants;
|
|
|
|
QDomNodeList children = e.childNodes();
|
|
for (int i = 0; i < children.size(); ++i) {
|
|
const QDomNode &n = children.at(i);
|
|
if (n.isElement())
|
|
variants += parseVariant(n.toElement());
|
|
}
|
|
|
|
return variants;
|
|
}
|
|
|
|
XKBLayout parseLayout(const QDomElement &e)
|
|
{
|
|
QDomElement configItem = find("configItem", e);
|
|
|
|
XKBLayout layout;
|
|
layout.name = find("name", configItem).text();
|
|
layout.description = find("description", configItem).text();
|
|
|
|
QDomElement variantList = find("variantList", e);
|
|
if (!variantList.isNull())
|
|
layout.variants = findVariants(variantList);
|
|
|
|
return layout;
|
|
}
|
|
|
|
QList<XKBLayout> findLayouts(const QDomElement &layoutList)
|
|
{
|
|
QList<XKBLayout> layouts;
|
|
|
|
QDomNodeList children = layoutList.childNodes();
|
|
for (int i = 0; i < children.size(); ++i) {
|
|
const QDomNode &n = children.at(i);
|
|
if (n.isElement())
|
|
layouts += parseLayout(n.toElement());
|
|
}
|
|
|
|
return layouts;
|
|
}
|
|
|
|
QString mapCountry(const QString &v)
|
|
{
|
|
static QMap<QString, QString> map;
|
|
static bool initialized = false;
|
|
if (!initialized) {
|
|
map["U.S. English"] = "UnitedStates";
|
|
map["PC-98xx Series"] = "Japan";
|
|
map["Bosnia and Herzegovina"] = "BosniaAndHerzegowina";
|
|
map["Czechia"] = "CzechRepublic";
|
|
map["Faroe Islands"] = "FaroeIslands";
|
|
map["Laos"] = "Laos";
|
|
map["Latin American"] = "Mexico";
|
|
map["Russia"] = "Russia";
|
|
map["Syria"] = "Syria";
|
|
map["Sri Lanka"] = "SriLanka";
|
|
map["United Kingdom"] = "UnitedKingdom";
|
|
map["Vietnam"] = "Vietnam";
|
|
map["Macedonian"] = "Macedonia";
|
|
map["Serbian"] = "Serbia";
|
|
map["Turkish "] = "Turkey";
|
|
map["Maori"] = "NewZealand";
|
|
map["Arabic"] = "UnitedArabEmirates";
|
|
initialized = true;
|
|
}
|
|
return map.value(v, v);
|
|
}
|
|
|
|
QString mapLanguage(const QString &v)
|
|
{
|
|
static QMap<QString, QString> map;
|
|
static bool initialized = false;
|
|
if (!initialized) {
|
|
map["us"] = "English";
|
|
map["us:intl"] = "English";
|
|
map["us:alt-intl"] = "English";
|
|
map["us:dvorak"] = "English";
|
|
map["us:rus"] = "Russian";
|
|
map["ara"] = "Arabic";
|
|
map["ara:azerty"] = "Arabic";
|
|
map["ara:azerty_digits"] = "Arabic";
|
|
map["ara:digits"] = "Arabic";
|
|
map["ara:qwerty"] = "Arabic";
|
|
map["ara:qwerty_digits"] = "Arabic";
|
|
map["al"] = "Albanian";
|
|
map["am"] = "Armenian";
|
|
map["am:phonetic"] = "Armenian";
|
|
map["az"] = "Azerbaijani";
|
|
map["az:cyrillic"] = "Azerbaijani";
|
|
map["by"] = "Belarusian";
|
|
map["by:winkeys"] = "Belarusian";
|
|
map["be"] = "Dutch";
|
|
map["be:iso-alternate"] = "Dutch";
|
|
map["be:nodeadkeys"] = "Dutch";
|
|
map["be:sundeadkeys"] = "Dutch";
|
|
map["bd"] = "Bengali";
|
|
map["bd:probhat"] = "Bengali";
|
|
map["in"] = "Hindi";
|
|
map["in:ben"] = "Bengali";
|
|
map["in:ben_probhat"] = "Bengali";
|
|
map["in:guj"] = "Gujarati";
|
|
map["in:guru"] = "Punjabi";
|
|
map["in:kan"] = "Kannada";
|
|
map["in:mal"] = "Malayalam";
|
|
map["in:ori"] = "Oriya";
|
|
map["in:tam_unicode"] = "Tamil";
|
|
map["in:tam_TAB"] = "Tamil";
|
|
map["in:tam_TSCII"] = "Tamil";
|
|
map["in:tam"] = "Tamil";
|
|
map["in:tel"] = "Telugu";
|
|
map["in:urd"] = "Urdu";
|
|
map["ba"] = "Bosnian";
|
|
map["br"] = "Portuguese";
|
|
map["br:nodeadkeys"] = "Portuguese";
|
|
map["bg"] = "Bulgarian";
|
|
map["bg:phonetic"] = "Bulgarian";
|
|
map["mm"] = "Burmese";
|
|
map["ca"] = "English";
|
|
map["ca:fr-dvorak"] = "French";
|
|
map["ca:fr-legacy"] = "French";
|
|
map["ca:multi"] = "English";
|
|
map["ca:multi-2gr"] = "English";
|
|
map["ca:ike"] = "Inuktitut";
|
|
map["hr"] = "Croatian";
|
|
map["hr:us"] = "Croatian";
|
|
map["cz"] = "Czech";
|
|
map["cz:bksl"] = "Czech";
|
|
map["cz:qwerty"] = "Czech";
|
|
map["cz:qwerty_bksl"] = "Czech";
|
|
map["dk"] = "Danish";
|
|
map["dk:nodeadkeys"] = "Danish";
|
|
map["nl"] = "Dutch";
|
|
map["bt"] = "Bhutani";
|
|
map["ee"] = "Estonian";
|
|
map["ee:nodeadkeys"] = "Estonian";
|
|
map["ir"] = "Persian";
|
|
map["fo"] = "Faroese";
|
|
map["fo:nodeadkeys"] = "Faroese";
|
|
map["fi"] = "Finnish";
|
|
map["fi:nodeadkeys"] = "Finnish";
|
|
map["fi:smi"] = "Finnish";
|
|
map["fr"] = "French";
|
|
map["fr:nodeadkeys"] = "French";
|
|
map["fr:sundeadkeys"] = "French";
|
|
map["fr:latin9"] = "French";
|
|
map["fr:latin9_nodeadkeys"] = "French";
|
|
map["fr:latin9_sundeadkeys"] = "French";
|
|
map["fr:dvorak"] = "French";
|
|
map["ge"] = "Georgian";
|
|
map["ge:ru"] = "Russian";
|
|
map["de"] = "German";
|
|
map["de:deadacute"] = "German";
|
|
map["de:deadgraveacute"] = "German";
|
|
map["de:nodeadkeys"] = "German";
|
|
map["de:ro"] = "Romanian";
|
|
map["de:ro_nodeadkeys"] = "Romanian";
|
|
map["de:dvorak"] = "German";
|
|
map["gr"] = "Greek";
|
|
map["gr:extended"] = "Greek";
|
|
map["gr:nodeadkeys"] = "Greek";
|
|
map["gr:polytonic"] = "Greek";
|
|
map["hu"] = "Hungarian";
|
|
map["hu:standard"] = "Hungarian";
|
|
map["hu:nodeadkeys"] = "Hungarian";
|
|
map["hu:qwerty"] = "Hungarian";
|
|
map["hu:101_qwertz_comma_dead"] = "Hungarian";
|
|
map["hu:101_qwertz_comma_nodead"] = "Hungarian";
|
|
map["hu:101_qwertz_dot_dead"] = "Hungarian";
|
|
map["hu:101_qwertz_dot_nodead"] = "Hungarian";
|
|
map["hu:101_qwerty_comma_dead"] = "Hungarian";
|
|
map["hu:101_qwerty_comma_nodead"] = "Hungarian";
|
|
map["hu:101_qwerty_dot_dead"] = "Hungarian";
|
|
map["hu:101_qwerty_dot_nodead"] = "Hungarian";
|
|
map["hu:102_qwertz_comma_dead"] = "Hungarian";
|
|
map["hu:102_qwertz_comma_nodead"] = "Hungarian";
|
|
map["hu:102_qwertz_dot_dead"] = "Hungarian";
|
|
map["hu:102_qwertz_dot_nodead"] = "Hungarian";
|
|
map["hu:102_qwerty_comma_dead"] = "Hungarian";
|
|
map["hu:102_qwerty_comma_nodead"] = "Hungarian";
|
|
map["hu:102_qwerty_dot_dead"] = "Hungarian";
|
|
map["hu:102_qwerty_dot_nodead"] = "Hungarian";
|
|
map["is"] = "Icelandic";
|
|
map["is:Sundeadkeys"] = "Icelandic";
|
|
map["is:nodeadkeys"] = "Icelandic";
|
|
map["il"] = "Hebrew";
|
|
map["il:lyx"] = "Hebrew";
|
|
map["il:si1452"] = "Hebrew";
|
|
map["il:phonetic"] = "Hebrew";
|
|
map["it"] = "Italian";
|
|
map["it:nodeadkeys"] = "Italian";
|
|
map["jp"] = "Japanese";
|
|
map["kg"] = "Kirghiz";
|
|
map["la"] = "Laothian";
|
|
map["latam"] = "Spanish";
|
|
map["latam:nodeadkeys"] = "Spanish";
|
|
map["latam:sundeadkeys"] = "Spanish";
|
|
map["lt"] = "Lithuanian";
|
|
map["lt:std"] = "Lithuanian";
|
|
map["lt:us"] = "Lithuanian";
|
|
map["lv"] = "Latvian";
|
|
map["lv:apostrophe"] = "Latvian";
|
|
map["lv:tilde"] = "Latvian";
|
|
map["lv:fkey"] = "Latvian";
|
|
map["mao"] = "Maori";
|
|
map["mkd"] = "Macedonian";
|
|
map["mkd:nodeadkeys"] = "Macedonian";
|
|
map["mt"] = "Maltese";
|
|
map["mt:us"] = "Maltese";
|
|
map["mn"] = "Mongolian";
|
|
map["no"] = "Norwegian";
|
|
map["no:nodeadkeys"] = "Norwegian";
|
|
map["no:dvorak"] = "Norwegian";
|
|
map["no:smi"] = "Norwegian";
|
|
map["no:smi_nodeadkeys"] = "Norwegian";
|
|
map["pl"] = "Polish";
|
|
map["pl:qwertz"] = "Polish";
|
|
map["pl:dvorak"] = "Polish";
|
|
map["pl:dvorak_quotes"] = "Polish";
|
|
map["pl:dvorak_altquotes"] = "Polish";
|
|
map["pt"] = "Portuguese";
|
|
map["pt:nodeadkeys"] = "Portuguese";
|
|
map["pt:sundeadkeys"] = "Portuguese";
|
|
map["ro"] = "Romanian";
|
|
map["ro:us"] = "English";
|
|
map["ro:de"] = "German";
|
|
map["ru"] = "Russian";
|
|
map["ru:phonetic"] = "Russian";
|
|
map["ru:typewriter"] = "Russian";
|
|
map["ru:winkeys"] = "Russian";
|
|
map["srp"] = "Serbian";
|
|
map["srp:yz"] = "Serbian";
|
|
map["srp:latin"] = "Serbian";
|
|
map["srp:latinunicode"] = "Serbian";
|
|
map["srp:latinyz"] = "Serbian";
|
|
map["srp:latinunicodeyz"] = "Serbian";
|
|
map["srp:alternatequotes"] = "Serbian";
|
|
map["srp:latinalternatequotes"] = "Serbian";
|
|
map["si"] = "Slovenian";
|
|
map["sk"] = "Slovak";
|
|
map["sk:bksl"] = "Slovak";
|
|
map["sk:qwerty"] = "Slovak";
|
|
map["sk:qwerty_bksl"] = "Slovak";
|
|
map["es"] = "Spanish";
|
|
map["es:nodeadkeys"] = "Spanish";
|
|
map["es:sundeadkeys"] = "Spanish";
|
|
map["es:dvorak"] = "Spanish";
|
|
map["se"] = "Swedish";
|
|
map["se:nodeadkeys"] = "Swedish";
|
|
map["se:dvorak"] = "Swedish";
|
|
map["se:rus"] = "Russian";
|
|
map["se:rus_nodeadkeys"] = "Russian";
|
|
map["se:smi"] = "Swedish";
|
|
map["ch"] = "German";
|
|
map["ch:de_nodeadkeys"] = "German";
|
|
map["ch:de_sundeadkeys"] = "German";
|
|
map["ch:fr"] = "French";
|
|
map["ch:fr_nodeadkeys"] = "French";
|
|
map["ch:fr_sundeadkeys"] = "French";
|
|
map["sy"] = "Arabic";
|
|
map["sy:syc"] = "Arabic";
|
|
map["sy:syc_phonetic"] = "Arabic";
|
|
map["tj"] = "Tajik";
|
|
map["lk"] = "Sinhala";
|
|
map["lk:tam_unicode"] = "Tamil";
|
|
map["lk:tam_TAB"] = "Tamil";
|
|
map["lk:tam_TSCII"] = "Tamil";
|
|
map["lk:sin_phonetic"] = "Sinhala";
|
|
map["th"] = "Thai";
|
|
map["th:tis"] = "Thai";
|
|
map["th:pat"] = "Thai";
|
|
map["tr"] = "Turkish";
|
|
map["tr:f"] = "Turkish";
|
|
map["tr:alt"] = "Turkish";
|
|
map["ua"] = "Ukrainian";
|
|
map["ua:phonetic"] = "Ukrainian";
|
|
map["ua:typewriter"] = "Ukrainian";
|
|
map["ua:winkeys"] = "Ukrainian";
|
|
map["ua:rstu"] = "Ukrainian";
|
|
map["ua:rstu_ru"] = "Ukrainian";
|
|
map["gb"] = "English";
|
|
map["gb:intl"] = "English";
|
|
map["gb:dvorak"] = "English";
|
|
map["uz"] = "Uzbek";
|
|
map["vn"] = "Vietnamese";
|
|
map["nec_vndr/jp"] = "Japanese";
|
|
map["ie"] = "Irish";
|
|
map["ie:CloGaelach"] = "Gaelic";
|
|
map["ie:UnicodeExpert"] = "Irish";
|
|
map["ie:ogam"] = "Gaelic";
|
|
map["ie:ogam_is434"] = "Gaelic";
|
|
map["pk"] = "Urdu";
|
|
initialized = true;
|
|
}
|
|
return map.value(v, v);
|
|
}
|
|
|
|
QString mapDirection(const QString &v)
|
|
{
|
|
static QMap<QString, QString> map;
|
|
static bool initialized = false;
|
|
if (!initialized) {
|
|
// 1. xkbdata-X11R7.0-1.0.1/symbols% grep -l '\([Hh]ebrew\|[Aa]rabic\)' **/*
|
|
map["Arabic"] = "Qt::RightToLeft";
|
|
map["Persian"] = "Qt::RightToLeft";
|
|
map["Urdu"] = "Qt::RightToLeft";
|
|
initialized = true;
|
|
}
|
|
return map.value(v, "Qt::LeftToRight");
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc != 2) {
|
|
fprintf(stderr, "usage: %s <xml input file>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
QCoreApplication app(argc, argv);
|
|
|
|
QFile file;
|
|
file.setFileName(argv[1]);
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
fprintf(stderr, "cannot open %s: %s\n", qPrintable(file.fileName()), qPrintable(file.errorString()));
|
|
return 1;
|
|
}
|
|
|
|
QDomDocument dom;
|
|
dom.setContent(&file);
|
|
|
|
if (dom.documentElement().tagName() != QLatin1String("xkbConfigRegistry")) {
|
|
fprintf(stderr, "cannot parse %s, this is not an XKB config file\n", qPrintable(file.fileName()));
|
|
return 1;
|
|
}
|
|
|
|
QDomElement layoutList = find("layoutList", dom.documentElement());
|
|
if (layoutList.isNull()) {
|
|
fprintf(stderr, "cannot parse %s, this is not an XKB config file\n", qPrintable(file.fileName()));
|
|
return 1;
|
|
}
|
|
|
|
QList<XKBLayout> layouts = findLayouts(layoutList);
|
|
|
|
// copyright and stuff
|
|
printf("/****************************************************************************\n"
|
|
"**\n"
|
|
"** Copyright (C) 2016 The Qt Company Ltd.\n"
|
|
"** Contact: https://www.qt.io/licensing/\n"
|
|
"**\n"
|
|
"** This file is part of the QtGui module of the Qt Toolkit.\n"
|
|
"**\n"
|
|
"** $QT_BEGIN_LICENSE:LGPL$\n"
|
|
"** Commercial License Usage\n"
|
|
"** Licensees holding valid commercial Qt licenses may use this file in\n"
|
|
"** accordance with the commercial license agreement provided with the\n"
|
|
"** Software or, alternatively, in accordance with the terms contained in\n"
|
|
"** a written agreement between you and The Qt Company. For licensing terms\n"
|
|
"** and conditions see https://www.qt.io/terms-conditions. For further\n"
|
|
"** information use the contact form at https://www.qt.io/contact-us.\n"
|
|
"**\n"
|
|
"** GNU Lesser General Public License Usage\n"
|
|
"** Alternatively, this file may be used under the terms of the GNU Lesser\n"
|
|
"** General Public License version 3 as published by the Free Software\n"
|
|
"** Foundation and appearing in the file LICENSE.LGPL3 included in the\n"
|
|
"** packaging of this file. Please review the following information to\n"
|
|
"** ensure the GNU Lesser General Public License version 3 requirements\n"
|
|
"** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.\n"
|
|
"**\n"
|
|
"** GNU General Public License Usage\n"
|
|
"** Alternatively, this file may be used under the terms of the GNU\n"
|
|
"** General Public License version 2.0 or (at your option) the GNU General\n"
|
|
"** Public license version 3 or any later version approved by the KDE Free\n"
|
|
"** Qt Foundation. The licenses are as published by the Free Software\n"
|
|
"** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3\n"
|
|
"** included in the packaging of this file. Please review the following\n"
|
|
"** information to ensure the GNU General Public License requirements will\n"
|
|
"** be met: https://www.gnu.org/licenses/gpl-2.0.html and\n"
|
|
"** https://www.gnu.org/licenses/gpl-3.0.html.\n"
|
|
"**\n"
|
|
"** $QT_END_LICENSE$\n"
|
|
"**\n"
|
|
"****************************************************************************/\n"
|
|
"\n"
|
|
"// This file is auto-generated, do not edit!\n"
|
|
"// (Generated using util/xkbdatagen)\n"
|
|
"\n");
|
|
|
|
// data structure
|
|
printf("static struct {\n"
|
|
" const char *layout;\n"
|
|
" const char *variant; // 0 means any variant\n"
|
|
" Qt::LayoutDirection direction;\n"
|
|
" QLocale::Language language;\n"
|
|
" QLocale::Country country;\n"
|
|
"} xkbLayoutData[] = {\n");
|
|
|
|
// contents
|
|
foreach (const XKBLayout &l, layouts) {
|
|
const QString country = mapCountry(l.description);
|
|
QString lang = mapLanguage(l.name);
|
|
if (lang.isEmpty())
|
|
lang = "C";
|
|
printf(" // name = %s, description = %s\n"
|
|
" { \"%s\", \"\", %s, QLocale::%s, QLocale::%s },\n",
|
|
l.name.toLatin1().constData(),
|
|
l.description.toLatin1().constData(),
|
|
l.name.toLatin1().constData(),
|
|
mapDirection(lang).toLatin1().constData(),
|
|
lang.toLatin1().constData(),
|
|
country.toLatin1().constData());
|
|
foreach (const QString &v, l.variants) {
|
|
QString vlang = mapLanguage(l.name + ":" + v);
|
|
if (vlang.isEmpty())
|
|
vlang = "C";
|
|
printf(" // name = %s:%s, description = %s\n"
|
|
" { \"%s\", \"%s\", %s, QLocale::%s, QLocale::%s },\n",
|
|
l.name.toLatin1().constData(),
|
|
v.toLatin1().constData(),
|
|
l.description.toLatin1().constData(),
|
|
l.name.toLatin1().constData(),
|
|
v.toLatin1().constData(),
|
|
mapDirection(vlang).toLatin1().constData(),
|
|
vlang.toLatin1().constData(),
|
|
country.toLatin1().constData());
|
|
}
|
|
}
|
|
|
|
// wrapping up
|
|
printf(" { 0, 0, Qt::LeftToRight, QLocale::C, QLocale::AnyCountry }\n"
|
|
"};\n");
|
|
|
|
return 0;
|
|
}
|