fix: preserve emoji commits through XIM
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <xcb-imdkit/encoding.h>
|
||||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||||
#include "../xim/keymap.h"
|
#include "../xim/keymap.h"
|
||||||
|
#include "../xim/ximtext.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -11,6 +15,23 @@ enum
|
|||||||
Group1 = 1<<13,
|
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
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
@@ -23,6 +44,8 @@ main(void)
|
|||||||
XKB_KEY_a, XKB_KEY_A, XKB_KEY_NoSymbol, XKB_KEY_NoSymbol,
|
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, 0) == XKB_KEY_a);
|
||||||
assert(keymaplookup(letters, 4, ShiftMask) == XKB_KEY_A);
|
assert(keymaplookup(letters, 4, ShiftMask) == XKB_KEY_A);
|
||||||
assert(keymaplookup(letters, 4, LockMask) == 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(punctuation, 2, LockMask|ShiftMask) == XKB_KEY_exclam);
|
||||||
assert(keymaplookup(missing, 4, Group1) == XKB_KEY_a);
|
assert(keymaplookup(missing, 4, Group1) == XKB_KEY_a);
|
||||||
assert(keymaplookup(NULL, 0, 0) == XKB_KEY_NoSymbol);
|
assert(keymaplookup(NULL, 0, 0) == XKB_KEY_NoSymbol);
|
||||||
|
checktext("한글");
|
||||||
|
checktext("😀");
|
||||||
|
checktext("❤️");
|
||||||
|
checktext("A😀한");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ $(PROG): $(OBJS) ../ipc.c ../ipc.h
|
|||||||
|
|
||||||
$(OBJS): ../ipc.h
|
$(OBJS): ../ipc.h
|
||||||
|
|
||||||
$(TEST): ../tests/xim_test.c keymap.c keymap.h
|
$(TEST): ../tests/xim_test.c keymap.c keymap.h ximtext.c ximtext.h
|
||||||
$(CC) $(CFLAGS) -o $@ ../tests/xim_test.c keymap.c $(XIM_LIBS)
|
$(CC) $(CFLAGS) -o $@ ../tests/xim_test.c keymap.c ximtext.c $(XIM_LIBS)
|
||||||
|
|
||||||
check: $(TEST)
|
check: $(TEST)
|
||||||
./$(TEST)
|
./$(TEST)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <xcb-imdkit/encoding.h>
|
#include <xcb-imdkit/encoding.h>
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
|
#include "ximtext.h"
|
||||||
|
|
||||||
typedef struct Ic Ic;
|
typedef struct Ic Ic;
|
||||||
struct Ic
|
struct Ic
|
||||||
@@ -97,7 +98,7 @@ commit(xcb_im_input_context_t *ic, char *s, int len)
|
|||||||
|
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
return;
|
return;
|
||||||
ct = xcb_utf8_to_compound_text(s, len, &clen);
|
ct = ximcompound(s, len, &clen);
|
||||||
if(ct == NULL)
|
if(ct == NULL)
|
||||||
return;
|
return;
|
||||||
xcb_im_commit_string(xim, ic, XCB_XIM_LOOKUP_CHARS, ct, clen, 0);
|
xcb_im_commit_string(xim, ic, XCB_XIM_LOOKUP_CHARS, ct, clen, 0);
|
||||||
|
|||||||
28
xim/ximtext.c
Normal file
28
xim/ximtext.c
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <xcb-imdkit/encoding.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
3
xim/ximtext.h
Normal file
3
xim/ximtext.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *ximcompound(const char*, size_t, size_t*);
|
||||||
Reference in New Issue
Block a user