diff --git a/tests/xim_test.c b/tests/xim_test.c index d6f281b..ffb2aee 100644 --- a/tests/xim_test.c +++ b/tests/xim_test.c @@ -1,8 +1,12 @@ #include #include #include +#include +#include +#include #include #include "../xim/keymap.h" +#include "../xim/ximtext.h" enum { @@ -11,6 +15,23 @@ enum Group1 = 1<<13, }; +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); +} + int main(void) { @@ -23,6 +44,8 @@ main(void) XKB_KEY_a, XKB_KEY_A, XKB_KEY_NoSymbol, XKB_KEY_NoSymbol, }; + xcb_compound_text_init(); + assert(keymaplookup(letters, 4, 0) == XKB_KEY_a); assert(keymaplookup(letters, 4, ShiftMask) == XKB_KEY_A); assert(keymaplookup(letters, 4, LockMask) == XKB_KEY_A); @@ -34,5 +57,9 @@ main(void) assert(keymaplookup(punctuation, 2, LockMask|ShiftMask) == XKB_KEY_exclam); assert(keymaplookup(missing, 4, Group1) == XKB_KEY_a); assert(keymaplookup(NULL, 0, 0) == XKB_KEY_NoSymbol); + checktext("ν•œκΈ€"); + checktext("πŸ˜€"); + checktext("❀️"); + checktext("AπŸ˜€ν•œ"); return 0; } diff --git a/xim/Makefile b/xim/Makefile index 3ba7904..953c337 100644 --- a/xim/Makefile +++ b/xim/Makefile @@ -15,8 +15,8 @@ $(PROG): $(OBJS) ../ipc.c ../ipc.h $(OBJS): ../ipc.h -$(TEST): ../tests/xim_test.c keymap.c keymap.h - $(CC) $(CFLAGS) -o $@ ../tests/xim_test.c keymap.c $(XIM_LIBS) +$(TEST): ../tests/xim_test.c keymap.c keymap.h ximtext.c ximtext.h + $(CC) $(CFLAGS) -o $@ ../tests/xim_test.c keymap.c ximtext.c $(XIM_LIBS) check: $(TEST) ./$(TEST) diff --git a/xim/main.c b/xim/main.c index 9f770f6..d6ddbd1 100644 --- a/xim/main.c +++ b/xim/main.c @@ -8,6 +8,7 @@ #include #include "ipc.h" #include "keymap.h" +#include "ximtext.h" typedef struct Ic Ic; struct Ic @@ -97,7 +98,7 @@ commit(xcb_im_input_context_t *ic, char *s, int len) if(len == 0) return; - ct = xcb_utf8_to_compound_text(s, len, &clen); + ct = ximcompound(s, len, &clen); if(ct == NULL) return; xcb_im_commit_string(xim, ic, XCB_XIM_LOOKUP_CHARS, ct, clen, 0); diff --git a/xim/ximtext.c b/xim/ximtext.c new file mode 100644 index 0000000..5e59db2 --- /dev/null +++ b/xim/ximtext.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include "ximtext.h" + +char* +ximcompound(const char *s, size_t len, size_t *outlen) +{ + static const char utf8[] = "\033%G"; + char *ct; + + if(s == NULL || len > SIZE_MAX - sizeof utf8) + return NULL; + ct = xcb_utf8_to_compound_text(s, len, outlen); + if(ct != NULL) + return ct; + /* X11 Compound Text reserves ESC % G for an embedded UTF-8 run. */ + ct = malloc(len + sizeof utf8); + if(ct == NULL) + return NULL; + memcpy(ct, utf8, sizeof utf8 - 1); + memcpy(ct + sizeof utf8 - 1, s, len); + ct[len + sizeof utf8 - 1] = '\0'; + if(outlen != NULL) + *outlen = len + sizeof utf8 - 1; + return ct; +} diff --git a/xim/ximtext.h b/xim/ximtext.h new file mode 100644 index 0000000..0e793af --- /dev/null +++ b/xim/ximtext.h @@ -0,0 +1,3 @@ +#include + +char *ximcompound(const char*, size_t, size_t*);