diff options
Diffstat (limited to 'specs/ch06.xml')
-rw-r--r-- | specs/ch06.xml | 1765 |
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> |