*
* A key, represented by a keycode, may generate different symbols according
* to keyboard state. For example, on a QWERTY keyboard, pressing the key
- * labled <A> generates the symbol 'a'. If the Shift key is held, it
+ * labled \<A\> generates the symbol 'a'. If the Shift key is held, it
* generates the symbol 'A'. If a different layout is used, say Greek,
* it generates the symbol 'α'. And so on.
*
/** Flags for xkb_keysym_from_name(). */
enum xkb_keysym_flags {
/** Find keysym by case-insensitive search. */
- XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0),
+ XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
};
/**
* @param[out] buffer A buffer to write the UTF-8 string into.
* @param[in] size The size of buffer. Must be at least 7.
*
- * @returns The number of bytes written to the buffer. If the keysym does
- * not have a Unicode representation, returns 0. If the buffer is too small,
- * returns -1.
+ * @returns The number of bytes written to the buffer (including the
+ * terminating byte). If the keysym does not have a Unicode
+ * representation, returns 0. If the buffer is too small, returns -1.
*/
int
xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size);
/** Flags for context creation. */
enum xkb_context_flags {
/** Create this context with an empty include path. */
- XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
+ XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0)
};
/**
/**
* Release a reference on a context, and possibly free it.
*
+ * @param context The context. If it is NULL, this function does nothing.
+ *
* @memberof xkb_context
*/
void
xkb_context_unref(struct xkb_context *context);
/**
+ * Store custom user data in the context.
+ *
+ * This may be useful in conjuction with xkb_context_set_log_fn() or other
+ * callbacks.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_set_user_data(struct xkb_context *context, void *user_data);
+
+/**
+ * Retrieves stored user data from the context.
+ *
+ * @returns The stored user data. If the user data wasn't set, or the
+ * passed in context is NULL, returns NULL.
+ *
+ * This may be useful to access private user data from callbacks like a
+ * custom logging function.
+ *
+ * @memberof xkb_context
+ **/
+void *
+xkb_context_get_user_data(struct xkb_context *context);
+
+/** @} */
+
+/**
+ * @defgroup include-path Include Paths
+ * Manipulating the include paths in a context.
+ *
+ * The include paths are the file-system paths that are searched when an
+ * include statement is encountered during keymap compilation.
+ * In most cases, the default include paths are sufficient.
+ *
+ * @{
+ */
+
+/**
* Append a new entry to the context's include path.
*
* @returns 1 on success, or 0 if the include path could not be added or is
/**
* Get a specific include path from the context's include path.
*
- * @returns The include path at the specified index within the context, or
- * NULL if the index is invalid.
+ * @returns The include path at the specified index. If the index is
+ * invalid, returns NULL.
*
* @memberof xkb_context
*/
const char *
xkb_context_include_path_get(struct xkb_context *context, unsigned int index);
-/**
- * Store custom user data in the context.
- *
- * This may be useful in conjuction with xkb_context_set_log_fn() or other
- * callbacks.
- *
- * @memberof xkb_context
- */
-void
-xkb_context_set_user_data(struct xkb_context *context, void *user_data);
-
-/**
- * Retrieves stored user data from the context.
- *
- * @returns The stored user data. If the user data wasn't set, or the
- * passed in context is NULL, returns NULL.
- *
- * This may be useful to access private user data from callbacks like a
- * custom logging function.
- *
- * @memberof xkb_context
- **/
-void *
-xkb_context_get_user_data(struct xkb_context *context);
-
/** @} */
/**
XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */
XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */
XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */
- XKB_LOG_LEVEL_DEBUG = 50, /**< Log everything. */
+ XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */
};
/**
/** Flags for keymap compilation. */
enum xkb_keymap_compile_flags {
/** Apparently you can't have empty enums. What a drag. */
- XKB_MAP_COMPILE_PLACEHOLDER = 0,
+ XKB_MAP_COMPILE_PLACEHOLDER = 0
};
/**
/** The possible keymap text formats. */
enum xkb_keymap_format {
/** The current/classic XKB text format, as generated by xkbcomp -xkb. */
- XKB_KEYMAP_FORMAT_TEXT_V1 = 1,
+ XKB_KEYMAP_FORMAT_TEXT_V1 = 1
};
/**
/**
* Release a reference on a keymap, and possibly free it.
*
+ * @param keymap The keymap. If it is NULL, this function does nothing.
+ *
* @memberof xkb_keymap
*/
void
xkb_keymap_unref(struct xkb_keymap *keymap);
-/* See xkb_keymap_get_as_string(). */
+/**
+ * Get the keymap as a string in the format from which it was created.
+ * @sa xkb_keymap_get_as_string()
+ **/
#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1)
/**
xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t key);
/**
- * Get the number of shift levels of a specific key and layout.
+ * Get the number of shift levels for a specific key and layout.
+ *
+ * If @c layout is out of range for this key (that is, larger or equal to
+ * the value returned by xkb_keymap_num_layouts_for_key()), it is brought
+ * back into range in a manner consistent with xkb_state_key_get_layout().
*
* @sa xkb_level_index_t
* @memberof xkb_keymap
xkb_layout_index_t layout);
/**
- * Get the number of LEDs in a keymap.
+ * Get the keysyms obtained from pressing a key in a given layout and
+ * shift level.
+ *
+ * This function is like xkb_state_key_get_syms(), only the layout and
+ * shift level are not derived from the keyboard state but are instead
+ * specified explicitly.
+ *
+ * @param[in] keymap The keymap.
+ * @param[in] key The keycode of the key.
+ * @param[in] layout The layout for which to get the keysyms.
+ * @param[in] level The shift level in the layout for which to get the
+ * keysyms. This must be smaller than:
+ * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode
+ * @param[out] syms_out An immutible array of keysyms corresponding to the
+ * key in the given layout and shift level.
+ *
+ * If @c layout is out of range for this key (that is, larger or equal to
+ * the value returned by xkb_keymap_num_layouts_for_key()), it is brought
+ * back into range in a manner consistent with xkb_state_key_get_layout().
+ *
+ * @returns The number of keysyms in the syms_out array. If no keysyms
+ * are produced by the key in the given layout and shift level, returns 0
+ * and sets syms_out to NULL.
+ *
+ * @sa xkb_state_key_get_syms()
+ * @memberof xkb_keymap
+ */
+int
+xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
+ xkb_keycode_t key,
+ xkb_layout_index_t layout,
+ xkb_level_index_t level,
+ const xkb_keysym_t **syms_out);
+
+/**
+ * Get the number of LEDs in the keymap.
*
* @warning The range [ 0...xkb_keymap_num_leds() ) includes all of the LEDs
* in the keymap, but may also contain inactive LEDs. When iterating over
/**
* Release a reference on a keybaord state object, and possibly free it.
*
+ * @param state The state. If it is NULL, this function does nothing.
+ *
* @memberof xkb_state
*/
void
/** Specifies the direction of the key (press / release). */
enum xkb_key_direction {
XKB_KEY_UP, /**< The key was released. */
- XKB_KEY_DOWN, /**< The key was pressed. */
+ XKB_KEY_DOWN /**< The key was pressed. */
};
/**
* e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
* exclude locked modifiers.
*
- * In XKB, the DEPRESSED states are also known as 'base'.
+ * In XKB, the DEPRESSED components are also known as 'base'.
*/
enum xkb_state_component {
/** Depressed modifiers, i.e. a key is physically holding them. */
* (derived from the other state components). */
XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
/** LEDs (derived from the other state components). */
- XKB_STATE_LEDS = (1 << 8),
+ XKB_STATE_LEDS = (1 << 8)
};
/**
xkb_layout_index_t layout);
/**
- * Get the keysyms obtained from pressing a key in a given layout and
- * shift level.
- *
- * This function is like xkb_state_key_get_syms(), only the layout and
- * shift level are not derived from the keyboard state but are instead
- * specified explicitly.
- *
- * @param[in] keymap The keymap.
- * @param[in] key The keycode of the key.
- * @param[in] layout The layout for which to get the keysyms. This must
- * be smaller than:
- * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode
- * Usually it would be:
- * @code xkb_state_key_get_layout(state, key) @endcode
- * @param[in] level The shift level in the layout for which to get the
- * keysyms. This must be smaller than:
- * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode
- * usually it would be:
- * @code xkb_state_key_get_level(state, key, layout) @endcode.
- * @param[out] syms_out An immutible array of keysyms corresponding the
- * key in the given layout and shift level.
- *
- * @returns The number of keysyms in the syms_out array. If no keysyms
- * are produced by the key in the given layout and shift level, returns 0
- * and sets syms_out to NULL.
- *
- * @sa xkb_state_key_get_syms()
- * @memberof xkb_keymap
- */
-int
-xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
- xkb_keycode_t key,
- xkb_layout_index_t layout,
- xkb_level_index_t level,
- const xkb_keysym_t **syms_out);
-
-/**
* Match flags for xkb_state_mod_indices_are_active and
* xkb_state_mod_names_are_active, specifying how the conditions for a
* successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with
XKB_STATE_MATCH_ALL = (1 << 1),
/** Makes matching non-exclusive, i.e. will not return false if a
* modifier not specified in the arguments is active. */
- XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16),
+ XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16)
};
/**
- * Update a state object from a set of explicit masks.
+ * Update a keyboard state from a set of explicit masks.
*
* This entrypoint is really only for window systems and the like, where a
* master process holds an xkb_state, then serializes it over a wire
*/
enum xkb_state_component
xkb_state_update_mask(struct xkb_state *state,
- xkb_mod_mask_t base_mods,
+ xkb_mod_mask_t depressed_mods,
xkb_mod_mask_t latched_mods,
xkb_mod_mask_t locked_mods,
- xkb_layout_index_t base_layout,
+ xkb_layout_index_t depressed_layout,
xkb_layout_index_t latched_layout,
xkb_layout_index_t locked_layout);
* If XKB_STATE_LAYOUT_EFFECTIVE is included, all other state components are
* ignored.
*
- * @returns A xkb_layout_mask_t representing the given components of the
+ * @returns A layout index representing the given components of the
* layout state.
*
* This function should not be used in regular clients; please use the
* Some functions, like xkb_state_key_get_syms(), look at the state of
* the modifiers in the keymap and derive from it the correct shift level
* to use for the key. For example, in a US layout, pressing the key
- * labeled <A> while the Shift modifier is active, generates the keysym 'A'.
+ * labeled \<A\> while the Shift modifier is active, generates the keysym 'A'.
* In this case, the Shift modifier is said to be consumed. However, the
* Num Lock modifier does not affect this translation at all, even if it
* active, so it is not consumed by this translation.
*
* It may be desireable for some application to not reuse consumed modifiers
- * for further processing, e.g. for hotkeys or keyboard shortcuts.
+ * for further processing, e.g. for hotkeys or keyboard shortcuts. To
+ * understand why, consider some requirements from a standard shortcut
+ * mechanism, and how they are implemented:
+ *
+ * 1. The shortcut's modifiers must match exactly to the state. For example,
+ * it is possible to bind separate actions to \<Alt\>\<Tab\> and to
+ * \<Alt\>\<Shift\>\<Tab\>. Further, if only \<Alt\>\<Tab\> is bound to
+ * an action, pressing \<Alt\>\<Shift\>\<Tab\> should not trigger the
+ * shortcut.
+ * Effectively, this means that the modifiers are compared using the
+ * equality operator (==).
+ * 2. Only relevant modifiers are considered for the matching. For example,
+ * Caps Lock and Num Lock should not generally affect the matching, e.g.
+ * when matching \<Alt\>\<Tab\> against the state, it does not matter
+ * whether Num Lock is active or not. These relevant, or significant,
+ * modifiers usually include Alt, Control, Shift, Super and similar.
+ * Effectively, this means that non-significant modifiers are masked out,
+ * before doing the comparison as described above.
+ * 3. The matching must be independent of the layout/keymap. For example,
+ * the \<Plus\> (+) symbol is found on the first level on some layouts,
+ * and requires holding Shift on others. If you simply bind the action
+ * to the \<Plus\> keysym, it would work for the unshifted kind, but
+ * not for the others, because the match against Shift would fail. If
+ * you bind the action to \<Shift\>\<Plus\>, only the shifted kind would
+ * work. So what is needed is to recognize that Shift is used up in the
+ * translation of the keysym itself, and therefore should not be included
+ * in the matching.
+ * Effectively, this means that consumed modifiers (Shift in this example)
+ * are masked out as well, before doing the comparison.
+ *
+ * To summarize, this is how the matching would be performed:
+ * @code
+ * (keysym == shortcut_keysym) &&
+ * ((state_modifiers & ~consumed_modifiers & significant_modifiers) == shortcut_modifiers)
+ * @endcode
+ *
+ * @c state_modifiers are the modifiers reported by
+ * xkb_state_mod_index_is_active() and similar functions.
+ * @c consumed_modifiers are the modifiers reported by
+ * xkb_state_mod_index_is_consumed().
+ * @c significant_modifiers are decided upon by the application/toolkit/user;
+ * it is up to them to decide whether these are configurable or hard-coded.
*
* @returns 1 if the modifier is consumed, 0 if it is not. If the modifier
* index is not valid in the keymap, returns -1.
*
- * @sa xkb_state_mod_mask_remove_consumend()
+ * @sa xkb_state_mod_mask_remove_consumed()
* @memberof xkb_state
*/
int