119 lines
2.5 KiB
C
119 lines
2.5 KiB
C
#include <assert.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <xcb-imdkit/encoding.h>
|
|
#include <xkbcommon/xkbcommon.h>
|
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
|
|
|
uint32_t keymaplookup(struct xkb_state*, uint8_t, uint16_t);
|
|
char *ximcompound(const char*, size_t, size_t*);
|
|
|
|
enum
|
|
{
|
|
ShiftMask = 1<<0,
|
|
LockMask = 1<<1,
|
|
Mod2Mask = 1<<4,
|
|
Mod5Mask = 1<<7,
|
|
Group1 = 1<<13,
|
|
};
|
|
|
|
static struct xkb_state*
|
|
keystate(const char *layout)
|
|
{
|
|
struct xkb_context *context;
|
|
struct xkb_keymap *keymap;
|
|
struct xkb_rule_names names;
|
|
struct xkb_state *state;
|
|
|
|
memset(&names, 0, sizeof names);
|
|
names.layout = layout;
|
|
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
assert(context != NULL);
|
|
keymap = xkb_keymap_new_from_names(context, &names,
|
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
assert(keymap != NULL);
|
|
state = xkb_state_new(keymap);
|
|
assert(state != NULL);
|
|
xkb_keymap_unref(keymap);
|
|
xkb_context_unref(context);
|
|
return state;
|
|
}
|
|
|
|
static void
|
|
checkkeys(void)
|
|
{
|
|
struct xkb_state *state;
|
|
|
|
state = keystate("de,ru");
|
|
assert(keymaplookup(state, 38, 0) == XKB_KEY_a);
|
|
assert(keymaplookup(state, 38, ShiftMask) == XKB_KEY_A);
|
|
assert(keymaplookup(state, 38, LockMask) == XKB_KEY_A);
|
|
assert(keymaplookup(state, 38, LockMask|ShiftMask) == XKB_KEY_a);
|
|
assert(keymaplookup(state, 26, Mod5Mask) == XKB_KEY_EuroSign);
|
|
assert(keymaplookup(state, 26, Group1) == XKB_KEY_Cyrillic_u);
|
|
assert(keymaplookup(state, 87, 0) == XKB_KEY_KP_End);
|
|
assert(keymaplookup(state, 87, Mod2Mask) == XKB_KEY_KP_1);
|
|
xkb_state_unref(state);
|
|
assert(keymaplookup(NULL, 38, 0) == XKB_KEY_NoSymbol);
|
|
}
|
|
|
|
static void
|
|
checktext(const char *s)
|
|
{
|
|
char *ct, *utf8;
|
|
size_t clen, len, ulen;
|
|
|
|
len = strlen(s);
|
|
ct = ximcompound(s, len, &clen);
|
|
assert(ct != NULL);
|
|
utf8 = xcb_compound_text_to_utf8(ct, clen, &ulen);
|
|
assert(utf8 != NULL);
|
|
assert(ulen == len);
|
|
assert(memcmp(utf8, s, len) == 0);
|
|
free(utf8);
|
|
free(ct);
|
|
}
|
|
|
|
static void
|
|
checkutf8run(void)
|
|
{
|
|
static const char s[] = "😀";
|
|
char *ct;
|
|
size_t n;
|
|
|
|
ct = ximcompound(s, sizeof s - 1, &n);
|
|
assert(ct != NULL);
|
|
assert(n >= 6);
|
|
assert(memcmp(ct, "\033%G", 3) == 0);
|
|
assert(memcmp(ct+n-3, "\033%@", 3) == 0);
|
|
free(ct);
|
|
}
|
|
|
|
static void
|
|
checkcorpus(void)
|
|
{
|
|
static const char *text[] = {
|
|
"한글",
|
|
"𠀋",
|
|
"👩💻",
|
|
};
|
|
size_t i;
|
|
|
|
for(i = 0; i < sizeof text / sizeof text[0]; i++)
|
|
checktext(text[i]);
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
xcb_compound_text_init();
|
|
|
|
checkkeys();
|
|
checkcorpus();
|
|
checktext("A😀한");
|
|
checkutf8run();
|
|
return 0;
|
|
}
|