aboutsummaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
authorIvan Tham <pickfire@riseup.net>2019-02-12 18:41:41 +0100
committerHiltjo Posthuma <hiltjo@codemadness.org>2019-02-12 18:45:15 +0100
commite85b6b64660214121164ea97fb098eaa4935f7db (patch)
treed08873d1902c94102ce19294efa0c5bcd2c8d040 /x.c
parent75f92eb3489275bfcad901e5ca424134eda6e2f4 (diff)
downloadst-patched-e85b6b64660214121164ea97fb098eaa4935f7db.tar.bz2
st-patched-e85b6b64660214121164ea97fb098eaa4935f7db.tar.xz
st-patched-e85b6b64660214121164ea97fb098eaa4935f7db.zip
better Input Method Editor (IME) support
Features: - Allow input methods swap with hotkey (E.g. left ctrl + left shift). - Over-the-spot pre-editing style, pre-edit data placed over insertion point. - Restart IME without segmentation fault. TODO: - Automatically pickup IME if st started before IME
Diffstat (limited to 'x.c')
-rw-r--r--x.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/x.c b/x.c
index 0422421..865dacc 100644
--- a/x.c
+++ b/x.c
@@ -139,6 +139,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
139static void xdrawglyph(Glyph, int, int); 139static void xdrawglyph(Glyph, int, int);
140static void xclear(int, int, int, int); 140static void xclear(int, int, int, int);
141static int xgeommasktogravity(int); 141static int xgeommasktogravity(int);
142static void ximopen(Display *);
143static void ximinstantiate(Display *, XPointer, XPointer);
144static void ximdestroy(XIM, XPointer, XPointer);
142static void xinit(int, int); 145static void xinit(int, int);
143static void cresize(int, int); 146static void cresize(int, int);
144static void xresize(int, int); 147static void xresize(int, int);
@@ -997,6 +1000,43 @@ xunloadfonts(void)
997} 1000}
998 1001
999void 1002void
1003ximopen(Display *dpy)
1004{
1005 XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy };
1006
1007 if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
1008 XSetLocaleModifiers("@im=local");
1009 if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
1010 XSetLocaleModifiers("@im=");
1011 if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL)
1012 die("XOpenIM failed. Could not open input device.\n");
1013 }
1014 }
1015 if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL)
1016 die("XSetIMValues failed. Could not set input method value.\n");
1017 xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
1018 XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
1019 if (xw.xic == NULL)
1020 die("XCreateIC failed. Could not obtain input method.\n");
1021}
1022
1023void
1024ximinstantiate(Display *dpy, XPointer client, XPointer call)
1025{
1026 ximopen(dpy);
1027 XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
1028 ximinstantiate, NULL);
1029}
1030
1031void
1032ximdestroy(XIM xim, XPointer client, XPointer call)
1033{
1034 xw.xim = NULL;
1035 XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
1036 ximinstantiate, NULL);
1037}
1038
1039void
1000xinit(int cols, int rows) 1040xinit(int cols, int rows)
1001{ 1041{
1002 XGCValues gcvalues; 1042 XGCValues gcvalues;
@@ -1033,7 +1073,7 @@ xinit(int cols, int rows)
1033 xw.attrs.background_pixel = dc.col[defaultbg].pixel; 1073 xw.attrs.background_pixel = dc.col[defaultbg].pixel;
1034 xw.attrs.border_pixel = dc.col[defaultbg].pixel; 1074 xw.attrs.border_pixel = dc.col[defaultbg].pixel;
1035 xw.attrs.bit_gravity = NorthWestGravity; 1075 xw.attrs.bit_gravity = NorthWestGravity;
1036 xw.attrs.event_mask = FocusChangeMask | KeyPressMask 1076 xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
1037 | ExposureMask | VisibilityChangeMask | StructureNotifyMask 1077 | ExposureMask | VisibilityChangeMask | StructureNotifyMask
1038 | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; 1078 | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
1039 xw.attrs.colormap = xw.cmap; 1079 xw.attrs.colormap = xw.cmap;
@@ -1061,22 +1101,7 @@ xinit(int cols, int rows)
1061 xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); 1101 xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
1062 1102
1063 /* input methods */ 1103 /* input methods */
1064 if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { 1104 ximopen(xw.dpy);
1065 XSetLocaleModifiers("@im=local");
1066 if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
1067 XSetLocaleModifiers("@im=");
1068 if ((xw.xim = XOpenIM(xw.dpy,
1069 NULL, NULL, NULL)) == NULL) {
1070 die("XOpenIM failed. Could not open input"
1071 " device.\n");
1072 }
1073 }
1074 }
1075 xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing
1076 | XIMStatusNothing, XNClientWindow, xw.win,
1077 XNFocusWindow, xw.win, NULL);
1078 if (xw.xic == NULL)
1079 die("XCreateIC failed. Could not obtain input method.\n");
1080 1105
1081 /* white cursor, black outline */ 1106 /* white cursor, black outline */
1082 cursor = XCreateFontCursor(xw.dpy, mouseshape); 1107 cursor = XCreateFontCursor(xw.dpy, mouseshape);
@@ -1555,6 +1580,16 @@ xfinishdraw(void)
1555} 1580}
1556 1581
1557void 1582void
1583xximspot(int x, int y)
1584{
1585 XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch };
1586 XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
1587
1588 XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL);
1589 XFree(attr);
1590}
1591
1592void
1558expose(XEvent *ev) 1593expose(XEvent *ev)
1559{ 1594{
1560 redraw(); 1595 redraw();