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