10f8248bfSmrg<?xml version="1.0" encoding="UTF-8" ?>
20f8248bfSmrg<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
30f8248bfSmrg	  "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
4eb411b4bSmrg<chapter id='Virtual_Modifiers'>
5e9fcaa8aSmrg<title>Virtual Modifiers</title>
6e9fcaa8aSmrg
7e9fcaa8aSmrg<para>
8e9fcaa8aSmrgThe core protocol specifies that certain keysyms, when bound to modifiers,
9e9fcaa8aSmrgaffect the rules of keycode to keysym interpretation for all keys; for example,
100f8248bfSmrgwhen the
110f8248bfSmrg<keysym>Num_Lock</keysym>
120f8248bfSmrgkeysym is bound to some modifier, that modifier is used to select between
13e9fcaa8aSmrgshifted and unshifted state for the numeric keypad keys. The core protocol does
14e9fcaa8aSmrgnot provide a convenient way to determine the mapping of modifier bits (in
150f8248bfSmrgparticular
160f8248bfSmrg<symbol>Mod1</symbol>
170f8248bfSmrgthrough
180f8248bfSmrg<symbol>Mod5</symbol>)
190f8248bfSmrgto keysyms such as
200f8248bfSmrg<keysym>Num_Lock</keysym>
210f8248bfSmrgand
220f8248bfSmrg<keysym>Mode_switch</keysym>.
230f8248bfSmrgUsing the core protocol only, a client application must retrieve and search
24e9fcaa8aSmrgthe modifier map to determine the keycodes bound to each modifier, and then
25e9fcaa8aSmrgretrieve and search the keyboard mapping to determine the keysyms bound to the
26e9fcaa8aSmrgkeycodes. It must repeat this process for all modifiers whenever any part of
27e9fcaa8aSmrgthe modifier mapping is changed.
28e9fcaa8aSmrg</para>
29e9fcaa8aSmrg
30e9fcaa8aSmrg
31e9fcaa8aSmrg<para>
32e9fcaa8aSmrgXkb alleviates these problems by defining virtual modifiers. In addition to the
330f8248bfSmrgeight core modifiers, referred to as the
340f8248bfSmrg<firstterm>real modifiers</firstterm>,
350f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifiers">
360f8248bfSmrg<primary>real modifiers</primary></indexterm>
370f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifiers">
380f8248bfSmrg<primary>modifiers</primary><secondary>real</secondary></indexterm>
390f8248bfSmrgXkb provides a set of sixteen named
400f8248bfSmrg<firstterm>virtual modifiers</firstterm>.
410f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifiers">
420f8248bfSmrg<primary>virtual modifiers</primary></indexterm>
430f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifiers">
440f8248bfSmrg<primary>modifiers</primary><secondary>virtual</secondary></indexterm>
450f8248bfSmrgEach virtual modifier can be bound to any set of the real modifiers
460f8248bfSmrg(
470f8248bfSmrg<symbol>Shift</symbol>,
480f8248bfSmrg<symbol>Lock</symbol>,
490f8248bfSmrg<symbol>Control</symbol>,
500f8248bfSmrgand
510f8248bfSmrg<symbol>Mod1</symbol>
520f8248bfSmrg&ndash;
530f8248bfSmrg<symbol>Mod5</symbol>).
540f8248bfSmrg
55e9fcaa8aSmrg</para>
56e9fcaa8aSmrg
57e9fcaa8aSmrg
58e9fcaa8aSmrg<para>
59e9fcaa8aSmrgThe separation of function from physical modifier bindings makes it easier to
60e9fcaa8aSmrgspecify more clearly the intent of a binding. X servers do not all assign
610f8248bfSmrgmodifiers the same way — for example,
620f8248bfSmrg<keysym>Num_Lock</keysym>
630f8248bfSmrgmight be bound to
640f8248bfSmrg<symbol>Mod2</symbol>
650f8248bfSmrgfor one vendor and to
660f8248bfSmrg<symbol>Mod4</symbol>
670f8248bfSmrgfor another. This makes it cumbersome to automatically remap the keyboard to a
68e9fcaa8aSmrgdesired configuration without some kind of prior knowledge about the keyboard
69e9fcaa8aSmrglayout and bindings. With XKB, applications can use virtual modifiers to
70e9fcaa8aSmrgspecify the desired behavior, without regard for the actual physical bindings
71e9fcaa8aSmrgin effect.
72e9fcaa8aSmrg</para>
73e9fcaa8aSmrg
74eb411b4bSmrg<sect1 id='Virtual_Modifier_Names_and_Masks'>
75e9fcaa8aSmrg<title>Virtual Modifier Names and Masks</title>
76e9fcaa8aSmrg
77e9fcaa8aSmrg<para>
780f8248bfSmrgVirtual modifiers are named by converting their string name to an X
790f8248bfSmrg<type>Atom</type>
800f8248bfSmrgand storing the Atom in the
810f8248bfSmrg<structfield>names.vmods</structfield>
820f8248bfSmrgarray in an
830f8248bfSmrg<structname>XkbDescRec</structname>
840f8248bfSmrgstructure (see <link linkend="The_XkbDescRec_Structure">section 6.1</link>). The position of a name Atom in the
850f8248bfSmrg<structfield>names.vmods</structfield>
860f8248bfSmrgarray defines the bit position used to represent the virtual modifier and also
87e9fcaa8aSmrgthe index used when accessing virtual modifier information in arrays: the name
880f8248bfSmrgin the i-th (0 relative) entry of
890f8248bfSmrg<structfield>names.vmods</structfield>
900f8248bfSmrgis the i-th virtual modifier, represented by the mask (1&lt;&lt;i). Throughout
91e9fcaa8aSmrgXkb, various functions have a parameter that is a mask representing virtual
92e9fcaa8aSmrgmodifier choices. In each case, the i-th bit (0 relative) of the mask
93e9fcaa8aSmrgrepresents the i-th virtual modifier.
94e9fcaa8aSmrg</para>
95e9fcaa8aSmrg
96e9fcaa8aSmrg
97e9fcaa8aSmrg<para>
980f8248bfSmrgTo set the name of a virtual modifier, use
990f8248bfSmrg<function>XkbSetNames</function>,
1000f8248bfSmrgusing
1010f8248bfSmrg<symbol>XkbVirtualModNamesMask</symbol>
1020f8248bfSmrgin
1030f8248bfSmrg<parameter>which</parameter>
1040f8248bfSmrgand the name in the
1050f8248bfSmrg<parameter>xkb</parameter>
1060f8248bfSmrgargument; to retrieve indicator names, use
1070f8248bfSmrg<function>XkbGetNames</function>.
1080f8248bfSmrgThese functions are discussed in <xref linkend="Symbolic_Names" />.
109e9fcaa8aSmrg</para>
110e9fcaa8aSmrg
111e9fcaa8aSmrg
112e9fcaa8aSmrg</sect1>
113eb411b4bSmrg<sect1 id='Modifier_Definitions'>
114e9fcaa8aSmrg<title>Modifier Definitions</title>
115e9fcaa8aSmrg
1160f8248bfSmrg<indexterm significance="preferred" zone="Modifier_Definitions">
1170f8248bfSmrg<primary><structname>XkbModsRec</structname></primary></indexterm>
1180f8248bfSmrg
119e9fcaa8aSmrg<para>
1200f8248bfSmrgAn Xkb
1210f8248bfSmrg<firstterm>modifier definition</firstterm>
1220f8248bfSmrg<indexterm significance="preferred" zone="grab_state">
1230f8248bfSmrg<primary>modifier definition</primary></indexterm>
1240f8248bfSmrgenumerates a collection of real and virtual modifiers but does not in itself
125e9fcaa8aSmrgbind those modifiers to any particular key or to each other. Modifier
126e9fcaa8aSmrgdefinitions are included in a number of structures in the keyboard description
127e9fcaa8aSmrgto define the collection of modifiers that affect or are affected by some other
128e9fcaa8aSmrgentity. A modifier definition is relevant only in the context of some other
1290f8248bfSmrgentity such as an indicator map, a control, or a key type. (See
1300f8248bfSmrg<link linkend="XkbIndicatorMapRec">section 8.2.2</link>,
1310f8248bfSmrg<link linkend="The_XkbControlsRec_Structure">section 10.8</link>, and
1320f8248bfSmrg<link linkend="Key_Types">section 15.2</link>.)
133e9fcaa8aSmrg</para>
134e9fcaa8aSmrg
135e9fcaa8aSmrg<para><programlisting>
136e9fcaa8aSmrgtypedef struct _XkbMods {
1370f8248bfSmrg    unsigned char   mask;       /* real_mods | vmods mapped to real modifiers */
1380f8248bfSmrg    unsigned char   real_mods;  /* real modifier bits */
1390f8248bfSmrg    unsigned short  vmods;      /* virtual modifier bits */
1400f8248bfSmrg} <structname>XkbModsRec</structname>, *XkbModsPtr;
141e9fcaa8aSmrg</programlisting></para>
142e9fcaa8aSmrg
143e9fcaa8aSmrg<para>
144e9fcaa8aSmrgAn Xkb modifier definition consists of a set of bit masks corresponding to the
1450f8248bfSmrgeight real modifiers
1460f8248bfSmrg(<structfield>real_mods</structfield>);
1470f8248bfSmrga similar set of bitmasks corresponding to the 16 named virtual modifiers
1480f8248bfSmrg(<structfield>vmods</structfield>);
1490f8248bfSmrgand an effective mask
1500f8248bfSmrg(<structfield>mask</structfield>).
1510f8248bfSmrgThe effective mask represents the set of all real modifiers that can
152e9fcaa8aSmrglogically be set either by setting any of the real modifiers or by setting any
1530f8248bfSmrgof the virtual modifiers in the definition.
1540f8248bfSmrg<structfield>mask</structfield>
1550f8248bfSmrgis derived from the real and virtual modifiers and should never be explicitly
156e9fcaa8aSmrgchanged — it contains all of the real modifiers specified in the definition
1570f8248bfSmrg(<structfield>real_mods</structfield>)
1580f8248bfSmrg<emphasis>plus</emphasis>
1590f8248bfSmrgany real modifiers that are bound to the virtual modifiers specified in the
1600f8248bfSmrgdefinition
1610f8248bfSmrg(<structfield>vmods</structfield>).
1620f8248bfSmrgThe binding of the virtual modifiers to real modifiers is exterior to the
163e9fcaa8aSmrgmodifier definition. Xkb automatically recomputes the mask field of modifier
164e9fcaa8aSmrgdefinitions as necessary. Whenever you access a modifier definition that has
165e9fcaa8aSmrgbeen retrieved using an Xkb library function, the mask field will be correct
166e9fcaa8aSmrgfor the keyboard mapping of interest.
167e9fcaa8aSmrg</para>
168e9fcaa8aSmrg
169e9fcaa8aSmrg
170e9fcaa8aSmrg</sect1>
171eb411b4bSmrg<sect1 id='Binding_Virtual_Modifiers_to_Real_Modifiers'>
172e9fcaa8aSmrg<title>Binding Virtual Modifiers to Real Modifiers</title>
173e9fcaa8aSmrg
174e9fcaa8aSmrg<para>
1750f8248bfSmrgThe binding of virtual modifiers to real modifiers is defined by the
1760f8248bfSmrg<structfield>server.vmods</structfield>
1770f8248bfSmrgarray in an
1780f8248bfSmrg<structname>XkbDescRec</structname>
1790f8248bfSmrgstructure. Each entry contains the real modifier bits that are bound to the
180e9fcaa8aSmrgvirtual modifier corresponding to the entry. The overall relationship of fields
181e9fcaa8aSmrgdealing with virtual modifiers in the server keyboard description are shown in
1820f8248bfSmrg<link linkend="figure16.2">Figure 16.2</link>.
183e9fcaa8aSmrg</para>
184e9fcaa8aSmrg
185e9fcaa8aSmrg
186e9fcaa8aSmrg</sect1>
187eb411b4bSmrg<sect1 id='Virtual_Modifier_Key_Mapping'>
188e9fcaa8aSmrg<title>Virtual Modifier Key Mapping</title>
189e9fcaa8aSmrg
190e9fcaa8aSmrg<para>
1910f8248bfSmrgXkb maintains a
1920f8248bfSmrg<firstterm>virtual modifier mapping</firstterm>,
1930f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifier_Key_Mapping">
1940f8248bfSmrg<primary>virtual modifier mapping</primary></indexterm>
1950f8248bfSmrg<indexterm significance="preferred" zone="Virtual_Modifier_Key_Mapping">
1960f8248bfSmrg<primary>modifiers</primary><secondary>virtual mapping</secondary></indexterm>
1970f8248bfSmrgwhich lists the virtual modifiers associated with, or bound to, each key. The
198e9fcaa8aSmrgreal modifiers bound to a virtual modifier always include all of the modifiers
199e9fcaa8aSmrgbound to any of the keys that specify that virtual modifier in their virtual
2000f8248bfSmrgmodifier mapping. The
2010f8248bfSmrg<structfield>server.vmodmap</structfield>
2020f8248bfSmrgarray indicates which virtual modifiers are bound to each key; each entry is a
2030f8248bfSmrgbitmask for the virtual modifier bits. The
2040f8248bfSmrg<structfield>server.vmodmap</structfield>
2050f8248bfSmrgarray is indexed by keycode.
206e9fcaa8aSmrg</para>
207e9fcaa8aSmrg
208e9fcaa8aSmrg
209e9fcaa8aSmrg<para>
2100f8248bfSmrgThe
2110f8248bfSmrg<structfield>vmodmap</structfield>
2120f8248bfSmrgand
2130f8248bfSmrg<structfield>vmods</structfield>
2140f8248bfSmrgmembers of the server map are the <quote>master</quote> virtual modifier definitions. Xkb
215e9fcaa8aSmrgautomatically propagates any changes to these fields to all other fields that
2160f8248bfSmrguse virtual modifier mappings (see <link linkend="Virtual_Modifier_Mapping">section 16.4</link>).
217e9fcaa8aSmrg</para>
218e9fcaa8aSmrg
219e9fcaa8aSmrg
220e9fcaa8aSmrg<para>
2210f8248bfSmrgFor example, if
2220f8248bfSmrg<symbol>Mod3</symbol>
2230f8248bfSmrgis bound to the
2240f8248bfSmrg<keysym>Num_Lock</keysym>
2250f8248bfSmrgkey by the core protocol modifier mapping, and the
2260f8248bfSmrg<emphasis>NumLock</emphasis>
2270f8248bfSmrgvirtual modifier is bound to they
2280f8248bfSmrg<keysym>Num_Lock</keysym>
2290f8248bfSmrgkey by the virtual modifier mapping,
2300f8248bfSmrg<symbol>Mod3</symbol>
2310f8248bfSmrgis added to the set of modifiers associated with
2320f8248bfSmrg<emphasis>NumLock</emphasis>.
233e9fcaa8aSmrg</para>
234e9fcaa8aSmrg
235e9fcaa8aSmrg
236e9fcaa8aSmrg<para>
237e9fcaa8aSmrgThe virtual modifier mapping is normally updated whenever actions are
2380f8248bfSmrgautomatically applied to symbols (see <link linkend="Virtual_Modifier_Mapping">section 16.4</link> for details), and few
239e9fcaa8aSmrgapplications should need to change the virtual modifier mapping explicitly.
240e9fcaa8aSmrg</para>
241e9fcaa8aSmrg
242e9fcaa8aSmrg
243e9fcaa8aSmrg<para>
2440f8248bfSmrgUse
2450f8248bfSmrg<function>XkbGetMap</function>
2460f8248bfSmrg(see <link linkend="Getting_Map_Components_from_the_Server">section 14.2</link>) to get the virtual modifiers from the server or use
2470f8248bfSmrg<function>XkbGetVirtualMods</function>
2480f8248bfSmrg(see <link linkend="Obtaining_Virtual_Modifier_Bindings_from_the_Server">section 16.4.1</link>) to update a local copy of the virtual modifiers bindings
249e9fcaa8aSmrgfrom the server. To set the binding of a virtual modifier to a real modifier,
2500f8248bfSmrguse
2510f8248bfSmrg<function>XkbSetMap</function>
2520f8248bfSmrg(see
2530f8248bfSmrg<link linkend="Changing_Map_Components_in_the_Server">section 14.3</link>).
254e9fcaa8aSmrg</para>
255e9fcaa8aSmrg
256e9fcaa8aSmrg
257e9fcaa8aSmrg<para>
258e9fcaa8aSmrgTo determine the mapping of virtual modifiers to core X protocol modifiers, use
2590f8248bfSmrg<function>XkbVirtualModsToReal</function>.
260e9fcaa8aSmrg</para>
261e9fcaa8aSmrg
2620f8248bfSmrg<indexterm significance="preferred" zone="XkbVirtualModsToReal"><primary><function>XkbVirtualModsToReal</function></primary></indexterm>
2630f8248bfSmrg<funcsynopsis id="XkbVirtualModsToReal">
2640f8248bfSmrg  <funcprototype>
2650f8248bfSmrg    <funcdef>Bool <function>XkbVirtualModsToReal</function></funcdef>
2660f8248bfSmrg<!-- (
2670f8248bfSmrg<parameter>xkb, virtual_mask, mask_rtrn</parameter>
2680f8248bfSmrg) -->
2690f8248bfSmrg
2700f8248bfSmrg    <paramdef>XkbDescPtr <parameter>xkb</parameter></paramdef>
2710f8248bfSmrg    <paramdef>unsigned int <parameter>virtual_mask</parameter></paramdef>
2720f8248bfSmrg    <paramdef>unsigned int *<parameter>mask_rtrn</parameter></paramdef>
2730f8248bfSmrg  </funcprototype>
2740f8248bfSmrg</funcsynopsis>
2750f8248bfSmrg<variablelist>
2760f8248bfSmrg  <varlistentry>
2770f8248bfSmrg    <term>
2780f8248bfSmrg      <parameter>xkb</parameter>
2790f8248bfSmrg    </term>
2800f8248bfSmrg    <listitem>
2810f8248bfSmrg      <para>
2820f8248bfSmrg        keyboard description for input device
2830f8248bfSmrg      </para>
2840f8248bfSmrg    </listitem>
2850f8248bfSmrg  </varlistentry>
2860f8248bfSmrg  <varlistentry>
2870f8248bfSmrg    <term>
2880f8248bfSmrg      <parameter>virtual_mask</parameter>
2890f8248bfSmrg    </term>
2900f8248bfSmrg    <listitem>
2910f8248bfSmrg      <para>
2920f8248bfSmrg        virtual modifier mask to translate
2930f8248bfSmrg      </para>
2940f8248bfSmrg    </listitem>
2950f8248bfSmrg  </varlistentry>
2960f8248bfSmrg  <varlistentry>
2970f8248bfSmrg    <term>
2980f8248bfSmrg      <parameter>mask_rtrn</parameter>
2990f8248bfSmrg    </term>
3000f8248bfSmrg    <listitem>
3010f8248bfSmrg      <para>
3020f8248bfSmrg        backfilled with real modifiers
3030f8248bfSmrg      </para>
3040f8248bfSmrg    </listitem>
3050f8248bfSmrg  </varlistentry>
3060f8248bfSmrg</variablelist>
307e9fcaa8aSmrg
308e9fcaa8aSmrg<para>
3090f8248bfSmrgIf the keyboard description defined by
3100f8248bfSmrg<parameter>xkb</parameter>
3110f8248bfSmrgincludes bindings for virtual modifiers,
3120f8248bfSmrg<function>XkbVirtualModsToReal</function>
3130f8248bfSmrguses those bindings to determine the set of real modifiers that correspond to
3140f8248bfSmrgthe set of virtual modifiers specified in
3150f8248bfSmrg<parameter>virtual_mask</parameter>.
3160f8248bfSmrgThe
3170f8248bfSmrg<parameter>virtual_mask</parameter>
3180f8248bfSmrgparameter is a mask specifying the virtual modifiers to translate; the i-th
3190f8248bfSmrgbit (0 relative) of the mask represents the i-th virtual modifier. If
3200f8248bfSmrg<parameter>mask_rtrn</parameter>
3210f8248bfSmrgis non-
3220f8248bfSmrg<symbol>NULL</symbol>,
3230f8248bfSmrg<function>XkbVirtualModsToReal</function>
3240f8248bfSmrgbackfills it with the resulting real modifier mask. If the keyboard
3250f8248bfSmrgdescription in
3260f8248bfSmrg<parameter>xkb</parameter>
3270f8248bfSmrgdoes not include virtual modifier bindings,
3280f8248bfSmrg<function>XkbVirtualModsToReal</function>
3290f8248bfSmrgreturns
3300f8248bfSmrg<symbol>False</symbol>;
3310f8248bfSmrgotherwise, it returns
3320f8248bfSmrg<symbol>True</symbol>.
333e9fcaa8aSmrg</para>
334e9fcaa8aSmrg
335e9fcaa8aSmrg<note><para>It is possible for a local (client-side) keyboard description (the
3360f8248bfSmrg<parameter>xkb</parameter>
3370f8248bfSmrgparameter) to not contain any virtual modifier information (simply because the
338e9fcaa8aSmrgclient has not requested it) while the server’s corresponding definition may
339e9fcaa8aSmrgcontain virtual modifier information. </para></note>
340e9fcaa8aSmrg
341e9fcaa8aSmrg
342eb411b4bSmrg<sect2 id='Inactive_Modifier_Sets'>
343e9fcaa8aSmrg<title>Inactive Modifier Sets</title>
344e9fcaa8aSmrg
345e9fcaa8aSmrg<para>
346e9fcaa8aSmrgAn unbound virtual modifier is one that is not bound to any real modifier
3470f8248bfSmrg(
3480f8248bfSmrg<structfield>server</structfield>-&gt;<structfield>vmods</structfield>
349e9fcaa8aSmrg[virtual_modifier_index] is zero).
350e9fcaa8aSmrg</para>
351e9fcaa8aSmrg
352e9fcaa8aSmrg
353e9fcaa8aSmrg<para>
354e9fcaa8aSmrgSome Xkb operations ignore modifier definitions in which the virtual modifiers
355e9fcaa8aSmrgare unbound. Consider this example:
356e9fcaa8aSmrg
3570f8248bfSmrg<literallayout>        if (state matches {Shift}) Do OneThing;
3580f8248bfSmrg        if (state matches {Shift+NumLock}) Do Another;
359e9fcaa8aSmrg</literallayout>
3600f8248bfSmrg</para>
361e9fcaa8aSmrg
362e9fcaa8aSmrg<para>
3630f8248bfSmrgIf the
3640f8248bfSmrg<emphasis>NumLock</emphasis>
3650f8248bfSmrgvirtual modifier is not bound to any real modifiers, the effective masks for
3660f8248bfSmrgthese two cases are identical (that is, contain only
3670f8248bfSmrg<symbol>Shift</symbol>).
3680f8248bfSmrgWhen it is essential to distinguish between
3690f8248bfSmrg<emphasis>OneThing</emphasis>
3700f8248bfSmrgand Another, Xkb considers only those modifier definitions for which all
371e9fcaa8aSmrgvirtual modifiers are bound.
372e9fcaa8aSmrg</para>
373e9fcaa8aSmrg
374e9fcaa8aSmrg
375e9fcaa8aSmrg</sect2>
376e9fcaa8aSmrg</sect1>
377eb411b4bSmrg<sect1 id='Conventions'>
378e9fcaa8aSmrg<title>Conventions</title>
379e9fcaa8aSmrg
3800f8248bfSmrg<indexterm significance="preferred" zone="Conventions">
3810f8248bfSmrg<primary>modifiers</primary><secondary>names</secondary></indexterm>
3820f8248bfSmrg
383e9fcaa8aSmrg<para>
384e9fcaa8aSmrgThe Xkb extension does not require any specific virtual modifier names.
385e9fcaa8aSmrgHowever, everyone benefits if the same names are used for common modifiers. The
386e9fcaa8aSmrgfollowing names are suggested:
387e9fcaa8aSmrg
3880f8248bfSmrg  <simplelist type='vert' columns='1'>
3890f8248bfSmrg    <member><emphasis>NumLock</emphasis></member>
3900f8248bfSmrg    <member><emphasis>ScrollLock</emphasis></member>
3910f8248bfSmrg    <member><emphasis>Alt</emphasis></member>
3920f8248bfSmrg    <member><emphasis>Meta</emphasis></member>
3930f8248bfSmrg    <member><emphasis>AltGr</emphasis></member>
3940f8248bfSmrg    <member><emphasis>LevelThree</emphasis></member>
3950f8248bfSmrg  </simplelist>
3960f8248bfSmrg</para>
397e9fcaa8aSmrg
398e9fcaa8aSmrg</sect1>
399eb411b4bSmrg<sect1 id='Example'>
400e9fcaa8aSmrg<title>Example</title>
401e9fcaa8aSmrg
402e9fcaa8aSmrg<para>
4030f8248bfSmrgIf the second (0-relative) entry in
4040f8248bfSmrg<structfield>names.vmods</structfield>
4050f8248bfSmrgcontains the Atom for "NumLock", then 0x4 (1&lt;&lt;2) is the virtual modifier
4060f8248bfSmrgbit for the
4070f8248bfSmrg<emphasis>NumLock</emphasis>
4080f8248bfSmrgvirtual modifier. If
4090f8248bfSmrg<structfield>server.vmods</structfield>
4100f8248bfSmrg[2] contains
4110f8248bfSmrg<symbol>Mod3Mask</symbol>,
4120f8248bfSmrgthen the
4130f8248bfSmrg<emphasis>NumLock</emphasis>
4140f8248bfSmrgvirtual modifier is bound to the
4150f8248bfSmrg<symbol>Mod3</symbol>
4160f8248bfSmrgreal modifier.
417e9fcaa8aSmrg</para>
418e9fcaa8aSmrg
419e9fcaa8aSmrg
420e9fcaa8aSmrg<para>
421e9fcaa8aSmrgA virtual modifier definition for this example would have:
422e9fcaa8aSmrg</para>
423e9fcaa8aSmrg
424e9fcaa8aSmrg<literallayout class='monospaced'>
425e9fcaa8aSmrg     real_mods = 0
426e9fcaa8aSmrg     vmods = 0x4 (NumLock named virtual modifier)
427e9fcaa8aSmrg     mask = 0x20 (Mod3Mask)
428e9fcaa8aSmrg</literallayout>
429e9fcaa8aSmrg
430e9fcaa8aSmrg<para>
4310f8248bfSmrgContinuing the example, if the keyboard has a
4320f8248bfSmrg<keysym>Num_Lock</keysym>
4330f8248bfSmrgkeysym bound to the key with keycode 14, and the
4340f8248bfSmrg<emphasis>NumLock</emphasis>
4350f8248bfSmrgvirtual modifier is bound to this key,
4360f8248bfSmrg<structfield>server.vmodmap[14]</structfield>
4370f8248bfSmrgcontains 0x4.
438e9fcaa8aSmrg</para>
439e9fcaa8aSmrg
440e9fcaa8aSmrg
441e9fcaa8aSmrg<para>
4420f8248bfSmrgFinally, if the keyboard also used the real
4430f8248bfSmrg<symbol>Mod1</symbol>
4440f8248bfSmrgmodifier for numeric lock operations, the modifier definition below would
4450f8248bfSmrgrepresent the situation where either the key bound to
4460f8248bfSmrg<symbol>Mod1</symbol>
4470f8248bfSmrgor the
4480f8248bfSmrg<emphasis>NumLock</emphasis>
4490f8248bfSmrgvirtual modifier could be used for this purpose:
450e9fcaa8aSmrg</para>
451e9fcaa8aSmrg
452e9fcaa8aSmrg<literallayout class='monospaced'>
453e9fcaa8aSmrg     real_mods = 0x8 (Mod1Mask)
454e9fcaa8aSmrg     vmods = 0x4 (NumLock named virtual modifier)
455e9fcaa8aSmrg     mask = 0x28 (Mod1Mask | Mod3Mask)
456e9fcaa8aSmrg</literallayout>
457e9fcaa8aSmrg</sect1>
458e9fcaa8aSmrg</chapter>
459