333 lines
11 KiB
XML
333 lines
11 KiB
XML
<?xml version="1.0" encoding="UTF-8" ?>
|
||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||
<chapter id='Replacing_a_Keyboard_On_the_Fly'>
|
||
<title>Replacing a Keyboard <quote>On the Fly</quote></title>
|
||
|
||
<para>
|
||
Some operating system and X server implementations allow
|
||
<quote>hot plugging</quote> of
|
||
input devices. When using these implementations, input devices can be unplugged
|
||
and new ones plugged in without restarting the software that is using those
|
||
devices. There is no provision in the standard X server for notification of
|
||
client programs if input devices are unplugged and/or new ones plugged in. In
|
||
the case of the X keyboard, this could result in the X server having a keymap
|
||
that does not match the new keyboard.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the X server implementation supports the X input device extension, a client
|
||
program may also change the X keyboard programmatically. The
|
||
XChangeKeyboardDevice input extension request allows a client to designate an
|
||
input extension keyboard device as the X keyboard, in which case the old X
|
||
keyboard device becomes inaccessible except via the input device extension. In
|
||
this case, core protocol
|
||
<symbol>MappingNotify</symbol>
|
||
and input extension
|
||
<symbol>XChangeDeviceNotify</symbol>
|
||
events are generated to notify all clients that a new keyboard with a new
|
||
keymap has been designated.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
When a client opens a connection to the X server, the server reports the
|
||
minimum and maximum keycodes. The server keeps track of the minimum and maximum
|
||
keycodes last reported to each client. When delivering events to a particular
|
||
client, the server filters out any events that fall outside of the valid range
|
||
for the client.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Xkb provides an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event that reports a change in keyboard geometry and/or the range of supported
|
||
keycodes. The server can generate an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event when it detects a new keyboard or in response to an
|
||
<function>XkbGetKeyboardByName</function>
|
||
request that loads a new keyboard description. Selecting for
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
events allows Xkb-aware clients to be notified whenever a keyboard change
|
||
occurs that may affect the keymap.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
When a client requests
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
events, the server compares the range of keycodes for the current keyboard to
|
||
the range of keycodes that are valid for the client. If they are not the same,
|
||
the server immediately sends the client an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event. Even if the <quote>new</quote> keyboard is not new to the server,
|
||
it is new to this particular client.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
When the server sends an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event to a client to inform it of a new keycode range, it resets the stored
|
||
range of legal keycodes for the client to the keycode range reported in the
|
||
event; it does not reset this range for the client if it does not sent an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event to a client. Because Xkb-unaware clients and Xkb-aware clients that do
|
||
not request
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
events are never sent these events, the server’s notion of the legal keycode
|
||
range never changes, and these clients never receive events from keys that fall
|
||
outside of their notion of the legal keycode range.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Clients that have not selected to receive
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
events do, however, receive the
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event when a keyboard change occurs. Clients that have not selected to receive
|
||
this event also receive numerous other events detailing the individual changes
|
||
that occur when a keyboard change occurs.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Clients wishing to track changes in
|
||
<structfield>min_key_code</structfield>
|
||
and
|
||
<structfield>max_key_code</structfield>
|
||
must watch for both
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
and
|
||
<symbol>XkbMapNotify</symbol>
|
||
events, because a simple mapping change causes an
|
||
<symbol>XkbMapNotify</symbol>
|
||
event and may change the range of valid keycodes, but does not cause an
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event. If a client does not select for
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
events, the server restricts the range of keycodes reported to the client.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
In addition to filtering out-of-range key events, Xkb:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Adjusts core protocol
|
||
<symbol>MappingNotify</symbol>
|
||
events to refer only to keys that match the stored legal range.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Reports keyboard mappings for keys that match the stored legal range to clients
|
||
that issue a core protocol
|
||
<systemitem>GetKeyboardMapping</systemitem>
|
||
request.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Reports modifier mappings only for keys that match the stored legal range to
|
||
clients that issue a core protocol
|
||
<systemitem>GetModifierMapping</systemitem>
|
||
request.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Restricts the core protocol
|
||
<systemitem>ChangeKeyboardMapping</systemitem>
|
||
and
|
||
<systemitem>SetModifierMapping</systemitem>
|
||
requests to keys that fall inside the stored legal range.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
In short, Xkb does everything possible to hide from Xkb-unaware clients the
|
||
fact that the range of legal keycodes has changed, because such clients cannot
|
||
be expected to deal with them. Xkb events and requests are not modified in this
|
||
manner; all Xkb events report the full range of legal keycodes. No requested
|
||
Xkb events are discarded, and no Xkb requests have their keycode range clamped.
|
||
</para>
|
||
|
||
<indexterm significance="preferred" zone="Replacing_a_Keyboard_On_the_Fly">
|
||
<primary>events</primary><secondary><symbol>XkbNewKeyboardNotify</symbol></secondary></indexterm>
|
||
<indexterm significance="preferred" zone="Replacing_a_Keyboard_On_the_Fly">
|
||
<primary><structname>XkbNewKeyboardNotifyEvent</structname></primary></indexterm>
|
||
|
||
<para>
|
||
The structure for the
|
||
<symbol>XkbNewKeyboardNotify</symbol>
|
||
event is defined as follows:
|
||
|
||
<programlisting>
|
||
typedef struct _XkbNewKeyboardNotify {
|
||
int type; /* Xkb extension base event code */
|
||
unsigned long serial; /* X server serial number for event */
|
||
Bool send_event; /* <symbol>True</symbol> ⇒ synthetically generated */
|
||
Display * display; /* server connection where event generated */
|
||
Time time; /* server time when event generated */
|
||
int xkb_type; /* <symbol>XkbNewKeyboardNotify</symbol> */
|
||
int device; /* device ID of new keyboard */
|
||
int old_device; /* device ID of old keyboard */
|
||
int min_key_code; /* min keycode of new keyboard */
|
||
int max_key_code; /* max keycode of new keyboard */
|
||
int old_min_key_code; /* min keycode of old keyboard */
|
||
int old_max_key_code; /* max keycode of old keyboard */
|
||
unsigned int changed; /* changed aspects - see masks below */
|
||
char req_major; /* major request that caused change */
|
||
char req_minor; /* minor request that caused change */
|
||
} <structname>XkbNewKeyboardNotifyEvent</structname>;
|
||
</programlisting></para>
|
||
|
||
<para>
|
||
To receive name notify events, use
|
||
<function>XkbSelectEvents</function>
|
||
(see <link linkend="Selecting_Xkb_Events">section 4.3</link>) with
|
||
<symbol>XkbNewKeyboardNotifyMask</symbol>
|
||
in both the
|
||
<parameter>bits_to_change</parameter>
|
||
and
|
||
<parameter>values_for_bits</parameter>
|
||
parameters. To receive events for only specific names, use
|
||
<function>XkbSelectEventDetails</function>.
|
||
Set the
|
||
<structfield>event_type</structfield>
|
||
parameter to
|
||
<symbol>XkbNewKeyboardNotify</symbol>,
|
||
and set both the
|
||
<parameter>bits_to_change</parameter>
|
||
and
|
||
<parameter>values_for_bits</parameter>
|
||
detail parameter to a mask composed of a bitwise OR of masks in
|
||
<link linkend="table19.1">Table 19.1</link>.
|
||
</para>
|
||
|
||
<table id='table19.1' frame='topbot'>
|
||
<title>XkbNewKeyboardNotifyEvent Details</title>
|
||
<?dbfo keep-together="always" ?>
|
||
<tgroup cols='3' align='left' colsep='0' rowsep='0'>
|
||
<colspec colname='c1' colwidth='2.0*'/>
|
||
<colspec colname='c2' colwidth='1.0*'/>
|
||
<colspec colname='c3' colwidth='2.0*'/>
|
||
<thead>
|
||
<row rowsep='1'>
|
||
<entry>XkbNewKeyboardNotify Event Details</entry>
|
||
<entry>Value</entry>
|
||
<entry>Circumstances</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><symbol>XkbNKN_KeycodesMask</symbol></entry>
|
||
<entry>(1L<<0)</entry>
|
||
<entry>Notification of keycode range changes wanted</entry>
|
||
</row>
|
||
<row>
|
||
<entry><symbol>XkbNKN_GeometryMask</symbol></entry>
|
||
<entry>(1L<<1)</entry>
|
||
<entry>Notification of geometry changes wanted</entry>
|
||
</row>
|
||
<row>
|
||
<entry><symbol>XkbNKN_DeviceIDMask</symbol></entry>
|
||
<entry>(1L<<2)</entry>
|
||
<entry>Notification of device ID changes wanted</entry>
|
||
</row>
|
||
<row>
|
||
<entry><symbol>XkbAllNewKeyboardEventsMask</symbol></entry>
|
||
<entry>(0x7)</entry>
|
||
<entry>Includes all of the above masks</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
The
|
||
<structfield>req_major</structfield>
|
||
and
|
||
<structfield>req_minor</structfield>
|
||
fields indicate what type of keyboard change has occurred.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If
|
||
<structfield>req_major</structfield>
|
||
and
|
||
<structfield>req_minor</structfield>
|
||
are zero, the device change was not caused by a software request to the server
|
||
— a spontaneous change has occurred, such as hot-plugging a new device. In
|
||
this case,
|
||
<structfield>device</structfield>
|
||
is the device identifier for the new, current X keyboard device, but no
|
||
implementation-independent guarantee can be made about
|
||
<structfield>old_device</structfield>.
|
||
<structfield>old_device</structfield>
|
||
may be identical to
|
||
<structfield>device</structfield>
|
||
(an implementor is permitted to reuse the device specifier when the device
|
||
changes); or it may be different. Note that
|
||
<structfield>req_major</structfield>
|
||
and
|
||
<structfield>req_minor</structfield>
|
||
being zero do not necessarily mean that the physical keyboard device has
|
||
changed; rather, they only imply a spontaneous change outside of software
|
||
control (some systems have keyboards that can change personality at the press
|
||
of a key).
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the keyboard change is the result of an X Input Extension
|
||
<systemitem>ChangeKeyboardDevice</systemitem>
|
||
request,
|
||
<structfield>req_major</structfield>
|
||
contains the input extension major opcode, and
|
||
<structfield>req_minor</structfield>
|
||
contains the input extension request number for
|
||
<symbol>X_ChangeKeyboardDevice</symbol>.
|
||
In this case,
|
||
<structfield>device</structfield>
|
||
and
|
||
<structfield>old_device</structfield>
|
||
are different, with
|
||
<structfield>device</structfield>
|
||
being the identifier for the new, current X keyboard device, and
|
||
<structfield>old_device</structfield>
|
||
being the identifier for the former device.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
If the keyboard change is the result of an
|
||
<function>XkbGetKeyboardByName</function>
|
||
function call, which generates an
|
||
<symbol>X_kbGetKbdByName</symbol>
|
||
request,
|
||
<structfield>req_major</structfield>
|
||
contains the Xkb extension base event code (see <link linkend="Initializing_the_Keyboard_Extension">section 2.4</link>), and
|
||
<structfield>req_minor</structfield>
|
||
contains the event code for the Xkb extension request
|
||
<symbol>X_kbGetKbdByName</symbol>.
|
||
<structfield>device</structfield>
|
||
contains the device identifier for the new device, but nothing definitive can
|
||
be said for
|
||
<structfield>old_device</structfield>;
|
||
it may be identical to
|
||
<structfield>device</structfield>,
|
||
or it may be different, depending on the implementation.
|
||
</para>
|
||
|
||
</chapter>
|