1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2 /* IM-JA Japanese Input Method
3 *
4 * Copyright (C) 2003 Botond Botyanszki
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 *
20 * Based on handler.c from nabi by Choe Hwanjin
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include <X11/keysym.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33 #include <gdk/gdkx.h>
34
35 #include "IMdkit/IMdkit.h"
36 #include "IMdkit/Xi18n.h"
37
38 #include "../error.h"
39 #include "../im-ja.h"
40
41 #include "xim-ic.h"
42 #include "xim-server.h"
43
44 extern IMJAXimServer *im_ja_xim_server;
45
xim_protocol_name(int major_code)46 static const char *xim_protocol_name(int major_code) {
47 switch (major_code) {
48 case XIM_CONNECT:
49 return "XIM_CONNECT";
50 case XIM_CONNECT_REPLY:
51 return "XIM_CONNECT_REPLY";
52 case XIM_DISCONNECT:
53 return "XIM_DISCONNECT";
54 case XIM_DISCONNECT_REPLY:
55 return "XIM_DISCONNECT_REPLY";
56 case XIM_AUTH_REQUIRED:
57 return "XIM_AUTH_REQUIRED";
58 case XIM_AUTH_REPLY:
59 return "XIM_AUTH_REPLY";
60 case XIM_AUTH_NEXT:
61 return "XIM_AUTH_NEXT";
62 case XIM_AUTH_SETUP:
63 return "XIM_AUTH_SETUP";
64 case XIM_AUTH_NG:
65 return "XIM_AUTH_NG";
66 case XIM_ERROR:
67 return "XIM_ERROR";
68 case XIM_OPEN:
69 return "XIM_OPEN";
70 case XIM_OPEN_REPLY:
71 return "XIM_OPEN_REPLY";
72 case XIM_CLOSE:
73 return "XIM_CLOSE";
74 case XIM_CLOSE_REPLY:
75 return "XIM_CLOSE_REPLY";
76 case XIM_REGISTER_TRIGGERKEYS:
77 return "XIM_REGISTER_TRIGGERKEYS";
78 case XIM_TRIGGER_NOTIFY:
79 return "XIM_TRIGGER_NOTIFY";
80 case XIM_TRIGGER_NOTIFY_REPLY:
81 return "XIM_TRIGGER_NOTIFY_REPLY";
82 case XIM_SET_EVENT_MASK:
83 return "XIM_SET_EVENT_MASK";
84 case XIM_ENCODING_NEGOTIATION:
85 return "XIM_ENCODING_NEGOTIATION";
86 case XIM_ENCODING_NEGOTIATION_REPLY:
87 return "XIM_ENCODING_NEGOTIATION_REPLY";
88 case XIM_QUERY_EXTENSION:
89 return "XIM_QUERY_EXTENSION";
90 case XIM_QUERY_EXTENSION_REPLY:
91 return "XIM_QUERY_EXTENSION_REPLY";
92 case XIM_SET_IM_VALUES:
93 return "XIM_SET_IM_VALUES";
94 case XIM_SET_IM_VALUES_REPLY:
95 return "XIM_SET_IM_VALUES_REPLY";
96 case XIM_GET_IM_VALUES:
97 return "XIM_GET_IM_VALUES";
98 case XIM_GET_IM_VALUES_REPLY:
99 return "XIM_GET_IM_VALUES_REPLY";
100 case XIM_CREATE_IC:
101 return "XIM_CREATE_IC";
102 case XIM_CREATE_IC_REPLY:
103 return "XIM_CREATE_IC_REPLY";
104 case XIM_DESTROY_IC:
105 return "XIM_DESTROY_IC";
106 case XIM_DESTROY_IC_REPLY:
107 return "XIM_DESTROY_IC_REPLY";
108 case XIM_SET_IC_VALUES:
109 return "XIM_SET_IC_VALUES";
110 case XIM_SET_IC_VALUES_REPLY:
111 return "XIM_SET_IC_VALUES_REPLY";
112 case XIM_GET_IC_VALUES:
113 return "XIM_GET_IC_VALUES";
114 case XIM_GET_IC_VALUES_REPLY:
115 return "XIM_GET_IC_VALUES_REPLY";
116 case XIM_SET_IC_FOCUS:
117 return "XIM_SET_IC_FOCUS";
118 case XIM_UNSET_IC_FOCUS:
119 return "XIM_UNSET_IC_FOCUS";
120 case XIM_FORWARD_EVENT:
121 return "XIM_FORWARD_EVENT";
122 case XIM_SYNC:
123 return "XIM_SYNC";
124 case XIM_SYNC_REPLY:
125 return "XIM_SYNC_REPLY";
126 case XIM_COMMIT:
127 return "XIM_COMMIT";
128 case XIM_RESET_IC:
129 return "XIM_RESET_IC";
130 case XIM_RESET_IC_REPLY:
131 return "XIM_RESET_IC_REPLY";
132 case XIM_GEOMETRY:
133 return "XIM_GEOMETRY";
134 case XIM_STR_CONVERSION:
135 return "XIM_STR_CONVERSION";
136 case XIM_STR_CONVERSION_REPLY:
137 return "XIM_STR_CONVERSION_REPLY";
138 case XIM_PREEDIT_START:
139 return "XIM_PREEDIT_START";
140 case XIM_PREEDIT_START_REPLY:
141 return "XIM_PREEDIT_START_REPLY";
142 case XIM_PREEDIT_DRAW:
143 return "XIM_PREEDIT_DRAW";
144 case XIM_PREEDIT_CARET:
145 return "XIM_PREEDIT_CARET";
146 case XIM_PREEDIT_CARET_REPLY:
147 return "XIM_PREEDIT_CARET_REPLY";
148 case XIM_PREEDIT_DONE:
149 return "XIM_PREEDIT_DONE";
150 case XIM_STATUS_START:
151 return "XIM_STATUS_START";
152 case XIM_STATUS_DRAW:
153 return "XIM_STATUS_DRAW";
154 case XIM_STATUS_DONE:
155 return "XIM_STATUS_DONE";
156 default:
157 break;
158 }
159
160 return "XIM_UNKNOWN";
161 }
162
im_ja_xim_handler_open(XIMS ims,IMProtocol * call_data)163 static Bool im_ja_xim_handler_open(XIMS ims, IMProtocol *call_data) {
164 IMJAXimConnect* connect;
165 IMOpenStruct *data = (IMOpenStruct *)call_data;
166
167 IM_JA_DEBUG("open connect_id = 0x%x\n", (int)data->connect_id);
168
169 connect = im_ja_xim_connect_create(data->connect_id);
170 im_ja_xim_server_add_connect(connect);
171
172 return True;
173 }
174
im_ja_xim_handler_close(XIMS ims,IMProtocol * call_data)175 static Bool im_ja_xim_handler_close(XIMS ims, IMProtocol *call_data) {
176 IMCloseStruct *data = (IMCloseStruct *)call_data;
177 IMJAXimConnect *connect;
178
179 IM_JA_DEBUG("im_ja_xim_handler_close: ");
180
181 connect = im_ja_xim_server_get_connect_by_id(data->connect_id);
182 im_ja_xim_server_remove_connect(connect);
183 im_ja_xim_connect_destroy(connect);
184
185 IM_JA_DEBUG("closing connect_id 0x%x\n", (int)data->connect_id);
186 return True;
187 }
188
im_ja_xim_handler_create_ic(XIMS ims,IMProtocol * call_data)189 static Bool im_ja_xim_handler_create_ic(XIMS ims, IMProtocol *call_data) {
190 IMJAContext *ic;
191 IMChangeICStruct *data = (IMChangeICStruct *)call_data;
192
193 IM_JA_DEBUG("im_ja_xim_handler_create_ic \t 0x%x\n", (int)data->connect_id);
194
195 ic = im_ja_xim_server_ic_create(data);
196 im_ja_xim_connect_add_ic(ic->connect, ic);
197
198 return True;
199 }
200
im_ja_xim_handler_destroy_ic(XIMS ims,IMProtocol * call_data)201 static Bool im_ja_xim_handler_destroy_ic(XIMS ims, IMProtocol *call_data) {
202 IMJAContext *ic;
203
204 IM_JA_DEBUG("im_ja_xim_handler_destroy_ic\n");
205 ic = im_ja_xim_server_get_ic(call_data->changeic.icid);
206
207 if (ic != NULL) {
208 im_ja_xim_connect_remove_ic(ic->connect, ic);
209 im_ja_context_destroy(ic);
210 }
211
212 return True;
213 }
214
im_ja_xim_handler_set_ic_values(XIMS ims,IMProtocol * call_data)215 static Bool im_ja_xim_handler_set_ic_values(XIMS ims, IMProtocol *call_data) {
216 IMChangeICStruct *data = (IMChangeICStruct *)call_data;
217 IMJAContext *ic;
218
219 IM_JA_DEBUG("im_ja_xim_handler_set_ic_values\n");
220 ic = im_ja_xim_server_get_ic(data->icid);
221
222 if (ic != NULL) im_ja_xim_ic_set_values(ic, data);
223
224 return True;
225 }
226
im_ja_xim_handler_get_ic_values(XIMS ims,IMProtocol * call_data)227 static Bool im_ja_xim_handler_get_ic_values(XIMS ims, IMProtocol *call_data) {
228 IMChangeICStruct *data = (IMChangeICStruct *)call_data;
229 IMJAContext *ic;
230
231 IM_JA_DEBUG("im_ja_xim_handler_get_ic_values\n");
232
233 ic = im_ja_xim_server_get_ic(data->icid);
234
235 if (ic != NULL) im_ja_xim_ic_get_values(ic, data);
236 return True;
237 }
238
im_ja_xim_handler_forward_event(XIMS ims,IMProtocol * call_data)239 static Bool im_ja_xim_handler_forward_event(XIMS ims, IMProtocol *call_data) {
240 gchar buf[64];
241 KeySym keysym;
242 XKeyEvent *kevent;
243 IMForwardEventStruct *data;
244 GdkKeymap *keymap;
245 GdkEvent *event;
246 GdkDisplay *display;
247 IMJAContext *ic;
248
249 IM_JA_DEBUG("im_ja_xim_handler_forward_event\n");
250
251 data = (IMForwardEventStruct *)call_data;
252
253 ic = im_ja_xim_server_get_ic(data->icid);
254 if (ic == NULL) return True;
255
256 if (data->event.type != KeyPress) {
257 IM_JA_DEBUG("Not a key press\n");
258 return True;
259 }
260
261 kevent = (XKeyEvent*)&data->event;
262
263 display = gdk_x11_lookup_xdisplay(im_ja_xim_server->display);
264
265 keymap = gdk_keymap_get_for_display(display);
266 event = gdk_event_new(GDK_KEY_PRESS);
267
268 event->key.time = kevent->time;
269 event->key.state = (guint) kevent->state;
270 event->key.hardware_keycode = kevent->keycode;
271 XLookupString(kevent, buf, 64, &keysym, NULL);
272 event->key.keyval = keysym;
273
274 if (im_ja_filter_keypress(ic, &event->key) == TRUE) return True;
275
276 IMForwardEvent(ims, (XPointer)data);
277 return True;
278 }
279
im_ja_xim_handler_set_ic_focus(XIMS ims,IMProtocol * call_data)280 static Bool im_ja_xim_handler_set_ic_focus(XIMS ims, IMProtocol *call_data) {
281 IMJAContext *ic;
282
283 IM_JA_DEBUG("im_ja_xim_handler_set_ic_focus\n");
284
285 ic = im_ja_xim_server_get_ic(call_data->changefocus.icid);
286
287 if (ic == NULL) return True;
288
289 if (ic->connect != NULL) im_ja_xim_ic_preedit_start(ic); /* FIXME */
290 im_ja_got_focus(ic);
291
292 return True;
293 }
294
im_ja_xim_handler_unset_ic_focus(XIMS ims,IMProtocol * call_data)295 static Bool im_ja_xim_handler_unset_ic_focus(XIMS ims, IMProtocol *call_data) {
296 IMJAContext *ic;
297
298 IM_JA_DEBUG("im_ja_xim_handler_unset_ic_focus\n");
299
300 ic = im_ja_xim_server_get_ic(call_data->changefocus.icid);
301 if (ic == NULL) return True;
302 im_ja_lost_focus(ic);
303
304 return True;
305 }
306
im_ja_xim_handler_reset_ic(XIMS ims,IMProtocol * call_data)307 static Bool im_ja_xim_handler_reset_ic(XIMS ims, IMProtocol *call_data) {
308 IM_JA_DEBUG("FIXME: im_ja_xim_handler_reset_ic\n");
309
310 return True;
311 }
312
im_ja_xim_handler_trigger_notify(XIMS ims,IMProtocol * call_data)313 static Bool im_ja_xim_handler_trigger_notify(XIMS ims, IMProtocol *call_data) {
314 /*IMTriggerNotifyStruct *data = (IMTriggerNotifyStruct *)call_data;*/
315
316 IM_JA_DEBUG("FIXME: im_ja_xim_handler_trigger_notify\n");
317 return True;
318 }
319
im_ja_xim_handler_preedit_start_reply(XIMS ims,IMProtocol * call_data)320 static Bool im_ja_xim_handler_preedit_start_reply(XIMS ims, IMProtocol *call_data) {
321 IM_JA_DEBUG("FIXME: im_ja_xim_handler_preedit_start_reply\n");
322 return True;
323 }
324
im_ja_xim_handler_preedit_caret_reply(XIMS ims,IMProtocol * call_data)325 static Bool im_ja_xim_handler_preedit_caret_reply(XIMS ims, IMProtocol *call_data) {
326 IM_JA_DEBUG("FIXME: im_ja_xim_handler_preedit_caret_reply\n");
327 return True;
328 }
329
im_ja_xim_handler(XIMS ims,IMProtocol * call_data)330 Bool im_ja_xim_handler(XIMS ims, IMProtocol *call_data) {
331 IM_JA_DEBUG("im_ja_xim_handler: %s\t 0x%x 0x%x\n",
332 xim_protocol_name(call_data->major_code),
333 call_data->any.connect_id,
334 call_data->changeic.icid);
335
336 switch (call_data->major_code) {
337 case XIM_OPEN:
338 return im_ja_xim_handler_open(ims, call_data);
339 case XIM_CLOSE:
340 return im_ja_xim_handler_close(ims, call_data);
341 case XIM_CREATE_IC:
342 return im_ja_xim_handler_create_ic(ims, call_data);
343 case XIM_DESTROY_IC:
344 return im_ja_xim_handler_destroy_ic(ims, call_data);
345 case XIM_SET_IC_VALUES:
346 return im_ja_xim_handler_set_ic_values(ims, call_data);
347 case XIM_GET_IC_VALUES:
348 return im_ja_xim_handler_get_ic_values(ims, call_data);
349 case XIM_FORWARD_EVENT:
350 return im_ja_xim_handler_forward_event(ims, call_data);
351 case XIM_SET_IC_FOCUS:
352 return im_ja_xim_handler_set_ic_focus(ims, call_data);
353 case XIM_UNSET_IC_FOCUS:
354 return im_ja_xim_handler_unset_ic_focus(ims, call_data);
355 case XIM_RESET_IC:
356 return im_ja_xim_handler_reset_ic(ims, call_data);
357 case XIM_TRIGGER_NOTIFY:
358 return im_ja_xim_handler_trigger_notify(ims, call_data);
359 case XIM_PREEDIT_START_REPLY:
360 return im_ja_xim_handler_preedit_start_reply(ims, call_data);
361 case XIM_PREEDIT_CARET_REPLY:
362 return im_ja_xim_handler_preedit_caret_reply(ims, call_data);
363 default:
364 IM_JA_DEBUG("Unknown IMDKit Protocol message type\n");
365 break;
366 }
367 return True;
368 }
369