summaryrefslogtreecommitdiff
path: root/ximserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'ximserver.c')
-rw-r--r--ximserver.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/ximserver.c b/ximserver.c
new file mode 100644
index 0000000..5fc3bd3
--- /dev/null
+++ b/ximserver.c
@@ -0,0 +1,158 @@
+#include <glib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "IMdkit/IMdkit.h"
+#include "IMdkit/Xi18n.h"
+
+#include "xmim.h"
+#include "context.h"
+#include "ximserver.h"
+
+static XIMS xims;
+
+#define ALL_LOCALES \
+ "aa,af,am,an,ar,as,ast,az,be,ber,bg,bn,bo,br,bs,byn,C,ca,crh,cs,csb,cy,da,de,dz,el,en,es,et,eu,fa,fi,fil,fo,fr,fur,fy,ga,gd,gez,gl,gu,gv,ha,he,hi,hne,hr,hsb,ht,hu,hy,id,ig,ik,is,it,iu,iw,ja,ka,kk,kl,km,kn,ko,ks,ku,kw,ky,lg,li,lo,lt,lv,mai,mg,mi,mk,ml,mn,mr,ms,mt,nan,nb,nds,ne,nl,nn,no,nr,nso,oc,om,or,pa,pa,pap,pl,pt,ro,ru,rw,sa,sc,sd,se,shs,si,sid,sk,sl,so,sq,sr,ss,st,sv,ta,te,tg,th,ti,tig,tk,tl,tn,tr,ts,tt,ug,uk,ur,uz,ve,vi,wa,wo,xh,yi,yo,zh,zu"
+
+static int xims_protocol_handler(XIMS ims, IMProtocol *call_data)
+{
+ switch (call_data->major_code) {
+ case XIM_OPEN:
+ g_debug("XIM_OPEN");
+ return True;
+ case XIM_CLOSE:
+ g_debug("XIM_CLOSE");
+ return True;
+ case XIM_CREATE_IC:
+ g_debug("XIM_CREATE_IC");
+ return context_create(&call_data->changeic);
+ case XIM_DESTROY_IC:
+ g_debug("XIM_DESTROY_IC");
+ return context_destroy(&call_data->changeic);
+ case XIM_SET_IC_VALUES:
+ g_debug("XIM_SET_IC_VALUES");
+ return context_set_values(&call_data->changeic);
+ case XIM_GET_IC_VALUES:
+ g_debug("XIM_GET_IC_VALUES");
+ return context_get_values(&call_data->changeic);
+ case XIM_SET_IC_FOCUS:
+ g_debug("XIM_SET_IC_FOCUS");
+ return context_set_focus(&call_data->changefocus);
+ case XIM_UNSET_IC_FOCUS:
+ g_debug("XIM_UNSET_IC_FOCUS");
+ return context_unset_focus(&call_data->changefocus);
+ case XIM_FORWARD_EVENT:
+ g_debug("XIM_FORWARD_EVENT");
+ return context_forward_event(&call_data->forwardevent);
+ case XIM_RESET_IC:
+ g_debug("XIM_RESET_IC");
+ return context_reset(&call_data->resetic);
+ case XIM_PREEDIT_START_REPLY:
+ g_debug("XIM_PREEDIT_START_REPLY");
+ return True;
+ default:
+ g_message("Unknown or unsupport XIM protocol message with major: %d",
+ call_data->major_code);
+ return False;
+ }
+}
+
+void xims_open()
+{
+ static XIMStyle ims_styles[] = {
+ XIMPreeditCallbacks | XIMStatusNothing,
+ XIMPreeditCallbacks | XIMStatusNone,
+ XIMPreeditPosition | XIMStatusNothing,
+ XIMPreeditPosition | XIMStatusNone,
+ XIMPreeditNothing | XIMStatusNothing,
+ XIMPreeditNothing | XIMStatusNone,
+ XIMPreeditNone | XIMStatusNothing,
+ XIMPreeditNone | XIMStatusNone,
+ 0
+ };
+ static XIMEncoding ims_encodings[] = {
+ "COMPOUND_TEXT",
+ NULL
+ };
+
+ XIMStyles styles = {
+ .count_styles = G_N_ELEMENTS(ims_styles) - 1,
+ .supported_styles = ims_styles
+ };
+ XIMEncodings encodings = {
+ .count_encodings = G_N_ELEMENTS(ims_encodings) - 1,
+ .supported_encodings = ims_encodings
+ };
+
+ contexts_init();
+ xims = IMOpenIM(x_dpy,
+ IMModifiers, "Xi18n",
+ IMServerWindow, x_win,
+ IMServerName, "xmim",
+ IMLocale, ALL_LOCALES,
+ IMServerTransport, "X/",
+ IMInputStyles, &styles,
+ IMEncodingList, &encodings,
+ IMProtocolHandler, xims_protocol_handler,
+ IMFilterEventMask, KeyPressMask | KeyReleaseMask,
+ NULL);
+}
+
+void xims_close()
+{
+ contexts_destroy();
+ IMCloseIM(xims);
+}
+
+void xims_commit(guint imid, guint icid, guint keysym, const char *text)
+{
+ g_return_if_fail(icid != 0);
+
+ XTextProperty tp;
+ IMCommitStruct cms = {0};
+
+ Xutf8TextListToTextProperty(x_dpy, (char**)&text, 1, XCompoundTextStyle, &tp);
+
+ cms.major_code = XIM_COMMIT;
+ cms.connect_id = imid;
+ cms.icid = icid;
+ cms.commit_string = ""; // Need to always put an string, even if empty
+
+ if (keysym) {
+ cms.flag |= XimLookupKeySym;
+ cms.keysym = keysym;
+ }
+ if (text && text[0]) {
+ cms.flag |= XimLookupChars;
+ cms.commit_string = (gchar *)tp.value;
+ }
+ g_warn_if_fail(cms.flag);
+
+ IMCommitString(xims, (XPointer)&cms);
+
+ XFree(tp.value);
+}
+
+void xims_forward_event(IMForwardEventStruct *call_data)
+{
+ IMForwardEvent(xims, (XPointer)call_data);
+}
+
+void xims_call_callback(XPointer data)
+{
+ IMCallCallback(xims, data);
+}
+
+void xims_insert_event(guint imid, guint icid, const XEvent *xev)
+{
+ IMForwardEventStruct s = {0};
+
+ s.major_code = XIM_FORWARD_EVENT;
+ s.connect_id = imid;
+ s.icid = icid;
+ s.sync_bit = 0;
+ s.serial_number = 0;
+
+ s.event = *xev;
+
+ xims_forward_event(&s);
+}