keymap: wrap the layout parameter if it is out of range for the key
[platform/upstream/libxkbcommon.git] / xkbcommon / xkbcommon.h
index e9b324f..244b35b 100644 (file)
@@ -167,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.
  *
@@ -342,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)
 };
 
 /**
@@ -375,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);
@@ -407,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)
 };
 
 /**
@@ -439,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
@@ -497,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);
-
 /** @} */
 
 /**
@@ -545,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. */
 };
 
 /**
@@ -641,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
 };
 
 /**
@@ -671,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
 };
 
 /**
@@ -724,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)
 
 /**
@@ -842,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
@@ -852,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
@@ -938,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
@@ -961,7 +1022,7 @@ 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. */
 };
 
 /**
@@ -969,7 +1030,7 @@ enum xkb_key_direction {
  * 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. */
@@ -995,7 +1056,7 @@ enum xkb_state_component {
      *  (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)
 };
 
 /**
@@ -1099,43 +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);
-
-/**
  * 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
@@ -1148,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
@@ -1175,10 +1199,10 @@ enum xkb_state_match {
  */
 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);
 
@@ -1214,7 +1238,7 @@ xkb_state_serialize_mods(struct xkb_state *state,
  * 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
@@ -1303,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