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