Skip to content

Commit

Permalink
keysyms: Add XKB_KEYSYM_NAME_MAX_SIZE
Browse files Browse the repository at this point in the history
Currently there is no indication of the maximum length of keysym names.

This is statically known, so add the new following API:
`XKB_KEYSYM_NAME_MAX_SIZE`.
  • Loading branch information
wismill committed Dec 6, 2023
1 parent d2b40a8 commit e47467b
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 17 deletions.
2 changes: 1 addition & 1 deletion doc/quick-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ from it. Given a keycode for a key, we can get its keysym:
We can see which keysym we got, and get its name:

~~~{.c}
char keysym_name[64];
char keysym_name[XKB_KEYSYM_NAME_MAX_SIZE];
if (keysym == XKB_KEY_Space)
<got a space>
Expand Down
14 changes: 12 additions & 2 deletions include/xkbcommon/xkbcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,15 @@ typedef uint32_t xkb_led_mask_t;
*/
#define XKB_KEYSYM_MAX 0x1fffffff

/**
* Maximum keysym name length.
*
* @since 1.7.0
* @sa xkb_keysym_get_name
* @ingroup keysyms
*/
#define XKB_KEYSYM_NAME_MAX_SIZE 27

/**
* Test whether a value is a valid extended keycode.
* @sa xkb_keycode_t
Expand Down Expand Up @@ -442,15 +451,16 @@ struct xkb_rule_names {
* @param[in] size Size of the buffer.
*
* @warning If the buffer passed is too small, the string is truncated
* (though still NUL-terminated); a size of at least 64 bytes is recommended.
* (though still NUL-terminated); a size of at least
* `XKB_KEYSYM_NAME_MAX_SIZE` bytes is recommended.
*
* @returns The number of bytes in the name, excluding the NUL byte. If
* the keysym is invalid, returns -1.
*
* You may check if truncation has occurred by comparing the return value
* with the length of buffer, similarly to the snprintf(3) function.
*
* @sa xkb_keysym_t
* @sa xkb_keysym_t, XKB_KEYSYM_NAME_MAX_SIZE
*/
int
xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size);
Expand Down
14 changes: 12 additions & 2 deletions include/xkbcommon/xkbcommon.h.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,15 @@ typedef uint32_t xkb_led_mask_t;
*/
#define XKB_KEYSYM_MAX 0x1fffffff

/**
* Maximum keysym name length.
*
* @since 1.7.0
* @sa xkb_keysym_get_name
* @ingroup keysyms
*/
#define XKB_KEYSYM_NAME_MAX_SIZE {{ XKB_KEYSYM_NAME_MAX_SIZE }}

/**
* Test whether a value is a valid extended keycode.
* @sa xkb_keycode_t
Expand Down Expand Up @@ -442,15 +451,16 @@ struct xkb_rule_names {
* @param[in] size Size of the buffer.
*
* @warning If the buffer passed is too small, the string is truncated
* (though still NUL-terminated); a size of at least 64 bytes is recommended.
* (though still NUL-terminated); a size of at least
* `XKB_KEYSYM_NAME_MAX_SIZE` bytes is recommended.
*
* @returns The number of bytes in the name, excluding the NUL byte. If
* the keysym is invalid, returns -1.
*
* You may check if truncation has occurred by comparing the return value
* with the length of buffer, similarly to the snprintf(3) function.
*
* @sa xkb_keysym_t
* @sa xkb_keysym_t, XKB_KEYSYM_NAME_MAX_SIZE
*/
int
xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size);
Expand Down
10 changes: 10 additions & 0 deletions scripts/update-headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,27 @@ def load_keysyms(path: Path) -> dict[str, int]:
keysym_max = 0
min_unicode_keysym = 0x01000100
max_unicode_keysym = 0x0110FFFF
canonical_names: dict[int, str] = {}
max_unicode_name = "U10FFFF"
max_keysym_name = "0x1fffffff" # XKB_KEYSYM_MAX
with path.open("rt", encoding="utf-8") as fd:
for line in fd:
if m := KEYSYM_PATTERN.match(line):
value = int(m.group("value"), 16)
keysym_min = min(keysym_min, value)
keysym_max = max(keysym_max, value)
if value not in canonical_names:
canonical_names[value] = m.group("name")
return {
"XKB_KEYSYM_MIN_ASSIGNED": min(keysym_min, min_unicode_keysym),
"XKB_KEYSYM_MAX_ASSIGNED": max(keysym_max, max_unicode_keysym),
"XKB_KEYSYM_MIN_EXPLICIT": keysym_min,
"XKB_KEYSYM_MAX_EXPLICIT": keysym_max,
"XKB_KEYSYM_NAME_MAX_SIZE": max(
max(len(name) for name in canonical_names.values()),
len(max_unicode_name),
len(max_keysym_name),
),
}


Expand Down
4 changes: 2 additions & 2 deletions src/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ ActionTypeText(enum xkb_action_type type)
const char *
KeysymText(struct xkb_context *ctx, xkb_keysym_t sym)
{
char *buffer = xkb_context_get_buffer(ctx, 64);
xkb_keysym_get_name(sym, buffer, 64);
char *buffer = xkb_context_get_buffer(ctx, XKB_KEYSYM_NAME_MAX_SIZE);
xkb_keysym_get_name(sym, buffer, XKB_KEYSYM_NAME_MAX_SIZE);
return buffer;
}

Expand Down
2 changes: 1 addition & 1 deletion test/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ test_key_seq_va(struct xkb_keymap *keymap, va_list ap)
const xkb_keysym_t *syms;
xkb_keysym_t sym;
unsigned int nsyms, i;
char ksbuf[64];
char ksbuf[XKB_KEYSYM_NAME_MAX_SIZE];

fprintf(stderr, "----\n");

Expand Down
2 changes: 1 addition & 1 deletion test/compose.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ test_compose_seq_va(struct xkb_compose_table *table, va_list ap)
{
int ret;
struct xkb_compose_state *state;
char buffer[64];
char buffer[XKB_KEYSYM_NAME_MAX_SIZE];

state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS);
assert(state);
Expand Down
14 changes: 9 additions & 5 deletions test/keysym.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ test_casestring(const char *string, xkb_keysym_t expected)
static int
test_keysym(xkb_keysym_t keysym, const char *expected)
{
char s[16];
char s[XKB_KEYSYM_NAME_MAX_SIZE];

xkb_keysym_get_name(keysym, s, sizeof(s));

Expand Down Expand Up @@ -117,11 +117,11 @@ get_keysym_name(xkb_keysym_t keysym, char *buffer, size_t size)
static int
test_utf32_to_keysym(uint32_t ucs, xkb_keysym_t expected)
{
char expected_name[64];
char actual_name[64];
char expected_name[XKB_KEYSYM_NAME_MAX_SIZE];
char actual_name[XKB_KEYSYM_NAME_MAX_SIZE];
xkb_keysym_t actual = xkb_utf32_to_keysym(ucs);
get_keysym_name(expected, expected_name, 64);
get_keysym_name(actual, actual_name, 64);
get_keysym_name(expected, expected_name, XKB_KEYSYM_NAME_MAX_SIZE);
get_keysym_name(actual, actual_name, XKB_KEYSYM_NAME_MAX_SIZE);

fprintf(stderr, "Code point 0x%lx: expected keysym: %s, actual: %s\n\n",
(unsigned long)ucs, expected_name, actual_name);
Expand Down Expand Up @@ -170,6 +170,10 @@ main(void)
char utf8[7];
int count = xkb_keysym_to_utf8(ks, utf8, sizeof(utf8));
assert(0 <= count && count <= 5);
/* Check maximum name length */
char name[XKB_KEYSYM_NAME_MAX_SIZE];
count = xkb_keysym_iterator_name(iter, name, sizeof(name));
assert(0 < count && (size_t)count <= sizeof(name));
} while (xkb_keysym_iterator_next(iter));
xkb_keysym_iterator_unref(iter);
assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED);
Expand Down
2 changes: 1 addition & 1 deletion tools/compile-compose.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ print_compose_table_entry(struct xkb_compose_table_entry *entry)
{
size_t nsyms;
const xkb_keysym_t *syms = xkb_compose_table_entry_sequence(entry, &nsyms);
char buf[128];
char buf[XKB_KEYSYM_NAME_MAX_SIZE];
for (size_t i = 0; i < nsyms; i++) {
xkb_keysym_get_name(syms[i], buf, sizeof(buf));
printf("<%s>", buf);
Expand Down
2 changes: 1 addition & 1 deletion tools/how-to-type.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ main(int argc, char *argv[])
uint32_t codepoint;
xkb_keysym_t keysym;
int ret;
char name[200];
char name[XKB_KEYSYM_NAME_MAX_SIZE];
struct xkb_keymap *keymap = NULL;
xkb_keycode_t min_keycode, max_keycode;
xkb_mod_index_t num_mods;
Expand Down
5 changes: 4 additions & 1 deletion tools/tools-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#endif

#include "tools-common.h"
#include "src/utils.h"

static void
print_keycode(struct xkb_keymap *keymap, const char* prefix,
Expand Down Expand Up @@ -155,7 +156,9 @@ tools_print_keycode_state(char *prefix,
xkb_keysym_t sym;
const xkb_keysym_t *syms;
int nsyms;
char s[16];
// FIXME: this buffer is used for xkb_compose_state_get_utf8,
// which can have a length up to 256. Need to import this constant from compose.
char s[MAX(16, XKB_KEYSYM_NAME_MAX_SIZE)];
xkb_layout_index_t layout;
enum xkb_compose_status status;

Expand Down

0 comments on commit e47467b

Please sign in to comment.