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– 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<<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>-><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<<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