1/*
2 * Copyright © 2013 Ran Benita
3 * SPDX-License-Identifier: MIT
4 */
5
6#ifndef _XKBCOMMON_COMPOSE_H
7#define _XKBCOMMON_COMPOSE_H
8
9#include <xkbcommon/xkbcommon.h>
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
15/**
16 * @file
17 * libxkbcommon Compose API - support for Compose and dead-keys.
18 */
19
20/**
21 * @defgroup compose Compose and dead-keys support
22 * Support for Compose and dead-keys.
23 * @since 0.5.0
24 *
25 * @{
26 */
27
28/**
29 * @page compose-overview Overview
30 * @parblock
31 *
32 * Compose and dead-keys are a common feature of many keyboard input
33 * systems. They extend the range of the keysyms that can be produced
34 * directly from a keyboard by using a sequence of key strokes, instead
35 * of just one.
36 *
37 * Here are some example sequences, in the libX11 Compose file format:
38 *
39 * <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE
40 * <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
41 *
42 * When the user presses a key which produces the `<dead_acute>` keysym,
43 * nothing initially happens (thus the key is dubbed a *dead-key*). But
44 * when the user enters `<a>`, “á” is *composed*, in place of “a”. If
45 * instead the user had entered a keysym which does not follow
46 * `<dead_acute>` in any compose sequence, the sequence is said to be
47 * *cancelled*.
48 *
49 * Compose files define many such sequences. For a description of the
50 * common file format for Compose files, see the `Compose(5)` man page.
51 *
52 * A successfully-composed sequence has two results: a keysym and a UTF-8
53 * string. At least one of the two is defined for each sequence. If only
54 * a keysym is given, the keysym’s string representation is used for the
55 * result string (using xkb_keysym_to_utf8()).
56 *
57 * This library provides low-level support for Compose file parsing and
58 * processing. Higher-level APIs (such as libX11’s `Xutf8LookupString(3)`)
59 * may be built upon it, or it can be used directly.
60 *
61 * @endparblock
62 */
63
64/**
65 * @page compose-conflicting Conflicting Sequences
66 * @parblock
67 *
68 * To avoid ambiguity, a sequence is not allowed to be a prefix of another.
69 * When such a conflict occurs, the sequence defined last is the one retained.
70 *
71 * Sequences of length 1 are allowed.
72 *
73 * @endparblock
74 */
75
76/**
77 * @page compose-cancellation Cancellation Behavior
78 * @parblock
79 *
80 * What should happen when a sequence is cancelled? For example, consider
81 * there are only the above sequences, and the input keysyms are
82 * `<dead_acute> <b>`. There are a few approaches:
83 *
84 * 1. Swallow the cancelling keysym; that is, no keysym is produced.
85 * This is the approach taken by libX11.
86 * 2. Let the cancelling keysym through; that is, `<b>` is produced.
87 * 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced.
88 * This is the approach taken by Microsoft Windows (approximately;
89 * instead of `<dead_acute>`, the underlying key is used. This is
90 * difficult to simulate with XKB keymaps).
91 *
92 * You can program whichever approach best fits users' expectations.
93 *
94 * @endparblock
95 */
96
97/**
98 * @struct xkb_compose_table
99 * Opaque Compose table object.
100 *
101 * The compose table holds the definitions of the Compose sequences, as
102 * gathered from Compose files. It is immutable.
103 */
104struct xkb_compose_table;
105
106/**
107 * @struct xkb_compose_state
108 * Opaque Compose state object.
109 *
110 * The compose state maintains state for compose sequence matching, such
111 * as which possible sequences are being matched, and the position within
112 * these sequences. It acts as a simple state machine wherein keysyms are
113 * the input, and composed keysyms and strings are the output.
114 *
115 * The compose state is usually associated with a keyboard device.
116 */
117struct xkb_compose_state;
118
119/** Flags affecting Compose file compilation. */
120enum xkb_compose_compile_flags {
121 /** Do not apply any flags. */
122 XKB_COMPOSE_COMPILE_NO_FLAGS = 0
123};
124
125/** The recognized Compose file formats. */
126enum xkb_compose_format {
127 /** The classic libX11 Compose text format, described in Compose(5). */
128 XKB_COMPOSE_FORMAT_TEXT_V1 = 1
129};
130
131/**
132 * @page compose-locale Compose Locale
133 * @parblock
134 *
135 * Compose files are locale dependent:
136 * - Compose files are written for a locale, and the locale is used when
137 * searching for the appropriate file to use.
138 * - Compose files may reference the locale internally, with directives
139 * such as `%%L`.
140 *
141 * As such, functions like `xkb_compose_table::xkb_compose_table_new_from_locale()`
142 * require a `locale` parameter. This will usually be the current locale (see
143 * `locale(7)` for more details). You may also want to allow the user to
144 * explicitly configure it, so he can use the Compose file of a given
145 * locale, but not use that locale for other things.
146 *
147 * You may query the current locale as follows:
148 *
149 * ```c
150 * const char *locale;
151 * locale = setlocale(LC_CTYPE, NULL);
152 * ```
153 *
154 * This will only give useful results if the program had previously set
155 * the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL`
156 * and a non-`NULL` argument.
157 *
158 * If you prefer not to use the locale system of the C runtime library,
159 * you may nevertheless obtain the user’s locale directly using
160 * environment variables, as described in `locale(7)`. For example,
161 *
162 * ```c
163 * const char *locale;
164 * locale = getenv("LC_ALL");
165 * if (!locale || !*locale)
166 * locale = getenv("LC_CTYPE");
167 * if (!locale || !*locale)
168 * locale = getenv("LANG");
169 * if (!locale || !*locale)
170 * locale = "C";
171 * ```
172 *
173 * Note that some locales supported by the C standard library may not
174 * have a Compose file assigned.
175 *
176 * @endparblock
177 */
178
179/**
180 * Create a compose table for a given locale.
181 *
182 * The locale is used for searching the file-system for an appropriate
183 * Compose file. The search order is described in Compose(5). It is
184 * affected by the following environment variables:
185 *
186 * 1. `XCOMPOSEFILE` - see Compose(5).
187 * 2. `XDG_CONFIG_HOME` - before `$HOME/.XCompose` is checked,
188 * `$XDG_CONFIG_HOME/XCompose` is checked (with a fall back to
189 * `$HOME/.config/XCompose` if `XDG_CONFIG_HOME` is not defined).
190 * This is a libxkbcommon extension to the search procedure in
191 * Compose(5) (since libxkbcommon 1.0.0). Note that other
192 * implementations, such as libX11, might not find a Compose file in
193 * this path.
194 * 3. `HOME` - see Compose(5).
195 * 4. `XLOCALEDIR` - if set, used as the base directory for the system’s
196 * X locale files, e.g. `/usr/share/X11/locale`, instead of the
197 * preconfigured directory.
198 *
199 * Since 1.12, system locales not registered in `$XLOCALEDIR` will fallback
200 * to `en_US.UTF-8`, if missing locale detection is supported by the C standard
201 * library in use.
202 *
203 * @param context
204 * The library context in which to create the compose table.
205 * @param locale
206 * The current locale. See @ref compose-locale.
207 * \n
208 * The value is copied, so it is safe to pass the result of `getenv(3)`
209 * (or similar) without fear of it being invalidated by a subsequent
210 * `setenv(3)` (or similar).
211 * @param flags
212 * Optional flags for the compose table, or 0.
213 *
214 * @returns A compose table for the given locale, or `NULL` if the
215 * compilation failed or a Compose file was not found.
216 *
217 * @memberof xkb_compose_table
218 */
219XKB_EXPORT struct xkb_compose_table *
220xkb_compose_table_new_from_locale(struct xkb_context *context,
221 const char *locale,
222 enum xkb_compose_compile_flags flags);
223
224/**
225 * Create a new compose table from a Compose file.
226 *
227 * @param context
228 * The library context in which to create the compose table.
229 * @param file
230 * The Compose file to compile.
231 * @param locale
232 * The current locale. See @ref compose-locale.
233 * @param format
234 * The text format of the Compose file to compile.
235 * @param flags
236 * Optional flags for the compose table, or 0.
237 *
238 * @returns A compose table compiled from the given file, or `NULL` if
239 * the compilation failed.
240 *
241 * @memberof xkb_compose_table
242 */
243XKB_EXPORT struct xkb_compose_table *
244xkb_compose_table_new_from_file(struct xkb_context *context,
245 FILE *file,
246 const char *locale,
247 enum xkb_compose_format format,
248 enum xkb_compose_compile_flags flags);
249
250/**
251 * Create a new compose table from a memory buffer.
252 *
253 * This is just like xkb_compose_table_new_from_file(), but instead of
254 * a file, gets the table as one enormous string.
255 *
256 * @see xkb_compose_table_new_from_file()
257 * @memberof xkb_compose_table
258 */
259XKB_EXPORT struct xkb_compose_table *
260xkb_compose_table_new_from_buffer(struct xkb_context *context,
261 const char *buffer, size_t length,
262 const char *locale,
263 enum xkb_compose_format format,
264 enum xkb_compose_compile_flags flags);
265
266/**
267 * Take a new reference on a compose table.
268 *
269 * @returns The passed in object.
270 *
271 * @memberof xkb_compose_table
272 */
273XKB_EXPORT struct xkb_compose_table *
274xkb_compose_table_ref(struct xkb_compose_table *table);
275
276/**
277 * Release a reference on a compose table, and possibly free it.
278 *
279 * @param table The object. If it is `NULL`, this function does nothing.
280 *
281 * @memberof xkb_compose_table
282 */
283XKB_EXPORT void
284xkb_compose_table_unref(struct xkb_compose_table *table);
285
286/**
287 * @struct xkb_compose_table_entry
288 * Opaque Compose table entry object.
289 *
290 * Represents a single entry in a Compose file in the iteration API.
291 * It is immutable.
292 *
293 * @sa xkb_compose_table_iterator_new
294 * @since 1.6.0
295 */
296struct xkb_compose_table_entry;
297
298/**
299 * Get the left-hand keysym sequence of a Compose table entry.
300 *
301 * For example, given the following entry:
302 *
303 * ```
304 * <dead_tilde> <space> : "~" asciitilde # TILDE
305 * ```
306 *
307 * it will return `{XKB_KEY_dead_tilde, XKB_KEY_space}`.
308 *
309 * @param[in] entry The compose table entry object to process.
310 *
311 * @param[out] sequence_length Number of keysyms in the sequence.
312 *
313 * @returns The array of left-hand side keysyms. The number of keysyms
314 * is returned in the @p sequence_length out-parameter.
315 *
316 * @memberof xkb_compose_table_entry
317 * @since 1.6.0
318 */
319XKB_EXPORT const xkb_keysym_t *
320xkb_compose_table_entry_sequence(struct xkb_compose_table_entry *entry,
321 size_t *sequence_length);
322
323/**
324 * Get the right-hand result keysym of a Compose table entry.
325 *
326 * For example, given the following entry:
327 *
328 * ```
329 * <dead_tilde> <space> : "~" asciitilde # TILDE
330 * ```
331 *
332 * it will return `XKB_KEY_asciitilde`.
333 *
334 * The keysym is optional; if the entry does not specify a keysym,
335 * returns `XKB_KEY_NoSymbol`.
336 *
337 * @memberof xkb_compose_table_entry
338 * @since 1.6.0
339 */
340XKB_EXPORT xkb_keysym_t
341xkb_compose_table_entry_keysym(struct xkb_compose_table_entry *entry);
342
343/**
344 * Get the right-hand result string of a Compose table entry.
345 *
346 * The string is UTF-8 encoded and `NULL`-terminated.
347 *
348 * For example, given the following entry:
349 *
350 * ```
351 * <dead_tilde> <space> : "~" asciitilde # TILDE
352 * ```
353 *
354 * it will return `"~"`.
355 *
356 * The string is optional; if the entry does not specify a string,
357 * returns the empty string.
358 *
359 * @memberof xkb_compose_table_entry
360 * @since 1.6.0
361 */
362XKB_EXPORT const char *
363xkb_compose_table_entry_utf8(struct xkb_compose_table_entry *entry);
364
365/**
366 * @struct xkb_compose_table_iterator
367 * Iterator over a compose table’s entries.
368 *
369 * @sa xkb_compose_table_iterator_new()
370 * @since 1.6.0
371 */
372struct xkb_compose_table_iterator;
373
374/**
375 * Create a new iterator for a compose table.
376 *
377 * Intended use:
378 *
379 * ```c
380 * struct xkb_compose_table_iterator *iter = xkb_compose_table_iterator_new(compose_table);
381 * struct xkb_compose_table_entry *entry;
382 * while ((entry = xkb_compose_table_iterator_next(iter))) {
383 * // ...
384 * }
385 * xkb_compose_table_iterator_free(iter);
386 * ```
387 *
388 * @returns A new compose table iterator, or `NULL` on failure.
389 *
390 * @memberof xkb_compose_table_iterator
391 * @sa xkb_compose_table_iterator_free()
392 * @since 1.6.0
393 */
394XKB_EXPORT struct xkb_compose_table_iterator *
395xkb_compose_table_iterator_new(struct xkb_compose_table *table);
396
397/**
398 * Free a compose iterator.
399 *
400 * @memberof xkb_compose_table_iterator
401 * @since 1.6.0
402 */
403XKB_EXPORT void
404xkb_compose_table_iterator_free(struct xkb_compose_table_iterator *iter);
405
406/**
407 * Get the next compose entry from a compose table iterator.
408 *
409 * The entries are returned in lexicographic order of the left-hand
410 * side of entries. This does not correspond to the order in which
411 * the entries appear in the Compose file.
412 *
413 * @attention The return value is valid until the next call to this function.
414 *
415 * Returns `NULL` in case there is no more entries.
416 *
417 * @memberof xkb_compose_table_iterator
418 * @since 1.6.0
419 */
420XKB_EXPORT struct xkb_compose_table_entry *
421xkb_compose_table_iterator_next(struct xkb_compose_table_iterator *iter);
422
423/** Flags for compose state creation. */
424enum xkb_compose_state_flags {
425 /** Do not apply any flags. */
426 XKB_COMPOSE_STATE_NO_FLAGS = 0
427};
428
429/**
430 * Create a new compose state object.
431 *
432 * @param table
433 * The compose table the state will use.
434 * @param flags
435 * Optional flags for the compose state, or 0.
436 *
437 * @returns A new compose state, or `NULL` on failure.
438 *
439 * @memberof xkb_compose_state
440 */
441XKB_EXPORT struct xkb_compose_state *
442xkb_compose_state_new(struct xkb_compose_table *table,
443 enum xkb_compose_state_flags flags);
444
445/**
446 * Take a new reference on a compose state object.
447 *
448 * @returns The passed in object.
449 *
450 * @memberof xkb_compose_state
451 */
452XKB_EXPORT struct xkb_compose_state *
453xkb_compose_state_ref(struct xkb_compose_state *state);
454
455/**
456 * Release a reference on a compose state object, and possibly free it.
457 *
458 * @param state The object. If `NULL`, do nothing.
459 *
460 * @memberof xkb_compose_state
461 */
462XKB_EXPORT void
463xkb_compose_state_unref(struct xkb_compose_state *state);
464
465/**
466 * Get the compose table which a compose state object is using.
467 *
468 * @returns The compose table which was passed to xkb_compose_state_new()
469 * when creating this state object.
470 *
471 * This function does not take a new reference on the compose table; you
472 * must explicitly reference it yourself if you plan to use it beyond the
473 * lifetime of the state.
474 *
475 * @memberof xkb_compose_state
476 */
477XKB_EXPORT struct xkb_compose_table *
478xkb_compose_state_get_compose_table(struct xkb_compose_state *state);
479
480/** Status of the Compose sequence state machine. */
481enum xkb_compose_status {
482 /** The initial state; no sequence has started yet. */
483 XKB_COMPOSE_NOTHING,
484 /** In the middle of a sequence. */
485 XKB_COMPOSE_COMPOSING,
486 /** A complete sequence has been matched. */
487 XKB_COMPOSE_COMPOSED,
488 /** The last sequence was cancelled due to an unmatched keysym. */
489 XKB_COMPOSE_CANCELLED
490};
491
492/** The effect of a keysym fed to xkb_compose_state_feed(). */
493enum xkb_compose_feed_result {
494 /** The keysym had no effect - it did not affect the status. */
495 XKB_COMPOSE_FEED_IGNORED,
496 /** The keysym started, advanced or cancelled a sequence. */
497 XKB_COMPOSE_FEED_ACCEPTED
498};
499
500/**
501 * Feed one keysym to the Compose sequence state machine.
502 *
503 * This function can advance into a compose sequence, cancel a sequence,
504 * start a new sequence, or do nothing in particular. The resulting
505 * status may be observed with `xkb_compose_state_get_status()`.
506 *
507 * Some keysyms, such as keysyms for modifier keys, are ignored - they
508 * have no effect on the status or otherwise.
509 *
510 * The following is a description of the possible status transitions, in
511 * the format CURRENT STATUS => NEXT STATUS, given a non-ignored input
512 * keysym `keysym`:
513 *
514 @verbatim
515 NOTHING or CANCELLED or COMPOSED =>
516 NOTHING if keysym does not start a sequence.
517 COMPOSING if keysym starts a sequence.
518 COMPOSED if keysym starts and terminates a single-keysym sequence.
519
520 COMPOSING =>
521 COMPOSING if keysym advances any of the currently possible
522 sequences but does not terminate any of them.
523 COMPOSED if keysym terminates one of the currently possible
524 sequences.
525 CANCELLED if keysym does not advance any of the currently
526 possible sequences.
527 @endverbatim
528 *
529 * The current Compose formats do not support multiple-keysyms. Therefore, if
530 * you are using a function such as `xkb_state::xkb_state_key_get_syms()`
531 * and it returns more than one keysym, consider feeding `XKB_KEY_NoSymbol`
532 * instead.
533 *
534 * @param state
535 * The compose state object.
536 * @param keysym
537 * A keysym, usually obtained after a key-press event, with a
538 * function such as `xkb_state::xkb_state_key_get_one_sym()`.
539 *
540 * @returns Whether the keysym was ignored. This is useful, for example,
541 * if you want to keep a record of the sequence matched thus far.
542 *
543 * @memberof xkb_compose_state
544 */
545XKB_EXPORT enum xkb_compose_feed_result
546xkb_compose_state_feed(struct xkb_compose_state *state,
547 xkb_keysym_t keysym);
548
549/**
550 * Reset the Compose sequence state machine.
551 *
552 * The status is set to `::XKB_COMPOSE_NOTHING`, and the current sequence
553 * is discarded.
554 *
555 * @memberof xkb_compose_state
556 */
557XKB_EXPORT void
558xkb_compose_state_reset(struct xkb_compose_state *state);
559
560/**
561 * Get the current status of the compose state machine.
562 *
563 * @see xkb_compose_status
564 * @memberof xkb_compose_state
565 **/
566XKB_EXPORT enum xkb_compose_status
567xkb_compose_state_get_status(struct xkb_compose_state *state);
568
569/**
570 * Get the result Unicode/UTF-8 string for a composed sequence.
571 *
572 * See @ref compose-overview for more details. This function is only
573 * useful when the status is `::XKB_COMPOSE_COMPOSED`.
574 *
575 * @param[in] state
576 * The compose state.
577 * @param[out] buffer
578 * A buffer to write the string into.
579 * @param[in] size
580 * Size of the buffer.
581 *
582 * @warning If the buffer passed is too small, the string is truncated
583 * (though still `NULL`-terminated).
584 *
585 * @returns
586 * The number of bytes required for the string, excluding the `NULL` byte.
587 * If the sequence is not complete, or does not have a viable result
588 * string, returns 0, and sets `buffer` to the empty string (if possible).
589 * @returns
590 * You may check if truncation has occurred by comparing the return value
591 * with the size of `buffer`, similarly to the `snprintf(3)` function.
592 * You may safely pass `NULL` and 0 to `buffer` and `size` to find the
593 * required size (without the `NULL`-byte).
594 *
595 * @memberof xkb_compose_state
596 **/
597XKB_EXPORT int
598xkb_compose_state_get_utf8(struct xkb_compose_state *state,
599 char *buffer, size_t size);
600
601/**
602 * Get the result keysym for a composed sequence.
603 *
604 * See @ref compose-overview for more details. This function is only
605 * useful when the status is `::XKB_COMPOSE_COMPOSED`.
606 *
607 * @returns The result keysym. If the sequence is not complete, or does
608 * not specify a result keysym, returns `XKB_KEY_NoSymbol`.
609 *
610 * @memberof xkb_compose_state
611 **/
612XKB_EXPORT xkb_keysym_t
613xkb_compose_state_get_one_sym(struct xkb_compose_state *state);
614
615/** @} */
616
617#ifdef __cplusplus
618} /* extern "C" */
619#endif
620
621#endif /* _XKBCOMMON_COMPOSE_H */