| /* |
| * Copyright © 2013 Ran Benita |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| * DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #ifndef _XKBCOMMON_COMPOSE_H |
| #define _XKBCOMMON_COMPOSE_H |
| |
| #include <xkbcommon/xkbcommon.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @file |
| * libxkbcommon Compose API - support for Compose and dead-keys. |
| */ |
| |
| /** |
| * @defgroup compose Compose and dead-keys support |
| * Support for Compose and dead-keys. |
| * @since 0.5.0 |
| * |
| * @{ |
| */ |
| |
| /** |
| * @page compose-overview Overview |
| * @parblock |
| * |
| * Compose and dead-keys are a common feature of many keyboard input |
| * systems. They extend the range of the keysysm that can be produced |
| * directly from a keyboard by using a sequence of key strokes, instead |
| * of just one. |
| * |
| * Here are some example sequences, in the libX11 Compose file format: |
| * |
| * <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE |
| * <Multi_key> <A> <T> : "@" at # COMMERCIAL AT |
| * |
| * When the user presses a key which produces the `<dead_acute>` keysym, |
| * nothing initially happens (thus the key is dubbed a "dead-key"). But |
| * when the user enters `<a>`, "á" is "composed", in place of "a". If |
| * instead the user had entered a keysym which does not follow |
| * `<dead_acute>` in any compose sequence, the sequence is said to be |
| * "cancelled". |
| * |
| * Compose files define many such sequences. For a description of the |
| * common file format for Compose files, see the Compose(5) man page. |
| * |
| * A successfuly-composed sequence has two results: a keysym and a UTF-8 |
| * string. At least one of the two is defined for each sequence. If only |
| * a keysym is given, the keysym's string representation is used for the |
| * result string (using xkb_keysym_to_utf8()). |
| * |
| * This library provides low-level support for Compose file parsing and |
| * processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3)) |
| * may be built upon it, or it can be used directly. |
| * |
| * @endparblock |
| */ |
| |
| /** |
| * @page compose-conflicting Conflicting Sequences |
| * @parblock |
| * |
| * To avoid ambiguity, a sequence is not allowed to be a prefix of another. |
| * In such a case, the conflict is resolved thus: |
| * |
| * 1. A longer sequence overrides a shorter one. |
| * 2. An equal sequence overrides an existing one. |
| * 3. A shorter sequence does not override a longer one. |
| * |
| * Sequences of length 1 are allowed. |
| * |
| * @endparblock |
| */ |
| |
| /** |
| * @page compose-cancellation Cancellation Behavior |
| * @parblock |
| * |
| * What should happen when a sequence is cancelled? For example, consider |
| * there are only the above sequences, and the input keysyms are |
| * `<dead_acute> <b>`. There are a few approaches: |
| * |
| * 1. Swallow the cancelling keysym; that is, no keysym is produced. |
| * This is the approach taken by libX11. |
| * 2. Let the cancelling keysym through; that is, `<b>` is produced. |
| * 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced. |
| * This is the approach taken by Microsoft Windows (approximately; |
| * instead of `<dead_acute>`, the underlying key is used. This is |
| * difficult to simulate with XKB keymaps). |
| * |
| * You can program whichever approach best fits users' expectations. |
| * |
| * @endparblock |
| */ |
| |
| /** |
| * @struct xkb_compose_table |
| * Opaque Compose table object. |
| * |
| * The compose table holds the definitions of the Compose sequences, as |
| * gathered from Compose files. It is immutable. |
| */ |
| struct xkb_compose_table; |
| |
| /** |
| * @struct xkb_compose_state |
| * Opaque Compose state object. |
| * |
| * The compose state maintains state for compose sequence matching, such |
| * as which possible sequences are being matched, and the position within |
| * these sequences. It acts as a simple state machine wherein keysyms are |
| * the input, and composed keysyms and strings are the output. |
| * |
| * The compose state is usually associated with a keyboard device. |
| */ |
| struct xkb_compose_state; |
| |
| /** Flags affecting Compose file compilation. */ |
| enum xkb_compose_compile_flags { |
| /** Do not apply any flags. */ |
| XKB_COMPOSE_COMPILE_NO_FLAGS = 0 |
| }; |
| |
| /** The recognized Compose file formats. */ |
| enum xkb_compose_format { |
| /** The classic libX11 Compose text format, described in Compose(5). */ |
| XKB_COMPOSE_FORMAT_TEXT_V1 = 1 |
| }; |
| |
| /** |
| * @page compose-locale Compose Locale |
| * @parblock |
| * |
| * Compose files are locale dependent: |
| * - Compose files are written for a locale, and the locale is used when |
| * searching for the appropriate file to use. |
| * - Compose files may reference the locale internally, with directives |
| * such as \%L. |
| * |
| * As such, functions like xkb_compose_table_new_from_locale() require |
| * a `locale` parameter. This will usually be the current locale (see |
| * locale(7) for more details). You may also want to allow the user to |
| * explicitly configure it, so he can use the Compose file of a given |
| * locale, but not use that locale for other things. |
| * |
| * You may query the current locale as follows: |
| * @code |
| * const char *locale; |
| * locale = setlocale(LC_CTYPE, NULL); |
| * @endcode |
| * |
| * This will only give useful results if the program had previously set |
| * the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL` |
| * and a non-NULL argument. |
| * |
| * If you prefer not to use the locale system of the C runtime library, |
| * you may nevertheless obtain the user's locale directly using |
| * environment variables, as described in locale(7). For example, |
| * @code |
| * const char *locale; |
| * locale = getenv("LC_ALL"); |
| * if (!locale || !*locale) |
| * locale = getenv("LC_CTYPE"); |
| * if (!locale || !*locale) |
| * locale = getenv("LANG"); |
| * if (!locale || !*locale) |
| * locale = "C"; |
| * @endcode |
| * |
| * Note that some locales supported by the C standard library may not |
| * have a Compose file assigned. |
| * |
| * @endparblock |
| */ |
| |
| /** |
| * Create a compose table for a given locale. |
| * |
| * The locale is used for searching the file-system for an appropriate |
| * Compose file. The search order is described in Compose(5). It is |
| * affected by the following environment variables: |
| * |
| * 1. `XCOMPOSEFILE` - see Compose(5). |
| * 2. `XDG_CONFIG_HOME` - before `$HOME/.XCompose` is checked, |
| * `$XDG_CONFIG_HOME/XCompose` is checked (with a fall back to |
| * `$HOME/.config/XCompose` if `XDG_CONFIG_HOME` is not defined). |
| * This is a libxkbcommon extension to the search procedure in |
| * Compose(5) (since libxkbcommon 1.0.0). Note that other |
| * implementations, such as libX11, might not find a Compose file in |
| * this path. |
| * 3. `HOME` - see Compose(5). |
| * 4. `XLOCALEDIR` - if set, used as the base directory for the system's |
| * X locale files, e.g. `/usr/share/X11/locale`, instead of the |
| * preconfigured directory. |
| * |
| * @param context |
| * The library context in which to create the compose table. |
| * @param locale |
| * The current locale. See @ref compose-locale. |
| * \n |
| * The value is copied, so it is safe to pass the result of getenv(3) |
| * (or similar) without fear of it being invalidated by a subsequent |
| * setenv(3) (or similar). |
| * @param flags |
| * Optional flags for the compose table, or 0. |
| * |
| * @returns A compose table for the given locale, or NULL if the |
| * compilation failed or a Compose file was not found. |
| * |
| * @memberof xkb_compose_table |
| */ |
| struct xkb_compose_table * |
| xkb_compose_table_new_from_locale(struct xkb_context *context, |
| const char *locale, |
| enum xkb_compose_compile_flags flags); |
| |
| /** |
| * Create a new compose table from a Compose file. |
| * |
| * @param context |
| * The library context in which to create the compose table. |
| * @param file |
| * The Compose file to compile. |
| * @param locale |
| * The current locale. See @ref compose-locale. |
| * @param format |
| * The text format of the Compose file to compile. |
| * @param flags |
| * Optional flags for the compose table, or 0. |
| * |
| * @returns A compose table compiled from the given file, or NULL if |
| * the compilation failed. |
| * |
| * @memberof xkb_compose_table |
| */ |
| struct xkb_compose_table * |
| xkb_compose_table_new_from_file(struct xkb_context *context, |
| FILE *file, |
| const char *locale, |
| enum xkb_compose_format format, |
| enum xkb_compose_compile_flags flags); |
| |
| /** |
| * Create a new compose table from a memory buffer. |
| * |
| * This is just like xkb_compose_table_new_from_file(), but instead of |
| * a file, gets the table as one enormous string. |
| * |
| * @see xkb_compose_table_new_from_file() |
| * @memberof xkb_compose_table |
| */ |
| struct xkb_compose_table * |
| xkb_compose_table_new_from_buffer(struct xkb_context *context, |
| const char *buffer, size_t length, |
| const char *locale, |
| enum xkb_compose_format format, |
| enum xkb_compose_compile_flags flags); |
| |
| /** |
| * Take a new reference on a compose table. |
| * |
| * @returns The passed in object. |
| * |
| * @memberof xkb_compose_table |
| */ |
| struct xkb_compose_table * |
| xkb_compose_table_ref(struct xkb_compose_table *table); |
| |
| /** |
| * Release a reference on a compose table, and possibly free it. |
| * |
| * @param table The object. If it is NULL, this function does nothing. |
| * |
| * @memberof xkb_compose_table |
| */ |
| void |
| xkb_compose_table_unref(struct xkb_compose_table *table); |
| |
| /** Flags for compose state creation. */ |
| enum xkb_compose_state_flags { |
| /** Do not apply any flags. */ |
| XKB_COMPOSE_STATE_NO_FLAGS = 0 |
| }; |
| |
| /** |
| * Create a new compose state object. |
| * |
| * @param table |
| * The compose table the state will use. |
| * @param flags |
| * Optional flags for the compose state, or 0. |
| * |
| * @returns A new compose state, or NULL on failure. |
| * |
| * @memberof xkb_compose_state |
| */ |
| struct xkb_compose_state * |
| xkb_compose_state_new(struct xkb_compose_table *table, |
| enum xkb_compose_state_flags flags); |
| |
| /** |
| * Take a new reference on a compose state object. |
| * |
| * @returns The passed in object. |
| * |
| * @memberof xkb_compose_state |
| */ |
| struct xkb_compose_state * |
| xkb_compose_state_ref(struct xkb_compose_state *state); |
| |
| /** |
| * Release a reference on a compose state object, and possibly free it. |
| * |
| * @param state The object. If NULL, do nothing. |
| * |
| * @memberof xkb_compose_state |
| */ |
| void |
| xkb_compose_state_unref(struct xkb_compose_state *state); |
| |
| /** |
| * Get the compose table which a compose state object is using. |
| * |
| * @returns The compose table which was passed to xkb_compose_state_new() |
| * when creating this state object. |
| * |
| * This function does not take a new reference on the compose table; you |
| * must explicitly reference it yourself if you plan to use it beyond the |
| * lifetime of the state. |
| * |
| * @memberof xkb_compose_state |
| */ |
| struct xkb_compose_table * |
| xkb_compose_state_get_compose_table(struct xkb_compose_state *state); |
| |
| /** Status of the Compose sequence state machine. */ |
| enum xkb_compose_status { |
| /** The initial state; no sequence has started yet. */ |
| XKB_COMPOSE_NOTHING, |
| /** In the middle of a sequence. */ |
| XKB_COMPOSE_COMPOSING, |
| /** A complete sequence has been matched. */ |
| XKB_COMPOSE_COMPOSED, |
| /** The last sequence was cancelled due to an unmatched keysym. */ |
| XKB_COMPOSE_CANCELLED |
| }; |
| |
| /** The effect of a keysym fed to xkb_compose_state_feed(). */ |
| enum xkb_compose_feed_result { |
| /** The keysym had no effect - it did not affect the status. */ |
| XKB_COMPOSE_FEED_IGNORED, |
| /** The keysym started, advanced or cancelled a sequence. */ |
| XKB_COMPOSE_FEED_ACCEPTED |
| }; |
| |
| /** |
| * Feed one keysym to the Compose sequence state machine. |
| * |
| * This function can advance into a compose sequence, cancel a sequence, |
| * start a new sequence, or do nothing in particular. The resulting |
| * status may be observed with xkb_compose_state_get_status(). |
| * |
| * Some keysyms, such as keysyms for modifier keys, are ignored - they |
| * have no effect on the status or otherwise. |
| * |
| * The following is a description of the possible status transitions, in |
| * the format CURRENT STATUS => NEXT STATUS, given a non-ignored input |
| * keysym `keysym`: |
| * |
| @verbatim |
| NOTHING or CANCELLED or COMPOSED => |
| NOTHING if keysym does not start a sequence. |
| COMPOSING if keysym starts a sequence. |
| COMPOSED if keysym starts and terminates a single-keysym sequence. |
| |
| COMPOSING => |
| COMPOSING if keysym advances any of the currently possible |
| sequences but does not terminate any of them. |
| COMPOSED if keysym terminates one of the currently possible |
| sequences. |
| CANCELLED if keysym does not advance any of the currently |
| possible sequences. |
| @endverbatim |
| * |
| * The current Compose formats do not support multiple-keysyms. |
| * Therefore, if you are using a function such as xkb_state_key_get_syms() |
| * and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol |
| * instead. |
| * |
| * @param state |
| * The compose state object. |
| * @param keysym |
| * A keysym, usually obtained after a key-press event, with a |
| * function such as xkb_state_key_get_one_sym(). |
| * |
| * @returns Whether the keysym was ignored. This is useful, for example, |
| * if you want to keep a record of the sequence matched thus far. |
| * |
| * @memberof xkb_compose_state |
| */ |
| enum xkb_compose_feed_result |
| xkb_compose_state_feed(struct xkb_compose_state *state, |
| xkb_keysym_t keysym); |
| |
| /** |
| * Reset the Compose sequence state machine. |
| * |
| * The status is set to XKB_COMPOSE_NOTHING, and the current sequence |
| * is discarded. |
| * |
| * @memberof xkb_compose_state |
| */ |
| void |
| xkb_compose_state_reset(struct xkb_compose_state *state); |
| |
| /** |
| * Get the current status of the compose state machine. |
| * |
| * @see xkb_compose_status |
| * @memberof xkb_compose_state |
| **/ |
| enum xkb_compose_status |
| xkb_compose_state_get_status(struct xkb_compose_state *state); |
| |
| /** |
| * Get the result Unicode/UTF-8 string for a composed sequence. |
| * |
| * See @ref compose-overview for more details. This function is only |
| * useful when the status is XKB_COMPOSE_COMPOSED. |
| * |
| * @param[in] state |
| * The compose state. |
| * @param[out] buffer |
| * A buffer to write the string into. |
| * @param[in] size |
| * Size of the buffer. |
| * |
| * @warning If the buffer passed is too small, the string is truncated |
| * (though still NUL-terminated). |
| * |
| * @returns |
| * The number of bytes required for the string, excluding the NUL byte. |
| * If the sequence is not complete, or does not have a viable result |
| * string, returns 0, and sets `buffer` to the empty string (if possible). |
| * @returns |
| * You may check if truncation has occurred by comparing the return value |
| * with the size of `buffer`, similarly to the `snprintf`(3) function. |
| * You may safely pass NULL and 0 to `buffer` and `size` to find the |
| * required size (without the NUL-byte). |
| * |
| * @memberof xkb_compose_state |
| **/ |
| int |
| xkb_compose_state_get_utf8(struct xkb_compose_state *state, |
| char *buffer, size_t size); |
| |
| /** |
| * Get the result keysym for a composed sequence. |
| * |
| * See @ref compose-overview for more details. This function is only |
| * useful when the status is XKB_COMPOSE_COMPOSED. |
| * |
| * @returns The result keysym. If the sequence is not complete, or does |
| * not specify a result keysym, returns XKB_KEY_NoSymbol. |
| * |
| * @memberof xkb_compose_state |
| **/ |
| xkb_keysym_t |
| xkb_compose_state_get_one_sym(struct xkb_compose_state *state); |
| |
| /** @} */ |
| |
| #ifdef __cplusplus |
| } /* extern "C" */ |
| #endif |
| |
| #endif /* _XKBCOMMON_COMPOSE_H */ |