summaryrefslogtreecommitdiff
path: root/ximserver.c
blob: 5fc3bd39e00704780dec9bf2d5ef13104575f45f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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);
}