keymap: wrap the layout parameter if it is out of range for the key
[platform/upstream/libxkbcommon.git] / xkbcommon / xkbcommon.h
index ddc715c..244b35b 100644 (file)
@@ -147,7 +147,17 @@ struct xkb_state;
  * keymap would assign each of them a keycode, by which the user should
  * refer to the key throughout the library.
  *
+ * Historically, the X11 protocol, and consequentially the XKB protocol,
+ * assign only 8 bits for keycodes.  This limits the number of different
+ * keys that can be used simultaneously in a single keymap to 256
+ * (disregarding other limitations).  This library does not share this limit;
+ * keycodes beyond 255 ('extended keycodes') are not treated specially.
+ * Keymaps and applications which are compatible with X11 should not use
+ * these keycodes.
+ *
  * @todo Explain how keycodes are mapped to scancodes.
+ *
+ * @sa xkb_keycode_is_legal_ext() xkb_keycode_is_legal_x11()
  */
 typedef uint32_t xkb_keycode_t;
 
@@ -157,7 +167,7 @@ typedef uint32_t xkb_keycode_t;
  *
  * 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.
  *
@@ -260,7 +270,17 @@ typedef uint32_t xkb_led_mask_t;
 #define XKB_LED_INVALID     (0xffffffff)
 
 #define XKB_KEYCODE_MAX     (0xffffffff - 1)
+
+/**
+ * Test whether a value is a valid extended keycode.
+ * @sa xkb_keycode_t
+ **/
 #define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX)
+
+/**
+ * Test whether a value is a valid X11 keycode.
+ * @sa xkb_keycode_t
+ */
 #define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255)
 
 /**
@@ -322,7 +342,7 @@ xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size);
 /** 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)
 };
 
 /**
@@ -355,9 +375,9 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags);
  * @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);
@@ -387,7 +407,7 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym);
 /** 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)
 };
 
 /**
@@ -419,12 +439,52 @@ xkb_context_ref(struct xkb_context *context);
 /**
  * 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
@@ -477,39 +537,14 @@ xkb_context_num_include_paths(struct xkb_context *context);
 /**
  * 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);
-
 /** @} */
 
 /**
@@ -525,7 +560,7 @@ enum xkb_log_level {
     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. */
 };
 
 /**
@@ -621,7 +656,7 @@ xkb_context_set_log_fn(struct xkb_context *context,
 /** 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
 };
 
 /**
@@ -651,7 +686,7 @@ xkb_keymap_new_from_names(struct xkb_context *context,
 /** 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
 };
 
 /**
@@ -704,12 +739,17 @@ xkb_keymap_ref(struct xkb_keymap *keymap);
 /**
  * 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)
 
 /**
@@ -822,7 +862,11 @@ xkb_layout_index_t
 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
@@ -832,7 +876,42 @@ xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key,
                               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
@@ -918,6 +997,8 @@ xkb_state_ref(struct xkb_state *state);
 /**
  * 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
@@ -941,18 +1022,53 @@ xkb_state_get_keymap(struct xkb_state *state);
 /** 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. */
+};
+
+/**
+ * Modifier and layout types for state objects.  This enum is bitmaskable,
+ * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
+ * exclude locked modifiers.
+ *
+ * In XKB, the DEPRESSED components are also known as 'base'.
+ */
+enum xkb_state_component {
+    /** Depressed modifiers, i.e. a key is physically holding them. */
+    XKB_STATE_MODS_DEPRESSED = (1 << 0),
+    /** Latched modifiers, i.e. will be unset after the next non-modifier
+     *  key press. */
+    XKB_STATE_MODS_LATCHED = (1 << 1),
+    /** Locked modifiers, i.e. will be unset after the key provoking the
+     *  lock has been pressed again. */
+    XKB_STATE_MODS_LOCKED = (1 << 2),
+    /** Effective modifiers, i.e. currently active and affect key
+     *  processing (derived from the other state components). */
+    XKB_STATE_MODS_EFFECTIVE = (1 << 3),
+    /** Depressed layout, i.e. a key is physically holding it. */
+    XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
+    /** Latched layout, i.e. will be unset after the next non-modifier
+     *  key press. */
+    XKB_STATE_LAYOUT_LATCHED = (1 << 5),
+    /** Locked layout, i.e. will be unset after the key provoking the lock
+     *  has been pressed again. */
+    XKB_STATE_LAYOUT_LOCKED = (1 << 6),
+    /** Effective layout, i.e. currently active and affects key processing
+     *  (derived from the other state components). */
+    XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
+    /** LEDs (derived from the other state components). */
+    XKB_STATE_LEDS = (1 << 8)
 };
 
 /**
  * Update the keyboard state to reflect a given key being pressed or
  * released.
  *
- * @todo Explain.
+ * @returns A mask of state components that have changed as a result of
+ * the update.  If nothing in the state has changed, returns 0.
  *
  * @memberof xkb_state
  */
-void
+enum xkb_state_component
 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
                      enum xkb_key_direction direction);
 
@@ -1044,63 +1160,6 @@ xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t key,
                         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);
-
-/**
- * Modifier and layout types for state objects.  This enum is bitmaskable,
- * e.g. (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED) is valid to exclude
- * locked modifiers.
- */
-enum xkb_state_component {
-    /** A key holding this modifier or layout is currently physically
-     *  depressed; also known as 'base'. */
-    XKB_STATE_DEPRESSED = (1 << 0),
-    /** Modifier or layout is latched, i.e. will be unset after the next
-     *  non-modifier key press. */
-    XKB_STATE_LATCHED = (1 << 1),
-    /** Modifier or layout is locked, i.e. will be unset after the key
-     *  provoking the lock has been pressed again. */
-    XKB_STATE_LOCKED = (1 << 2),
-    /** Combinatination of depressed, latched, and locked. */
-    XKB_STATE_EFFECTIVE =
-        (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED),
-};
-
-/**
  * 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
@@ -1113,11 +1172,11 @@ enum xkb_state_match {
     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
@@ -1133,40 +1192,63 @@ enum xkb_state_match {
  *
  * Please do not use this unless you fit the description above.
  *
+ * @returns A mask of state components that have changed as a result of
+ * the update.  If nothing in the state has changed, returns 0.
+ *
  * @memberof xkb_state
  */
-void
-xkb_state_update_mask(struct xkb_state *state, xkb_mod_mask_t base_mods,
-                      xkb_mod_mask_t latched_mods, xkb_mod_mask_t locked_mods,
-                      xkb_layout_index_t base_layout,
+enum xkb_state_component
+xkb_state_update_mask(struct xkb_state *state,
+                      xkb_mod_mask_t depressed_mods,
+                      xkb_mod_mask_t latched_mods,
+                      xkb_mod_mask_t locked_mods,
+                      xkb_layout_index_t depressed_layout,
                       xkb_layout_index_t latched_layout,
                       xkb_layout_index_t locked_layout);
 
 /**
- * The counterpart to xkb_state_update_mask, to be used on the server side
- * of serialization.
+ * The counterpart to xkb_state_update_mask for modifiers, to be used on
+ * the server side of serialization.
  *
- * @returns A xkb_mod_mask_t representing the given component(s) of the
- * state.
+ * @param state      The keyboard state.
+ * @param components A mask of the modifier state components to serialize.
+ * State components other than XKB_STATE_MODS_* are ignored.
+ * If XKB_STATE_MODS_EFFECTIVE is included, all other state components are
+ * ignored.
+ *
+ * @returns A xkb_mod_mask_t representing the given components of the
+ * modifier state.
  *
  * This function should not be used in regular clients; please use the
- * xkb_state_mod_*_is_active or xkb_state_foreach_active_mod API instead.
+ * xkb_state_mod_*_is_active API instead.
  *
  * @memberof xkb_state
  */
 xkb_mod_mask_t
 xkb_state_serialize_mods(struct xkb_state *state,
-                         enum xkb_state_component component);
+                         enum xkb_state_component components);
 
 /**
- * The layout equivalent of xkb_state_serialize_mods.
+ * The counterpart to xkb_state_update_mask for layouts, to be used on
+ * the server side of serialization.
+ *
+ * @param state      The keyboard state.
+ * @param components A mask of the layout state components to serialize.
+ * State components other than XKB_STATE_LAYOUT_* are ignored.
+ * If XKB_STATE_LAYOUT_EFFECTIVE is included, all other state components are
+ * ignored.
+ *
+ * @returns A layout index representing the given components of the
+ * layout state.
+ *
+ * This function should not be used in regular clients; please use the
+ * xkb_state_layout_*_is_active API instead.
  *
- * @sa xkb_state_serialize_mods
  * @memberof xkb_state
  */
 xkb_layout_index_t
 xkb_state_serialize_layout(struct xkb_state *state,
-                           enum xkb_state_component component);
+                           enum xkb_state_component components);
 
 /**
  * Test whether a modifier is active in a given keyboard state by name.
@@ -1245,18 +1327,59 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
  * 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