xim: one file at the top level, keymaplookup in it
xim/keymap.c held one 37-line function apart from xim.c, with its own prototype typed by hand in xim.c and nelem spelt out because it avoided dat.h — all so that a test could link it without imdkit, though the XIM adapter test #includes xim.c whole anyway. It lives in xim.c now, and xim.c, the last file of its directory, sits beside ibus.c.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,8 +11,6 @@
|
|||||||
/tests/daemon_collision_test
|
/tests/daemon_collision_test
|
||||||
/tests/daemon_failure_test
|
/tests/daemon_failure_test
|
||||||
/tests/daemon_restart_test
|
/tests/daemon_restart_test
|
||||||
/xim/*.o
|
|
||||||
/xim/xim_test
|
|
||||||
/gtk/im-strans.so
|
/gtk/im-strans.so
|
||||||
/bench/bench
|
/bench/bench
|
||||||
/bench/perf.data*
|
/bench/perf.data*
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -20,10 +20,8 @@ DOCKER_RUN = docker run --rm --user "$$(id -u):$$(id -g)" \
|
|||||||
-v "$(CURDIR):/src" $(DOCKER_IMAGE)
|
-v "$(CURDIR):/src" $(DOCKER_IMAGE)
|
||||||
|
|
||||||
SRCS = dict.c font.c ibus.c ipc.c ko.c main.c popup_layout.c \
|
SRCS = dict.c font.c ibus.c ipc.c ko.c main.c popup_layout.c \
|
||||||
srv.c str.c strans.c trie.c vi.c win.c
|
srv.c str.c strans.c trie.c vi.c win.c xim.c
|
||||||
XIMSRCS = xim/xim.c xim/keymap.c
|
OBJS = $(SRCS:.c=.o)
|
||||||
XIMOBJS = $(XIMSRCS:.c=.o)
|
|
||||||
OBJS = $(SRCS:.c=.o) $(XIMOBJS)
|
|
||||||
|
|
||||||
all: $(PROG) gtk
|
all: $(PROG) gtk
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ $(OBJS): dat.h fn.h ipc.h
|
|||||||
ibus.o: PROJECT_CPPFLAGS += $(IBUS_CFLAGS)
|
ibus.o: PROJECT_CPPFLAGS += $(IBUS_CFLAGS)
|
||||||
font.o: PROJECT_CPPFLAGS += $(TEXT_CFLAGS)
|
font.o: PROJECT_CPPFLAGS += $(TEXT_CFLAGS)
|
||||||
win.o: PROJECT_CPPFLAGS += $(POPUP_CFLAGS)
|
win.o: PROJECT_CPPFLAGS += $(POPUP_CFLAGS)
|
||||||
$(XIMOBJS): PROJECT_CPPFLAGS += -I. $(XIM_CFLAGS)
|
xim.o: PROJECT_CPPFLAGS += $(XIM_CFLAGS)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CPPFLAGS) $(PROJECT_CPPFLAGS) $(WARN_CFLAGS) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(PROJECT_CPPFLAGS) $(WARN_CFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|||||||
@@ -32,14 +32,12 @@ FAULT = daemon_collision_test daemon_failure_test daemon_restart_test
|
|||||||
LIVE = $(SMOKE) $(FAULT)
|
LIVE = $(SMOKE) $(FAULT)
|
||||||
TESTSRC = test_util.c str_test.c trie_test.c \
|
TESTSRC = test_util.c str_test.c trie_test.c \
|
||||||
ko_test.c vi_test.c engine_test.c dict_test.c ipc_test.c \
|
ko_test.c vi_test.c engine_test.c dict_test.c ipc_test.c \
|
||||||
popup_test.c font_test.c ibus_test.c server_test.c keymap_test.c \
|
popup_test.c font_test.c ibus_test.c server_test.c xim_adapter_test.c
|
||||||
xim_adapter_test.c
|
|
||||||
TESTOBJ = $(TESTSRC:.c=.o)
|
TESTOBJ = $(TESTSRC:.c=.o)
|
||||||
PARENTSRC = str.c trie.c dict.c ko.c vi.c ipc.c popup_layout.c \
|
PARENTSRC = str.c trie.c dict.c ko.c vi.c ipc.c popup_layout.c \
|
||||||
font.c
|
font.c
|
||||||
PARENTOBJ = $(PARENTSRC:%.c=unit_%.o)
|
PARENTOBJ = $(PARENTSRC:%.c=unit_%.o)
|
||||||
XIMOBJ = unit_xim_keymap.o
|
COMMONOBJ = $(TESTOBJ) $(PARENTOBJ)
|
||||||
COMMONOBJ = $(TESTOBJ) $(PARENTOBJ) $(XIMOBJ)
|
|
||||||
OBJS = unit_test.o stress_test.o $(COMMONOBJ)
|
OBJS = unit_test.o stress_test.o $(COMMONOBJ)
|
||||||
|
|
||||||
all: $(PROG) $(STRESS) $(LIVE)
|
all: $(PROG) $(STRESS) $(LIVE)
|
||||||
@@ -123,15 +121,11 @@ unit_test.o stress_test.o $(TESTOBJ): test.h ../dat.h ../fn.h ../ipc.h \
|
|||||||
engine_test.o: ../strans.c
|
engine_test.o: ../strans.c
|
||||||
ibus_test.o: UNIT_CPPFLAGS += $(IBUS_CFLAGS)
|
ibus_test.o: UNIT_CPPFLAGS += $(IBUS_CFLAGS)
|
||||||
ibus_test.o: ../ibus.c
|
ibus_test.o: ../ibus.c
|
||||||
keymap_test.o xim_adapter_test.o: UNIT_CPPFLAGS += $(XIM_CFLAGS)
|
xim_adapter_test.o: UNIT_CPPFLAGS += $(XIM_CFLAGS)
|
||||||
xim_adapter_test.o: ../xim/xim.c
|
xim_adapter_test.o: ../xim.c
|
||||||
server_test.o: ../srv.c
|
server_test.o: ../srv.c
|
||||||
unit_font.o: UNIT_CPPFLAGS += $(TEXT_CFLAGS)
|
unit_font.o: UNIT_CPPFLAGS += $(TEXT_CFLAGS)
|
||||||
|
|
||||||
unit_xim_keymap.o: ../xim/keymap.c
|
|
||||||
$(CC) $(CPPFLAGS) $(UNIT_CPPFLAGS) $(XIM_CFLAGS) $(UNIT_CFLAGS) \
|
|
||||||
$(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
unit_%.o: ../%.c ../dat.h ../fn.h ../ipc.h
|
unit_%.o: ../%.c ../dat.h ../fn.h ../ipc.h
|
||||||
$(CC) $(CPPFLAGS) $(UNIT_CPPFLAGS) $(UNIT_CFLAGS) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(UNIT_CPPFLAGS) $(UNIT_CFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
#include "dat.h"
|
|
||||||
#include "fn.h"
|
|
||||||
#include "test.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);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ShiftMask = 1<<0,
|
|
||||||
LockMask = 1<<1,
|
|
||||||
Mod2Mask = 1<<4,
|
|
||||||
Mod5Mask = 1<<7,
|
|
||||||
Group1 = 1<<13,
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
xim_keymap_lookup(struct ct *t)
|
|
||||||
{
|
|
||||||
struct xkb_context *context;
|
|
||||||
struct xkb_keymap *keymap;
|
|
||||||
struct xkb_rule_names names;
|
|
||||||
struct xkb_state *state;
|
|
||||||
|
|
||||||
memset(&names, 0, sizeof names);
|
|
||||||
names.layout = "de,ru";
|
|
||||||
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
||||||
keymap = xkb_keymap_new_from_names(context, &names,
|
|
||||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
||||||
if(!CT_CHECK(t, keymap != nil)){
|
|
||||||
xkb_context_unref(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state = xkb_state_new(keymap);
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_a, keymaplookup(state, 38, 0));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_A, keymaplookup(state, 38, ShiftMask));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_A, keymaplookup(state, 38, LockMask));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_a, keymaplookup(state, 38, LockMask|ShiftMask));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_EuroSign, keymaplookup(state, 26, Mod5Mask));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_Cyrillic_u, keymaplookup(state, 26, Group1));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_KP_End, keymaplookup(state, 87, 0));
|
|
||||||
CT_EQ_UINT(t, XKB_KEY_KP_1, keymaplookup(state, 87, Mod2Mask));
|
|
||||||
xkb_state_unref(state);
|
|
||||||
xkb_keymap_unref(keymap);
|
|
||||||
xkb_context_unref(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* imdkit carries any UTF-8 text through COMPOUND_TEXT unchanged. */
|
|
||||||
void
|
|
||||||
xim_compound_text(struct ct *t)
|
|
||||||
{
|
|
||||||
static char *text[] = { "A😀한", "한글", "𠀋", "👩💻" };
|
|
||||||
char *ct, *utf8;
|
|
||||||
size_t clen, len, ulen;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
xcb_compound_text_init();
|
|
||||||
for(i = 0; i < nelem(text); i++){
|
|
||||||
len = strlen(text[i]);
|
|
||||||
ct = xcb_utf8_to_compound_text(text[i], len, &clen);
|
|
||||||
if(!CT_CHECK(t, ct != nil))
|
|
||||||
continue;
|
|
||||||
utf8 = xcb_compound_text_to_utf8(ct, clen, &ulen);
|
|
||||||
if(CT_CHECK(t, utf8 != nil)){
|
|
||||||
CT_EQ_SIZE(t, len, ulen);
|
|
||||||
CT_EQ_MEM(t, text[i], utf8, len);
|
|
||||||
}
|
|
||||||
free(utf8);
|
|
||||||
free(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -67,7 +67,7 @@ static int wireflush(xcb_connection_t*);
|
|||||||
#define xcb_translate_coordinates wiretranslate
|
#define xcb_translate_coordinates wiretranslate
|
||||||
#define xcb_translate_coordinates_reply wiretranslatereply
|
#define xcb_translate_coordinates_reply wiretranslatereply
|
||||||
#define xcb_flush wireflush
|
#define xcb_flush wireflush
|
||||||
#include "xim/xim.c"
|
#include "xim.c"
|
||||||
#undef xcb_im_commit_string
|
#undef xcb_im_commit_string
|
||||||
#undef xcb_im_preedit_start_callback
|
#undef xcb_im_preedit_start_callback
|
||||||
#undef xcb_im_preedit_draw_callback
|
#undef xcb_im_preedit_draw_callback
|
||||||
@@ -1104,3 +1104,61 @@ xim_adapter_commit_encoding(struct ct *t)
|
|||||||
commit(&state, text, 0);
|
commit(&state, text, 0);
|
||||||
CT_EQ_INT(t, 0, nwirecalls);
|
CT_EQ_INT(t, 0, nwirecalls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xim_keymap_lookup(struct ct *t)
|
||||||
|
{
|
||||||
|
enum { ShiftMask = 1<<0, LockMask = 1<<1, Mod2Mask = 1<<4,
|
||||||
|
Mod5Mask = 1<<7, Group1 = 1<<13 };
|
||||||
|
struct xkb_context *context;
|
||||||
|
struct xkb_keymap *keymap;
|
||||||
|
struct xkb_rule_names names;
|
||||||
|
struct xkb_state *state;
|
||||||
|
|
||||||
|
memset(&names, 0, sizeof names);
|
||||||
|
names.layout = "de,ru";
|
||||||
|
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
keymap = xkb_keymap_new_from_names(context, &names,
|
||||||
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
if(!CT_CHECK(t, keymap != nil)){
|
||||||
|
xkb_context_unref(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = xkb_state_new(keymap);
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_a, keymaplookup(state, 38, 0));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_A, keymaplookup(state, 38, ShiftMask));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_A, keymaplookup(state, 38, LockMask));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_a, keymaplookup(state, 38, LockMask|ShiftMask));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_EuroSign, keymaplookup(state, 26, Mod5Mask));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_Cyrillic_u, keymaplookup(state, 26, Group1));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_KP_End, keymaplookup(state, 87, 0));
|
||||||
|
CT_EQ_UINT(t, XKB_KEY_KP_1, keymaplookup(state, 87, Mod2Mask));
|
||||||
|
xkb_state_unref(state);
|
||||||
|
xkb_keymap_unref(keymap);
|
||||||
|
xkb_context_unref(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* imdkit carries any UTF-8 text through COMPOUND_TEXT unchanged. */
|
||||||
|
void
|
||||||
|
xim_compound_text(struct ct *t)
|
||||||
|
{
|
||||||
|
static char *text[] = { "A😀한", "한글", "𠀋", "👩💻" };
|
||||||
|
char *ct, *utf8;
|
||||||
|
size_t clen, len, ulen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
xcb_compound_text_init();
|
||||||
|
for(i = 0; i < nelem(text); i++){
|
||||||
|
len = strlen(text[i]);
|
||||||
|
ct = xcb_utf8_to_compound_text(text[i], len, &clen);
|
||||||
|
if(!CT_CHECK(t, ct != nil))
|
||||||
|
continue;
|
||||||
|
utf8 = xcb_compound_text_to_utf8(ct, clen, &ulen);
|
||||||
|
if(CT_CHECK(t, utf8 != nil)){
|
||||||
|
CT_EQ_SIZE(t, len, ulen);
|
||||||
|
CT_EQ_MEM(t, text[i], utf8, len);
|
||||||
|
}
|
||||||
|
free(utf8);
|
||||||
|
free(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,12 +8,11 @@
|
|||||||
#include <xcb/xkb.h>
|
#include <xcb/xkb.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
|
#include <xkbcommon/xkbcommon-names.h>
|
||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
#include <xcb-imdkit/imdkit.h>
|
#include <xcb-imdkit/imdkit.h>
|
||||||
#include <xcb-imdkit/encoding.h>
|
#include <xcb-imdkit/encoding.h>
|
||||||
|
|
||||||
u32int keymaplookup(struct xkb_state*, uint8_t, u16int);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* One XIM input context. Only PreeditCallbacks clients draw the preedit
|
* One XIM input context. Only PreeditCallbacks clients draw the preedit
|
||||||
* themselves (cap); the popup shows it for the others. engaged means the
|
* themselves (cap); the popup shows it for the others. engaged means the
|
||||||
@@ -374,6 +373,33 @@ resetic(Ic *state, xcb_im_reset_ic_reply_fr_t *reply)
|
|||||||
reply->byte_length_of_committed_string = nwire;
|
reply->byte_length_of_committed_string = nwire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The keysym for an X core key event, with its modifier and group state. */
|
||||||
|
static u32int
|
||||||
|
keymaplookup(struct xkb_state *state, uchar keycode, u16int corestate)
|
||||||
|
{
|
||||||
|
static char *modname[] = {
|
||||||
|
XKB_MOD_NAME_SHIFT, XKB_MOD_NAME_CAPS, XKB_MOD_NAME_CTRL,
|
||||||
|
XKB_MOD_NAME_MOD1, XKB_MOD_NAME_MOD2, XKB_MOD_NAME_MOD3,
|
||||||
|
XKB_MOD_NAME_MOD4, XKB_MOD_NAME_MOD5,
|
||||||
|
};
|
||||||
|
struct xkb_keymap *keymap;
|
||||||
|
xkb_mod_index_t index;
|
||||||
|
xkb_mod_mask_t mods;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
keymap = xkb_state_get_keymap(state);
|
||||||
|
mods = 0;
|
||||||
|
for(i = 0; i < nelem(modname); i++){
|
||||||
|
if(!(corestate & (1 << i)))
|
||||||
|
continue;
|
||||||
|
index = xkb_keymap_mod_get_index(keymap, modname[i]);
|
||||||
|
if(index != XKB_MOD_INVALID)
|
||||||
|
mods |= (xkb_mod_mask_t)1 << index;
|
||||||
|
}
|
||||||
|
xkb_state_update_mask(state, mods, 0, 0, 0, 0, (corestate >> 13) & 3);
|
||||||
|
return xkb_state_key_get_one_sym(state, keycode);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kpress(Ic *state, xcb_key_press_event_t *ev)
|
kpress(Ic *state, xcb_key_press_event_t *ev)
|
||||||
{
|
{
|
||||||
37
xim/keymap.c
37
xim/keymap.c
@@ -1,37 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <xcb/xcb.h>
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
|
||||||
#include <xkbcommon/xkbcommon-names.h>
|
|
||||||
|
|
||||||
/* The keysym for an X core key event, with its modifier and group state. */
|
|
||||||
uint32_t
|
|
||||||
keymaplookup(struct xkb_state *state, uint8_t keycode, uint16_t corestate)
|
|
||||||
{
|
|
||||||
static const char *modname[] = {
|
|
||||||
XKB_MOD_NAME_SHIFT,
|
|
||||||
XKB_MOD_NAME_CAPS,
|
|
||||||
XKB_MOD_NAME_CTRL,
|
|
||||||
XKB_MOD_NAME_MOD1,
|
|
||||||
XKB_MOD_NAME_MOD2,
|
|
||||||
XKB_MOD_NAME_MOD3,
|
|
||||||
XKB_MOD_NAME_MOD4,
|
|
||||||
XKB_MOD_NAME_MOD5,
|
|
||||||
};
|
|
||||||
struct xkb_keymap *keymap;
|
|
||||||
xkb_mod_index_t index;
|
|
||||||
xkb_mod_mask_t mods;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
keymap = xkb_state_get_keymap(state);
|
|
||||||
mods = 0;
|
|
||||||
for(i = 0; i < (int)(sizeof modname / sizeof modname[0]); i++){
|
|
||||||
if(!(corestate & (1U << i)))
|
|
||||||
continue;
|
|
||||||
index = xkb_keymap_mod_get_index(keymap, modname[i]);
|
|
||||||
if(index != XKB_MOD_INVALID)
|
|
||||||
mods |= (xkb_mod_mask_t)1 << index;
|
|
||||||
}
|
|
||||||
xkb_state_update_mask(state, mods, 0, 0, 0, 0,
|
|
||||||
(corestate >> 13) & 3);
|
|
||||||
return xkb_state_key_get_one_sym(state, keycode);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user