   How  to  further enhance XKB configurationKamil Toman, Ivan U.
   Pascal25  November  2002This  guide  is aimed to relieve one's
   labour  to  create  a new (internationalized) keyboard layout.
   Unlike   other   documents   this  guide  accents  the  keymap
   developer's  point  of  view.OverviewThe  developer  of  a new
   layout  should  read  the  xkb  protocol  specification (The X
   Keyboard   Extension:  Protocol  Specification)  at  least  to
   clarify  for  himself  some  xkb-specific  terms  used in this
   document  and  elsewhere  in  xkb configuration. Also it shows
   wise  to understand how the X server and a client digest their
   keyboard inputs (with and without xkb).A useful source is also
   Ivan  Pascal's  text  about xkb configuration often referenced
   throughout  this  document.Note that this document covers only
   enhancements  which  are to be made to XFree86 version 4.3 and
   X11R6.7.0  and  above.The BasicsAt the startup (or at later at
   user's  command)  X  server  starts  its  xkb  keyboard module
   extension   and  reads  data  from  a  compiled  configuration
   file.This  compiled  configuration  file  is  prepared  by the
   program  xkbcomp  which  behaves  altogether  as  an  ordinary
   compiler  (see  man xkbcomp). Its input are human readable xkb
   configuration  files which are verified and then composed into
   a  useful  xkb  configuration.  Users  don't need to mess with
   xkbcomp  themselves,  for them it is invisible. Usually, it is
   started  upon  X  server startup.As you probably already know,
   the   xkb   configuration   consists  of  five  main  modules:
   KeycodesTables  that  defines  translation  from keyboard scan
   codes  into  reasonable symbolic names, maximum, minimum legal
   keycodes,  symbolic  aliases  and  description  of  physically
   present LED-indicators. The primary sence of this component is
   to  allow  definitions  of  maps  of symbols (see below) to be
   independent of physical keyboard scancodes. There are two main
   naming  conventions  for  symbolic  names  (always  four bytes
   long):  names  which  express  some  traditional  meaning like
   <SPCE>  (stands  for  space  bar)  or names which express some
   relative  positioning  on  a  keyboard, for example <AE01> (an
   exclamation mark on US keyboards), on the right there are keys
   <AE02>,  <AE03>  etc. TypesTypes describe how the produced key
   is  changed  by  active  modifiers  (like Shift, Control, Alt,
   ...).  There  are several predefined types which cover most of
   used    combinations.CompatCompatibility   component   defines
   internal  behaviour  of  modifiers. Using compat component you
   can  assign  various  actions  (elaborately  described  in xkb
   specification)  to  key  events.  This is also the place where
   LED-indicators  behaviour is defined.SymbolsFor i18n purposes,
   this  is  the  most  important  table.  It defines what values
   (=symbols) are assigned to what keycodes (represented by their
   symbolic  name, see above). There may be defined more than one
   value  for  each  key and then it depends on a key type and on
   modifiers state (respective compat component) which value will
   be the resulting one.GeometryGeometry files aren't used by xkb
   itself  but  they  may  be  used  by some external programs to
   depict  a  keyboard image. All these components have the files
   located  in  xkb configuration tree in subdirectories with the
   same   names   (usually   in  /usr/lib/X11/xkb).Enhancing  XKB
   ConfigurationMost  of  xkb  enhancements  concerns  a  need to
   define  new  output  symbols for the some input key events. In
   other  words,  a  need  to  define a new symbol map (for a new
   language,  standard  or  just  to  feel  more comfortable when
   typing  text).What  do  you need to do? Generally, you have to
   define  following  things: the map of symbols itself the rules
   to  allow  users  to select the new mapping the description of
   the new layout First of all, it is good to go through existing
   layouts  and  to  examine them if there is something you could
   easily  adjust  to  fit  your  needs. Even if there is nothing
   similar  you  may get some ideas about basic concepts and used
   tricks.Levels  And GroupsSince XFree86 4.3.0 and X11R6.7.0 you
   can  use  multi-layout concept of xkb configuration. Though it
   is  still in boundaries of xkb protocol and general ideas, the
   keymap designer must obey new rules when creating new maps. In
   exchange  we  get  a  more  powerful and cleaner configuration
   system.Remember  that  it is the application which must decide
   which  symbol  matches  which  keycode  according to effective
   modifier  state. The X server itself sends only an input event
   message  to.  Of course, usually the general interpretation is
   processed  by Xlib, Xaw, Motif, Qt, Gtk and similar libraries.
   The  X server only supplies its mapping table (usually upon an
   application  startup).You  can  think of the X server's symbol
   table  as  of a irregular table where each keycode has its row
   and where each combination of modifiers determines exactly one
   column.  The  resulting  cell  then  gives the proper symbolic
   value.  Not  all  keycodes  need  to bind different values for
   different combination of modifiers. <ENTER> key, for instance,
   usually doesn't depend on any modifiers so it its row has only
   one  column  defined.Note  that  in  XKB  there  is  no  prior
   assumption   that  certain  modifiers  are  bound  to  certain
   columns.  By  editing  proper files (see ) this mapping can be
   changed  as  well.Unlike  the  original  X  protocol  the  XKB
   approach  is  far  more flexible. It is comfortable to add one
   additional  XKB term - group. You can think of a group as of a
   vector of columns per each keycode (naturally the dimension of
   this  vector  may  differ  for different keycodes). What is it
   good  for?  The  group is not very useful unless you intend to
   use  more  than  one  logically different set of symbols (like
   more than one alphabet) defined in a single mapping table. But
   then,  the  group  has a natural meaning - each symbol set has
   its own group and changing it means selecting a different one.
   XKB  approach  allows up to four different groups. The columns
   inside  each  group  are  called  (shift) levels. The X server
   knows  the current group and reports it together with modifier
   set  and  with  a keycode in key events.To sum it up: for each
   keycode  XKB  keyboard map contains up to four one-dimensional
   tables  -  groups  (logically  different symbol sets) for each
   group  of  a  keycode XKB keyboard map contains some columns -
   shift  levels  (values reached by combinations of Shift, Ctrl,
   Alt,  ...  modifiers)  different  keycodes  can have different
   number  of  groups  different  groups  of one keycode can have
   different  number  of shift levels the current group number is
   tracked  by  X  server  It  is clear that if you sanely define
   levels,  groups  and  sanely  bind  modifiers  and  associated
   actions   you  can  have  simultaneously  loaded  up  to  four
   different  symbol  sets where each of them would reside in its
   own  group.The  multi-layout  concept  provides  a facility to
   manipulate  xkb  groups  and  symbol definitions in a way that
   allows  almost  arbitrary  composition  of  predefined  symbol
   tables.  To  keep  it fully functional you have to: define all
   symbols  only in the first group (re)define any modifiers with
   extra  care  to avoid strange (anisometric) behaviour Defining
   New  LayoutsSee Some Words About XKB internals for explanation
   of  used xkb terms and problems addressed by XKB extension.See
   Common  notes  about XKB configuration files language for more
   precise   explanation   of   syntax   of   xkb   configuration
   files.Predefined  XKB  Symbol  SetsIf  you are about to define
   some  European  symbol map extension, you might want to use on
   of  four  predefined latin alphabet layouts.Okay, let's assume
   you  want extend an existing keymap and you want to override a
   few  keys.  Let's  take  a  simple U.K. keyboard as an example
   (defined   in   pc/gb):   partial   default  alphanumeric_keys
   xkb_symbols  "basic"  { include "pc/latin" name[Group1]="Great
   Britain"; key <AE02> { [ 2, quotedbl, twosuperior, oneeighth ]
   };  key  <AE03>  { [ 3, sterling, threesuperior, sterling ] };
   key  <AC11> { [apostrophe, at, dead_circumflex, dead_caron] };
   key  <TLDE>  {  [  grave,  notsign, bar, bar ] }; key <BKSL> {
   [numbersign,  asciitilde,  dead_grave,  dead_breve  ]  };  key
   <RALT>   {   type[Group1]="TWO_LEVEL",   [   ISO_Level3_Shift,
   Multi_key  ]  }; modifier_map Mod5 { <RALT> }; }; It defines a
   new  layout  in  basic variant as an extension of common latin
   alphabet layout. The layout (symbol set) name is set to "Great
   Britain". Then there are redefinitions of a few keycodes and a
   modifiers  binding.  As you can see the number of shift levels
   is the same for <AE02>, <AE03>, <AC11>, <TLDE> and <BKSL> keys
   but it differs from number of shift levels of <RALT>.Note that
   the  <RALT>  key  itself is a binding key for Mod5 and that it
   serves  like  a  shift  modifier for LevelThree, together with
   Shift  as a multi-key. It is a good habit to respect this rule
   in  a  new  similar  layout.Okay,  you  could  now define more
   variants  of your new layout besides basic simply by including
   (augmenting/overriding/...)  the basic definition and altering
   what  may  be needed.Key TypesThe differences in the number of
   columns (shift levels) are caused by a different types of keys
   (see  the  types  definition in section basics). Most keycodes
   have  implicitly set the keytype in the included pc/latin file
   to FOUR_LEVEL_ALPHABETIC. The only exception is <RALT> keycode
   which  is  explicitly  set  TWO_LEVEL  keytype.All those names
   refer  to  pre-defined  shift  level  schemes. Usually you can
   choose a suitable shift level scheme from default types scheme
   list  in  proper  xkb  component's subdirectory. The most used
   schemes   are:   ONE_LEVELThe  key  does  not  depend  on  any
   modifiers.   The   symbol   from   first   level   is   always
   chosen.TWO_LEVELThe key uses a modifier Shift and may have two
   possible  values.  The  second  level  may  be chosen by Shift
   modifier.  If  Lock  modifier  (usually Caps-lock) applies the
   symbol    is    further    processed   using   system-specific
   capitalization  rules.  If  both Shift+Lock modifier apply the
   symbol from the second level is taken and capitalization rules
   are  applied  (and  usually  have no effect).ALPHABETICThe key
   uses  modifiers  Shift  and  Lock.  It  may  have two possible
   values. The second level may be chosen by Shift modifier. When
   Lock  modifier  applies,  the  symbol  from the first level is
   taken    and    further    processed   using   system-specific
   capitalization  rules.  If  both Shift+Lock modifier apply the
   symbol  from  the  first  level is taken and no capitalization
   rules   applied.   This  is  often  called  shift-cancels-caps
   behaviour.THREE_LEVELIs the same as TWO_LEVEL but it considers
   an  extra  modifier - LevelThree which can be used to gain the
   symbol  value  from  the third level. If both Shift+LevelThree
   modifiers  apply the value from the third level is also taken.
   As  in  TWO_LEVEL,  the  Lock  modifier  doesn't influence the
   resulting level. Only Shift and LevelThree are taken into that
   consideration.  If  the Lock modifier is active capitalization
   rules  are  applied  on  the resulting symbol.FOUR_LEVELIs the
   same   as   THREE_LEVEL   but   unlike   LEVEL_THREE  if  both
   Shift+LevelThree  modifiers apply the symbol is taken from the
   fourth level.FOUR_LEVEL_ALPHABETICIs similar to FOUR_LEVEL but
   also defines shift-cancels-caps behaviour as in ALPHABETIC. If
   Lock+LevelThree apply the symbol from the third level is taken
   and    the    capitalization    rules    are    applied.    If
   Lock+Shift+LevelThree apply the symbol from the third level is
   taken  and  no  capitalization  rules are applied.KEYPADAs the
   name  suggest  this  scheme  is  primarily  used  for  numeric
   keypads.  The  scheme  considers  two  modifiers  -  Shift and
   NumLock.  If  none  of  modifiers  applies the symbol from the
   first  level  is  taken.  If either Shift or NumLock modifiers
   apply  the  symbol  from  the  second  level is taken. If both
   Shift+NumLock  modifiers apply the symbol from the first level
   is taken. Again, shift-cancels-caps
   variant.FOUR_LEVEL_KEYPADIs   similar  to  KEYPAD  scheme  but
   considers  also  LevelThree  modifier.  If LevelThree modifier
   applies   the  symbol  from  the  third  level  is  taken.  If
   Shift+LevelThree  or  NumLock+LevelThree apply the symbol from
   the  fourth  level  is  taken. If all Shift+NumLock+LevelThree
   modifiers apply the symbol from the third level is taken. This
   also,   shift-cancels-caps  variant.Besides  that,  there  are
   several schemes for special purposes: PC_BREAKIt is similar to
   TWO_LEVEL  scheme but it considers the Control modifier rather
   than  Shift.  That  means, the symbol from the second level is
   chosen  by  Control rather than by Shift.PC_SYSRQIt is similar
   to  TWO_LEVEL  scheme but it considers the Alt modifier rather
   than  Shift.  That  means, the symbol from the second level is
   chosen  by  Alt  rather  than  by  Shift.CTRL+ALTThe  key uses
   modifiers Alt and Control. It may have two possible values. If
   only one modifier (Alt or Control) applies the symbol from the
   first  level  is  chosen.  Only  if both Alt+Control modifiers
   apply  the symbol from the second level is chosen.SHIFT+ALTThe
   key  uses  modifiers  Shift  and Alt. It may have two possible
   values. If only one modifier (Alt or Shift) applies the symbol
   from  the  first  level  is  chosen.  Only  if  both Alt+Shift
   modifiers  apply the symbol from the second level is chosen.If
   needed,  special  caps  schemes may be used. They redefine the
   standard behaviour of all *ALPHABETIC types. The layouts (maps
   of  symbols)  with  keys  defined  in  respective  types  then
   automatically  change  their  behaviour  accordingly. Possible
   redefinitions are:
   internalinternal_nocancelshiftshift_nocancel   None  of  these
   schemes  should  be used directly. They are defined merely for
   'caps:'  xkb  options  (used  to  globally  change the layouts
   behaviour).Don't  alter any of existing key types. If you need
   a  different behaviour create a new one.More On Definitions Of
   TypesWhen   the  XKB  software  deals  with  a  separate  type
   description  it  gets a complete list of modifiers that should
   be taken into account from the 'modifiers=<list of modifiers>'
   list   and   expects   that  a  set  of  'map[<combination  of
   modifiers>]=<list of modifiers>' instructions that contain the
   mapping  for  each  combination of modifiers mentioned in that
   list.  Modifiers  that are not explicitly listed are NOT taken
   into  account  when  the resulting shift level is computed. If
   some  combination  is  omitted the program (subroutine) should
   choose   the   first  level  for  this  combination  (a  quite
   reasonable   behavior).Lets   consider  an  example  with  two
   modifiers   ModOne  and  ModTwo:  type  "..."  {  modifiers  =
   ModOne+ModTwo; map[None] = Level1; map[ModOne] = Level2; }; In
   this case the map statements for ModTwo only and ModOne+ModTwo
   are  omitted.  It  means  that  if  the  ModTwo  is active the
   subroutine  can't  found explicit mapping for such combination
   an  will use the default level i.e. Level1.But in the case the
   type  described as: type "..." { modifiers = ModOne; map[None]
   =  Level1;  map[ModOne]  =  Level2;  }; the ModTwo will not be
   taken  into  account  and  the  resulting level depends on the
   ModOne  state  only.  That  means,  ModTwo  alone produces the
   Level1  but  the combination ModOne+ModTwo produces the Level2
   as  well  as  ModOne  alone.What  does  it  mean if the second
   modifier  is  the  Lock?  It means that in the first case (the
   Lock   itself  is  included  in  the  list  of  modifiers  but
   combinations  with  this  modifier aren't mentioned in the map
   statements)  the internal capitalization rules will be applied
   to the symbol from the first level. But in the second case the
   capitalization   will   be   applied   to  the  symbol  chosen
   accordingly  to he first modifier - and this can be the symbol
   from  the  first as well as from the second level.Usually, all
   modifiers  introduced  in 'modifiers=<list of modifiers>' list
   are  used  for  shift  level  calculation  and then discarded.
   Sometimes this is not desirable. If you want to use a modifier
   for  shift level calculation but you don't want to discard it,
   you may list in 'preserve[<combination of modifiers>]=<list of
   modifiers>'.  That  means,  for a given combination all listed
   modifiers will be preserved. If the Lock modifier is preserved
   then the resulting symbol is passed to internal capitalization
   routine  regardless whether it has been used for a shift level
   calculation  or not.Any key type description can use both real
   and  virtual  modifiers.  Since  real  modifiers  always  have
   standard names it is not necessary to explicitly declare them.
   Virtual modifiers can have arbitrary names and can be declared
   (prior   using   them)   directly   in  key  type  definition:
   virtual_modifiers  <comma-separated  list  of  modifiers> ; as
   seen   in   for  example  basic,  pc  or  mousekeys  key  type
   definitions.RulesOnce  you  are  finished with your symbol map
   you need to add it to rules file. The rules file describes how
   all  the  five  basic  keycodes,  types,  compat,  symbols and
   geometry  components  should  be  composed  to give a sensible
   resulting  xkb  configuration.The main advantage of rules over
   formerly  used keymaps is a possibility to simply parameterize
   (once)  fixed patterns of configurations and thus to elegantly
   allow  substitutions  of  various  local  configurations  into
   predefined  templates.A pattern in a rules file (often located
   in  /usr/lib/X11/xkb/rules)  can  be  parameterized  with four
   other  arguments: Model, Layout, Variant and Options. For most
   cases  parameters  model  and  layout should be sufficient for
   choosing  a  functional keyboard mapping.The rules file itself
   is composed of pattern lines and lines with rules. The pattern
   line  starts  with an exclamation mark ('!') and describes how
   will  the  xkb interpret the following lines (rules). A sample
   rules file looks like this: ! model = keycodes macintosh_old =
   macintosh  ...  *  =  xorg  !  model  = symbols hp = +inet(%m)
   microsoftpro  =  +inet(%m)  geniuscomfy  =  +inet(%m)  ! model
   layout[1]  =  symbols macintosh us = macintosh/us%(v[1]) * * =
   pc/pc(%m)+pc/%l[1]%(v[1])   !   model   layout[2]   =  symbols
   macintosh    us    =    +macintosh/us[2]%(v[2]):2    *   *   =
   +pc/%l[2]%(v[2]):2   !   option   =   types   caps:internal  =
   +caps(internal)            caps:internal_nocancel            =
   +caps(internal_nocancel)   Each   rule  defines  what  certain
   combination  of  values  on  the left side of equal sign ('=')
   results  in.  For  example  a  (keyboard)  model macintosh_old
   instructs  xkb  to  take  definitions  of  keycodes  from file
   keycodes/macintosh  while the rest of models (represented by a
   wild   card   '*')   instructs  it  to  take  them  from  file
   keycodes/xorg. The wild card represents all possible values on
   the  left  side  which  were  not found in any of the previous
   rules.  The more specialized (more complete) rules have higher
   precedence  than  general  ones,  i.e.  the more general rules
   supply  reasonable  default  values.As  you can see some lines
   contain  substitution  parameters - the parameters preceded by
   the percent sign ('%'). The first alphabetical character after
   the  percent sign expands to the value which has been found on
   the  left  side. For example +%l%(v) expands into +cz(bksl) if
   the  respective  values on the left side were cz layout in its
   bksl  variant.  More, if the layout resp. variant parameter is
   followed  by  a  pair of brackets ('[', ']') it means that xkb
   should  place  the  layout  resp.  variant  into specified xkb
   group.  If  the  brackets  are  omitted the first group is the
   default  value.So  the  second  block of rules enhances symbol
   definitions  for  some  particular  keyboard models with extra
   keys  (for  internet, multimedia, ...) . Other models are left
   intact.  Similarly,  the  last  block  overrides some key type
   definitions,  so  the  common global behaviour ''shift cancels
   caps''  or  ''shift doesn't cancel caps'' can be selected. The
   rest  of  rules  produces  special symbols for each variant us
   layout  of  macintosh  keyboard  and  standard  pc  symbols in
   appropriate  variants  as  a  default.  Descriptive  Files  of
   RulesNow  you  just  need  to  add  a  detailed description to
   <rules>.xml  description file so the other users (and external
   programs  which  often parse this file) know what is your work
   about.Old Descriptive FilesThe formerly used descriptive files
   were  named <rules>.lst Its structure is very simple and quite
   self  descriptive  but such simplicity had also some cavities,
   for example there was no way how to describe local variants of
   layouts  and  there  were  problems  with  the localization of
   descriptions.   To  preserve  compatibility  with  some  older
   programs,  new  XML  descriptive files can be converted to old
   format  '.lst'.For  each  parameter  of  rules  file should be
   described  its meaning. For the rules file described above the
   .lst  file  could  look like: ! model pc104 Generic 104-key PC
   microsoft  Microsoft  Natural  pc98  PC-98xx  Series macintosh
   Original  Macintosh  ...  ! layout us U.S. English cz Czech de
   German    ...    !    option   caps:internal   uses   internal
   capitalization. Shift cancels Caps caps:internal_nocancel uses
   internal  capitalization.  Shift  doesn't cancel Caps And that
   should be it. Enjoy creating your own xkb mapping.
