#include #include #include #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); }