Home | History | Annotate | Download | only in xkbcommon
      1 /*
      2  * Copyright  2013 Ran Benita
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #ifndef _XKBCOMMON_X11_H
     25 #define _XKBCOMMON_X11_H
     26 
     27 #include <xcb/xcb.h>
     28 #include <xkbcommon/xkbcommon.h>
     29 
     30 #ifdef __cplusplus
     31 extern "C" {
     32 #endif
     33 
     34 /**
     35  * @file
     36  * libxkbcommon-x11 API - Additional X11 support for xkbcommon.
     37  */
     38 
     39 /**
     40  * @defgroup x11 X11 support
     41  * Additional X11 support for xkbcommon.
     42  * @since 0.4.0
     43  *
     44  * @{
     45  */
     46 
     47 /**
     48  * @page x11-overview Overview
     49  * @parblock
     50  *
     51  * The xkbcommon-x11 module provides a means for creating an xkb_keymap
     52  * corresponding to the currently active keymap on the X server.  To do
     53  * so, it queries the XKB X11 extension using the xcb-xkb library.  It
     54  * can be used as a replacement for Xlib's keyboard handling.
     55  *
     56  * Following is an example workflow using xkbcommon-x11.  A complete
     57  * example may be found in the test/interactive-x11.c file in the
     58  * xkbcommon source repository.  On startup:
     59  *
     60  * 1. Connect to the X server using xcb_connect().
     61  * 2. Setup the XKB X11 extension.  You can do this either by using the
     62  *    xcb_xkb_use_extension() request directly, or by using the
     63  *    xkb_x11_setup_xkb_extension() helper function.
     64  *
     65  * The XKB extension supports using separate keymaps and states for
     66  * different keyboard devices.  The devices are identified by an integer
     67  * device ID and are managed by another X11 extension, XInput (or its
     68  * successor, XInput2).  The original X11 protocol only had one keyboard
     69  * device, called the "core keyboard", which is still supported as a
     70  * "virtual device".
     71  *
     72  * 3. We will use the core keyboard as an example.  To get its device ID,
     73  *    use either the xcb_xkb_get_device_info() request directly, or the
     74  *    xkb_x11_get_core_keyboard_device_id() helper function.
     75  * 4. Create an initial xkb_keymap for this device, using the
     76  *    xkb_x11_keymap_new_from_device() function.
     77  * 5. Create an initial xkb_state for this device, using the
     78  *    xkb_x11_state_new_from_device() function.
     79  *
     80  * @note At this point, you may consider setting various XKB controls and
     81  * XKB per-client flags.  For example, enabling detectable autorepeat: \n
     82  * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
     83  *
     84  * Next, you need to react to state changes (e.g. a modifier was pressed,
     85  * the layout was changed) and to keymap changes (e.g. a tool like xkbcomp,
     86  * setxkbmap or xmodmap was used):
     87  *
     88  * 6. Select to listen to at least the following XKB events:
     89  *    NewKeyboardNotify, MapNotify, StateNotify; using the
     90  *    xcb_xkb_select_events_aux() request.
     91  * 7. When NewKeyboardNotify or MapNotify are received, recreate the
     92  *    xkb_keymap and xkb_state as described above.
     93  * 8. When StateNotify is received, update the xkb_state accordingly
     94  *    using the xkb_state_update_mask() function.
     95  *
     96  * @note It is also possible to use the KeyPress/KeyRelease @p state
     97  * field to find the effective modifier and layout state, instead of
     98  * using XkbStateNotify: \n
     99  * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
    100  * \n However, XkbStateNotify is more accurate.
    101  *
    102  * @note There is no need to call xkb_state_update_key(); the state is
    103  * already synchronized.
    104  *
    105  * Finally, when a key event is received, you can use ordinary xkbcommon
    106  * functions, like xkb_state_key_get_one_sym() and xkb_state_key_get_utf8(),
    107  * as you normally would.
    108  *
    109  * @endparblock
    110  */
    111 
    112 /**
    113  * The minimal compatible major version of the XKB X11 extension which
    114  * this library can use.
    115  */
    116 #define XKB_X11_MIN_MAJOR_XKB_VERSION 1
    117 /**
    118  * The minimal compatible minor version of the XKB X11 extension which
    119  * this library can use (for the minimal major version).
    120  */
    121 #define XKB_X11_MIN_MINOR_XKB_VERSION 0
    122 
    123 /** Flags for the xkb_x11_setup_xkb_extension() function. */
    124 enum xkb_x11_setup_xkb_extension_flags {
    125     /** Do not apply any flags. */
    126     XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS = 0
    127 };
    128 
    129 /**
    130  * Setup the XKB X11 extension for this X client.
    131  *
    132  * The xkbcommon-x11 library uses various XKB requests.  Before doing so,
    133  * an X client must notify the server that it will be using the extension.
    134  * This function (or an XCB equivalent) must be called before any other
    135  * function in this library is used.
    136  *
    137  * Some X servers may not support or disable the XKB extension.  If you
    138  * want to support such servers, you need to use a different fallback.
    139  *
    140  * You may call this function several times; it is idempotent.
    141  *
    142  * @param connection
    143  *     An XCB connection to the X server.
    144  * @param major_xkb_version
    145  *     See @p minor_xkb_version.
    146  * @param minor_xkb_version
    147  *     The XKB extension version to request.  To operate correctly, you
    148  *     must have (major_xkb_version, minor_xkb_version) >=
    149  *     (XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION),
    150  *     though this is not enforced.
    151  * @param flags
    152  *     Optional flags, or 0.
    153  * @param[out] major_xkb_version_out
    154  *     See @p minor_xkb_version_out.
    155  * @param[out] minor_xkb_version_out
    156  *     Backfilled with the compatible XKB extension version numbers picked
    157  *     by the server.  Can be NULL.
    158  * @param[out] base_event_out
    159  *     Backfilled with the XKB base (also known as first) event code, needed
    160  *     to distinguish XKB events.  Can be NULL.
    161  * @param[out] base_error_out
    162  *     Backfilled with the XKB base (also known as first) error code, needed
    163  *     to distinguish XKB errors.  Can be NULL.
    164  *
    165  * @returns 1 on success, or 0 on failure.
    166  */
    167 int
    168 xkb_x11_setup_xkb_extension(xcb_connection_t *connection,
    169                             uint16_t major_xkb_version,
    170                             uint16_t minor_xkb_version,
    171                             enum xkb_x11_setup_xkb_extension_flags flags,
    172                             uint16_t *major_xkb_version_out,
    173                             uint16_t *minor_xkb_version_out,
    174                             uint8_t *base_event_out,
    175                             uint8_t *base_error_out);
    176 
    177 /**
    178  * Get the keyboard device ID of the core X11 keyboard.
    179  *
    180  * @param connection An XCB connection to the X server.
    181  *
    182  * @returns A device ID which may be used with other xkb_x11_* functions,
    183  *          or -1 on failure.
    184  */
    185 int32_t
    186 xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
    187 
    188 /**
    189  * Create a keymap from an X11 keyboard device.
    190  *
    191  * This function queries the X server with various requests, fetches the
    192  * details of the active keymap on a keyboard device, and creates an
    193  * xkb_keymap from these details.
    194  *
    195  * @param context
    196  *     The context in which to create the keymap.
    197  * @param connection
    198  *     An XCB connection to the X server.
    199  * @param device_id
    200  *     An XInput 1 device ID (in the range 0-255) with input class KEY.
    201  *     Passing values outside of this range is an error.
    202  * @param flags
    203  *     Optional flags for the keymap, or 0.
    204  *
    205  * @returns A keymap retrieved from the X server, or NULL on failure.
    206  *
    207  * @memberof xkb_keymap
    208  */
    209 struct xkb_keymap *
    210 xkb_x11_keymap_new_from_device(struct xkb_context *context,
    211                                xcb_connection_t *connection,
    212                                int32_t device_id,
    213                                enum xkb_keymap_compile_flags flags);
    214 
    215 /**
    216  * Create a new keyboard state object from an X11 keyboard device.
    217  *
    218  * This function is the same as xkb_state_new(), only pre-initialized
    219  * with the state of the device at the time this function is called.
    220  *
    221  * @param keymap
    222  *     The keymap for which to create the state.
    223  * @param connection
    224  *     An XCB connection to the X server.
    225  * @param device_id
    226  *     An XInput 1 device ID (in the range 0-255) with input class KEY.
    227  *     Passing values outside of this range is an error.
    228  *
    229  * @returns A new keyboard state object, or NULL on failure.
    230  *
    231  * @memberof xkb_state
    232  */
    233 struct xkb_state *
    234 xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
    235                               xcb_connection_t *connection,
    236                               int32_t device_id);
    237 
    238 /** @} */
    239 
    240 #ifdef __cplusplus
    241 } /* extern "C" */
    242 #endif
    243 
    244 #endif /* _XKBCOMMON_X11_H */
    245