summaryrefslogtreecommitdiff
path: root/specs/ch06.xml
diff options
context:
space:
mode:
Diffstat (limited to 'specs/ch06.xml')
-rw-r--r--specs/ch06.xml1765
1 files changed, 1765 insertions, 0 deletions
diff --git a/specs/ch06.xml b/specs/ch06.xml
new file mode 100644
index 0000000..74a8e3c
--- /dev/null
+++ b/specs/ch06.xml
@@ -0,0 +1,1765 @@
+<chapter id='key_event_processing_in_the_server'>
+<title>Key Event Processing in the Server</title>
+
+<para>
+This section describes the steps involved in processing a key event within the
+server when XKB is present. Key events can be generated due to keyboard
+activity and passed to XKB by the DDX layer, or they can be synthesized by
+another extension, such as XTEST.
+</para>
+
+<sect1 id='applying_global_controls'>
+<title>Applying Global Controls</title>
+
+<para>
+When the X Keyboard Extension receives a key event, it first checks the global
+key controls to decide whether to process the event immediately or at all. The
+global key controls which might affect the event, in descending order of
+priority, are:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>If a key is pressed while the <emphasis>
+BounceKeys</emphasis>
+ control is enabled, the extension generates the event only if the key is
+active. When a key is released, the server deactivates the key and starts a
+<emphasis>
+bounce keys timer</emphasis>
+ with an interval specified by the debounce delay.
+ </para>
+ <para>
+If the bounce keys timer expires or if some other key is pressed before the
+timer expires, the server reactivates the corresponding key and deactivates the
+timer. Neither expiration nor deactivation of a bounce keys timer causes an
+event.</para>
+</listitem>
+<listitem>
+ <para>If the <emphasis>
+SlowKeys</emphasis>
+ control is enabled, the extension sets a <emphasis>
+slow keys timer</emphasis>
+ with an interval specified by the slow keys delay, but does not process the
+key event immediately. The corresponding key release deactivates this timer.
+ </para>
+ <para>
+If the slow keys timer expires, the server generates a key press for the
+corresponding key, sends an <emphasis>
+XkbAccessXNotify</emphasis>
+ and deactivates the timer.
+ </para>
+</listitem>
+<listitem>
+ <para>The extension processes key press events normally whether or not the
+<emphasis>
+RepeatKeys</emphasis>
+ control is active, but if <emphasis>
+RepeatKeys</emphasis>
+ are enabled and per-key autorepeat is enabled for the event key, the extension
+processes key press events normally, but it also initiates an <emphasis>
+autorepeat timer</emphasis>
+ with an interval specified by the autorepeat delay. The corresponding key
+release deactivates the timer.
+ </para>
+ <para>
+If the autorepeat timer expires, the server generates a key release and a key
+press for the corresponding key and reschedules the timer according to the
+autorepeat interval.
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+Key events are processed by each global control in turn: if the <emphasis>
+BounceKeys</emphasis>
+ control accepts a key event, <emphasis>
+SlowKeys</emphasis>
+ considers it. Once <emphasis>
+SlowKeys</emphasis>
+ allows or synthesizes an event, the <emphasis>
+RepeatKeys</emphasis>
+ control acts on it.
+</para>
+
+
+</sect1>
+<sect1 id='key_behavior'>
+<title>Key Behavior</title>
+
+<para>
+Once an event is accepted by all of the controls or generated by a timer, the
+server checks the per-key behavior of the corresponding key. This extension
+currently defines the following key behaviors:
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='2'>
+<colspec align="left" colsep="0"/>
+<colspec align="left" colsep="0"/>
+<thead>
+ <row rowsep='1'>
+ <entry>Behavior</entry>
+ <entry>Effect</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry><emphasis>
+KB_Default</emphasis>
+ </entry>
+ <entry>Press and release events are processed normally.</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>
+KB_Lock</emphasis>
+ </entry>
+ <entry>If a key is logically up (i.e. the corresponding bit of the core key
+map is cleared) when it is pressed, the key press is processed normally and the
+corresponding release is ignored. If the key is logically down when pressed,
+the key press is ignored but the corresponding release is processed normally.
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+KB_RadioGroup
+</emphasis>
+ </para>
+ <para>
+ flags: CARD8
+ </para>
+ <para>
+ index: CARD8
+ </para>
+ </entry>
+ <entry><para>If another member of the radio group specified by <emphasis>
+index</emphasis>
+ is logically down when a key is pressed, the server synthesizes a key release
+for the member that is logically down and then processes the new key press
+event normally. </para>
+<para>
+If the key itself is logically down when pressed, the key press event is
+ignored, but the processing of the corresponding key release depends on the
+value of the <emphasis>
+RGAllowNone</emphasis>
+ bit in <emphasis>
+flags</emphasis>
+. If it is set, the key release is processed normally; otherwise the key
+release is also ignored.
+</para>
+<para>
+All other key release events are ignored.</para>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+KB_Overlay1
+</emphasis>
+ </para>
+ <para>
+ key: KEYCODE
+ </para>
+ </entry>
+ <entry>If the <emphasis>
+Overlay1</emphasis>
+ control is enabled, events from this key are reported as if they came from the
+key specified in <emphasis>
+key</emphasis>
+. Otherwise, press and release events are processed normally.</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+KB_Overlay2
+</emphasis>
+ </para>
+ <para>
+ key: KEYCODE
+ </para>
+ </entry>
+ <entry>If the <emphasis>
+Overlay2</emphasis>
+ control is enabled, events from this key are reported as if they came from the
+key specified in <emphasis>
+key</emphasis>
+. Otherwise, press and release events are processed normally.</entry>
+ </row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+The X server uses key behavior to determine whether to process or filter out
+any given key event; key behavior is independent of keyboard modifier or group
+state (each key has exactly one behavior.
+</para>
+
+<para>
+Key behaviors can be used to simulate any of these types of keys or to indicate
+an unmodifiable physical, electrical or software driver characteristic of a
+key. An optional <emphasis>
+permanent</emphasis>
+ flag can modify any of the supported behaviors and indicates that behavior
+describes an unalterable physical, electrical or software aspect of the
+keyboard. Permanent behaviors cannot be changed or set by the <emphasis>
+XkbSetMap</emphasis>
+ request. The <emphasis>
+permanent</emphasis>
+ flag indicates a characteristic of the underlying system that XKB cannot
+affect, so XKB treats all permanent behaviors as if they were <emphasis>
+KB_Default</emphasis>
+ and does not filter key events described in the table above.
+</para>
+
+
+</sect1>
+<sect1 id='key_actions'>
+<title>Key Actions</title>
+
+<para>
+Once the server has applied the global controls and per-key behavior and has
+decided to process a key event, it applies <emphasis>
+key actions</emphasis>
+ to determine the effects of the key on the internal state of the server. A key
+action consists of an operator and some optional data. XKB supports actions
+which:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>change base, latched or locked modifiers or group
+ </para>
+</listitem>
+<listitem>
+ <para>move the core pointer or simulate core pointer button events
+ </para>
+</listitem>
+<listitem>
+ <para>change most aspects of keyboard behavior
+ </para>
+</listitem>
+<listitem>
+ <para>terminate or suspend the server
+ </para>
+</listitem>
+<listitem>
+ <para>send a message to interested clients
+ </para>
+</listitem>
+<listitem>
+ <para>simulate events on other keys
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+Each key has an optional list of actions. If present, this list parallels the
+list of symbols associated with the key (i.e. it has one action per symbol
+associated with the key). For key press events, the server looks up the action
+to be applied from this list using the key symbol mapping associated with the
+event key, just as a client looks up symbols as described in <ulink
+url="XKBproto.htm#50332257_24122">See Determining the KeySym Associated with a
+Key Event</ulink>; if the event key does not have any actions, the server uses
+the <emphasis>
+SA_NoAction</emphasis>
+ event for that key regardless of modifier or group state.
+</para>
+
+
+<para>
+Key actions have essentially two halves; the effects on the server when the key
+is pressed and the effects when the key is released. The action applied for a
+key press event determines the further actions, if any, that are applied to the
+corresponding release event or to events that occur while the key is held down.
+Clients can change the actions associated with a key while the key is down
+without changing the action applied next time the key is released; subsequent
+press-release pairs will use the newly bound key action.
+</para>
+
+
+<para>
+Most actions directly change the state of the keyboard or server; some actions
+also modify other actions that occur simultaneously with them. Two actions
+occur simultaneously if the keys which invoke the actions are both logically
+down at the same time, regardless of the order in which they are pressed or
+delay between the activation of one and the other.
+</para>
+
+
+<para>
+Most actions which affect keyboard modifier state accept a modifier definition
+(see <ulink url="XKBproto.htm#50332257_51617">See Virtual Modifiers</ulink>)
+named <emphasis>
+mods</emphasis>
+ and a boolean flag name <emphasis>
+useModMap</emphasis>
+ among their arguments. These two fields combine to specify the modifiers
+affected by the action as follows: If <emphasis>
+useModMap</emphasis>
+ is <emphasis>
+True</emphasis>
+, the action sets any modifiers bound by the modifier mapping to the key that
+initiated the action; otherwise, the action sets the modifiers specified by
+<emphasis>
+mods</emphasis>
+. For brevity in the text of the following definitions, we refer to this
+combination of <emphasis>
+useModMap</emphasis>
+ and <emphasis>
+mods</emphasis>
+ as the "action modifiers."
+</para>
+
+
+<para>
+The X Keyboard Extension supports the following actions:
+</para>
+
+<informaltable frame='none'>
+<tgroup cols='2'>
+<colspec align="left" colsep="0"/>
+<colspec align="left" colsep="0"/>
+<thead>
+ <row rowsep='1'>
+ <entry>Action</entry>
+ <entry>Effect</entry>
+ </row>
+</thead>
+<tbody>
+ <row rowsep='0'>
+ <entry><emphasis>SA_NoAction</emphasis></entry>
+ <entry>
+ <itemizedlist>
+ <listitem>
+ <para>
+No direct effect, though <emphasis>SA_NoAction</emphasis>
+ events may change the effect of other server actions (see below).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>SA_SetMods</emphasis>
+ </para>
+ <para>
+ mods: MOD_DEF
+ </para>
+ <para>
+ useModMap: BOOL
+ </para>
+ <para>
+ clearLocks: BOOL
+ </para>
+ </entry>
+ <entry>
+ <itemizedlist>
+ <listitem>
+ <para>
+Key press adds any action modifiers to the keyboard’s base modifiers<emphasis>.</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Key release clears any action modifiers in the keyboard’s base
+modifiers, provided that no other key which affects the same modifiers is
+logically down.
+ </para>
+ </listitem>
+ <listitem>
+ <para>If no keys were operated simultaneously with this key and <emphasis>
+clearLocks</emphasis>
+ is set, release unlocks any action modifiers.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LatchMods
+</emphasis>
+ </para>
+ <para>
+ mods: MOD_DEF
+ </para>
+ <para>
+ useModMap: BOOL
+ </para>
+ <para>
+ clearLocks: BOOL
+ </para>
+ <para>
+ latchToLock: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>Key press and release events have the same effect as for <emphasis>
+SA_SetMods</emphasis>
+; if no keys were operated simultaneously with the latching modifier key, key
+release events have the following additional effects:
+ </para>
+</listitem>
+<listitem>
+ <para>Modifiers that were unlocked due to <emphasis>
+clearLocks</emphasis>
+ have no further effect.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+latchToLock</emphasis>
+ is set, key release locks and then unlatches any remaining action modifiers
+that are already latched.
+ </para>
+</listitem>
+<listitem>
+ <para>Finally, key release latches any action modifiers that were not used by
+the <emphasis>
+clearLocks</emphasis>
+ or <emphasis>
+latchToLock</emphasis>
+ flags.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LockMods
+ </emphasis>
+ </para>
+ <para>
+ mods: MOD_DEF
+ </para>
+ <para>
+ useModMap: BOOL
+ </para>
+ <para>
+ noLock: BOOL
+ </para>
+ <para>
+ noUnlock: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>Key press sets the base and possibly the locked state of any action
+modifiers. If <emphasis>
+noLock</emphasis>
+ is <emphasis>
+True</emphasis>
+, only the base state is changed.
+ </para>
+</listitem>
+<listitem>
+ <para>For key release events, clears any action modifiers in the keyboard’s
+base modifiers, provided that no other key which affects the same modifiers is
+down. If <emphasis>
+noUnlock</emphasis>
+ is <emphasis>
+False</emphasis>
+ and any of the action modifiers were locked before the corresponding key press
+occurred, key release unlocks them.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_SetGroup
+</emphasis>
+ </para>
+ <para>
+ group: INT8
+ </para>
+ <para>
+ groupAbsolute: BOOL
+ </para>
+ <para>
+ clearLocks: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+groupAbsolute</emphasis>
+ is set, key press events change the base keyboard group to <emphasis>
+group</emphasis>
+; otherwise, they add <emphasis>
+group</emphasis>
+ to the base keyboard group. In either case, the resulting effective keyboard
+group is brought back into range depending on the value of the <emphasis>
+GroupsWrap</emphasis>
+ control for the keyboard.
+ </para>
+</listitem>
+<listitem>
+ <para>If an <emphasis>
+SA_ISOLock</emphasis>
+ key is pressed while this key is held down, key release has no effect,
+otherwise it cancels the effects of the press.
+ </para>
+</listitem>
+<listitem>
+ <para>If no keys were operated simultaneously with this key and <emphasis>
+clearLocks</emphasis>
+ is set, key release also sets the locked keyboard group to <emphasis>
+Group1</emphasis>
+.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LatchGroup
+ </emphasis>
+ </para>
+ <para>
+ group: INT8
+ </para>
+ <para>
+ groupAbsolute: BOOL
+ </para>
+ <para>
+ clearLocks: BOOL
+ </para>
+ <para>
+ latchToLock: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>Key press and release events have the same effect as an <emphasis>
+SA_SetGroup</emphasis>
+ action; if no keys were operated simultaneously with the latching group key
+and the <emphasis>
+clearLocks</emphasis>
+ flag was not set or had no effect, key release has the following additional
+effects:
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+latchToLock</emphasis>
+ is set and the latched keyboard group is non-zero, the key release adds the
+delta applied by the corresponding key press to the locked keyboard group and
+subtracts it from the latched keyboard group. The locked and effective keyboard
+group are brought back into range according to the value of the global
+<emphasis>
+GroupsWrap</emphasis>
+ control for the keyboard.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, key release adds the key press delta to the latched keyboard
+group.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LockGroup
+ </emphasis>
+ </para>
+ <para>
+ group: INT8
+ </para>
+ <para>
+ groupAbsolute: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+groupAbsolute</emphasis>
+ is set, key press sets the locked keyboard group to <emphasis>
+group</emphasis>
+. Otherwise, key press adds <emphasis>
+group</emphasis>
+ to the locked keyboard group. In either case, the resulting locked and
+effective group is brought back into range depending on the value of the
+<emphasis>
+GroupsWrap</emphasis>
+ control for the keyboard.
+ </para>
+</listitem>
+<listitem>
+ <para>Key release has no effect.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_MovePtr
+</emphasis>
+ </para>
+ <para>
+ x, y: INT16
+ </para>
+ <para>
+ noAccel: BOOL
+ </para>
+ <para>
+ absoluteX: BOOL
+ </para>
+ <para>
+ absoluteY: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+MouseKeys</emphasis>
+ are not enabled, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+, otherwise this action cancels any pending repeat key timers for this key and
+has the following additional effects.
+ </para>
+</listitem>
+<listitem>
+ <para>Key press generates a core pointer <emphasis>
+MotionNotify</emphasis>
+ event instead of the usual <emphasis>
+KeyPress</emphasis>
+. If <emphasis>
+absoluteX</emphasis>
+ is <emphasis>
+True</emphasis>
+, <emphasis>
+x</emphasis>
+ specifies the new pointer X coordinate, otherwise <emphasis>
+x</emphasis>
+ is added to the current pointer X coordinate; <emphasis>
+absoluteY</emphasis>
+ and <emphasis>
+y</emphasis>
+ specify the new Y coordinate in the same way.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+noAccel</emphasis>
+ is <emphasis>
+False</emphasis>
+, and the <emphasis>
+MouseKeysAccel</emphasis>
+ keyboard control is enabled, key press also initiates the mouse keys timer for
+this key; every time this timer expires, the cursor moves again. The distance
+the cursor moves in these subsequent events is determined by the mouse keys
+acceleration as described in <ulink url="XKBproto.htm#50332257_29074">See The
+MouseKeysAccel Control</ulink>.
+ </para>
+</listitem>
+<listitem>
+ <para>Key release disables the mouse keys timer (if it was initiated by the
+corresponding key press) but has no other effect and is ignored (does not
+generate an event of any type).
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_PtrBtn
+ </emphasis>
+ </para>
+ <para>
+ button: CARD8
+ </para>
+ <para>
+ count: CARD8
+ </para>
+ <para>
+ useDfltBtn: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+MouseKeys</emphasis>
+ are not enabled, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+useDfltBtn</emphasis>
+ is set, the event is generated for the current default core button. Otherwise,
+the event is generated for the button specified by <emphasis>
+button</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>If the mouse button specified for this action is logically down, the
+key press and corresponding release are ignored and have no effect.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, key press causes one or more core pointer button events
+instead of the usual key press. If <emphasis>
+count</emphasis>
+ is <emphasis>
+0</emphasis>
+, key press generates a single <emphasis>
+ButtonPress</emphasis>
+ event; if <emphasis>
+count</emphasis>
+ is greater than <emphasis>
+0</emphasis>
+, key press generates <emphasis>
+count</emphasis>
+ pairs of <emphasis>
+ButtonPress</emphasis>
+ and <emphasis>
+ButtonRelease</emphasis>
+ events.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+count</emphasis>
+ is <emphasis>
+0</emphasis>
+, key release generates a core pointer <emphasis>
+ButtonRelease</emphasis>
+ which matches the event generated by the corresponding key press; if count is
+non-zero, key release does not cause a <emphasis>
+ButtonRelease</emphasis>
+ event. Key release never causes a key release event.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LockPtrBtn
+</emphasis>
+ </para>
+ <para>
+ button: BUTTON
+ </para>
+ <para>
+ noLock: BOOL
+ </para>
+ <para>
+ noUnlock: BOOL
+ </para>
+ <para>
+ useDfltBtn: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+MouseKeys</emphasis>
+ are not enabled, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, if the button specified by <emphasis>
+useDfltBtn</emphasis>
+ and <emphasis>
+button</emphasis>
+ is not locked, key press causes a <emphasis>
+ButtonPress</emphasis>
+ instead of a key press and locks the button. If the button is already locked
+or if <emphasis>
+noLock</emphasis>
+ is <emphasis>
+True</emphasis>
+, key press is ignored and has no effect.
+ </para>
+</listitem>
+<listitem>
+ <para>If the corresponding key press was ignored, and if <emphasis>
+noUnlock</emphasis>
+ is <emphasis>
+False</emphasis>
+, key release generates a <emphasis>
+ButtonRelease</emphasis>
+ event instead of a key release event and unlocks the specified button. If the
+corresponding key press locked a button, key release is ignored and has no
+effect.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_SetPtrDflt
+</emphasis>
+ </para>
+ <para>
+ affect: CARD8
+ </para>
+ <para>
+ value: CARD8
+ </para>
+ <para>
+ dfltBtnAbs: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+MouseKeys</emphasis>
+ are not enabled, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, both key press and key release are ignored, but key press
+changes the pointer value specified by <emphasis>
+affect </emphasis>
+to <emphasis>
+value</emphasis>
+, as follows:
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+which</emphasis>
+ is <emphasis>
+SA_AffectDfltBtn</emphasis>
+, <emphasis>
+value</emphasis>
+ and <emphasis>
+dfltBtnAbs</emphasis>
+ specify the default pointer button used by the various pointer actions as
+follow: If <emphasis>
+dfltBtnAbs </emphasis>
+is True, value specifies the button to be used, otherwise, <emphasis>
+value</emphasis>
+ specifies the amount to be added to the current default button. In either
+case, illegal button choices are wrapped back into range.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_ISOLock
+</emphasis>
+ </para>
+ <para>
+ dfltIsGroup: <emphasis>
+False
+</emphasis>
+ </para>
+ <para>
+ mods: MOD_DEF
+ </para>
+ <para>
+ useModMap: BOOL
+ </para>
+ <para>
+ noLock: BOOL
+ </para>
+ <para>
+ noUnlock: BOOL
+ </para>
+ <para>
+ noAffectMods: BOOL
+ </para>
+ <para>
+ noAffectGrp: BOOL
+ </para>
+ <para>
+ noAffectPtr: BOOL
+ </para>
+ <para>
+ noAffectCtrls: BOOL
+ </para>
+ <para>
+or
+ </para>
+ <para>
+ dfltIsGroup: <emphasis>
+True
+</emphasis>
+ </para>
+ <para>
+ group: INT8
+ </para>
+ <para>
+ groupAbsolute: BOOL
+ </para>
+ <para>
+ noAffectMods: BOOL
+ </para>
+ <para>
+ noAffectGrp: BOOL
+ </para>
+ <para>
+ noAffectPtr: BOOL
+ </para>
+ <para>
+ noAffectCtrls: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+dfltIsGroup</emphasis>
+ is <emphasis>
+True</emphasis>
+, key press sets the base group specified by <emphasis>
+groupAbsolute</emphasis>
+ and <emphasis>
+group</emphasis>
+. Otherwise, key press sets the action modifiers in the keyboard’s base
+modifiers.
+ </para>
+</listitem>
+<listitem>
+ <para>Key release clears the base modifiers or group that were set by the key
+press; it may have additional effects if no other appropriate actions occur
+simultaneously with the <emphasis>
+SA_ISOLock</emphasis>
+ operation.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+noAffectMods</emphasis>
+ is <emphasis>
+False</emphasis>
+, any <emphasis>
+SA_SetMods</emphasis>
+ or <emphasis>
+SA_LatchMods</emphasis>
+ actions that occur simultaneously with the <emphasis>
+ISOLock</emphasis>
+ action are treated as <emphasis>
+SA_LockMods</emphasis>
+ instead.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+noAffectGrp</emphasis>
+ is <emphasis>
+False</emphasis>
+, any <emphasis>
+SA_SetGroup</emphasis>
+ or <emphasis>
+SA_LatchGroup</emphasis>
+ actions that occur simultaneously with this action are treated as <emphasis>
+SA_LockGroup</emphasis>
+ actions instead.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+noAffectPtr</emphasis>
+ is <emphasis>
+False</emphasis>
+, <emphasis>
+SA_PtrBtn</emphasis>
+ actions that occur simultaneously with the <emphasis>
+SA_ISOLock</emphasis>
+ action are treated as <emphasis>
+SA_LockPtrBtn</emphasis>
+ actions instead.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+noAffectCtrls</emphasis>
+ is <emphasis>
+False</emphasis>
+, any <emphasis>
+SA_SetControls</emphasis>
+ actions that occur simultaneously with the <emphasis>
+SA_ISOLock</emphasis>
+ action are treated as <emphasis>
+SA_LockControls</emphasis>
+ actions instead.
+ </para>
+</listitem>
+<listitem>
+ <para>If no other actions were transformed by the <emphasis>
+SA_ISOLock</emphasis>
+ action, key release locks the group or modifiers specified by the action
+arguments.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry><emphasis>
+SA_TerminateServer</emphasis>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>Key press terminates the server. Key release is ignored.
+ </para>
+</listitem>
+<listitem>
+ <para>This action is optional; servers are free to ignore it. If ignored, it
+behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_SwitchScreen
+</emphasis>
+ </para>
+ <para>
+ num: INT8
+ </para>
+ <para>
+ switchApp: BOOL
+ </para>
+ <para>
+ screenAbs: BOOL
+ </para>
+</entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>If the server supports this action and multiple screens or displays
+(either virtual or real), this action changes to the active screen indicated by
+<emphasis>
+num</emphasis>
+ and <emphasis>
+screenAbs</emphasis>
+. If <emphasis>
+screenAbs</emphasis>
+ is <emphasis>
+True</emphasis>
+, num specifies the index of the new screen; otherwise, num specifies an offset
+from the current screen to the new screen.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+switchApp</emphasis>
+ is <emphasis>
+False</emphasis>
+, it should switch to another screen on the same server. Otherwise it should
+switch to another X server or application which shares the same physical
+display.
+ </para>
+</listitem>
+<listitem>
+ <para>This action is optional; servers are free to ignore the action or any
+of its flags if they do not support the requested behavior. If the action is
+ignored, it behaves like <emphasis>
+SA_NoAction</emphasis>
+, otherwise neither key press nor release generate an event.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para><emphasis>SA_SetControls</emphasis></para>
+ <para>controls: KB_BOOLCTRLMASK</para>
+ </entry>
+ <entry>
+ <itemizedlist>
+ <listitem>
+ <para>
+Key press enables any boolean controls that are specified in <emphasis>
+controls</emphasis>
+ and not already enabled at the time of the key press. Key release disables any
+controls that were enabled by the corresponding key press. This action can
+cause <emphasis>
+XkbControlsNotify</emphasis>
+ events.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para><emphasis>SA_LockControls</emphasis></para>
+ <para>
+ controls: KB_BOOLCTRLMASK
+ </para>
+ <para>
+ noLock: BOOL
+ </para>
+ <para>
+ noUnlock: BOOL
+ </para>
+ </entry>
+ <entry>
+<itemizedlist>
+<listitem>
+ <para>If <emphasis>
+noLock</emphasis>
+ is <emphasis>
+False</emphasis>
+, key press locks and enables any controls that are specified in <emphasis>
+controls</emphasis>
+ and not already locked at the time of the key press.
+</para>
+<para>
+If <emphasis>
+noUnlock</emphasis>
+ is <emphasis>
+False</emphasis>
+, key release unlocks and disables any controls that are specified in <emphasis>
+controls</emphasis>
+ and were not enabled at the time of the corresponding key press.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_ActionMessage</emphasis>
+:
+ pressMsg: BOOL
+ </para>
+ <para>
+ releaseMsg: BOOL
+ </para>
+ <para>
+ genEvent: BOOL
+ </para>
+ <para>
+ message: STRING
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>if <emphasis>
+pressMsg</emphasis>
+ is <emphasis>
+True</emphasis>
+, key press generates an <emphasis>
+XkbActionMessage</emphasis>
+ event which reports the keycode, event type and the contents of <emphasis>
+message</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+releaseMsg</emphasis>
+ is <emphasis>
+True</emphasis>
+, key release generates an <emphasis>
+XkbActionMessage</emphasis>
+ event which reports the keycode, event type and contents of <emphasis>
+message</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+genEvent</emphasis>
+ is <emphasis>
+True</emphasis>
+, both press and release generate key press and key release events, regardless
+of whether they also cause an <emphasis>
+XkbActionMessage</emphasis>
+.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_RedirectKey
+</emphasis>
+ </para>
+ <para>
+ newKey: KEYCODE
+ </para>
+ <para>
+ modsMask: KEYMASK
+ </para>
+ <para>
+ mods: KEYMASK
+ </para>
+ <para>
+ vmodsMask: CARD16
+ </para>
+ <para>
+ vmods: CARD16
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>Key press causes a key press event for the key specified by <emphasis>
+newKey</emphasis>
+ instead of for the actual key. The state reported in this event reports of the
+current effective modifiers changed as follow: Any real modifiers specified in
+<emphasis>
+modsMask</emphasis>
+ are set to corresponding values from <emphasis>
+mods</emphasis>
+. Any real modifiers bound to the virtual modifiers specified in <emphasis>
+vmodsMask</emphasis>
+ are either set or cleared, depending on the corresponding value in <emphasis>
+vmods</emphasis>
+. If the real and virtual modifier definitions specify conflicting values for a
+single modifier, the real modifier definition has priority.
+ </para>
+</listitem>
+<listitem>
+ <para>Key release causes a key release event for the key specified by
+<emphasis>
+newKey</emphasis>
+; the state field for this event consists of the effective keyboard modifiers
+at the time of the release, changed as described above.
+ </para>
+</listitem>
+<listitem>
+ <para>The <emphasis>
+SA_RedirectKey</emphasis>
+ action normally redirects to another key on the same device as the key or
+button which caused the event, unless that device does not belong to the input
+extension KEYCLASS, in which case this action causes an event on the core
+keyboard device.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_DeviceBtn
+</emphasis>
+ </para>
+ <para>
+ count: CARD8
+ </para>
+ <para>
+ button: BUTTON
+ </para>
+ <para>
+ device: CARD8
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>The <emphasis>
+device</emphasis>
+ field specifies the ID of an extension device; the <emphasis>
+button</emphasis>
+ field specifies the index of a button on that device. If the button specified
+by this action is logically down, the key press and corresponding release are
+ignored and have no effect. If the device or button specified by this action
+are illegal, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, key press causes one or more input extension device button
+events instead of the usual key press event. If <emphasis>
+count</emphasis>
+ is <emphasis>
+0</emphasis>
+, key press generates a single <emphasis>
+DeviceButtonPress</emphasis>
+ event; if <emphasis>
+count</emphasis>
+ is greater than <emphasis>
+0</emphasis>
+, key press generates <emphasis>
+count</emphasis>
+ pairs of <emphasis>
+DeviceButtonPress</emphasis>
+ and <emphasis>
+DeviceButtonRelease</emphasis>
+ events.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+count</emphasis>
+ is <emphasis>
+0</emphasis>
+, key release generates an input extension <emphasis>
+DeviceButtonRelease</emphasis>
+ which matches the event generated by the corresponding key press; if count is
+non-zero, key release does not cause a <emphasis>
+DeviceButtonRelease</emphasis>
+ event. Key release never causes a key release event.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+ <para>
+ <emphasis>
+SA_LockDeviceBtn
+</emphasis>
+ </para>
+ <para>
+ button: BUTTON
+ </para>
+ <para>
+ device: CARD8
+ </para>
+ <para>
+ noLock: BOOL
+ </para>
+ <para>
+ noUnlock: BOOL
+ </para>
+ </entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>The <emphasis>
+device</emphasis>
+ field specifies the ID of an extension device; the <emphasis>
+button</emphasis>
+ field specifies the index of a button on that device. If the device or button
+specified by this action are illegal, it behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, if the specified button is not locked and if <emphasis>
+noLock</emphasis>
+ is <emphasis>
+False</emphasis>
+, key press causes an input extension <emphasis>
+DeviceButtonPress</emphasis>
+ event instead of a key press event and locks the button. If the button is
+already locked or if <emphasis>
+noLock</emphasis>
+ is <emphasis>
+True</emphasis>
+, key press is ignored and has no effect.
+ </para>
+</listitem>
+<listitem>
+ <para>If the corresponding key press was ignored, and if <emphasis>
+noUnlock</emphasis>
+ is <emphasis>
+False</emphasis>
+, key release generates an input extension <emphasis>
+DeviceButtonRelease</emphasis>
+ event instead of a core protocol or input extension key release event and
+unlocks the specified button. If the corresponding key press locked a button,
+key release is ignored and has no effect.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+ <row rowsep='0'>
+ <entry>
+<para>
+ <emphasis>
+SA_DeviceValuator
+</emphasis>
+</para>
+<para>
+ <emphasis>
+device</emphasis>
+: CARD8
+</para>
+<para>
+ <emphasis>
+val1What</emphasis>
+: SA_DVOP
+</para>
+<para>
+ <emphasis>
+val1</emphasis>
+: CARD8
+</para>
+<para>
+ <emphasis>
+val1Value</emphasis>
+: INT8
+</para>
+<para>
+ <emphasis>
+val1Scale</emphasis>
+: 0...7
+</para>
+<para>
+ <emphasis>
+val2What</emphasis>
+: BOOL
+</para>
+<para>
+ <emphasis>
+val2</emphasis>
+: CARD8
+</para>
+<para>
+ <emphasis>
+val2Value</emphasis>
+: INT8
+</para>
+<para>
+ <emphasis>
+val2Scale</emphasis>
+: 0...7
+</para>
+</entry>
+<entry>
+<itemizedlist>
+<listitem>
+ <para>The <emphasis>
+device</emphasis>
+ field specifies the ID of an extension device; <emphasis>
+val1</emphasis>
+ and <emphasis>
+val2</emphasis>
+ specify valuators on that device. If <emphasis>
+device</emphasis>
+ is illegal or if neither <emphasis>
+val1</emphasis>
+ nor <emphasis>
+val2</emphasis>
+ specifies a legal valuator, this action behaves like <emphasis>
+SA_NoAction</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+valn</emphasis>
+ specifies a legal valuator and <emphasis>
+valnWhat</emphasis>
+ is not <emphasis>
+SA_IgnoreVal</emphasis>
+, the specified value is adjusted as specified by <emphasis>
+valnWhat</emphasis>
+:
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+valnWhat</emphasis>
+ is <emphasis>
+SA_SetValMin</emphasis>
+, <emphasis>
+valn</emphasis>
+ is set to its minimum legal value.
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+valnWhat</emphasis>
+ is <emphasis>
+SA_SetValCenter</emphasis>
+, <emphasis>
+valn</emphasis>
+ is centered (to (max-min)/2).
+ </para>
+</listitem>
+<listitem>
+ <para>If <emphasis>
+valnWhat</emphasis>
+ is <emphasis>
+SA_SetValMax</emphasis>
+, <emphasis>
+valn</emphasis>
+ is set to its maximum legal value.
+ </para>
+</listitem>
+<listitem>
+ <para>if <emphasis>
+valnWhat</emphasis>
+ is <emphasis>
+SA_SetValRelative</emphasis>
+, <mediaobject>
+ <imageobject> <imagedata fileref="XKBproto-4.gif"/>
+ </imageobject>
+ </mediaobject>
+
+ is added to <emphasis>
+valn</emphasis>
+.
+ </para>
+</listitem>
+<listitem>
+ <para>if <emphasis>
+valnWhat</emphasis>
+ is <emphasis>
+SA_SetValAbsolute</emphasis>
+, <emphasis>
+valn</emphasis>
+ is set to <mediaobject>
+ <imageobject> <imagedata fileref="XKBproto-5.gif"/>
+ </imageobject>
+ </mediaobject>
+
+.
+ </para>
+</listitem>
+<listitem>
+ <para>Illegal values for <emphasis>
+SA_SetValRelative</emphasis>
+ or <emphasis>
+SA_SetValAbsolute</emphasis>
+ are clamped into range.
+ </para>
+</listitem>
+</itemizedlist>
+</entry>
+ </row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>
+If <emphasis>
+StickyKeys</emphasis>
+ are enabled, all <emphasis>
+SA_SetMods</emphasis>
+ and <emphasis>
+SA_SetGroup</emphasis>
+ actions act like <emphasis>
+SA_LatchMods</emphasis>
+ and <emphasis>
+SA_LatchGroup</emphasis>
+ respectively. If the <emphasis>
+LatchToLock</emphasis>
+ AccessX option is set, either action behaves as if both the <emphasis>
+SA_ClearLocks</emphasis>
+ and <emphasis>
+SA_LatchToLock</emphasis>
+ flags are set.
+</para>
+
+
+<para>
+Actions which cause an event from another key or from a button on another
+device immediately generate the specified event. These actions do not consider
+the behavior or actions (if any) that are bound to the key or button to which
+the event is redirected.
+</para>
+
+
+<para>
+Core events generated by server actions contain the keyboard state that was in
+effect at the time the key event occurred; the reported state does not reflect
+any changes in state that occur as a result of the actions bound to the key
+event that caused them.
+</para>
+
+
+<para>
+Events sent to clients that have not issued an <emphasis>
+XkbUseExtension</emphasis>
+ request contain a compatibility state in place of the actual XKB keyboard
+state. See <ulink url="XKBproto.htm#50332257_39705">See Effects of XKB on Core
+Protocol Events</ulink> for a description of this compatibility mapping.
+</para>
+
+
+</sect1>
+<sect1 id='delivering_a_key_or_button_event_to_a_client'>
+<title>Delivering a Key or Button Event to a Client</title>
+
+<para>
+The window and client that receive core protocol and input extension key or
+button events are determined using the focus policy, window hierarchy and
+passive grabs as specified by the core protocol and the input extension, with
+the following changes:
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>A passive grab triggers if the modifier state specified in the grab
+matches the grab compatibility state (described in <ulink
+url="XKBproto.htm#50332257_32581">See Compatibility Components of Keyboard
+State</ulink>). Clients can choose to use the XKB grab state instead by setting
+the <emphasis>
+GrabsUseXKBState</emphasis>
+ per-client flag. This flag affects all passive grabs that are requested by the
+client which sets it but does not affect passive grabs that are set by any
+other client.
+ </para>
+</listitem>
+<listitem>
+ <para>The state field of events which trigger a passive grab reports the XKB
+or compatibility grab state in effect at the time the grab is triggered; the
+state field of the corresponding release event reports the corresponding grab
+state in effect when the key or button is released.
+ </para>
+</listitem>
+<listitem>
+ <para>If the <emphasis>
+LookupStateWhenGrabbed</emphasis>
+ per-client flag is set, all key or button events that occur while a keyboard
+or pointer grab is active contain the XKB or compatibility lookup state,
+depending on the value of the <emphasis>
+GrabsUseXKBState</emphasis>
+ per-client flag. If <emphasis>
+LookupStateWhenGrabbed</emphasis>
+ is not set, they include the XKB or compatibility grab state, instead.
+ </para>
+</listitem>
+<listitem>
+ <para>Otherwise, the state field of events that do not trigger a passive grab
+report is derived from the XKB effective modifiers and group, as described in
+<ulink url="XKBproto.htm#50332257_90933">See Computing A State Field from an
+XKB State</ulink>.
+ </para>
+</listitem>
+<listitem>
+ <para>If a key release event is the result of an autorepeating key that is
+being held down, and the client to which the event is reported has requested
+detectable autorepeat (see <ulink url="XKBproto.htm#50332257_79074">See
+Detectable Autorepeat</ulink>), the event is not delivered to the client.
+ </para>
+</listitem>
+</itemizedlist>
+
+<para>
+The following section explains the intent of the XKB interactions with core
+protocol grabs and the reason that the per-client flags are needed.
+</para>
+
+
+<sect2 id='xkb_interactions_with_core_protocol_grabs'>
+<title>XKB Interactions With Core Protocol Grabs</title>
+
+<para>
+XKB provides the separate lookup and grab states to help work around some
+difficulties with the way the core protocol specifies passive grabs.
+Unfortunately, many clients work around those problems differently, and the way
+that XKB handles grabs and reports keyboard state can sometimes interact with
+those client workarounds in unexpected and unpleasant ways.
+</para>
+
+
+<para>
+To provide more reasonable behavior for clients that are aware of XKB without
+causing problems for clients that are unaware of XKB, this extension provides
+two per-client flags that specify the way that XKB and the core protocol should
+interact.
+</para>
+
+<itemizedlist>
+<listitem>
+ <para>The largest problems arise from the fact that an XKB state field
+encodes an explicit keyboard group in bits 13-14 (as described in <ulink
+url="XKBproto.htm#50332257_90933">See Computing A State Field from an XKB
+State</ulink>), while pre-XKB clients use one of the eight keyboard modifiers
+to select an alternate keyboard group. To make existing clients behave
+reasonably, XKB normally uses the compatibility grab state instead of the XKB
+grab state to determine whether or not a passive grab is triggered. XKB-aware
+clients can set the <emphasis>
+GrabsUseXKBState</emphasis>
+ per-client flag to indicate that they are specifying passive grabs using an
+XKB state.
+ </para>
+</listitem>
+<listitem>
+ <para>Some toolkits start an active grab when a passive grab is triggered, in
+order to have more control over the conditions under which the grab is
+terminated. Unfortunately, the fact that XKB reports a different state in
+events that trigger or terminate grabs means that this grab simulation can fail
+to terminate the grab under some conditions. To work around this problem, XKB
+normally reports the grab state in all events whenever a grab is active.
+Clients which do not use active grabs like this can set the <emphasis>
+LookupStateWhenGrabbed</emphasis>
+ per-client flag in order to receive the same state component whether or not a
+grab is active.
+ </para>
+<para>
+The <emphasis>
+GrabsUseXKBState</emphasis>
+ per-client flag also applies to the state of events sent while a grab is
+active. If it is set, events during a grab contain the XKB lookup or grab
+state; by default, events during a grab contain the compatibility lookup or
+grab state.</para>
+</listitem>
+</itemizedlist>
+
+<para>
+The state used to trigger a passive grab is controlled by the setting of the
+<emphasis>
+GrabsUseXKBState</emphasis>
+ per-client flag at the time the grab is registered. Changing this flag does
+not affect existing passive grabs.
+</para>
+</sect2>
+</sect1>
+</chapter>