kdelibs/kdeui/util/kkeyboardlayout.cpp

1319 lines
100 KiB
C++
Raw Normal View History

/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config-kkeyserver.h"
#include "kkeyboardlayout.h"
#include "kstandarddirs.h"
#include "klocale.h"
#include "kdebug.h"
#include <QX11Info>
#include <QMap>
#include <QTimer>
#include <QProcess>
#if defined(HAVE_XKB)
# include <X11/Xatom.h>
# include <X11/Xlib.h>
# include <X11/XKBlib.h>
# include <X11/extensions/XKBrules.h>
#endif
static const int s_layouttimeout = 500;
static const char s_xkbseparator = ',';
// NOTE: scooped via scoop-rules.py script, make sure to pipe it to `sort -u -k 2 -t ',' -f`
static const struct modelDescriptionData {
const char* name;
const char* description;
} modelDescriptionTbl[] = {
{ "a4techKB21", I18N_NOOP2("Keyboard model description", "A4Tech KB-21") },
{ "a4techKBS8", I18N_NOOP2("Keyboard model description", "A4Tech KBS-8") },
{ "a4_rfkb23", I18N_NOOP2("Keyboard model description", "A4Tech Wireless Desktop RFKB-23") },
{ "airkey", I18N_NOOP2("Keyboard model description", "Acer AirKey V") },
{ "acer_c300", I18N_NOOP2("Keyboard model description", "Acer C300") },
{ "acer_ferrari4k", I18N_NOOP2("Keyboard model description", "Acer Ferrari 4000") },
{ "acer_laptop", I18N_NOOP2("Keyboard model description", "Acer laptop") },
{ "scorpius", I18N_NOOP2("Keyboard model description", "Advance Scorpius KI") },
{ "applealu_ansi", I18N_NOOP2("Keyboard model description", "Apple Aluminium (ANSI)") },
{ "applealu_iso", I18N_NOOP2("Keyboard model description", "Apple Aluminium (ISO)") },
{ "applealu_jis", I18N_NOOP2("Keyboard model description", "Apple Aluminium (JIS)") },
{ "apple_laptop", I18N_NOOP2("Keyboard model description", "Apple laptop") },
{ "apple", I18N_NOOP2("Keyboard model description", "Apple") },
{ "asus_laptop", I18N_NOOP2("Keyboard model description", "Asus laptop") },
{ "azonaRF2300", I18N_NOOP2("Keyboard model description", "Azona RF2300 Wireless Internet") },
{ "benqx730", I18N_NOOP2("Keyboard model description", "BenQ X-Touch 730") },
{ "benqx800", I18N_NOOP2("Keyboard model description", "BenQ X-Touch 800") },
{ "benqx", I18N_NOOP2("Keyboard model description", "BenQ X-Touch") },
{ "brother", I18N_NOOP2("Keyboard model description", "Brother Internet") },
{ "btc5090", I18N_NOOP2("Keyboard model description", "BTC 5090") },
{ "btc5113rf", I18N_NOOP2("Keyboard model description", "BTC 5113RF Multimedia") },
{ "btc5126t", I18N_NOOP2("Keyboard model description", "BTC 5126T") },
{ "btc6301urf", I18N_NOOP2("Keyboard model description", "BTC 6301URF") },
{ "btc9000", I18N_NOOP2("Keyboard model description", "BTC 9000") },
{ "btc9000a", I18N_NOOP2("Keyboard model description", "BTC 9000A") },
{ "btc9001ah", I18N_NOOP2("Keyboard model description", "BTC 9001AH") },
{ "btc9019u", I18N_NOOP2("Keyboard model description", "BTC 9019U") },
{ "btc9116u", I18N_NOOP2("Keyboard model description", "BTC 9116U Mini Wireless Internet and Gaming") },
{ "cherrybunlim", I18N_NOOP2("Keyboard model description", "Cherry B.UNLIMITED") },
{ "cherrybluea", I18N_NOOP2("Keyboard model description", "Cherry Blue Line CyBo@rd (alt.)") },
{ "cherryblue", I18N_NOOP2("Keyboard model description", "Cherry Blue Line CyBo@rd") },
{ "cherrycyboard", I18N_NOOP2("Keyboard model description", "Cherry CyBo@rd USB-Hub") },
{ "cherrycmexpert", I18N_NOOP2("Keyboard model description", "Cherry CyMotion Expert") },
{ "cymotionlinux", I18N_NOOP2("Keyboard model description", "Cherry CyMotion Master Linux") },
{ "cherryblueb", I18N_NOOP2("Keyboard model description", "Cherry CyMotion Master XPress") },
{ "chicony", I18N_NOOP2("Keyboard model description", "Chicony Internet") },
{ "chicony9885", I18N_NOOP2("Keyboard model description", "Chicony KB-9885") },
{ "chicony0108", I18N_NOOP2("Keyboard model description", "Chicony KU-0108") },
{ "chicony0420", I18N_NOOP2("Keyboard model description", "Chicony KU-0420") },
{ "chromebook", I18N_NOOP2("Keyboard model description", "Chromebook") },
{ "classmate", I18N_NOOP2("Keyboard model description", "Classmate PC") },
{ "armada", I18N_NOOP2("Keyboard model description", "Compaq Armada laptop") },
{ "compaqeak8", I18N_NOOP2("Keyboard model description", "Compaq Easy Access") },
{ "compaqik13", I18N_NOOP2("Keyboard model description", "Compaq Internet (13 keys)") },
{ "compaqik18", I18N_NOOP2("Keyboard model description", "Compaq Internet (18 keys)") },
{ "compaqik7", I18N_NOOP2("Keyboard model description", "Compaq Internet (7 keys)") },
{ "ipaq", I18N_NOOP2("Keyboard model description", "Compaq iPaq") },
{ "presario", I18N_NOOP2("Keyboard model description", "Compaq Presario laptop") },
{ "creativedw7000", I18N_NOOP2("Keyboard model description", "Creative Desktop Wireless 7000") },
{ "dell101", I18N_NOOP2("Keyboard model description", "Dell 101-key PC") },
{ "inspiron", I18N_NOOP2("Keyboard model description", "Dell Inspiron 6000/8000 laptop") },
{ "latitude", I18N_NOOP2("Keyboard model description", "Dell Latitude laptop") },
{ "precision_m", I18N_NOOP2("Keyboard model description", "Dell Precision M laptop") },
{ "dellm65", I18N_NOOP2("Keyboard model description", "Dell Precision M65 laptop") },
{ "dellsk8125", I18N_NOOP2("Keyboard model description", "Dell SK-8125") },
{ "dellsk8135", I18N_NOOP2("Keyboard model description", "Dell SK-8135") },
{ "dellusbmm", I18N_NOOP2("Keyboard model description", "Dell USB Multimedia") },
{ "dell", I18N_NOOP2("Keyboard model description", "Dell") },
{ "dexxa", I18N_NOOP2("Keyboard model description", "Dexxa Wireless Desktop") },
{ "diamond", I18N_NOOP2("Keyboard model description", "Diamond 9801/9802") },
{ "dtk2000", I18N_NOOP2("Keyboard model description", "DTK2000") },
{ "emachines", I18N_NOOP2("Keyboard model description", "eMachines m6800 laptop") },
{ "ennyah_dkb1008", I18N_NOOP2("Keyboard model description", "Ennyah DKB-1008") },
{ "everex", I18N_NOOP2("Keyboard model description", "Everex STEPnote") },
{ "compalfl90", I18N_NOOP2("Keyboard model description", "FL90") },
{ "fscaa1667g", I18N_NOOP2("Keyboard model description", "Fujitsu-Siemens Amilo laptop") },
{ "pc101", I18N_NOOP2("Keyboard model description", "Generic 101-key PC") },
{ "pc102", I18N_NOOP2("Keyboard model description", "Generic 102-key PC") },
{ "pc104alt", I18N_NOOP2("Keyboard model description", "Generic 104-key PC with L-shaped Enter key") },
{ "pc104", I18N_NOOP2("Keyboard model description", "Generic 104-key PC") },
{ "pc105", I18N_NOOP2("Keyboard model description", "Generic 105-key PC") },
{ "pc86", I18N_NOOP2("Keyboard model description", "Generic 86-key PC") },
{ "geniuscomfy", I18N_NOOP2("Keyboard model description", "Genius Comfy KB-12e") },
{ "genius", I18N_NOOP2("Keyboard model description", "Genius Comfy KB-16M/Multimedia KWD-910") },
{ "geniuscomfy2", I18N_NOOP2("Keyboard model description", "Genius Comfy KB-21e-Scroll") },
{ "geniuskb19e", I18N_NOOP2("Keyboard model description", "Genius KB-19e NB") },
{ "geniuskkb2050hs", I18N_NOOP2("Keyboard model description", "Genius KKB-2050HS") },
{ "gyration", I18N_NOOP2("Keyboard model description", "Gyration") },
{ "macintosh_hhk", I18N_NOOP2("Keyboard model description", "Happy Hacking for Mac") },
{ "hhk", I18N_NOOP2("Keyboard model description", "Happy Hacking") },
{ "hpi6", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Internet") },
{ "hpmini110", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Mini 110 laptop") },
{ "hp250x", I18N_NOOP2("Keyboard model description", "Hewlett-Packard NEC SK-2500 Multimedia") },
{ "hpnx9020", I18N_NOOP2("Keyboard model description", "Hewlett-Packard nx9020") },
{ "hp500fa", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook 500 FA") },
{ "hp5xx", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook 500") },
{ "hp6000", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook 6000/6100") },
{ "hpxe3gc", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook XE3 GC") },
{ "hpxe3gf", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook XE3 GF") },
{ "hpxt1000", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Omnibook XT1000") },
{ "hpdv5", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Pavilion dv5") },
{ "hpzt11xx", I18N_NOOP2("Keyboard model description", "Hewlett-Packard Pavilion ZT1100") },
{ "honeywell_euroboard", I18N_NOOP2("Keyboard model description", "Honeywell Euroboard") },
{ "rapidaccess2", I18N_NOOP2("Keyboard model description", "IBM Rapid Access II") },
{ "rapidaccess", I18N_NOOP2("Keyboard model description", "IBM Rapid Access") },
{ "ibm_spacesaver", I18N_NOOP2("Keyboard model description", "IBM Space Saver") },
{ "thinkpad", I18N_NOOP2("Keyboard model description", "IBM ThinkPad 560Z/600/600E/A22E") },
{ "thinkpad60", I18N_NOOP2("Keyboard model description", "IBM ThinkPad R60/T60/R61/T61") },
{ "thinkpadz60", I18N_NOOP2("Keyboard model description", "IBM ThinkPad Z60m/Z60t/Z61m/Z61t") },
{ "flexpro", I18N_NOOP2("Keyboard model description", "Keytronic FlexPro") },
{ "kinesis", I18N_NOOP2("Keyboard model description", "Kinesis") },
{ "logiaccess", I18N_NOOP2("Keyboard model description", "Logitech Access") },
{ "logicda", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop (alt.)") },
{ "logiex110", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop EX110") },
{ "logicd_it", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop iTouch") },
{ "logiclx300", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop LX-300") },
{ "logicd_nav", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop Navigator") },
{ "logicd_opt", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop Optical") },
{ "logicdpa2", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop Pro (2nd alt.)") },
{ "logicd", I18N_NOOP2("Keyboard model description", "Logitech Cordless Desktop") },
{ "logicfn", I18N_NOOP2("Keyboard model description", "Logitech Cordless Freedom/Desktop Navigator") },
{ "logidinovoedge", I18N_NOOP2("Keyboard model description", "Logitech diNovo Edge") },
{ "logidinovo", I18N_NOOP2("Keyboard model description", "Logitech diNovo") },
{ "logitech_g15", I18N_NOOP2("Keyboard model description", "Logitech G15 extra keys via G15daemon") },
{ "logii350", I18N_NOOP2("Keyboard model description", "Logitech Internet 350") },
{ "logicink", I18N_NOOP2("Keyboard model description", "Logitech Internet Navigator") },
{ "logiik", I18N_NOOP2("Keyboard model description", "Logitech Internet") },
{ "logiitc", I18N_NOOP2("Keyboard model description", "Logitech iTouch Cordless Y-RB6") },
{ "logiinkseusb", I18N_NOOP2("Keyboard model description", "Logitech iTouch Internet Navigator SE USB") },
{ "logiinkse", I18N_NOOP2("Keyboard model description", "Logitech iTouch Internet Navigator SE") },
{ "itouch", I18N_NOOP2("Keyboard model description", "Logitech iTouch") },
{ "logiultraxc", I18N_NOOP2("Keyboard model description", "Logitech Ultra-X Cordless Media Desktop") },
{ "logiultrax", I18N_NOOP2("Keyboard model description", "Logitech Ultra-X") },
{ "logitech_base", I18N_NOOP2("Keyboard model description", "Logitech") },
{ "macbook79", I18N_NOOP2("Keyboard model description", "MacBook/MacBook Pro (intl.)") },
{ "macbook78", I18N_NOOP2("Keyboard model description", "MacBook/MacBook Pro") },
{ "macintosh_old", I18N_NOOP2("Keyboard model description", "Macintosh Old") },
{ "macintosh", I18N_NOOP2("Keyboard model description", "Macintosh") },
{ "mx1998", I18N_NOOP2("Keyboard model description", "Memorex MX1998") },
{ "mx2500", I18N_NOOP2("Keyboard model description", "Memorex MX2500 EZ-Access") },
{ "mx2750", I18N_NOOP2("Keyboard model description", "Memorex MX2750") },
{ "microsoftccurve2k", I18N_NOOP2("Keyboard model description", "Microsoft Comfort Curve 2000") },
{ "microsoftprose", I18N_NOOP2("Keyboard model description", "Microsoft Internet Pro (Swedish)") },
{ "microsoftinet", I18N_NOOP2("Keyboard model description", "Microsoft Internet") },
{ "microsoftelite", I18N_NOOP2("Keyboard model description", "Microsoft Natural Elite") },
{ "microsoft4000", I18N_NOOP2("Keyboard model description", "Microsoft Natural Ergonomic 4000") },
{ "microsoftprooem", I18N_NOOP2("Keyboard model description", "Microsoft Natural Pro OEM") },
{ "microsoftprousb", I18N_NOOP2("Keyboard model description", "Microsoft Natural Pro USB/Internet Pro") },
{ "microsoftpro", I18N_NOOP2("Keyboard model description", "Microsoft Natural Pro/Internet Pro") },
{ "microsoft7000", I18N_NOOP2("Keyboard model description", "Microsoft Natural Wireless Ergonomic 7000") },
{ "microsoft", I18N_NOOP2("Keyboard model description", "Microsoft Natural") },
{ "microsoftoffice", I18N_NOOP2("Keyboard model description", "Microsoft Office Keyboard") },
{ "microsoftsurface", I18N_NOOP2("Keyboard model description", "Microsoft Surface") },
{ "microsoftmult", I18N_NOOP2("Keyboard model description", "Microsoft Wireless Multimedia 1.0A") },
{ "sk1300", I18N_NOOP2("Keyboard model description", "NEC SK-1300") },
{ "sk2500", I18N_NOOP2("Keyboard model description", "NEC SK-2500") },
{ "sk6200", I18N_NOOP2("Keyboard model description", "NEC SK-6200") },
{ "sk7100", I18N_NOOP2("Keyboard model description", "NEC SK-7100") },
{ "omnikey101", I18N_NOOP2("Keyboard model description", "Northgate OmniKey 101") },
{ "olpc", I18N_NOOP2("Keyboard model description", "OLPC") },
{ "oretec", I18N_NOOP2("Keyboard model description", "Ortek Multimedia/Internet MCK-800") },
{ "pc98", I18N_NOOP2("Keyboard model description", "PC-98") },
{ "propeller", I18N_NOOP2("Keyboard model description", "Propeller Voyager KTEZ-1000") },
{ "qtronix", I18N_NOOP2("Keyboard model description", "QTronix Scorpius 98N+") },
{ "samsung4500", I18N_NOOP2("Keyboard model description", "Samsung SDM 4500P") },
{ "samsung4510", I18N_NOOP2("Keyboard model description", "Samsung SDM 4510P") },
{ "sanwaskbkg3", I18N_NOOP2("Keyboard model description", "Sanwa Supply SKB-KG3") },
{ "silvercrest", I18N_NOOP2("Keyboard model description", "Silvercrest Multimedia Wireless") },
{ "apex300", I18N_NOOP2("Keyboard model description", "SteelSeries Apex 300 (Apex RAW)") },
{ "sun_type6_jp", I18N_NOOP2("Keyboard model description", "Sun Type 6 (Japanese)") },
{ "sun_type6_jp_usb", I18N_NOOP2("Keyboard model description", "Sun Type 6 USB (Japanese)") },
{ "sun_type6_unix_usb", I18N_NOOP2("Keyboard model description", "Sun Type 6 USB (Unix)") },
{ "sun_type6_euro_usb", I18N_NOOP2("Keyboard model description", "Sun Type 6/7 USB (European)") },
{ "sun_type6_usb", I18N_NOOP2("Keyboard model description", "Sun Type 6/7 USB") },
{ "sun_type7_euro_usb", I18N_NOOP2("Keyboard model description", "Sun Type 7 USB (European)") },
{ "sun_type7_jp_usb", I18N_NOOP2("Keyboard model description", "Sun Type 7 USB (Japanese)/Japanese 106-key") },
{ "sun_type7_unix_usb", I18N_NOOP2("Keyboard model description", "Sun Type 7 USB (Unix)") },
{ "sun_type7_usb", I18N_NOOP2("Keyboard model description", "Sun Type 7 USB") },
{ "sp_inet", I18N_NOOP2("Keyboard model description", "Super Power Multimedia") },
{ "sven", I18N_NOOP2("Keyboard model description", "SVEN Ergonomic 2500") },
{ "sven303", I18N_NOOP2("Keyboard model description", "SVEN Slim 303") },
{ "symplon", I18N_NOOP2("Keyboard model description", "Symplon PaceBook tablet") },
{ "targa_v811", I18N_NOOP2("Keyboard model description", "Targa Visionary 811") },
{ "toshiba_s3000", I18N_NOOP2("Keyboard model description", "Toshiba Satellite S3000") },
{ "teck227", I18N_NOOP2("Keyboard model description", "Truly Ergonomic 227") },
{ "teck229", I18N_NOOP2("Keyboard model description", "Truly Ergonomic 229") },
{ "trustda", I18N_NOOP2("Keyboard model description", "Trust Direct Access") },
{ "trust_slimline", I18N_NOOP2("Keyboard model description", "Trust Slimline") },
{ "trust", I18N_NOOP2("Keyboard model description", "Trust Wireless Classic") },
{ "tm2020", I18N_NOOP2("Keyboard model description", "TypeMatrix EZ-Reach 2020") },
{ "tm2030PS2", I18N_NOOP2("Keyboard model description", "TypeMatrix EZ-Reach 2030 PS2") },
{ "tm2030USB-102", I18N_NOOP2("Keyboard model description", "TypeMatrix EZ-Reach 2030 USB (102/105:EU mode)") },
{ "tm2030USB-106", I18N_NOOP2("Keyboard model description", "TypeMatrix EZ-Reach 2030 USB (106:JP mode)") },
{ "tm2030USB", I18N_NOOP2("Keyboard model description", "TypeMatrix EZ-Reach 2030 USB") },
{ "unitekkb1925", I18N_NOOP2("Keyboard model description", "Unitek KB-1925") },
{ "vsonku306", I18N_NOOP2("Keyboard model description", "ViewSonic KU-306 Internet") },
{ "winbook", I18N_NOOP2("Keyboard model description", "Winbook Model XP5") },
{ "yahoo", I18N_NOOP2("Keyboard model description", "Yahoo! Internet") }
};
static const qint16 modelDescriptionTblSize = sizeof(modelDescriptionTbl) / sizeof(modelDescriptionData);
static const struct layoutDescriptionData {
const char* name;
const char* description;
} layoutDescriptionTbl[] = {
{ "custom", I18N_NOOP2("Keyboard layout description", "A user-defined custom Layout") },
{ "al", I18N_NOOP2("Keyboard layout description", "Albanian") },
{ "et", I18N_NOOP2("Keyboard layout description", "Amharic") },
{ "ma", I18N_NOOP2("Keyboard layout description", "Arabic (Morocco)") },
{ "sy", I18N_NOOP2("Keyboard layout description", "Arabic (Syria)") },
{ "ara", I18N_NOOP2("Keyboard layout description", "Arabic") },
{ "am", I18N_NOOP2("Keyboard layout description", "Armenian") },
{ "az", I18N_NOOP2("Keyboard layout description", "Azerbaijani") },
{ "ml", I18N_NOOP2("Keyboard layout description", "Bambara") },
{ "bd", I18N_NOOP2("Keyboard layout description", "Bangla") },
{ "by", I18N_NOOP2("Keyboard layout description", "Belarusian") },
{ "be", I18N_NOOP2("Keyboard layout description", "Belgian") },
{ "dz", I18N_NOOP2("Keyboard layout description", "Berber (Algeria, Latin)") },
{ "ba", I18N_NOOP2("Keyboard layout description", "Bosnian") },
{ "brai", I18N_NOOP2("Keyboard layout description", "Braille") },
{ "bg", I18N_NOOP2("Keyboard layout description", "Bulgarian") },
{ "mm", I18N_NOOP2("Keyboard layout description", "Burmese") },
{ "cn", I18N_NOOP2("Keyboard layout description", "Chinese") },
{ "hr", I18N_NOOP2("Keyboard layout description", "Croatian") },
{ "cz", I18N_NOOP2("Keyboard layout description", "Czech") },
{ "dk", I18N_NOOP2("Keyboard layout description", "Danish") },
{ "af", I18N_NOOP2("Keyboard layout description", "Dari") },
{ "mv", I18N_NOOP2("Keyboard layout description", "Dhivehi") },
{ "nl", I18N_NOOP2("Keyboard layout description", "Dutch") },
{ "bt", I18N_NOOP2("Keyboard layout description", "Dzongkha") },
{ "au", I18N_NOOP2("Keyboard layout description", "English (Australian)") },
{ "cm", I18N_NOOP2("Keyboard layout description", "English (Cameroon)") },
{ "gh", I18N_NOOP2("Keyboard layout description", "English (Ghana)") },
{ "ng", I18N_NOOP2("Keyboard layout description", "English (Nigeria)") },
{ "za", I18N_NOOP2("Keyboard layout description", "English (South Africa)") },
{ "gb", I18N_NOOP2("Keyboard layout description", "English (UK)") },
{ "us", I18N_NOOP2("Keyboard layout description", "English (US)") },
{ "epo", I18N_NOOP2("Keyboard layout description", "Esperanto") },
{ "ee", I18N_NOOP2("Keyboard layout description", "Estonian") },
{ "fo", I18N_NOOP2("Keyboard layout description", "Faroese") },
{ "ph", I18N_NOOP2("Keyboard layout description", "Filipino") },
{ "fi", I18N_NOOP2("Keyboard layout description", "Finnish") },
{ "ca", I18N_NOOP2("Keyboard layout description", "French (Canada)") },
{ "cd", I18N_NOOP2("Keyboard layout description", "French (Democratic Republic of the Congo)") },
{ "tg", I18N_NOOP2("Keyboard layout description", "French (Togo)") },
{ "fr", I18N_NOOP2("Keyboard layout description", "French") },
{ "ge", I18N_NOOP2("Keyboard layout description", "Georgian") },
{ "at", I18N_NOOP2("Keyboard layout description", "German (Austria)") },
{ "ch", I18N_NOOP2("Keyboard layout description", "German (Switzerland)") },
{ "de", I18N_NOOP2("Keyboard layout description", "German") },
{ "gr", I18N_NOOP2("Keyboard layout description", "Greek") },
{ "il", I18N_NOOP2("Keyboard layout description", "Hebrew") },
{ "hu", I18N_NOOP2("Keyboard layout description", "Hungarian") },
{ "is", I18N_NOOP2("Keyboard layout description", "Icelandic") },
{ "in", I18N_NOOP2("Keyboard layout description", "Indian") },
{ "jv", I18N_NOOP2("Keyboard layout description", "Indonesian (Javanese)") },
{ "id", I18N_NOOP2("Keyboard layout description", "Indonesian (Latin)") },
{ "iq", I18N_NOOP2("Keyboard layout description", "Iraqi") },
{ "ie", I18N_NOOP2("Keyboard layout description", "Irish") },
{ "it", I18N_NOOP2("Keyboard layout description", "Italian") },
{ "jp", I18N_NOOP2("Keyboard layout description", "Japanese") },
{ "kz", I18N_NOOP2("Keyboard layout description", "Kazakh") },
{ "kh", I18N_NOOP2("Keyboard layout description", "Khmer (Cambodia)") },
{ "kr", I18N_NOOP2("Keyboard layout description", "Korean") },
{ "kg", I18N_NOOP2("Keyboard layout description", "Kyrgyz") },
{ "la", I18N_NOOP2("Keyboard layout description", "Lao") },
{ "lv", I18N_NOOP2("Keyboard layout description", "Latvian") },
{ "lt", I18N_NOOP2("Keyboard layout description", "Lithuanian") },
{ "mk", I18N_NOOP2("Keyboard layout description", "Macedonian") },
{ "my", I18N_NOOP2("Keyboard layout description", "Malay (Jawi, Arabic Keyboard)") },
{ "mt", I18N_NOOP2("Keyboard layout description", "Maltese") },
{ "mao", I18N_NOOP2("Keyboard layout description", "Maori") },
{ "md", I18N_NOOP2("Keyboard layout description", "Moldavian") },
{ "mn", I18N_NOOP2("Keyboard layout description", "Mongolian") },
{ "me", I18N_NOOP2("Keyboard layout description", "Montenegrin") },
{ "gn", I18N_NOOP2("Keyboard layout description", "N'Ko (AZERTY)") },
{ "np", I18N_NOOP2("Keyboard layout description", "Nepali") },
{ "no", I18N_NOOP2("Keyboard layout description", "Norwegian") },
{ "ir", I18N_NOOP2("Keyboard layout description", "Persian") },
{ "pl", I18N_NOOP2("Keyboard layout description", "Polish") },
{ "br", I18N_NOOP2("Keyboard layout description", "Portuguese (Brazil)") },
{ "pt", I18N_NOOP2("Keyboard layout description", "Portuguese") },
{ "ro", I18N_NOOP2("Keyboard layout description", "Romanian") },
{ "ru", I18N_NOOP2("Keyboard layout description", "Russian") },
{ "rs", I18N_NOOP2("Keyboard layout description", "Serbian") },
{ "lk", I18N_NOOP2("Keyboard layout description", "Sinhala (phonetic)") },
{ "sk", I18N_NOOP2("Keyboard layout description", "Slovak") },
{ "si", I18N_NOOP2("Keyboard layout description", "Slovenian") },
{ "latam", I18N_NOOP2("Keyboard layout description", "Spanish (Latin American)") },
{ "es", I18N_NOOP2("Keyboard layout description", "Spanish") },
{ "ke", I18N_NOOP2("Keyboard layout description", "Swahili (Kenya)") },
{ "tz", I18N_NOOP2("Keyboard layout description", "Swahili (Tanzania)") },
{ "se", I18N_NOOP2("Keyboard layout description", "Swedish") },
{ "tw", I18N_NOOP2("Keyboard layout description", "Taiwanese") },
{ "tj", I18N_NOOP2("Keyboard layout description", "Tajik") },
{ "th", I18N_NOOP2("Keyboard layout description", "Thai") },
{ "bw", I18N_NOOP2("Keyboard layout description", "Tswana") },
{ "tr", I18N_NOOP2("Keyboard layout description", "Turkish") },
{ "tm", I18N_NOOP2("Keyboard layout description", "Turkmen") },
{ "ua", I18N_NOOP2("Keyboard layout description", "Ukrainian") },
{ "pk", I18N_NOOP2("Keyboard layout description", "Urdu (Pakistan)") },
{ "uz", I18N_NOOP2("Keyboard layout description", "Uzbek") },
{ "vn", I18N_NOOP2("Keyboard layout description", "Vietnamese") },
{ "sn", I18N_NOOP2("Keyboard layout description", "Wolof") }
};
static const qint16 layoutDescriptionTblSize = sizeof(layoutDescriptionTbl) / sizeof(layoutDescriptionData);
static const struct variantDescriptionData {
const char* name;
const char* name2;
const char* description;
} variantDescriptionTbl[] = {
{ "gh", "akan", I18N_NOOP2("Keyboard variant description", "Akan") },
{ "al", "plisi", I18N_NOOP2("Keyboard variant description", "Albanian (Plisi)") },
{ "al", "veqilharxhi", I18N_NOOP2("Keyboard variant description", "Albanian (Veqilharxhi)") },
{ "dz", "ar", I18N_NOOP2("Keyboard variant description", "Arabic (Algeria)") },
{ "ara", "azerty", I18N_NOOP2("Keyboard variant description", "Arabic (AZERTY)") },
{ "ara", "azerty_digits", I18N_NOOP2("Keyboard variant description", "Arabic (AZERTY, Eastern Arabic numerals)") },
{ "ara", "buckwalter", I18N_NOOP2("Keyboard variant description", "Arabic (Buckwalter)") },
{ "ara", "digits", I18N_NOOP2("Keyboard variant description", "Arabic (Eastern Arabic numerals)") },
{ "ara", "mac", I18N_NOOP2("Keyboard variant description", "Arabic (Macintosh)") },
{ "ara", "olpc", I18N_NOOP2("Keyboard variant description", "Arabic (OLPC)") },
{ "pk", "ara", I18N_NOOP2("Keyboard variant description", "Arabic (Pakistan)") },
{ "ara", "qwerty", I18N_NOOP2("Keyboard variant description", "Arabic (QWERTY)") },
{ "ara", "qwerty_digits", I18N_NOOP2("Keyboard variant description", "Arabic (QWERTY, Eastern Arabic numerals)") },
{ "am", "eastern-alt", I18N_NOOP2("Keyboard variant description", "Armenian (alt. eastern)") },
{ "am", "phonetic-alt", I18N_NOOP2("Keyboard variant description", "Armenian (alt. phonetic)") },
{ "am", "eastern", I18N_NOOP2("Keyboard variant description", "Armenian (eastern)") },
{ "am", "phonetic", I18N_NOOP2("Keyboard variant description", "Armenian (phonetic)") },
{ "am", "western", I18N_NOOP2("Keyboard variant description", "Armenian (western)") },
{ "es", "ast", I18N_NOOP2("Keyboard variant description", "Asturian (Spain, with bottom-dot H and L)") },
{ "gh", "avn", I18N_NOOP2("Keyboard variant description", "Avatime") },
{ "az", "cyrillic", I18N_NOOP2("Keyboard variant description", "Azerbaijani (Cyrillic)") },
{ "in", "ben", I18N_NOOP2("Keyboard variant description", "Bangla (India)") },
{ "in", "ben_inscript", I18N_NOOP2("Keyboard variant description", "Bangla (India, Baishakhi InScript)") },
{ "in", "ben_baishakhi", I18N_NOOP2("Keyboard variant description", "Bangla (India, Baishakhi)") },
{ "in", "ben_bornona", I18N_NOOP2("Keyboard variant description", "Bangla (India, Bornona)") },
{ "in", "ben_gitanjali", I18N_NOOP2("Keyboard variant description", "Bangla (India, Gitanjali)") },
{ "in", "ben_probhat", I18N_NOOP2("Keyboard variant description", "Bangla (India, Probhat)") },
{ "bd", "probhat", I18N_NOOP2("Keyboard variant description", "Bangla (Probhat)") },
{ "ru", "bak", I18N_NOOP2("Keyboard variant description", "Bashkirian") },
{ "by", "intl", I18N_NOOP2("Keyboard variant description", "Belarusian (intl.)") },
{ "by", "latin", I18N_NOOP2("Keyboard variant description", "Belarusian (Latin)") },
{ "by", "legacy", I18N_NOOP2("Keyboard variant description", "Belarusian (legacy)") },
{ "be", "oss", I18N_NOOP2("Keyboard variant description", "Belgian (alt.)") },
{ "be", "iso-alternate", I18N_NOOP2("Keyboard variant description", "Belgian (ISO, alt.)") },
{ "be", "oss_latin9", I18N_NOOP2("Keyboard variant description", "Belgian (Latin-9 only, alt.)") },
{ "be", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Belgian (no dead keys)") },
{ "be", "wang", I18N_NOOP2("Keyboard variant description", "Belgian (Wang 724 AZERTY)") },
{ "dz", "ber", I18N_NOOP2("Keyboard variant description", "Berber (Algeria, Tifinagh)") },
{ "ma", "tifinagh-alt", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh alt.)") },
{ "ma", "tifinagh-extended-phonetic", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh extended phonetic)") },
{ "ma", "tifinagh-extended", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh extended)") },
{ "ma", "tifinagh-phonetic", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh phonetic)") },
{ "ma", "tifinagh-alt-phonetic", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh phonetic, alt.)") },
{ "ma", "tifinagh", I18N_NOOP2("Keyboard variant description", "Berber (Morocco, Tifinagh)") },
{ "ba", "us", I18N_NOOP2("Keyboard variant description", "Bosnian (US)") },
{ "ba", "unicodeus", I18N_NOOP2("Keyboard variant description", "Bosnian (US, with Bosnian digraphs)") },
{ "ba", "unicode", I18N_NOOP2("Keyboard variant description", "Bosnian (with Bosnian digraphs)") },
{ "ba", "alternatequotes", I18N_NOOP2("Keyboard variant description", "Bosnian (with guillemets)") },
{ "brai", "left_hand_invert", I18N_NOOP2("Keyboard variant description", "Braille (left-handed inverted thumb)") },
{ "brai", "left_hand", I18N_NOOP2("Keyboard variant description", "Braille (left-handed)") },
{ "brai", "right_hand_invert", I18N_NOOP2("Keyboard variant description", "Braille (right-handed inverted thumb)") },
{ "brai", "right_hand", I18N_NOOP2("Keyboard variant description", "Braille (right-handed)") },
{ "bg", "bekl", I18N_NOOP2("Keyboard variant description", "Bulgarian (enhanced)") },
{ "bg", "bas_phonetic", I18N_NOOP2("Keyboard variant description", "Bulgarian (new phonetic)") },
{ "bg", "phonetic", I18N_NOOP2("Keyboard variant description", "Bulgarian (traditional phonetic)") },
{ "mm", "zawgyi", I18N_NOOP2("Keyboard variant description", "Burmese Zawgyi") },
{ "cm", "azerty", I18N_NOOP2("Keyboard variant description", "Cameroon (AZERTY, intl.)") },
{ "cm", "dvorak", I18N_NOOP2("Keyboard variant description", "Cameroon (Dvorak, intl.)") },
{ "cm", "qwerty", I18N_NOOP2("Keyboard variant description", "Cameroon Multilingual (QWERTY, intl.)") },
{ "ca", "multix", I18N_NOOP2("Keyboard variant description", "Canadian (intl.)") },
{ "ca", "multi", I18N_NOOP2("Keyboard variant description", "Canadian (intl., 1st part)") },
{ "ca", "multi-2gr", I18N_NOOP2("Keyboard variant description", "Canadian (intl., 2nd part)") },
{ "es", "cat", I18N_NOOP2("Keyboard variant description", "Catalan (Spain, with middle-dot L)") },
{ "us", "chr", I18N_NOOP2("Keyboard variant description", "Cherokee") },
{ "ru", "cv_latin", I18N_NOOP2("Keyboard variant description", "Chuvash (Latin)") },
{ "ru", "cv", I18N_NOOP2("Keyboard variant description", "Chuvash") },
{ "ie", "CloGaelach", I18N_NOOP2("Keyboard variant description", "CloGaelach") },
{ "ua", "crh_alt", I18N_NOOP2("Keyboard variant description", "Crimean Tatar (Turkish Alt-Q)") },
{ "ua", "crh_f", I18N_NOOP2("Keyboard variant description", "Crimean Tatar (Turkish F)") },
{ "ua", "crh", I18N_NOOP2("Keyboard variant description", "Crimean Tatar (Turkish Q)") },
{ "hr", "us", I18N_NOOP2("Keyboard variant description", "Croatian (US)") },
{ "hr", "unicodeus", I18N_NOOP2("Keyboard variant description", "Croatian (US, with Croatian digraphs)") },
{ "hr", "unicode", I18N_NOOP2("Keyboard variant description", "Croatian (with Croatian digraphs)") },
{ "hr", "alternatequotes", I18N_NOOP2("Keyboard variant description", "Croatian (with guillemets)") },
{ "cz", "qwerty", I18N_NOOP2("Keyboard variant description", "Czech (QWERTY)") },
{ "cz", "qwerty_bksl", I18N_NOOP2("Keyboard variant description", "Czech (QWERTY, extended backslash)") },
{ "cz", "qwerty-mac", I18N_NOOP2("Keyboard variant description", "Czech (QWERTY, Macintosh)") },
{ "cz", "ucw", I18N_NOOP2("Keyboard variant description", "Czech (UCW, only accented letters)") },
{ "cz", "dvorak-ucw", I18N_NOOP2("Keyboard variant description", "Czech (US, Dvorak, UCW support)") },
{ "cz", "bksl", I18N_NOOP2("Keyboard variant description", "Czech (with <\\|> key)") },
{ "dk", "dvorak", I18N_NOOP2("Keyboard variant description", "Danish (Dvorak)") },
{ "dk", "mac", I18N_NOOP2("Keyboard variant description", "Danish (Macintosh)") },
{ "dk", "mac_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Danish (Macintosh, no dead keys)") },
{ "dk", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Danish (no dead keys)") },
{ "dk", "winkeys", I18N_NOOP2("Keyboard variant description", "Danish (Windows)") },
{ "af", "fa-olpc", I18N_NOOP2("Keyboard variant description", "Dari (Afghanistan, OLPC)") },
{ "nl", "mac", I18N_NOOP2("Keyboard variant description", "Dutch (Macintosh)") },
{ "nl", "std", I18N_NOOP2("Keyboard variant description", "Dutch (standard)") },
{ "nl", "us", I18N_NOOP2("Keyboard variant description", "Dutch (US)") },
{ "ca", "eng", I18N_NOOP2("Keyboard variant description", "English (Canada)") },
{ "us", "dvorak-classic", I18N_NOOP2("Keyboard variant description", "English (classic Dvorak)") },
{ "us", "colemak", I18N_NOOP2("Keyboard variant description", "English (Colemak)") },
{ "us", "colemak_dh_iso", I18N_NOOP2("Keyboard variant description", "English (Colemak-DH ISO)") },
{ "us", "colemak_dh", I18N_NOOP2("Keyboard variant description", "English (Colemak-DH)") },
{ "us", "dvorak", I18N_NOOP2("Keyboard variant description", "English (Dvorak)") },
{ "us", "dvorak-alt-intl", I18N_NOOP2("Keyboard variant description", "English (Dvorak, alt. intl.)") },
{ "us", "dvorak-intl", I18N_NOOP2("Keyboard variant description", "English (Dvorak, intl., with dead keys)") },
{ "us", "dvorak-l", I18N_NOOP2("Keyboard variant description", "English (Dvorak, left-handed)") },
{ "us", "dvorak-mac", I18N_NOOP2("Keyboard variant description", "English (Dvorak, Macintosh)") },
{ "us", "dvorak-r", I18N_NOOP2("Keyboard variant description", "English (Dvorak, right-handed)") },
{ "gh", "gillbt", I18N_NOOP2("Keyboard variant description", "English (Ghana, GILLBT)") },
{ "gh", "generic", I18N_NOOP2("Keyboard variant description", "English (Ghana, multilingual)") },
{ "in", "eng", I18N_NOOP2("Keyboard variant description", "English (India, with rupee)") },
{ "us", "altgr-intl", I18N_NOOP2("Keyboard variant description", "English (intl., with AltGr dead keys)") },
{ "us", "mac", I18N_NOOP2("Keyboard variant description", "English (Macintosh)") },
{ "ml", "us-intl", I18N_NOOP2("Keyboard variant description", "English (Mali, US, intl.)") },
{ "ml", "us-mac", I18N_NOOP2("Keyboard variant description", "English (Mali, US, Macintosh)") },
{ "us", "norman", I18N_NOOP2("Keyboard variant description", "English (Norman)") },
{ "us", "dvp", I18N_NOOP2("Keyboard variant description", "English (programmer Dvorak)") },
{ "us", "olpc2", I18N_NOOP2("Keyboard variant description", "English (the divide/multiply toggle the layout)") },
{ "gb", "colemak", I18N_NOOP2("Keyboard variant description", "English (UK, Colemak)") },
{ "gb", "colemak_dh", I18N_NOOP2("Keyboard variant description", "English (UK, Colemak-DH)") },
{ "gb", "dvorak", I18N_NOOP2("Keyboard variant description", "English (UK, Dvorak)") },
{ "gb", "dvorakukp", I18N_NOOP2("Keyboard variant description", "English (UK, Dvorak, with UK punctuation)") },
{ "gb", "extd", I18N_NOOP2("Keyboard variant description", "English (UK, extended, Windows)") },
{ "gb", "intl", I18N_NOOP2("Keyboard variant description", "English (UK, intl., with dead keys)") },
{ "gb", "mac", I18N_NOOP2("Keyboard variant description", "English (UK, Macintosh)") },
{ "gb", "mac_intl", I18N_NOOP2("Keyboard variant description", "English (UK, Macintosh, intl.)") },
{ "us", "alt-intl", I18N_NOOP2("Keyboard variant description", "English (US, alt. intl.)") },
{ "us", "euro", I18N_NOOP2("Keyboard variant description", "English (US, euro on 5)") },
{ "us", "intl", I18N_NOOP2("Keyboard variant description", "English (US, intl., with dead keys)") },
{ "us", "symbolic", I18N_NOOP2("Keyboard variant description", "English (US, Symbolic)") },
{ "us", "workman", I18N_NOOP2("Keyboard variant description", "English (Workman)") },
{ "us", "workman-intl", I18N_NOOP2("Keyboard variant description", "English (Workman, intl., with dead keys)") },
{ "br", "nativo-epo", I18N_NOOP2("Keyboard variant description", "Esperanto (Brazil, Nativo)") },
{ "epo", "legacy", I18N_NOOP2("Keyboard variant description", "Esperanto (legacy)") },
{ "pt", "nativo-epo", I18N_NOOP2("Keyboard variant description", "Esperanto (Portugal, Nativo)") },
{ "ee", "dvorak", I18N_NOOP2("Keyboard variant description", "Estonian (Dvorak)") },
{ "ee", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Estonian (no dead keys)") },
{ "ee", "us", I18N_NOOP2("Keyboard variant description", "Estonian (US)") },
{ "gh", "ewe", I18N_NOOP2("Keyboard variant description", "Ewe") },
{ "fo", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Faroese (no dead keys)") },
{ "ph", "capewell-dvorak-bay", I18N_NOOP2("Keyboard variant description", "Filipino (Capewell-Dvorak, Baybayin)") },
{ "ph", "capewell-dvorak", I18N_NOOP2("Keyboard variant description", "Filipino (Capewell-Dvorak, Latin)") },
{ "ph", "capewell-qwerf2k6-bay", I18N_NOOP2("Keyboard variant description", "Filipino (Capewell-QWERF 2006, Baybayin)") },
{ "ph", "capewell-qwerf2k6", I18N_NOOP2("Keyboard variant description", "Filipino (Capewell-QWERF 2006, Latin)") },
{ "ph", "colemak-bay", I18N_NOOP2("Keyboard variant description", "Filipino (Colemak, Baybayin)") },
{ "ph", "colemak", I18N_NOOP2("Keyboard variant description", "Filipino (Colemak, Latin)") },
{ "ph", "dvorak-bay", I18N_NOOP2("Keyboard variant description", "Filipino (Dvorak, Baybayin)") },
{ "ph", "dvorak", I18N_NOOP2("Keyboard variant description", "Filipino (Dvorak, Latin)") },
{ "ph", "qwerty-bay", I18N_NOOP2("Keyboard variant description", "Filipino (QWERTY, Baybayin)") },
{ "fi", "classic", I18N_NOOP2("Keyboard variant description", "Finnish (classic)") },
{ "fi", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Finnish (classic, no dead keys)") },
{ "fi", "mac", I18N_NOOP2("Keyboard variant description", "Finnish (Macintosh)") },
{ "fi", "winkeys", I18N_NOOP2("Keyboard variant description", "Finnish (Windows)") },
{ "fr", "oss", I18N_NOOP2("Keyboard variant description", "French (alt.)") },
{ "fr", "oss_latin9", I18N_NOOP2("Keyboard variant description", "French (alt., Latin-9 only)") },
{ "fr", "oss_nodeadkeys", I18N_NOOP2("Keyboard variant description", "French (alt., no dead keys)") },
{ "fr", "azerty", I18N_NOOP2("Keyboard variant description", "French (AZERTY)") },
{ "fr", "afnor", I18N_NOOP2("Keyboard variant description", "French (AZERTY, AFNOR)") },
{ "fr", "bepo", I18N_NOOP2("Keyboard variant description", "French (BEPO)") },
{ "fr", "bepo_afnor", I18N_NOOP2("Keyboard variant description", "French (BEPO, AFNOR)") },
{ "fr", "bepo_latin9", I18N_NOOP2("Keyboard variant description", "French (BEPO, Latin-9 only)") },
{ "fr", "bre", I18N_NOOP2("Keyboard variant description", "French (Breton)") },
{ "cm", "french", I18N_NOOP2("Keyboard variant description", "French (Cameroon)") },
{ "ca", "fr-dvorak", I18N_NOOP2("Keyboard variant description", "French (Canada, Dvorak)") },
{ "ca", "fr-legacy", I18N_NOOP2("Keyboard variant description", "French (Canada, legacy)") },
{ "fr", "dvorak", I18N_NOOP2("Keyboard variant description", "French (Dvorak)") },
{ "fr", "latin9", I18N_NOOP2("Keyboard variant description", "French (legacy, alt.)") },
{ "fr", "latin9_nodeadkeys", I18N_NOOP2("Keyboard variant description", "French (legacy, alt., no dead keys)") },
{ "fr", "mac", I18N_NOOP2("Keyboard variant description", "French (Macintosh)") },
{ "ml", "fr-oss", I18N_NOOP2("Keyboard variant description", "French (Mali, alt.)") },
{ "ma", "french", I18N_NOOP2("Keyboard variant description", "French (Morocco)") },
{ "fr", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "French (no dead keys)") },
{ "ch", "fr", I18N_NOOP2("Keyboard variant description", "French (Switzerland)") },
{ "ch", "fr_mac", I18N_NOOP2("Keyboard variant description", "French (Switzerland, Macintosh)") },
{ "ch", "fr_nodeadkeys", I18N_NOOP2("Keyboard variant description", "French (Switzerland, no dead keys)") },
{ "fr", "us", I18N_NOOP2("Keyboard variant description", "French (US)") },
{ "it", "fur", I18N_NOOP2("Keyboard variant description", "Friulian (Italy)") },
{ "gh", "fula", I18N_NOOP2("Keyboard variant description", "Fula") },
{ "gh", "ga", I18N_NOOP2("Keyboard variant description", "Ga") },
{ "ge", "ergonomic", I18N_NOOP2("Keyboard variant description", "Georgian (ergonomic)") },
{ "fr", "geo", I18N_NOOP2("Keyboard variant description", "Georgian (France, AZERTY Tskapo)") },
{ "it", "geo", I18N_NOOP2("Keyboard variant description", "Georgian (Italy)") },
{ "ge", "mess", I18N_NOOP2("Keyboard variant description", "Georgian (MESS)") },
{ "at", "mac", I18N_NOOP2("Keyboard variant description", "German (Austria, Macintosh)") },
{ "at", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "German (Austria, no dead keys)") },
{ "de", "deadacute", I18N_NOOP2("Keyboard variant description", "German (dead acute)") },
{ "de", "deadgraveacute", I18N_NOOP2("Keyboard variant description", "German (dead grave acute)") },
{ "de", "deadtilde", I18N_NOOP2("Keyboard variant description", "German (dead tilde)") },
{ "de", "dvorak", I18N_NOOP2("Keyboard variant description", "German (Dvorak)") },
{ "de", "e1", I18N_NOOP2("Keyboard variant description", "German (E1)") },
{ "de", "e2", I18N_NOOP2("Keyboard variant description", "German (E2)") },
{ "de", "mac", I18N_NOOP2("Keyboard variant description", "German (Macintosh)") },
{ "de", "mac_nodeadkeys", I18N_NOOP2("Keyboard variant description", "German (Macintosh, no dead keys)") },
{ "de", "neo", I18N_NOOP2("Keyboard variant description", "German (Neo 2)") },
{ "de", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "German (no dead keys)") },
{ "de", "qwerty", I18N_NOOP2("Keyboard variant description", "German (QWERTY)") },
{ "ch", "legacy", I18N_NOOP2("Keyboard variant description", "German (Switzerland, legacy)") },
{ "ch", "de_mac", I18N_NOOP2("Keyboard variant description", "German (Switzerland, Macintosh)") },
{ "ch", "de_nodeadkeys", I18N_NOOP2("Keyboard variant description", "German (Switzerland, no dead keys)") },
{ "de", "T3", I18N_NOOP2("Keyboard variant description", "German (T3)") },
{ "de", "us", I18N_NOOP2("Keyboard variant description", "German (US)") },
{ "gr", "extended", I18N_NOOP2("Keyboard variant description", "Greek (extended)") },
{ "gr", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Greek (no dead keys)") },
{ "gr", "polytonic", I18N_NOOP2("Keyboard variant description", "Greek (polytonic)") },
{ "gr", "simple", I18N_NOOP2("Keyboard variant description", "Greek (simple)") },
{ "in", "guj", I18N_NOOP2("Keyboard variant description", "Gujarati") },
{ "cn", "altgr-pinyin", I18N_NOOP2("Keyboard variant description", "Hanyu Pinyin Letters (with AltGr dead keys)") },
{ "gh", "hausa", I18N_NOOP2("Keyboard variant description", "Hausa (Ghana)") },
{ "ng", "hausa", I18N_NOOP2("Keyboard variant description", "Hausa (Nigeria)") },
{ "us", "haw", I18N_NOOP2("Keyboard variant description", "Hawaiian") },
{ "il", "biblical", I18N_NOOP2("Keyboard variant description", "Hebrew (Biblical, Tiro)") },
{ "il", "lyx", I18N_NOOP2("Keyboard variant description", "Hebrew (lyx)") },
{ "il", "phonetic", I18N_NOOP2("Keyboard variant description", "Hebrew (phonetic)") },
{ "in", "bolnagri", I18N_NOOP2("Keyboard variant description", "Hindi (Bolnagri)") },
{ "in", "hin-kagapa", I18N_NOOP2("Keyboard variant description", "Hindi (KaGaPa, phonetic)") },
{ "in", "hin-wx", I18N_NOOP2("Keyboard variant description", "Hindi (Wx)") },
{ "hu", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Hungarian (no dead keys)") },
{ "hu", "qwerty", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY)") },
{ "hu", "101_qwerty_comma_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 101-key, comma, dead keys)") },
{ "hu", "101_qwerty_comma_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 101-key, comma, no dead keys)") },
{ "hu", "101_qwerty_dot_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 101-key, dot, dead keys)") },
{ "hu", "101_qwerty_dot_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 101-key, dot, no dead keys)") },
{ "hu", "102_qwerty_comma_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 102-key, comma, dead keys)") },
{ "hu", "102_qwerty_comma_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 102-key, comma, no dead keys)") },
{ "hu", "102_qwerty_dot_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 102-key, dot, dead keys)") },
{ "hu", "102_qwerty_dot_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTY, 102-key, dot, no dead keys)") },
{ "hu", "101_qwertz_comma_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 101-key, comma, dead keys)") },
{ "hu", "101_qwertz_comma_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 101-key, comma, no dead keys)") },
{ "hu", "101_qwertz_dot_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 101-key, dot, dead keys)") },
{ "hu", "101_qwertz_dot_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 101-key, dot, no dead keys)") },
{ "hu", "102_qwertz_comma_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 102-key, comma, dead keys)") },
{ "hu", "102_qwertz_comma_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 102-key, comma, no dead keys)") },
{ "hu", "102_qwertz_dot_dead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 102-key, dot, dead keys)") },
{ "hu", "102_qwertz_dot_nodead", I18N_NOOP2("Keyboard variant description", "Hungarian (QWERTZ, 102-key, dot, no dead keys)") },
{ "hu", "standard", I18N_NOOP2("Keyboard variant description", "Hungarian (standard)") },
{ "is", "dvorak", I18N_NOOP2("Keyboard variant description", "Icelandic (Dvorak)") },
{ "is", "mac", I18N_NOOP2("Keyboard variant description", "Icelandic (Macintosh)") },
{ "is", "mac_legacy", I18N_NOOP2("Keyboard variant description", "Icelandic (Macintosh, legacy)") },
{ "ng", "igbo", I18N_NOOP2("Keyboard variant description", "Igbo") },
{ "in", "iipa", I18N_NOOP2("Keyboard variant description", "Indic IPA") },
{ "id", "phoneticx", I18N_NOOP2("Keyboard variant description", "Indonesian (Arab Pegon, extended phonetic)") },
{ "id", "phonetic", I18N_NOOP2("Keyboard variant description", "Indonesian (Arab Pegon, phonetic)") },
{ "ca", "ike", I18N_NOOP2("Keyboard variant description", "Inuktitut") },
{ "ie", "UnicodeExpert", I18N_NOOP2("Keyboard variant description", "Irish (UnicodeExpert)") },
{ "it", "ibm", I18N_NOOP2("Keyboard variant description", "Italian (IBM 142)") },
{ "it", "intl", I18N_NOOP2("Keyboard variant description", "Italian (intl., with dead keys)") },
{ "it", "mac", I18N_NOOP2("Keyboard variant description", "Italian (Macintosh)") },
{ "it", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Italian (no dead keys)") },
{ "it", "us", I18N_NOOP2("Keyboard variant description", "Italian (US)") },
{ "it", "winkeys", I18N_NOOP2("Keyboard variant description", "Italian (Windows)") },
{ "jp", "dvorak", I18N_NOOP2("Keyboard variant description", "Japanese (Dvorak)") },
{ "jp", "kana86", I18N_NOOP2("Keyboard variant description", "Japanese (Kana 86)") },
{ "jp", "kana", I18N_NOOP2("Keyboard variant description", "Japanese (Kana)") },
{ "jp", "mac", I18N_NOOP2("Keyboard variant description", "Japanese (Macintosh)") },
{ "jp", "OADG109A", I18N_NOOP2("Keyboard variant description", "Japanese (OADG 109A)") },
{ "dz", "azerty-deadkeys", I18N_NOOP2("Keyboard variant description", "Kabyle (AZERTY, with dead keys)") },
{ "dz", "qwerty-gb-deadkeys", I18N_NOOP2("Keyboard variant description", "Kabyle (QWERTY, UK, with dead keys)") },
{ "dz", "qwerty-us-deadkeys", I18N_NOOP2("Keyboard variant description", "Kabyle (QWERTY, US, with dead keys)") },
{ "ru", "xal", I18N_NOOP2("Keyboard variant description", "Kalmyk") },
{ "in", "kan-kagapa", I18N_NOOP2("Keyboard variant description", "Kannada (KaGaPa, phonetic)") },
{ "in", "kan", I18N_NOOP2("Keyboard variant description", "Kannada") },
{ "pl", "csb", I18N_NOOP2("Keyboard variant description", "Kashubian") },
{ "kz", "ext", I18N_NOOP2("Keyboard variant description", "Kazakh (extended)") },
{ "kz", "latin", I18N_NOOP2("Keyboard variant description", "Kazakh (Latin)") },
{ "kz", "kazrus", I18N_NOOP2("Keyboard variant description", "Kazakh (with Russian)") },
{ "ke", "kik", I18N_NOOP2("Keyboard variant description", "Kikuyu") },
{ "ru", "kom", I18N_NOOP2("Keyboard variant description", "Komi") },
{ "kr", "kr104", I18N_NOOP2("Keyboard variant description", "Korean (101/104-key compatible)") },
{ "ir", "ku_ara", I18N_NOOP2("Keyboard variant description", "Kurdish (Iran, Arabic-Latin)") },
{ "ir", "ku_f", I18N_NOOP2("Keyboard variant description", "Kurdish (Iran, F)") },
{ "ir", "ku_alt", I18N_NOOP2("Keyboard variant description", "Kurdish (Iran, Latin Alt-Q)") },
{ "ir", "ku", I18N_NOOP2("Keyboard variant description", "Kurdish (Iran, Latin Q)") },
{ "iq", "ku_ara", I18N_NOOP2("Keyboard variant description", "Kurdish (Iraq, Arabic-Latin)") },
{ "iq", "ku_f", I18N_NOOP2("Keyboard variant description", "Kurdish (Iraq, F)") },
{ "iq", "ku_alt", I18N_NOOP2("Keyboard variant description", "Kurdish (Iraq, Latin Alt-Q)") },
{ "iq", "ku", I18N_NOOP2("Keyboard variant description", "Kurdish (Iraq, Latin Q)") },
{ "sy", "ku_f", I18N_NOOP2("Keyboard variant description", "Kurdish (Syria, F)") },
{ "sy", "ku_alt", I18N_NOOP2("Keyboard variant description", "Kurdish (Syria, Latin Alt-Q)") },
{ "sy", "ku", I18N_NOOP2("Keyboard variant description", "Kurdish (Syria, Latin Q)") },
{ "tr", "ku_f", I18N_NOOP2("Keyboard variant description", "Kurdish (Turkey, F)") },
{ "tr", "ku_alt", I18N_NOOP2("Keyboard variant description", "Kurdish (Turkey, Latin Alt-Q)") },
{ "tr", "ku", I18N_NOOP2("Keyboard variant description", "Kurdish (Turkey, Latin Q)") },
{ "kg", "phonetic", I18N_NOOP2("Keyboard variant description", "Kyrgyz (phonetic)") },
{ "la", "stea", I18N_NOOP2("Keyboard variant description", "Lao (STEA)") },
{ "lv", "adapted", I18N_NOOP2("Keyboard variant description", "Latvian (adapted)") },
{ "lv", "apostrophe", I18N_NOOP2("Keyboard variant description", "Latvian (apostrophe)") },
{ "lv", "ergonomic", I18N_NOOP2("Keyboard variant description", "Latvian (ergonomic, ŪGJRMV)") },
{ "lv", "fkey", I18N_NOOP2("Keyboard variant description", "Latvian (F)") },
{ "lv", "modern", I18N_NOOP2("Keyboard variant description", "Latvian (modern)") },
{ "lv", "tilde", I18N_NOOP2("Keyboard variant description", "Latvian (tilde)") },
{ "lt", "ibm", I18N_NOOP2("Keyboard variant description", "Lithuanian (IBM LST 1205-92)") },
{ "lt", "lekp", I18N_NOOP2("Keyboard variant description", "Lithuanian (LEKP)") },
{ "lt", "lekpa", I18N_NOOP2("Keyboard variant description", "Lithuanian (LEKPa)") },
{ "lt", "ratise", I18N_NOOP2("Keyboard variant description", "Lithuanian (Ratise)") },
{ "lt", "std", I18N_NOOP2("Keyboard variant description", "Lithuanian (standard)") },
{ "lt", "us", I18N_NOOP2("Keyboard variant description", "Lithuanian (US)") },
{ "de", "dsb_qwertz", I18N_NOOP2("Keyboard variant description", "Lower Sorbian (QWERTZ)") },
{ "de", "dsb", I18N_NOOP2("Keyboard variant description", "Lower Sorbian") },
{ "mk", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Macedonian (no dead keys)") },
{ "my", "phonetic", I18N_NOOP2("Keyboard variant description", "Malay (Jawi, phonetic)") },
{ "in", "mal_enhanced", I18N_NOOP2("Keyboard variant description", "Malayalam (enhanced InScript, with rupee)") },
{ "in", "mal_lalitha", I18N_NOOP2("Keyboard variant description", "Malayalam (Lalitha)") },
{ "in", "mal", I18N_NOOP2("Keyboard variant description", "Malayalam") },
{ "mt", "alt-gb", I18N_NOOP2("Keyboard variant description", "Maltese (UK, with AltGr overrides)") },
{ "mt", "us", I18N_NOOP2("Keyboard variant description", "Maltese (US)") },
{ "mt", "alt-us", I18N_NOOP2("Keyboard variant description", "Maltese (US, with AltGr overrides)") },
{ "in", "eeyek", I18N_NOOP2("Keyboard variant description", "Manipuri (Eeyek)") },
{ "in", "marathi", I18N_NOOP2("Keyboard variant description", "Marathi (enhanced InScript)") },
{ "in", "mar-kagapa", I18N_NOOP2("Keyboard variant description", "Marathi (KaGaPa, phonetic)") },
{ "ru", "chm", I18N_NOOP2("Keyboard variant description", "Mari") },
{ "cm", "mmuock", I18N_NOOP2("Keyboard variant description", "Mmuock") },
{ "md", "gag", I18N_NOOP2("Keyboard variant description", "Moldavian (Gagauz)") },
{ "mm", "mnw-a1", I18N_NOOP2("Keyboard variant description", "Mon (A1)") },
{ "mm", "mnw", I18N_NOOP2("Keyboard variant description", "Mon") },
{ "cn", "mon_trad", I18N_NOOP2("Keyboard variant description", "Mongolian (Bichig)") },
{ "cn", "mon_trad_galik", I18N_NOOP2("Keyboard variant description", "Mongolian (Galik)") },
{ "cn", "mon_manchu_galik", I18N_NOOP2("Keyboard variant description", "Mongolian (Manchu Galik)") },
{ "cn", "mon_trad_manchu", I18N_NOOP2("Keyboard variant description", "Mongolian (Manchu)") },
{ "cn", "mon_todo_galik", I18N_NOOP2("Keyboard variant description", "Mongolian (Todo Galik)") },
{ "cn", "mon_trad_todo", I18N_NOOP2("Keyboard variant description", "Mongolian (Todo)") },
{ "cn", "mon_trad_xibe", I18N_NOOP2("Keyboard variant description", "Mongolian (Xibe)") },
{ "me", "cyrillic", I18N_NOOP2("Keyboard variant description", "Montenegrin (Cyrillic)") },
{ "me", "cyrillicalternatequotes", I18N_NOOP2("Keyboard variant description", "Montenegrin (Cyrillic, with guillemets)") },
{ "me", "cyrillicyz", I18N_NOOP2("Keyboard variant description", "Montenegrin (Cyrillic, ZE and ZHE swapped)") },
{ "me", "latinyz", I18N_NOOP2("Keyboard variant description", "Montenegrin (Latin, QWERTY)") },
{ "me", "latinunicode", I18N_NOOP2("Keyboard variant description", "Montenegrin (Latin, Unicode)") },
{ "me", "latinunicodeyz", I18N_NOOP2("Keyboard variant description", "Montenegrin (Latin, Unicode, QWERTY)") },
{ "me", "latinalternatequotes", I18N_NOOP2("Keyboard variant description", "Montenegrin (Latin, with guillemets)") },
{ "fi", "smi", I18N_NOOP2("Keyboard variant description", "Northern Saami (Finland)") },
{ "no", "smi", I18N_NOOP2("Keyboard variant description", "Northern Saami (Norway)") },
{ "no", "smi_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Northern Saami (Norway, no dead keys)") },
{ "se", "smi", I18N_NOOP2("Keyboard variant description", "Northern Saami (Sweden)") },
{ "no", "colemak", I18N_NOOP2("Keyboard variant description", "Norwegian (Colemak)") },
{ "no", "dvorak", I18N_NOOP2("Keyboard variant description", "Norwegian (Dvorak)") },
{ "no", "mac", I18N_NOOP2("Keyboard variant description", "Norwegian (Macintosh)") },
{ "no", "mac_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Norwegian (Macintosh, no dead keys)") },
{ "no", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Norwegian (no dead keys)") },
{ "no", "winkeys", I18N_NOOP2("Keyboard variant description", "Norwegian (Windows)") },
{ "fr", "oci", I18N_NOOP2("Keyboard variant description", "Occitan") },
{ "ie", "ogam_is434", I18N_NOOP2("Keyboard variant description", "Ogham (IS434)") },
{ "ie", "ogam", I18N_NOOP2("Keyboard variant description", "Ogham") },
{ "in", "olck", I18N_NOOP2("Keyboard variant description", "Ol Chiki") },
{ "tr", "otkf", I18N_NOOP2("Keyboard variant description", "Old Turkic (F)") },
{ "tr", "otk", I18N_NOOP2("Keyboard variant description", "Old Turkic") },
{ "in", "ori-bolnagri", I18N_NOOP2("Keyboard variant description", "Oriya (Bolnagri)") },
{ "in", "ori-wx", I18N_NOOP2("Keyboard variant description", "Oriya (Wx)") },
{ "in", "ori", I18N_NOOP2("Keyboard variant description", "Oriya") },
{ "ge", "os", I18N_NOOP2("Keyboard variant description", "Ossetian (Georgia)") },
{ "ru", "os_legacy", I18N_NOOP2("Keyboard variant description", "Ossetian (legacy)") },
{ "ru", "os_winkeys", I18N_NOOP2("Keyboard variant description", "Ossetian (Windows)") },
{ "tr", "otf", I18N_NOOP2("Keyboard variant description", "Ottoman (F)") },
{ "tr", "ot", I18N_NOOP2("Keyboard variant description", "Ottoman (Q)") },
{ "rs", "rue", I18N_NOOP2("Keyboard variant description", "Pannonian Rusyn") },
{ "af", "ps-olpc", I18N_NOOP2("Keyboard variant description", "Pashto (Afghanistan, OLPC)") },
{ "af", "ps", I18N_NOOP2("Keyboard variant description", "Pashto") },
{ "ir", "pes_keypad", I18N_NOOP2("Keyboard variant description", "Persian (with Persian keypad)") },
{ "gb", "pl", I18N_NOOP2("Keyboard variant description", "Polish (British keyboard)") },
{ "pl", "dvorak", I18N_NOOP2("Keyboard variant description", "Polish (Dvorak)") },
{ "pl", "dvorak_altquotes", I18N_NOOP2("Keyboard variant description", "Polish (Dvorak, with Polish quotes on key 1)") },
{ "pl", "dvorak_quotes", I18N_NOOP2("Keyboard variant description", "Polish (Dvorak, with Polish quotes on quotemark key)") },
{ "pl", "legacy", I18N_NOOP2("Keyboard variant description", "Polish (legacy)") },
{ "pl", "dvp", I18N_NOOP2("Keyboard variant description", "Polish (programmer Dvorak)") },
{ "pl", "qwertz", I18N_NOOP2("Keyboard variant description", "Polish (QWERTZ)") },
{ "br", "dvorak", I18N_NOOP2("Keyboard variant description", "Portuguese (Brazil, Dvorak)") },
{ "br", "thinkpad", I18N_NOOP2("Keyboard variant description", "Portuguese (Brazil, IBM/Lenovo ThinkPad)") },
{ "br", "nativo-us", I18N_NOOP2("Keyboard variant description", "Portuguese (Brazil, Nativo for US keyboards)") },
{ "br", "nativo", I18N_NOOP2("Keyboard variant description", "Portuguese (Brazil, Nativo)") },
{ "br", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Portuguese (Brazil, no dead keys)") },
{ "pt", "mac", I18N_NOOP2("Keyboard variant description", "Portuguese (Macintosh)") },
{ "pt", "mac_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Portuguese (Macintosh, no dead keys)") },
{ "pt", "nativo-us", I18N_NOOP2("Keyboard variant description", "Portuguese (Nativo for US keyboards)") },
{ "pt", "nativo", I18N_NOOP2("Keyboard variant description", "Portuguese (Nativo)") },
{ "pt", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Portuguese (no dead keys)") },
{ "in", "jhelum", I18N_NOOP2("Keyboard variant description", "Punjabi (Gurmukhi Jhelum)") },
{ "in", "guru", I18N_NOOP2("Keyboard variant description", "Punjabi (Gurmukhi)") },
{ "de", "ro", I18N_NOOP2("Keyboard variant description", "Romanian (Germany)") },
{ "de", "ro_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Romanian (Germany, no dead keys)") },
{ "ro", "std", I18N_NOOP2("Keyboard variant description", "Romanian (standard)") },
{ "ro", "winkeys", I18N_NOOP2("Keyboard variant description", "Romanian (Windows)") },
{ "by", "ru", I18N_NOOP2("Keyboard variant description", "Russian (Belarus)") },
{ "cz", "rus", I18N_NOOP2("Keyboard variant description", "Russian (Czech, phonetic)") },
{ "ru", "dos", I18N_NOOP2("Keyboard variant description", "Russian (DOS)") },
{ "ge", "ru", I18N_NOOP2("Keyboard variant description", "Russian (Georgia)") },
{ "de", "ru", I18N_NOOP2("Keyboard variant description", "Russian (Germany, phonetic)") },
{ "kz", "ruskaz", I18N_NOOP2("Keyboard variant description", "Russian (Kazakhstan, with Kazakh)") },
{ "ru", "legacy", I18N_NOOP2("Keyboard variant description", "Russian (legacy)") },
{ "ru", "mac", I18N_NOOP2("Keyboard variant description", "Russian (Macintosh)") },
{ "ru", "phonetic", I18N_NOOP2("Keyboard variant description", "Russian (phonetic)") },
{ "ru", "phonetic_azerty", I18N_NOOP2("Keyboard variant description", "Russian (phonetic, AZERTY)") },
{ "ru", "phonetic_dvorak", I18N_NOOP2("Keyboard variant description", "Russian (phonetic, Dvorak)") },
{ "ru", "phonetic_fr", I18N_NOOP2("Keyboard variant description", "Russian (phonetic, French)") },
{ "ru", "phonetic_winkeys", I18N_NOOP2("Keyboard variant description", "Russian (phonetic, Windows)") },
{ "ru", "phonetic_YAZHERTY", I18N_NOOP2("Keyboard variant description", "Russian (phonetic, YAZHERTY)") },
{ "pl", "ru_phonetic_dvorak", I18N_NOOP2("Keyboard variant description", "Russian (Poland, phonetic Dvorak)") },
{ "se", "rus", I18N_NOOP2("Keyboard variant description", "Russian (Sweden, phonetic)") },
{ "se", "rus_nodeadkeys", I18N_NOOP2("Keyboard variant description", "Russian (Sweden, phonetic, no dead keys)") },
{ "ru", "typewriter", I18N_NOOP2("Keyboard variant description", "Russian (typewriter)") },
{ "ru", "typewriter-legacy", I18N_NOOP2("Keyboard variant description", "Russian (typewriter, legacy)") },
{ "ua", "rstu_ru", I18N_NOOP2("Keyboard variant description", "Russian (Ukraine, standard RSTU)") },
{ "us", "rus", I18N_NOOP2("Keyboard variant description", "Russian (US, phonetic)") },
{ "tw", "saisiyat", I18N_NOOP2("Keyboard variant description", "Saisiyat (Taiwan)") },
{ "lt", "sgs", I18N_NOOP2("Keyboard variant description", "Samogitian") },
{ "in", "san-kagapa", I18N_NOOP2("Keyboard variant description", "Sanskrit (KaGaPa, phonetic)") },
{ "gb", "gla", I18N_NOOP2("Keyboard variant description", "Scottish Gaelic") },
{ "rs", "alternatequotes", I18N_NOOP2("Keyboard variant description", "Serbian (Cyrillic, with guillemets)") },
{ "rs", "yz", I18N_NOOP2("Keyboard variant description", "Serbian (Cyrillic, ZE and ZHE swapped)") },
{ "rs", "latin", I18N_NOOP2("Keyboard variant description", "Serbian (Latin)") },
{ "rs", "latinyz", I18N_NOOP2("Keyboard variant description", "Serbian (Latin, QWERTY)") },
{ "rs", "latinunicode", I18N_NOOP2("Keyboard variant description", "Serbian (Latin, Unicode)") },
{ "rs", "latinunicodeyz", I18N_NOOP2("Keyboard variant description", "Serbian (Latin, Unicode, QWERTY)") },
{ "rs", "latinalternatequotes", I18N_NOOP2("Keyboard variant description", "Serbian (Latin, with guillemets)") },
{ "ru", "srp", I18N_NOOP2("Keyboard variant description", "Serbian (Russia)") },
{ "us", "hbs", I18N_NOOP2("Keyboard variant description", "Serbo-Croatian (US)") },
{ "mm", "zgt", I18N_NOOP2("Keyboard variant description", "Shan (Zawgyi Tai)") },
{ "mm", "shn", I18N_NOOP2("Keyboard variant description", "Shan") },
{ "it", "scn", I18N_NOOP2("Keyboard variant description", "Sicilian") },
{ "pl", "szl", I18N_NOOP2("Keyboard variant description", "Silesian") },
{ "pk", "snd", I18N_NOOP2("Keyboard variant description", "Sindhi") },
{ "lk", "us", I18N_NOOP2("Keyboard variant description", "Sinhala (US)") },
{ "sk", "bksl", I18N_NOOP2("Keyboard variant description", "Slovak (extended backslash)") },
{ "sk", "qwerty", I18N_NOOP2("Keyboard variant description", "Slovak (QWERTY)") },
{ "sk", "qwerty_bksl", I18N_NOOP2("Keyboard variant description", "Slovak (QWERTY, extended backslash)") },
{ "si", "us", I18N_NOOP2("Keyboard variant description", "Slovenian (US)") },
{ "si", "alternatequotes", I18N_NOOP2("Keyboard variant description", "Slovenian (with guillemets)") },
{ "es", "deadtilde", I18N_NOOP2("Keyboard variant description", "Spanish (dead tilde)") },
{ "es", "dvorak", I18N_NOOP2("Keyboard variant description", "Spanish (Dvorak)") },
{ "latam", "colemak-gaming", I18N_NOOP2("Keyboard variant description", "Spanish (Latin American, Colemak for gaming)") },
{ "latam", "colemak", I18N_NOOP2("Keyboard variant description", "Spanish (Latin American, Colemak)") },
{ "latam", "deadtilde", I18N_NOOP2("Keyboard variant description", "Spanish (Latin American, dead tilde)") },
{ "latam", "dvorak", I18N_NOOP2("Keyboard variant description", "Spanish (Latin American, Dvorak)") },
{ "latam", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Spanish (Latin American, no dead keys)") },
{ "es", "mac", I18N_NOOP2("Keyboard variant description", "Spanish (Macintosh)") },
{ "es", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Spanish (no dead keys)") },
{ "es", "winkeys", I18N_NOOP2("Keyboard variant description", "Spanish (Windows)") },
{ "se", "dvorak", I18N_NOOP2("Keyboard variant description", "Swedish (Dvorak)") },
{ "se", "us_dvorak", I18N_NOOP2("Keyboard variant description", "Swedish (Dvorak, intl.)") },
{ "se", "mac", I18N_NOOP2("Keyboard variant description", "Swedish (Macintosh)") },
{ "se", "nodeadkeys", I18N_NOOP2("Keyboard variant description", "Swedish (no dead keys)") },
{ "se", "svdvorak", I18N_NOOP2("Keyboard variant description", "Swedish (Svdvorak)") },
{ "se", "us", I18N_NOOP2("Keyboard variant description", "Swedish (US)") },
{ "se", "swl", I18N_NOOP2("Keyboard variant description", "Swedish Sign Language") },
{ "sy", "syc_phonetic", I18N_NOOP2("Keyboard variant description", "Syriac (phonetic)") },
{ "sy", "syc", I18N_NOOP2("Keyboard variant description", "Syriac") },
{ "tw", "indigenous", I18N_NOOP2("Keyboard variant description", "Taiwanese (indigenous)") },
{ "tj", "legacy", I18N_NOOP2("Keyboard variant description", "Tajik (legacy)") },
{ "in", "tam", I18N_NOOP2("Keyboard variant description", "Tamil (InScript)") },
{ "lk", "tam_unicode", I18N_NOOP2("Keyboard variant description", "Tamil (Sri Lanka, TamilNet '99)") },
{ "lk", "tam_TAB", I18N_NOOP2("Keyboard variant description", "Tamil (Sri Lanka, TamilNet '99, TAB encoding)") },
{ "in", "tam_tamilnet_with_tam_nums", I18N_NOOP2("Keyboard variant description", "Tamil (TamilNet '99 with Tamil numerals)") },
{ "in", "tam_tamilnet", I18N_NOOP2("Keyboard variant description", "Tamil (TamilNet '99)") },
{ "in", "tam_tamilnet_TAB", I18N_NOOP2("Keyboard variant description", "Tamil (TamilNet '99, TAB encoding)") },
{ "in", "tam_tamilnet_TSCII", I18N_NOOP2("Keyboard variant description", "Tamil (TamilNet '99, TSCII encoding)") },
{ "ma", "rif", I18N_NOOP2("Keyboard variant description", "Tarifit") },
{ "ru", "tt", I18N_NOOP2("Keyboard variant description", "Tatar") },
{ "in", "tel-kagapa", I18N_NOOP2("Keyboard variant description", "Telugu (KaGaPa, phonetic)") },
{ "in", "tel-sarala", I18N_NOOP2("Keyboard variant description", "Telugu (Sarala)") },
{ "in", "tel", I18N_NOOP2("Keyboard variant description", "Telugu") },
{ "th", "pat", I18N_NOOP2("Keyboard variant description", "Thai (Pattachote)") },
{ "th", "tis", I18N_NOOP2("Keyboard variant description", "Thai (TIS-820.2538)") },
{ "cn", "tib_asciinum", I18N_NOOP2("Keyboard variant description", "Tibetan (with ASCII numerals)") },
{ "cn", "tib", I18N_NOOP2("Keyboard variant description", "Tibetan") },
{ "tr", "alt", I18N_NOOP2("Keyboard variant description", "Turkish (Alt-Q)") },
{ "tr", "f", I18N_NOOP2("Keyboard variant description", "Turkish (F)") },
{ "de", "tr", I18N_NOOP2("Keyboard variant description", "Turkish (Germany)") },
{ "tr", "intl", I18N_NOOP2("Keyboard variant description", "Turkish (intl., with dead keys)") },
{ "tm", "alt", I18N_NOOP2("Keyboard variant description", "Turkmen (Alt-Q)") },
{ "ru", "udm", I18N_NOOP2("Keyboard variant description", "Udmurt") },
{ "ua", "homophonic", I18N_NOOP2("Keyboard variant description", "Ukrainian (homophonic)") },
{ "ua", "legacy", I18N_NOOP2("Keyboard variant description", "Ukrainian (legacy)") },
{ "ua", "macOS", I18N_NOOP2("Keyboard variant description", "Ukrainian (macOS)") },
{ "ua", "phonetic", I18N_NOOP2("Keyboard variant description", "Ukrainian (phonetic)") },
{ "ua", "rstu", I18N_NOOP2("Keyboard variant description", "Ukrainian (standard RSTU)") },
{ "ua", "typewriter", I18N_NOOP2("Keyboard variant description", "Ukrainian (typewriter)") },
{ "ua", "winkeys", I18N_NOOP2("Keyboard variant description", "Ukrainian (Windows)") },
{ "in", "urd-phonetic3", I18N_NOOP2("Keyboard variant description", "Urdu (alt. phonetic)") },
{ "pk", "urd-crulp", I18N_NOOP2("Keyboard variant description", "Urdu (Pakistan, CRULP)") },
{ "pk", "urd-nla", I18N_NOOP2("Keyboard variant description", "Urdu (Pakistan, NLA)") },
{ "in", "urd-phonetic", I18N_NOOP2("Keyboard variant description", "Urdu (phonetic)") },
{ "in", "urd-winkeys", I18N_NOOP2("Keyboard variant description", "Urdu (Windows)") },
{ "cn", "ug", I18N_NOOP2("Keyboard variant description", "Uyghur") },
{ "af", "uz", I18N_NOOP2("Keyboard variant description", "Uzbek (Afghanistan)") },
{ "af", "uz-olpc", I18N_NOOP2("Keyboard variant description", "Uzbek (Afghanistan, OLPC)") },
{ "uz", "latin", I18N_NOOP2("Keyboard variant description", "Uzbek (Latin)") },
{ "vn", "fr", I18N_NOOP2("Keyboard variant description", "Vietnamese (French)") },
{ "vn", "us", I18N_NOOP2("Keyboard variant description", "Vietnamese (US)") },
{ "ru", "sah", I18N_NOOP2("Keyboard variant description", "Yakut") },
{ "ng", "yoruba", I18N_NOOP2("Keyboard variant description", "Yoruba") }
};
static const qint16 variantDescriptionTblSize = sizeof(variantDescriptionTbl) / sizeof(variantDescriptionData);
static const struct optionDescriptionData {
const char* name;
const char* description;
} optionDescriptionTbl[] = {
{ "compose:caps-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Caps Lock") },
{ "compose:lctrl-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Left Ctrl") },
{ "compose:lwin-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Left Win") },
{ "compose:menu-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Menu") },
{ "compose:rctrl-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Right Ctrl") },
{ "compose:rwin-altgr", I18N_NOOP2("Keyboard option description", "3rd level of Right Win") },
{ "compose:102-altgr", I18N_NOOP2("Keyboard option description", "3rd level of the \"< >\" key") },
{ "altwin:menu", I18N_NOOP2("Keyboard option description", "Add the standard behavior to Menu key") },
{ "grab:break_actions", I18N_NOOP2("Keyboard option description", "Allow breaking grabs with keyboard actions (warning: security risk)") },
{ "grab:debug", I18N_NOOP2("Keyboard option description", "Allow grab and window tree logging") },
{ "altwin:meta_alt", I18N_NOOP2("Keyboard option description", "Alt and Meta are on Alt") },
{ "altwin", I18N_NOOP2("Keyboard option description", "Alt and Win behavior") },
{ "altwin:alt_super_win", I18N_NOOP2("Keyboard option description", "Alt is mapped to Right Win, Super to Menu") },
{ "altwin:alt_win", I18N_NOOP2("Keyboard option description", "Alt is mapped to Win and the usual Alt") },
{ "altwin:swap_alt_win", I18N_NOOP2("Keyboard option description", "Alt is swapped with Win") },
{ "grp:alt_caps_toggle", I18N_NOOP2("Keyboard option description", "Alt+Caps Lock") },
{ "grp:ctrl_alt_toggle", I18N_NOOP2("Keyboard option description", "Alt+Ctrl") },
{ "grp:alt_shift_toggle", I18N_NOOP2("Keyboard option description", "Alt+Shift") },
{ "grp:alt_space_toggle", I18N_NOOP2("Keyboard option description", "Alt+Space") },
{ "lv3:alt_switch", I18N_NOOP2("Keyboard option description", "Any Alt") },
{ "grp:win_switch", I18N_NOOP2("Keyboard option description", "Any Win (while pressed)") },
{ "lv3:win_switch", I18N_NOOP2("Keyboard option description", "Any Win") },
{ "apple:alupckeys", I18N_NOOP2("Keyboard option description", "Apple Aluminium emulates Pause, PrtSc, Scroll Lock") },
{ "ctrl:aa_ctrl", I18N_NOOP2("Keyboard option description", "At the bottom left") },
{ "esperanto:colemak", I18N_NOOP2("Keyboard option description", "At the corresponding key in a Colemak layout") },
{ "esperanto:dvorak", I18N_NOOP2("Keyboard option description", "At the corresponding key in a Dvorak layout") },
{ "esperanto:qwerty", I18N_NOOP2("Keyboard option description", "At the corresponding key in a QWERTY layout") },
{ "lv3:bksl_switch", I18N_NOOP2("Keyboard option description", "Backslash") },
{ "lv3:bksl_switch_latch", I18N_NOOP2("Keyboard option description", "Backslash; acts as onetime lock when pressed together with another 3rd level chooser") },
{ "grp:alts_toggle", I18N_NOOP2("Keyboard option description", "Both Alt together") },
{ "grp:ctrls_toggle", I18N_NOOP2("Keyboard option description", "Both Ctrl together") },
{ "shift:both_capslock", I18N_NOOP2("Keyboard option description", "Both Shift together enable Caps Lock") },
{ "shift:both_capslock_cancel", I18N_NOOP2("Keyboard option description", "Both Shift together enable Caps Lock; one Shift key disables it") },
{ "shift:both_shiftlock", I18N_NOOP2("Keyboard option description", "Both Shift together enable Shift Lock") },
{ "grp:shifts_toggle", I18N_NOOP2("Keyboard option description", "Both Shift together") },
{ "grp:caps_switch", I18N_NOOP2("Keyboard option description", "Caps Lock (while pressed), Alt+Caps Lock for the original Caps Lock action") },
{ "caps:shift_nocancel", I18N_NOOP2("Keyboard option description", "Caps Lock acts as Shift with locking; Shift does not affect Caps Lock") },
{ "caps:shift", I18N_NOOP2("Keyboard option description", "Caps Lock acts as Shift with locking; Shift \"pauses\" Caps Lock") },
{ "ctrl:nocaps", I18N_NOOP2("Keyboard option description", "Caps Lock as Ctrl") },
{ "ctrl:swapcaps_hyper", I18N_NOOP2("Keyboard option description", "Caps Lock as Ctrl, Ctrl as Hyper") },
{ "caps", I18N_NOOP2("Keyboard option description", "Caps Lock behavior") },
{ "caps:none", I18N_NOOP2("Keyboard option description", "Caps Lock is disabled") },
{ "grp:shift_caps_switch", I18N_NOOP2("Keyboard option description", "Caps Lock to first layout; Shift+Caps Lock to last layout") },
{ "caps:capslock", I18N_NOOP2("Keyboard option description", "Caps Lock toggles normal capitalization of alphabetic characters") },
{ "caps:shiftlock", I18N_NOOP2("Keyboard option description", "Caps Lock toggles Shift Lock (affects all keys)") },
{ "caps:internal_nocancel", I18N_NOOP2("Keyboard option description", "Caps Lock uses internal capitalization; Shift does not affect Caps Lock") },
{ "caps:internal", I18N_NOOP2("Keyboard option description", "Caps Lock uses internal capitalization; Shift \"pauses\" Caps Lock") },
{ "grp:caps_toggle", I18N_NOOP2("Keyboard option description", "Caps Lock") },
{ "lv3:caps_switch_latch", I18N_NOOP2("Keyboard option description", "Caps Lock; acts as onetime lock when pressed together with another 3rd-level chooser") },
{ "compat", I18N_NOOP2("Keyboard option description", "Compatibility options") },
{ "mod_led:compose", I18N_NOOP2("Keyboard option description", "Compose") },
{ "altwin:ctrl_alt_win", I18N_NOOP2("Keyboard option description", "Ctrl is mapped to Alt, Alt to Win") },
{ "altwin:ctrl_rwin", I18N_NOOP2("Keyboard option description", "Ctrl is mapped to Right Win and the usual Ctrl") },
{ "altwin:ctrl_win", I18N_NOOP2("Keyboard option description", "Ctrl is mapped to Win and the usual Ctrl") },
{ "ctrl", I18N_NOOP2("Keyboard option description", "Ctrl position") },
{ "terminate:ctrl_alt_bksp", I18N_NOOP2("Keyboard option description", "Ctrl+Alt+Backspace") },
{ "grp:ctrl_shift_toggle", I18N_NOOP2("Keyboard option description", "Ctrl+Shift") },
{ "currencysign", I18N_NOOP2("Keyboard option description", "Currency signs") },
{ "numpad:pc", I18N_NOOP2("Keyboard option description", "Default numeric keypad keys") },
{ "misc:apl", I18N_NOOP2("Keyboard option description", "Enable APL overlay characters") },
{ "misc:typo", I18N_NOOP2("Keyboard option description", "Enable extra typographic characters") },
{ "lv3:enter_switch", I18N_NOOP2("Keyboard option description", "Enter on keypad") },
{ "esperanto", I18N_NOOP2("Keyboard option description", "Esperanto letters with superscripts") },
{ "eurosign:2", I18N_NOOP2("Keyboard option description", "Euro on 2") },
{ "eurosign:4", I18N_NOOP2("Keyboard option description", "Euro on 4") },
{ "eurosign:5", I18N_NOOP2("Keyboard option description", "Euro on 5") },
{ "eurosign:e", I18N_NOOP2("Keyboard option description", "Euro on E") },
{ "kpdl:kposs", I18N_NOOP2("Keyboard option description", "Four-level key with abstract separators") },
{ "kpdl:commaoss", I18N_NOOP2("Keyboard option description", "Four-level key with comma") },
{ "kpdl:dotoss", I18N_NOOP2("Keyboard option description", "Four-level key with dot") },
{ "kpdl:dotoss_latin9", I18N_NOOP2("Keyboard option description", "Four-level key with dot, Latin-9 only") },
{ "kpdl:momayyezoss", I18N_NOOP2("Keyboard option description", "Four-level key with momayyez") },
{ "keypad:hex", I18N_NOOP2("Keyboard option description", "Hexadecimal") },
{ "altwin:hyper_win", I18N_NOOP2("Keyboard option description", "Hyper is mapped to Win") },
{ "japan", I18N_NOOP2("Keyboard option description", "Japanese keyboard options") },
{ "japan:kana_lock", I18N_NOOP2("Keyboard option description", "Kana Lock key is locking") },
{ "Compose", I18N_NOOP2("Keyboard option description", "key Position of Compose key") },
{ "terminate", I18N_NOOP2("Keyboard option description", "Key sequence to kill the X server") },
{ "lv5", I18N_NOOP2("Keyboard option description", "Key to choose 5th level") },
{ "lv2", I18N_NOOP2("Keyboard option description", "Key to choose the 2nd level") },
{ "lv3", I18N_NOOP2("Keyboard option description", "Key to choose the 3rd level") },
{ "korean", I18N_NOOP2("Keyboard option description", "Korean Hangul/Hanja keys") },
{ "keypad", I18N_NOOP2("Keyboard option description", "Layout of numeric keypad") },
{ "grp:lswitch", I18N_NOOP2("Keyboard option description", "Left Alt (while pressed)") },
{ "ctrl:swap_lalt_lctl_lwin", I18N_NOOP2("Keyboard option description", "Left Alt as Ctrl, Left Ctrl as Win, Left Win as Left Alt") },
{ "altwin:swap_lalt_lwin", I18N_NOOP2("Keyboard option description", "Left Alt is swapped with Left Win") },
{ "grp:lalt_toggle", I18N_NOOP2("Keyboard option description", "Left Alt") },
{ "grp:lalt_lshift_toggle", I18N_NOOP2("Keyboard option description", "Left Alt+Left Shift") },
{ "ctrl:lctrl_meta", I18N_NOOP2("Keyboard option description", "Left Ctrl as Meta") },
{ "grp:lctrl_rctrl_switch", I18N_NOOP2("Keyboard option description", "Left Ctrl to first layout; Right Ctrl to last layout") },
{ "grp:lctrl_toggle", I18N_NOOP2("Keyboard option description", "Left Ctrl") },
{ "grp:lctrl_lshift_toggle", I18N_NOOP2("Keyboard option description", "Left Ctrl+Left Shift") },
{ "grp:lctrl_lwin_rctrl_menu", I18N_NOOP2("Keyboard option description", "Left Ctrl+Left Win to first layout; Right Ctrl+Menu to second layout") },
{ "grp:lctrl_lwin_toggle", I18N_NOOP2("Keyboard option description", "Left Ctrl+Left Win") },
{ "grp:lshift_toggle", I18N_NOOP2("Keyboard option description", "Left Shift") },
{ "grp:lwin_switch", I18N_NOOP2("Keyboard option description", "Left Win (while pressed)") },
{ "lv5:lwin_switch_lock", I18N_NOOP2("Keyboard option description", "Left Win chooses 5th level and acts as a one-time lock if pressed with another 5th level chooser") },
{ "grp:win_menu_switch", I18N_NOOP2("Keyboard option description", "Left Win to first layout; Right Win/Menu to last layout") },
{ "grp:lwin_toggle", I18N_NOOP2("Keyboard option description", "Left Win") },
{ "kpdl:comma", I18N_NOOP2("Keyboard option description", "Legacy key with comma") },
{ "kpdl:dot", I18N_NOOP2("Keyboard option description", "Legacy key with dot") },
{ "keypad:legacy_wang", I18N_NOOP2("Keyboard option description", "Legacy Wang 724") },
{ "keypad:legacy", I18N_NOOP2("Keyboard option description", "Legacy") },
{ "caps:backspace", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Backspace") },
{ "caps:ctrl_modifier", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Ctrl") },
{ "caps:escape", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Esc") },
{ "caps:escape_shifted_capslock", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Esc, but Shift + Caps Lock is the regular Caps Lock") },
{ "caps:hyper", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Hyper") },
{ "caps:menu", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Menu key") },
{ "caps:numlock", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Num Lock") },
{ "caps:super", I18N_NOOP2("Keyboard option description", "Make Caps Lock an additional Super") },
{ "korean:ralt_hangul", I18N_NOOP2("Keyboard option description", "Make right Alt a Hangul key") },
{ "korean:ralt_hanja", I18N_NOOP2("Keyboard option description", "Make right Alt a Hanja key") },
{ "korean:rctrl_hangul", I18N_NOOP2("Keyboard option description", "Make right Ctrl a Hangul key") },
{ "korean:rctrl_hanja", I18N_NOOP2("Keyboard option description", "Make right Ctrl a Hanja key") },
{ "japan:hztg_escape", I18N_NOOP2("Keyboard option description", "Make Zenkaku Hankaku an additional Esc") },
{ "grp:menu_switch", I18N_NOOP2("Keyboard option description", "Menu (while pressed), Shift+Menu for Menu") },
{ "ctrl:menu_rctrl", I18N_NOOP2("Keyboard option description", "Menu as Right Ctrl") },
{ "lv5:menu_switch", I18N_NOOP2("Keyboard option description", "Menu chooses 5th level") },
{ "altwin:menu_win", I18N_NOOP2("Keyboard option description", "Menu is mapped to Win") },
{ "grp:menu_toggle", I18N_NOOP2("Keyboard option description", "Menu") },
{ "altwin:left_meta_win", I18N_NOOP2("Keyboard option description", "Meta is mapped to Left Win") },
{ "altwin:meta_win", I18N_NOOP2("Keyboard option description", "Meta is mapped to Win") },
{ "japan:nicola_f_bs", I18N_NOOP2("Keyboard option description", "NICOLA-F style Backspace") },
{ "nbsp:level2", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 2nd level") },
{ "nbsp:level3", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 3rd level") },
{ "nbsp:level3s", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 3rd level, nothing at the 4th level") },
{ "nbsp:level3n", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 3rd level, thin non-breaking space at the 4th level") },
{ "nbsp:level4", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 4th level") },
{ "nbsp:level4nl", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 4th level, thin non-breaking space at the 6th level (via Ctrl+Shift)") },
{ "nbsp:level4n", I18N_NOOP2("Keyboard option description", "Non-breaking space at the 4th level, thin non-breaking space at the 6th level") },
{ "nbsp", I18N_NOOP2("Keyboard option description", "Non-breaking space input") },
{ "numpad:microsoft", I18N_NOOP2("Keyboard option description", "Num Lock on: digits; Shift for arrows. Num Lock off: arrows (as in Windows)") },
{ "grp_led:num", I18N_NOOP2("Keyboard option description", "Num Lock") },
{ "numpad:mac", I18N_NOOP2("Keyboard option description", "Numeric keypad always enters digits (as in macOS)") },
{ "kpdl", I18N_NOOP2("Keyboard option description", "Numeric keypad Delete behavior") },
{ "solaris", I18N_NOOP2("Keyboard option description", "Old Solaris keycodes compatibility") },
{ "compose:paus", I18N_NOOP2("Keyboard option description", "Pause") },
{ "keypad:atm", I18N_NOOP2("Keyboard option description", "Phone and ATM style") },
{ "compose:prsc", I18N_NOOP2("Keyboard option description", "PrtSc") },
{ "grp:switch", I18N_NOOP2("Keyboard option description", "Right Alt (while pressed)") },
{ "lv5:ralt_switch_lock", I18N_NOOP2("Keyboard option description", "Right Alt chooses 5th level and acts as a one-time lock if pressed with another 5th level chooser") },
{ "lv5:ralt_switch", I18N_NOOP2("Keyboard option description", "Right Alt chooses 5th level") },
{ "lv3:ralt_alt", I18N_NOOP2("Keyboard option description", "Right Alt never chooses 3rd level") },
{ "grp:toggle", I18N_NOOP2("Keyboard option description", "Right Alt") },
{ "lv3:ralt_switch_multikey", I18N_NOOP2("Keyboard option description", "Right Alt; Shift+Right Alt as Compose") },
{ "grp:rctrl_switch", I18N_NOOP2("Keyboard option description", "Right Ctrl (while pressed)") },
{ "ctrl:rctrl_ralt", I18N_NOOP2("Keyboard option description", "Right Ctrl as Right Alt") },
{ "grp:rctrl_toggle", I18N_NOOP2("Keyboard option description", "Right Ctrl") },
{ "grp:rctrl_rshift_toggle", I18N_NOOP2("Keyboard option description", "Right Ctrl+Right Shift") },
{ "grp:rshift_toggle", I18N_NOOP2("Keyboard option description", "Right Shift") },
{ "grp:rwin_switch", I18N_NOOP2("Keyboard option description", "Right Win (while pressed)") },
{ "lv5:rwin_switch_lock", I18N_NOOP2("Keyboard option description", "Right Win chooses 5th level and acts as a one-time lock if pressed with another 5th level chooser") },
{ "grp:rwin_toggle", I18N_NOOP2("Keyboard option description", "Right Win") },
{ "rupeesign:4", I18N_NOOP2("Keyboard option description", "Rupee on 4") },
{ "grp:sclk_toggle", I18N_NOOP2("Keyboard option description", "Scroll Lock") },
{ "kpdl:semi", I18N_NOOP2("Keyboard option description", "Semicolon on third level") },
{ "keypad:pointerkeys", I18N_NOOP2("Keyboard option description", "Shift + Num Lock enables PointerKeys") },
{ "shift:breaks_caps", I18N_NOOP2("Keyboard option description", "Shift cancels Caps Lock") },
{ "numpad:shift3", I18N_NOOP2("Keyboard option description", "Shift does not cancel Num Lock, chooses 3rd level instead") },
{ "grp:shift_caps_toggle", I18N_NOOP2("Keyboard option description", "Shift+Caps Lock") },
{ "srvrkeys:none", I18N_NOOP2("Keyboard option description", "Special keys (Ctrl+Alt+<key>) handled in a server") },
{ "solaris:sun_compat", I18N_NOOP2("Keyboard option description", "Sun key compatibility") },
{ "ctrl:swapcaps", I18N_NOOP2("Keyboard option description", "Swap Ctrl and Caps Lock") },
{ "caps:swapescape", I18N_NOOP2("Keyboard option description", "Swap Esc and Caps Lock") },
{ "ctrl:swap_lalt_lctl", I18N_NOOP2("Keyboard option description", "Swap Left Alt with Left Ctrl") },
{ "ctrl:swap_lwin_lctl", I18N_NOOP2("Keyboard option description", "Swap Left Win with Left Ctrl") },
{ "ctrl:swap_rwin_rctl", I18N_NOOP2("Keyboard option description", "Swap Right Win with Right Ctrl") },
{ "grp", I18N_NOOP2("Keyboard option description", "Switching to another layout") },
{ "lv5:lsgt_switch_lock", I18N_NOOP2("Keyboard option description", "The \"< >\" key chooses 5th level and acts as a one-time lock if pressed with another 5th level chooser") },
{ "lv5:lsgt_switch", I18N_NOOP2("Keyboard option description", "The \"< >\" key chooses 5th level") },
{ "lv2:lsgt_switch", I18N_NOOP2("Keyboard option description", "The \"< >\" key") },
{ "lv3:lsgt_switch_latch", I18N_NOOP2("Keyboard option description", "The \"< >\" key; acts as onetime lock when pressed together with another 3rd level chooser") },
{ "ctrl:ac_ctrl", I18N_NOOP2("Keyboard option description", "To the left of \"A\"") },
{ "keypad:future", I18N_NOOP2("Keyboard option description", "Unicode arrows and math operators on default level") },
{ "keypad:oss", I18N_NOOP2("Keyboard option description", "Unicode arrows and math operators") },
{ "mod_led", I18N_NOOP2("Keyboard option description", "Use keyboard LED to indicate modifiers") },
{ "grp_led", I18N_NOOP2("Keyboard option description", "Use keyboard LED to show alternative layout") },
{ "nbsp:none", I18N_NOOP2("Keyboard option description", "Usual space at any level") },
{ "keypad:future_wang", I18N_NOOP2("Keyboard option description", "Wang 724 keypad with Unicode arrows and math operators on default level") },
{ "keypad:oss_wang", I18N_NOOP2("Keyboard option description", "Wang 724 keypad with Unicode arrows and math operators") },
{ "altwin:prtsc_rwin", I18N_NOOP2("Keyboard option description", "Win is mapped to PrtSc and the usual Win") },
{ "grp:win_space_toggle", I18N_NOOP2("Keyboard option description", "Win+Space") },
{ "nbsp:zwnj2", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level") },
{ "nbsp:zwnj2nb3", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, non-breaking space at the 3rd level") },
{ "nbsp:zwnj2nb3s", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, non-breaking space at the 3rd level, nothing at the 4th level") },
{ "nbsp:zwnj2nb3nnb4", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, non-breaking space at the 3rd level, thin non-breaking space at the 4th level") },
{ "nbsp:zwnj2nb3zwj4", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, non-breaking space at the 3rd level, zero-width joiner at the 4th level") },
{ "nbsp:zwnj2zwj3", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, zero-width joiner at the 3rd level") },
{ "nbsp:zwnj2zwj3nb4", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 2nd level, zero-width joiner at the 3rd level, non-breaking space at the 4th level") },
{ "nbsp:zwnj3zwj4", I18N_NOOP2("Keyboard option description", "Zero-width non-joiner at the 3rd level, zero-width joiner at the 4th level") },
};
static const qint16 optionDescriptionTblSize = sizeof(optionDescriptionTbl) / sizeof(optionDescriptionData);
bool KKeyboardType::operator==(const KKeyboardType &other) const
{
return (rule == other.rule
&& model == other.model
&& layout == other.layout
&& variant == other.variant
&& option == other.option
);
}
class KKeyboardLayoutPrivate
{
public:
KKeyboardLayoutPrivate(KKeyboardLayout *parent);
~KKeyboardLayoutPrivate();
void _k_checkLayouts();
QList<KKeyboardType> currentlayouts;
QString setxkbmapexe;
private:
KKeyboardLayout* m_parent;
QTimer* m_timer;
};
KKeyboardLayoutPrivate::KKeyboardLayoutPrivate(KKeyboardLayout *parent)
: m_parent(parent),
m_timer(new QTimer(parent))
{
m_timer->setInterval(s_layouttimeout);
QObject::connect(
m_timer, SIGNAL(timeout()),
m_parent, SLOT(_k_checkLayouts())
);
m_timer->start();
}
KKeyboardLayoutPrivate::~KKeyboardLayoutPrivate()
{
m_timer->stop();
}
void KKeyboardLayoutPrivate::_k_checkLayouts()
{
const QList<KKeyboardType> layouts = m_parent->layouts();
if (layouts != currentlayouts) {
currentlayouts = layouts;
kDebug() << "XKB layouts changed";
emit m_parent->layoutChanged();
}
}
KKeyboardLayout::KKeyboardLayout(QObject *parent)
: QObject(parent),
d(new KKeyboardLayoutPrivate(this))
{
}
KKeyboardLayout::~KKeyboardLayout()
{
delete d;
}
QList<KKeyboardType> KKeyboardLayout::layouts() const
{
QList<KKeyboardType> result;
#if defined(HAVE_XKB)
XkbRF_VarDefsRec xkbvardefs;
const Bool xkbresult = XkbRF_GetNamesProp(QX11Info::display(), NULL, &xkbvardefs);
if (xkbresult != True) {
kWarning() << "Could not get XKB layouts";
} else {
const QByteArray xkbmodel = QByteArray::fromRawData(xkbvardefs.model, qstrlen(xkbvardefs.model));
const QByteArray xkblayout = QByteArray::fromRawData(xkbvardefs.layout, qstrlen(xkbvardefs.layout));
const QByteArray xkbvariants = QByteArray::fromRawData(xkbvardefs.variant, qstrlen(xkbvardefs.variant));
const QByteArray xkboptions = QByteArray::fromRawData(xkbvardefs.options, qstrlen(xkbvardefs.options));
const QList<QByteArray> splitlayouts = xkblayout.split(s_xkbseparator);
const QList<QByteArray> splitvariants = xkbvariants.split(s_xkbseparator);
for (int i = 0; i < splitlayouts.size(); i++) {
KKeyboardType kkeyboardtype;
kkeyboardtype.model = xkbmodel;
kkeyboardtype.layout = splitlayouts.at(i);
if (i < splitvariants.size()) {
kkeyboardtype.variant = splitvariants.at(i);
}
kkeyboardtype.option = xkboptions;
result.append(kkeyboardtype);
}
}
#endif
if (result.size() == 0) {
result.append(KKeyboardLayout::defaultLayout());
}
return result;
}
bool KKeyboardLayout::setLayouts(const QList<KKeyboardType> &layouts)
{
if (layouts.size() == 0) {
kWarning() << "Empty keyboard layouts";
return false;
}
QByteArray xkbrule;
QByteArray xkbmodel;
QByteArray xkblayouts;
QList<QByteArray> xkbvariants;
QList<QByteArray> xkboptions;
foreach (const KKeyboardType &layout, layouts) {
if (layout.layout.isEmpty()) {
kWarning() << "Invalid keyboard layout";
return false;
}
// NOTE: -rules and -model can be speicified only once
if (!xkbrule.isEmpty() && xkbrule != layout.rule) {
kWarning() << "Conflicting keyboard layout rules";
return false;
}
xkbrule = layout.rule;
if (!xkbmodel.isEmpty() && xkbmodel != layout.model) {
kWarning() << "Conflicting keyboard layout models";
return false;
}
xkbmodel = layout.model;
// NOTE: layouts and variants have to be joined, variant can be empty
if (!xkblayouts.isEmpty()) {
xkblayouts.append(s_xkbseparator);
}
xkblayouts.append(layout.layout);
xkbvariants.append(layout.variant);
// NOTE: options can be empty, also -option argument must be used per-option
if (!layout.option.isEmpty()) {
xkboptions.append(layout.option);
}
}
kDebug() << "Changing XKB layouts to" << xkbrule << xkbmodel << xkblayouts << xkbvariants << xkboptions;
// setting the property is simply not enough, X11 server has to load rules and whatnot
if (d->setxkbmapexe.isEmpty()) {
d->setxkbmapexe = KStandardDirs::findExe("setxkbmap");
}
if (d->setxkbmapexe.isEmpty()) {
kWarning() << "Could not find setxkbmap";
return false;
}
// NOTE: options have to be reset first
static const QStringList setxkbmapresetargs = QStringList()
<< QString::fromLatin1("-option");
int setxkbmapstatus = QProcess::execute(d->setxkbmapexe, setxkbmapresetargs);
if (setxkbmapstatus != 0) {
kWarning() << "Could not reset XKB map" << setxkbmapstatus;
return false;
}
QStringList setxkbmapargs = QStringList()
<< QString::fromLatin1("-layout")
<< QString::fromLatin1(xkblayouts.constData(), xkblayouts.size());
if (!xkbrule.isEmpty()) {
setxkbmapargs << QString::fromLatin1("-rules");
setxkbmapargs << QString::fromLatin1(xkbrule.constData(), xkbrule.size());
}
if (!xkbmodel.isEmpty()) {
setxkbmapargs << QString::fromLatin1("-model");
setxkbmapargs << QString::fromLatin1(xkbmodel.constData(), xkbmodel.size());
}
if (!xkbvariants.isEmpty()) {
QByteArray xkbvariantsdata;
foreach (const QByteArray &xkbvariant, xkbvariants) {
xkbvariantsdata.append(xkbvariant);
xkbvariantsdata.append(s_xkbseparator);
}
xkbvariantsdata.chop(1);
setxkbmapargs << QString::fromLatin1("-variant");
setxkbmapargs << QString::fromLatin1(xkbvariantsdata.constData(), xkbvariantsdata.size());
}
foreach (const QByteArray &option, xkboptions) {
setxkbmapargs << QString::fromLatin1("-option");
setxkbmapargs << QString::fromLatin1(option.constData(), option.size());
}
setxkbmapstatus = QProcess::execute(d->setxkbmapexe, setxkbmapargs);
if (setxkbmapstatus != 0) {
kWarning() << "Could not set XKB map" << setxkbmapstatus << setxkbmapargs;
return false;
}
return true;
}
KKeyboardType KKeyboardLayout::defaultLayout()
{
// should all else fail this is a default that will work for most cases (assuming the XKB data
// is installed that is)
KKeyboardType defaultlayout;
defaultlayout.rule = "base";
defaultlayout.model = "pc105";
defaultlayout.layout = "us";
return defaultlayout;
}
QList<QByteArray> KKeyboardLayout::modelNames()
{
QList<QByteArray> result;
result.reserve(modelDescriptionTblSize);
for (int i = 0; i < modelDescriptionTblSize; i++) {
result.append(modelDescriptionTbl[i].name);
}
return result;
}
QList<QByteArray> KKeyboardLayout::layoutNames()
{
QList<QByteArray> result;
result.reserve(layoutDescriptionTblSize);
for (int i = 0; i < layoutDescriptionTblSize; i++) {
result.append(layoutDescriptionTbl[i].name);
}
return result;
}
QList<QByteArray> KKeyboardLayout::variantNames(const QByteArray &layout)
{
QList<QByteArray> result;
for (int i = 0; i < variantDescriptionTblSize; i++) {
if (qstrcmp(layout.constData(), variantDescriptionTbl[i].name) == 0) {
result.append(variantDescriptionTbl[i].name2);
}
}
return result;
}
QList<QByteArray> KKeyboardLayout::optionNames()
{
QList<QByteArray> result;
result.reserve(optionDescriptionTblSize);
for (int i = 0; i < optionDescriptionTblSize; i++) {
result.append(optionDescriptionTbl[i].name);
}
return result;
}
QString KKeyboardLayout::modelDescription(const QByteArray &model)
{
for (int i = 0; i < modelDescriptionTblSize; i++) {
if (qstrcmp(model.constData(), modelDescriptionTbl[i].name) == 0) {
return ki18nc("Keyboard model description", modelDescriptionTbl[i].description).toString();
}
}
return QString::fromLatin1(model.constData(), model.size());
}
QString KKeyboardLayout::layoutDescription(const QByteArray &layout)
{
for (int i = 0; i < layoutDescriptionTblSize; i++) {
if (qstrcmp(layout.constData(), layoutDescriptionTbl[i].name) == 0) {
return ki18nc("Keyboard layout description", layoutDescriptionTbl[i].description).toString();
}
}
return QString::fromLatin1(layout.constData(), layout.size());
}
QString KKeyboardLayout::variantDescription(const QByteArray &layout, const QByteArray &variant)
{
if (variant.isEmpty()) {
return i18nc("Keyboard variant description", "None");
}
for (int i = 0; i < variantDescriptionTblSize; i++) {
if (qstrcmp(layout.constData(), variantDescriptionTbl[i].name) == 0
&& qstrcmp(variant.constData(), variantDescriptionTbl[i].name2) == 0) {
return ki18nc("Keyboard variant description", variantDescriptionTbl[i].description).toString();
}
}
return QString::fromLatin1(variant.constData(), variant.size());
}
QString KKeyboardLayout::optionDescription(const QByteArray &option)
{
if (option.isEmpty()) {
return i18nc("Keyboard option description", "None");
}
for (int i = 0; i < optionDescriptionTblSize; i++) {
if (qstrcmp(option.constData(), optionDescriptionTbl[i].name) == 0) {
return ki18nc("Keyboard option description", optionDescriptionTbl[i].description).toString();
}
}
return QString::fromLatin1(option.constData(), option.size());
}
#include "moc_kkeyboardlayout.cpp"