mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-30 21:21:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			500 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			500 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * 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 */
 | 
