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