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 ic.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 <glib.h>
31 #include <gdk/gdkx.h>
32 
33 #include "../error.h"
34 #include "../im-ja.h"
35 #include "../im-ja-impl.h"
36 
37 #include "xim-ic.h"
38 #include "xim-server.h"
39 #include "xim-fontset.h"
40 
41 extern IMJAXimServer *im_ja_xim_server;
42 
43 static void im_ja_xim_ic_init_preedit(IMJAContext *ic);
44 /*static void debug_preedit(IMJAContext *ic);*/
45 
46 #define streql(x, y) (strcmp((x), (y)) == 0)
47 
48 
im_ja_xim_connect_create(CARD16 id)49 IMJAXimConnect *im_ja_xim_connect_create(CARD16 id) {
50 	IMJAXimConnect* connect;
51 
52 	IM_JA_DEBUG("im_ja_xim_connect_create\n");
53 
54 	connect = g_new0(IMJAXimConnect, 1);
55 	connect->id = id;
56 	connect->ic_list = NULL;
57 	connect->next = NULL;
58 
59 	return connect;
60 }
61 
im_ja_xim_connect_destroy(IMJAXimConnect * connect)62 void im_ja_xim_connect_destroy(IMJAXimConnect* connect) {
63 	IMJAContext *ic;
64 	GSList *list;
65 
66 	/* remove all input contexts */
67 	list = connect->ic_list;
68 	while (list != NULL) {
69 		ic = (IMJAContext*)(list->data);
70 		if (ic != NULL) im_ja_context_destroy(ic);
71 		list = list->next;
72 	}
73 
74 	g_slist_free(connect->ic_list);
75 	g_free(connect);
76 }
77 
im_ja_xim_connect_add_ic(IMJAXimConnect * connect,IMJAContext * ic)78 void im_ja_xim_connect_add_ic(IMJAXimConnect* connect, IMJAContext *ic) {
79 	if (connect == NULL || ic == NULL) return;
80 	connect->ic_list = g_slist_prepend(connect->ic_list, ic);
81 }
82 
im_ja_xim_connect_remove_ic(IMJAXimConnect * connect,IMJAContext * ic)83 void im_ja_xim_connect_remove_ic(IMJAXimConnect* connect, IMJAContext *ic) {
84 	if (connect == NULL || ic == NULL) return;
85 	connect->ic_list = g_slist_remove(connect->ic_list, ic);
86 }
87 
im_ja_xim_ic_init_values(IMJAContext * ic)88 void im_ja_xim_ic_init_values(IMJAContext *ic) {
89 	IM_JA_DEBUG("im_ja_xim_ic_init_values\n");
90 
91 	ic->connect = im_ja_xim_server_get_connect_by_id(ic->connect_id);
92 
93 	/* preedit attr */
94 	ic->preedit.width = 1;	/* minimum window size is 1 x 1 */
95 	ic->preedit.height = 1;	/* minimum window size is 1 x 1 */
96 	ic->preedit.foreground = im_ja_xim_server->preedit_fg;
97 	ic->preedit.background = im_ja_xim_server->preedit_bg;
98 	ic->preedit.state = XIMPreeditEnable;
99 	ic->preedit.start = False;
100 
101 	/* set some sane values for the default colors */
102 	if ((ic->original_colors[0].red == ic->original_colors[1].red)
103 			&& (ic->original_colors[0].green == ic->original_colors[1].green)
104 			&& (ic->original_colors[0].blue == ic->original_colors[1].blue)) {
105 		IM_JA_DEBUG("**Warning** same fg and bg values\n");
106 		ic->original_colors[0].red = 0xffff;
107 		ic->original_colors[0].green = 0xffff;
108 		ic->original_colors[0].blue = 0xffff;
109 		ic->original_colors[1].red = 0;
110 		ic->original_colors[1].green = 0;
111 		ic->original_colors[1].blue = 0;
112 	}
113 
114 	if (ic->prev_preedit_buf == NULL) {
115 		ic->prev_preedit_buf = g_new0(gchar, BUFFERSIZE);
116 	}
117 }
118 
119 
im_ja_xim_ic_is_destroyed(IMJAContext * ic)120 static gboolean im_ja_xim_ic_is_destroyed(IMJAContext *ic) {
121 	if (ic->id > 0 && ic->id < im_ja_xim_server->ic_table_size) {
122 		return im_ja_xim_server->ic_table[ic->id] == NULL;
123 	}
124 	else return TRUE;
125 }
126 
127 
im_ja_context_impl_destroy(IMJAContext * ic)128 void im_ja_context_impl_destroy(IMJAContext *ic) {
129 	IM_JA_DEBUG("im_ja_context_impl_destroy\n");
130 
131 	if (im_ja_xim_ic_is_destroyed(ic)) return;
132 
133 	/* we do not delete, just save it in ic_freed */
134 	if (im_ja_xim_server->ic_freed == NULL) {
135 		im_ja_xim_server->ic_freed = ic;
136 		im_ja_xim_server->ic_freed->next = NULL;
137 	}
138 	else {
139 		ic->next = im_ja_xim_server->ic_freed;
140 		im_ja_xim_server->ic_freed = ic;
141 	}
142 
143 	im_ja_xim_server->ic_table[ic->id] = NULL;
144 
145 	ic->connect_id = 0;
146 	ic->client_window = 0;
147 	ic->focus_window = 0;
148 	g_free(ic->resource_name);
149 	ic->resource_name = NULL;
150 	g_free(ic->resource_class);
151 	ic->resource_class = NULL;
152 
153 	ic->connect = NULL;
154 
155 	ic->preedit.area.x = 0;
156 	ic->preedit.area.y = 0;
157 	ic->preedit.area.width = 0;
158 	ic->preedit.area.height = 0;
159 	ic->preedit.area_needed.x = 0;
160 	ic->preedit.area_needed.y = 0;
161 	ic->preedit.area_needed.width = 0;
162 	ic->preedit.area_needed.height = 0;
163 	ic->preedit.spot.x = 0;
164 	ic->preedit.spot.y = 0;
165 	ic->preedit.cmap = 0;
166 
167 	ic->preedit.width = 1;
168 	ic->preedit.height = 1;
169 	ic->preedit.ascent = 0;
170 	ic->preedit.descent = 0;
171 	ic->preedit.line_space = 0;
172 	ic->preedit.cursor = 0;
173 
174 	ic->preedit.state = XIMPreeditEnable;
175 	ic->preedit.start = False;
176 
177 	/* destroy preedit window */
178 	if (ic->preedit.window != 0) {
179 		XDestroyWindow(im_ja_xim_server->display, ic->preedit.window);
180 		ic->preedit.window = 0;
181 		/* XFreeGC ?? */
182 	}
183 
184 	/* destroy fontset data */
185 	if (ic->preedit.font_set) {
186 		im_ja_xim_fontset_free(im_ja_xim_server->display, ic->preedit.font_set);
187 		g_free(ic->preedit.base_font);
188 		ic->preedit.font_set = NULL;
189 		ic->preedit.base_font = NULL;
190 	}
191 
192 	/* status attributes */
193 	ic->status_attr.area.x = 0;
194 	ic->status_attr.area.y = 0;
195 	ic->status_attr.area.width = 0;
196 	ic->status_attr.area.height = 0;
197 
198 	ic->status_attr.area_needed.x = 0;
199 	ic->status_attr.area_needed.y = 0;
200 	ic->status_attr.area_needed.width = 0;
201 	ic->status_attr.area_needed.height = 0;
202 
203 	ic->status_attr.cmap = 0;
204 	ic->status_attr.foreground = 0;
205 	ic->status_attr.background = 0;
206 	ic->status_attr.background = 0;
207 	ic->status_attr.bg_pixmap = 0;
208 	ic->status_attr.line_space = 0;
209 	ic->status_attr.cursor = 0;
210 	ic->status_attr.base_font = NULL;
211 
212 }
213 
214 
215 /*
216 void im_ja_xim_ic_real_destroy(IMJAContext *ic) {
217 	if (ic == NULL) return;
218 
219 	g_free(ic->resource_name);
220 	g_free(ic->resource_class);
221 	g_free(ic->preedit.base_font);
222 	g_free(ic->status_attr.base_font);
223 
224 	if (ic->preedit.window != 0) {
225 		XDestroyWindow(im_ja_xim_server->display, ic->preedit.window);
226 	}
227 	if (ic->preedit.font_set) {
228 		im_ja_xim_fontset_free(im_ja_xim_server->display, ic->preedit.font_set);
229 	}
230 
231 	if (ic->preedit.gc) XFreeGC(im_ja_xim_server->display, ic->preedit.gc);
232 
233 	g_free(ic);
234 }
235 */
236 
237 
im_ja_xim_ic_preedit_show(IMJAContext * ic)238 void im_ja_xim_ic_preedit_show(IMJAContext *ic) {
239 	IM_JA_DEBUG("im_ja_xim_ic_preedit_show\n");
240 	im_ja_xim_ic_init_preedit(ic);
241 	if (ic->preedit.window == 0) {
242 		IM_JA_DEBUG(" error: no preedit.window!\n");
243 		return;
244 	}
245 
246 	if (strlen(ic->preedit_buf) > 0) {
247 		XFlush(im_ja_xim_server->display);
248 		XMapRaised(im_ja_xim_server->display, ic->preedit.window);
249 		/*debug_preedit(ic);*/
250 	}
251 }
252 
253 /*
254 static void im_ja_xim_ic_preedit_hide(IMJAContext *ic) {
255 	if (ic->preedit.window == 0) return;
256 
257 	XUnmapWindow(im_ja_xim_server->display, ic->preedit.window);
258 }
259 */
260 
261 /* move and resize preedit window */
im_ja_xim_ic_preedit_configure(IMJAContext * ic)262 static void im_ja_xim_ic_preedit_configure(IMJAContext *ic) {
263 	IM_JA_DEBUG("im_ja_xim_ic_preedit_configure\n");
264 
265 	im_ja_xim_ic_init_preedit(ic);
266 	if (ic->preedit.window == 0) {
267 		IM_JA_DEBUG(" no preedit window!\n");
268 		return;
269 	}
270 
271 	IM_JA_DEBUG(" move&resize preedit\n");
272 	XMoveResizeWindow(im_ja_xim_server->display, ic->preedit.window,
273 										ic->preedit.spot.x - 1, /* -1 is for hiding the cursor of the window (hack ?) */
274 										ic->preedit.spot.y - ic->preedit.ascent,
275 										ic->preedit.width,
276 										ic->preedit.height);
277 }
278 
279 /*
280 static void debug_preedit(IMJAContext *ic) {
281 	XWindowAttributes attribs;
282 
283 	if (ic->preedit.window == 0) {
284 		IM_JA_DEBUG(" NO PREEDIT WINDOW\n");
285 		return;
286 	}
287 
288 	XGetWindowAttributes(im_ja_xim_server->display, ic->preedit.window, &attribs);
289 
290 	IM_JA_DEBUG(" PREEDIT WINDOW:\n");
291 	IM_JA_DEBUG("  X: %d", attribs.x);
292 	IM_JA_DEBUG("  Y: %d", attribs.y);
293 	IM_JA_DEBUG("  WIDTH: %d", attribs.width);
294 	IM_JA_DEBUG("  HEIGHT: %d", attribs.height);
295 	IM_JA_DEBUG("  MAP STATE: ");
296 	switch (attribs.map_state) {
297 		case IsUnmapped:
298 			IM_JA_DEBUG("Unmapped");
299 			break;
300 		case IsUnviewable:
301 			IM_JA_DEBUG("Unviewable");
302 			break;
303 		case IsViewable:
304 			IM_JA_DEBUG("Viewable");
305 			break;
306 	}
307 
308 
309 	IM_JA_DEBUG("\n PREEDIT AREA:\n");
310 	IM_JA_DEBUG("  X: %d", ic->preedit.area.x);
311 	IM_JA_DEBUG("  Y: %d", ic->preedit.area.y);
312 	IM_JA_DEBUG("  WIDTH: %d", ic->preedit.area.width);
313 	IM_JA_DEBUG("  HEIGHT: %d\n", ic->preedit.area.height);
314 
315 	IM_JA_DEBUG(" SPOT:\n");
316 	IM_JA_DEBUG("  X: %d", ic->preedit.spot.x);
317 	IM_JA_DEBUG("  Y: %d\n", ic->preedit.spot.y);
318 
319 	IM_JA_DEBUG(" PREEDIT :\n");
320 	IM_JA_DEBUG("  WIDTH: %d", ic->preedit.width);
321 	IM_JA_DEBUG("  HEIGHT: %d\n", ic->preedit.height);
322 	IM_JA_DEBUG("  ASCENT: %d", ic->preedit.ascent);
323 	IM_JA_DEBUG("  DESCENT: %d\n", ic->preedit.descent);
324 
325 }
326 */
327 
328 /*
329 static void im_ja_preedit_area_update_attribs(IMJAContext *ic) {
330 	XWindowAttributes attribs;
331 
332 	if (ic->preedit.window == 0) return;
333 
334 	XGetWindowAttributes(im_ja_xim_server->display, ic->preedit.window, &attribs);
335 	ic->preedit.area.x = attribs.x;
336 	ic->preedit.area.y = attribs.y;
337 	ic->preedit.area.width = attribs.width;
338 	ic->preedit.area.height = attribs.height;
339 
340 }
341 */
342 
im_ja_xim_ic_preedit_draw(IMJAContext * ic)343 void im_ja_xim_ic_preedit_draw(IMJAContext *ic) {
344 	int width;
345 	int cursor_pos;
346 
347 	/*
348 		FIXME: GTKify this if possible:
349 		  - use preeditarea
350 		  - implement im_ja_xim_get_preedit_string()  and use that
351 			  instead of directly accessing preedit_buf
352 	*/
353 
354 	/* FIXME2: this cannot draw multi line preedit
355 	 */
356 
357 	IM_JA_DEBUG("im_ja_xim_ic_preedit_draw\n");
358 	if (strlen(ic->preedit_buf) == 0) return;
359 
360 	if (ic->preedit.window == 0) {
361 		/* im_ja_xim_ic_preedit_window_new(ic); */
362 	}
363 
364 	if (ic->preedit.font_set == 0) {
365 		IM_JA_DEBUG(" NO PREEDIT FONTSET\n");
366 		return;
367 	}
368 
369 	if (ic->preedit.gc == 0) {
370 		IM_JA_DEBUG(" NO PREEDIT GC\n");
371 		return;
372 	}
373 
374 	width = Xutf8TextEscapement(ic->preedit.font_set, ic->preedit_buf, strlen(ic->preedit_buf));
375 	cursor_pos = Xutf8TextEscapement(ic->preedit.font_set, ic->preedit_buf, im_ja_get_cursor_pos_bytes(ic));
376 
377 	if (ic->preedit.width != width) {
378 		ic->preedit.width = width;
379 		ic->preedit.height = ic->preedit.ascent + ic->preedit.descent;
380 		IM_JA_DEBUG(" resize preedit to %d x %d\n", ic->preedit.width, ic->preedit.height);
381 		XResizeWindow(im_ja_xim_server->display, ic->preedit.window,	ic->preedit.width, ic->preedit.height);
382 	}
383 
384 	/* if preedit window is out of focus window
385 	 	 we force to put it in focus window (preedit.area) */
386 	if (ic->preedit.spot.x + ic->preedit.width > ic->preedit.area.width) {
387 		ic->preedit.spot.x = ic->preedit.area.width - ic->preedit.width;
388 		XMoveWindow(im_ja_xim_server->display, ic->preedit.window,
389 								ic->preedit.spot.x, ic->preedit.spot.y - ic->preedit.ascent);
390 	}
391 
392 	/* debug_preedit(ic); */
393 
394 	Xutf8DrawString(im_ja_xim_server->display,
395 									ic->preedit.window,
396 									ic->preedit.font_set,
397 									ic->preedit.gc,
398 									0,
399 									ic->preedit.ascent,
400 									ic->preedit_buf,
401 									strlen(ic->preedit_buf));
402 
403 	if (ic->preedit_reverse_start != ic->preedit_reverse_end) {
404 		int reverse_start_pos;
405 		int reverse_end_pos;
406 		int reverse_length;
407 
408 		reverse_length = ic->preedit_reverse_end - ic->preedit_reverse_start;
409 		reverse_start_pos = Xutf8TextEscapement(ic->preedit.font_set, ic->preedit_buf, ic->preedit_reverse_start);
410 		reverse_end_pos = Xutf8TextEscapement(ic->preedit.font_set, ic->preedit_buf, ic->preedit_reverse_end);
411 
412 		/*
413 		IM_JA_DEBUG("REVERSE LENGTH: %d\n", reverse_length);
414 		IM_JA_DEBUG("REVERSE START POS: %d\n", reverse_start_pos);
415 		IM_JA_DEBUG("REVERSE STRING: %s\n", ic->preedit_buf + ic->preedit_reverse_start);
416 		*/
417 
418 		XFillRectangle(im_ja_xim_server->display,
419 									 ic->preedit.window,
420 									 ic->preedit.gc,
421 									 reverse_start_pos,
422 									 0,
423 									 reverse_end_pos - reverse_start_pos,
424 									 ic->preedit.ascent + ic->preedit.descent);
425 
426 		Xutf8DrawString(im_ja_xim_server->display,
427 										ic->preedit.window,
428 										ic->preedit.font_set,
429 										ic->preedit.reverse_gc,
430 										reverse_start_pos,
431 										ic->preedit.ascent,
432 										ic->preedit_buf + ic->preedit_reverse_start,
433 										reverse_length);
434 	}
435 
436 	if (cursor_pos >= ic->preedit.width) cursor_pos--;
437 
438 	XFillRectangle(im_ja_xim_server->display,
439 								 ic->preedit.window,
440 								 ic->preedit.gc,
441 								 cursor_pos,
442 								 0,
443 								 1,
444 								 ic->preedit.ascent + ic->preedit.descent);
445 
446 	XDrawLine(im_ja_xim_server->display,
447 						ic->preedit.window,
448 						ic->preedit.gc,
449 						0,
450 						ic->preedit.ascent + ic->preedit.descent - 1,
451 						ic->preedit.width - 1,
452 						ic->preedit.ascent + ic->preedit.descent - 1);
453 
454 	XFlush(im_ja_xim_server->display);
455 
456 }
457 
im_ja_xim_ic_preedit_event_filter(GdkXEvent * xevent,GdkEvent * gevent,gpointer data)458 static GdkFilterReturn im_ja_xim_ic_preedit_event_filter(GdkXEvent *xevent, GdkEvent *gevent, gpointer data) {
459 	IMJAContext *ic = (IMJAContext *)data;
460 	XEvent *event = (XEvent*)xevent;
461 
462 	IM_JA_DEBUG("im_ja_xim_preedit_event_filter\n");
463 
464 	if (ic == NULL) return GDK_FILTER_REMOVE;
465 	if (ic->preedit.window == 0) return GDK_FILTER_REMOVE;
466 
467 	if (event->xany.window != ic->preedit.window)	return GDK_FILTER_CONTINUE;
468 
469 	switch (event->type) {
470 	case DestroyNotify:
471 		IM_JA_DEBUG("DESTROYNOTIFY\n");
472 		if (!im_ja_xim_ic_is_destroyed(ic)) {
473 	    /* preedit window is destroyed, so we set it 0 */
474 	    ic->preedit.window = 0;
475 			im_ja_context_destroy(ic);
476 		}
477 		return GDK_FILTER_REMOVE;
478 		break;
479 	case Expose:
480 		IM_JA_DEBUG("Redraw Window\n");
481 		im_ja_xim_ic_preedit_draw(ic);
482 		break;
483 	default:
484 		IM_JA_DEBUG("event type: %d\n", event->type);
485 		break;
486 	}
487 
488 	return GDK_FILTER_CONTINUE;
489 }
490 
491 
im_ja_xim_ic_preedit_window_new(IMJAContext * ic)492 static void im_ja_xim_ic_preedit_window_new(IMJAContext *ic) {
493 	GdkWindow *gdk_window;
494 	Window parent = 0;
495 	XSetWindowAttributes attr;
496 
497 	IM_JA_DEBUG("im_ja_xim_ic_preedit_window_new()\n");
498 
499 	if (ic->focus_window != 0) {
500 		parent = ic->focus_window;
501 		IM_JA_DEBUG(" using focus_window as parent\n");
502 	}
503 	else if (ic->client_window != 0) {
504 		parent = ic->client_window;
505 		IM_JA_DEBUG(" using client_window as parent\n");
506 	}
507 	/*
508 	else {
509 		parent = DefaultRootWindow(im_ja_xim_server->display);
510 		IM_JA_DEBUG(" using root_window as parent\n");
511 	}
512 	*/
513 
514 	if (parent == 0) {
515 		IM_JA_DEBUG(" ERROR: no parent!\n");
516 		return;
517 	}
518 
519 	IM_JA_DEBUG(" creating %d x %d\n", ic->preedit.width, ic->preedit.height);
520 
521 	ic->preedit.window = XCreateSimpleWindow(im_ja_xim_server->display,
522 																					 parent,
523 																					 ic->preedit.spot.x,
524 																					 ic->preedit.spot.y - ic->preedit.ascent,
525 																					 ic->preedit.width,
526 																					 ic->preedit.height,
527 																					 0,
528 																					 im_ja_xim_server->preedit_fg, /* FIXME */
529 																					 im_ja_xim_server->preedit_bg); /* FIXME */
530 
531 	attr.override_redirect = True;
532 	XChangeWindowAttributes(im_ja_xim_server->display, ic->preedit.window, CWOverrideRedirect,
533 													&attr);
534 
535 	XSelectInput(im_ja_xim_server->display, ic->preedit.window,
536 							 ExposureMask | StructureNotifyMask);
537 
538 	/* install our preedit window event filter */
539 	gdk_window = gdk_window_foreign_new(ic->preedit.window);
540 	if (gdk_window != NULL) {
541 		gdk_window_add_filter(gdk_window, im_ja_xim_ic_preedit_event_filter, (gpointer)ic);
542 		g_object_unref(gdk_window);
543 	}
544 	IM_JA_DEBUG(" done.\n");
545 }
546 
im_ja_xim_preedit_create_gc(IMJAContext * ic)547 static void im_ja_xim_preedit_create_gc(IMJAContext *ic) {
548 	if (ic->preedit.gc == 0) {
549 		XGCValues values;
550 
551 		values.foreground = im_ja_xim_server->preedit_fg;
552 		values.background = im_ja_xim_server->preedit_bg;
553 
554 		ic->preedit.gc = XCreateGC(im_ja_xim_server->display,
555 															 im_ja_xim_server->window,
556 															 GCForeground | GCBackground,
557 															 &values);
558 	}
559 
560 	if (ic->preedit.reverse_gc == 0) {
561 		XGCValues rev_values;
562 
563 		rev_values.background = im_ja_xim_server->preedit_fg;
564 		rev_values.foreground = im_ja_xim_server->preedit_bg;
565 
566 		/*
567 		//rev_values.background = im_ja_xim_server->preedit_bg;
568 		//rev_values.foreground = im_ja_xim_server->preedit_fg;
569 		*/
570 		ic->preedit.reverse_gc = XCreateGC(im_ja_xim_server->display,
571 																			 im_ja_xim_server->window,
572 																			 GCForeground | GCBackground,
573 																			 &rev_values);
574 	}
575 
576 }
577 
im_ja_xim_ic_init_preedit(IMJAContext * ic)578 static void im_ja_xim_ic_init_preedit(IMJAContext *ic) {
579 	IM_JA_DEBUG("im_ja_xim_ic_init_preedit()\n");
580 	if (ic->input_style & XIMPreeditPosition) {
581 		if ((ic->preedit.gc == 0) || (ic->preedit.reverse_gc == 0)) {
582 			im_ja_xim_preedit_create_gc(ic);
583 		}
584 
585 		/* For Preedit Position aka Over the Spot */
586 		if (ic->preedit.window == 0) {
587 			im_ja_xim_ic_preedit_window_new(ic);
588 		}
589 	}
590 }
591 
im_ja_xim_ic_set_focus_window(IMJAContext * ic,Window focus_window)592 static void im_ja_xim_ic_set_focus_window(IMJAContext *ic, Window focus_window) {
593 	XWindowAttributes attribs;
594 
595 	/* FIXME: focus window is client window (in gtkimcontext)?? */
596 	IM_JA_DEBUG("im_ja_xim_ic_set_focus_window\n");
597 
598 
599 	XGetWindowAttributes(im_ja_xim_server->display, focus_window, &attribs);
600 
601 	IM_JA_DEBUG(" FOCUS WINDOW: ");
602 	IM_JA_DEBUG("  X: %d", attribs.x);
603 	IM_JA_DEBUG("  Y: %d", attribs.y);
604 	IM_JA_DEBUG("  WIDTH: %d", attribs.width);
605 	IM_JA_DEBUG("  HEIGHT: %d\n", attribs.height);
606 
607 	ic->focus_window = focus_window;
608 	im_ja_xim_ic_init_preedit(ic);
609 }
610 
im_ja_xim_ic_set_preedit_foreground(IMJAContext * ic,unsigned long foreground)611 static void im_ja_xim_ic_set_preedit_foreground(IMJAContext *ic, unsigned long foreground) { /* FIXME: use conf */
612 	IM_JA_DEBUG("im_ja_xim_ic_set_preedit_foreground: %d\n", (int) foreground);
613 
614 	/* foreground = im_ja_xim_server->preedit_fg; */
615 	im_ja_xim_server->preedit_fg = foreground;
616 	ic->preedit.foreground = foreground;
617 
618 	if (ic->focus_window == 0) return;
619 
620 	if ((ic->preedit.gc == 0) || (ic->preedit.reverse_gc == 0)) {
621 		im_ja_xim_preedit_create_gc(ic);
622 	}
623 
624 	XSetForeground(im_ja_xim_server->display, ic->preedit.gc,	ic->preedit.foreground);
625 
626 	/* XSetForeground(im_ja_xim_server->display, ic->preedit.reverse_gc, ic->preedit.foreground); */
627 	XSetBackground(im_ja_xim_server->display, ic->preedit.reverse_gc,	ic->preedit.foreground);
628 
629 }
630 
631 
im_ja_xim_ic_set_preedit_background(IMJAContext * ic,unsigned long background)632 static void im_ja_xim_ic_set_preedit_background(IMJAContext *ic, unsigned long background) { /* FIXME: use conf */
633 	IM_JA_DEBUG("im_ja_xim_ic_set_preedit_background: %d\n", (int) background);
634 
635 	/* background = im_ja_xim_server->preedit_bg; */
636 	im_ja_xim_server->preedit_bg = background;
637 	ic->preedit.background = background;
638 
639 	if (ic->focus_window == 0) return;
640 
641 	if ((ic->preedit.gc == 0) || (ic->preedit.reverse_gc == 0)) {
642 		im_ja_xim_preedit_create_gc(ic);
643 	}
644 
645 	XSetBackground(im_ja_xim_server->display, ic->preedit.gc, ic->preedit.background);
646 
647 	/* XSetBackground(im_ja_xim_server->display, ic->preedit.reverse_gc, ic->preedit.background); */
648 	XSetForeground(im_ja_xim_server->display, ic->preedit.reverse_gc, ic->preedit.background);
649 
650 }
651 
652 
im_ja_xim_ic_load_preedit_fontset(IMJAContext * ic,char * font_name)653 static void im_ja_xim_ic_load_preedit_fontset(IMJAContext *ic, char *font_name) {
654 	IMJAXimFontSet *fontset;
655 
656 	IM_JA_DEBUG("im_ja_xim_ic_load_preedit_fontset\n");
657 
658 	if (ic->preedit.base_font != NULL && strcmp(ic->preedit.base_font, font_name) == 0) {
659 		/* same font, do not create fontset */
660 		return;
661 	}
662 
663 	if (ic->preedit.base_font != NULL) g_free(ic->preedit.base_font);
664 	ic->preedit.base_font = g_strdup(font_name);
665 	if (ic->preedit.font_set)	im_ja_xim_fontset_free(im_ja_xim_server->display, ic->preedit.font_set);
666 
667 	fontset = im_ja_xim_fontset_create(im_ja_xim_server->display, font_name);
668 	if (fontset == NULL) {
669 		IM_JA_DEBUG("WARNING: FONTSET == NULL\n");
670 		return;
671 	}
672 
673 	ic->preedit.font_set = fontset->xfontset;
674 	ic->preedit.ascent = fontset->ascent;
675 	ic->preedit.descent = fontset->descent;
676 	ic->preedit.height = ic->preedit.ascent + ic->preedit.descent;
677 	ic->preedit.width = 1;
678 }
679 
680 
im_ja_xim_ic_set_spot(IMJAContext * ic,XPoint * point)681 static void im_ja_xim_ic_set_spot(IMJAContext *ic, XPoint *point) {
682 
683 	IM_JA_DEBUG("im_ja_xim_ic_set_spot\n");
684 
685 	if (point == NULL) return;
686 
687 	ic->preedit.spot.x = point->x + 1;
688 	ic->preedit.spot.y = point->y;
689 
690 	IM_JA_DEBUG(" X: %d, Y: %d\n", ic->preedit.spot.x, ic->preedit.spot.y);
691 
692 	im_ja_cursor_location_changed(ic, ic->preedit.spot.x, ic->preedit.spot.y + 3);
693 
694 
695 	/* if preedit window is out of focus window
696 	 * we force it in focus window (preedit.area) */
697 	if (ic->preedit.spot.x + ic->preedit.width > ic->preedit.area.width) {
698 		ic->preedit.spot.x = ic->preedit.area.width - ic->preedit.width;
699 	}
700 
701 	im_ja_xim_ic_preedit_configure(ic);
702 
703 	/* FIXME
704 	if (im_ja_xim_ic_is_empty(ic)) im_ja_xim_ic_preedit_hide(ic);
705 	else
706 	*/
707 	im_ja_xim_ic_preedit_show(ic);
708 
709 }
710 /*
711     XIMPreeditCallbacks | XIMStatusCallbacks,
712     XIMPreeditCallbacks | XIMStatusArea,
713     XIMPreeditCallbacks | XIMStatusNothing,
714 
715 		XIMPreeditPosition  | XIMStatusCallbacks,
716 		XIMPreeditPosition  | XIMStatusArea,
717 		XIMPreeditPosition  | XIMStatusNothing,
718 
719     XIMPreeditArea      | XIMStatusCallbacks,
720     XIMPreeditArea      | XIMStatusArea,
721     XIMPreeditArea      | XIMStatusNothing,
722 
723     XIMPreeditNothing   | XIMStatusNothing,
724 */
725 
im_ja_xim_ic_set_client_window(IMJAContext * ic,Window win)726 static void im_ja_xim_ic_set_client_window(IMJAContext *ic, Window win) {
727 	XWindowAttributes attribs;
728 	GdkWindow *gdk_window;
729 
730 	IM_JA_DEBUG("im_ja_xim_ic_set_client_window\n");
731 
732 	ic->client_window = win;
733 
734 	if (ic->client_window == 0) {
735 		IM_JA_DEBUG(" NO CLIENT WINDOW\n");
736 		return;
737 	}
738 
739 	XGetWindowAttributes(im_ja_xim_server->display, ic->client_window, &attribs);
740 
741 	IM_JA_DEBUG(" CLIENT WINDOW: ");
742 	IM_JA_DEBUG("  X: %d", attribs.x);
743 	IM_JA_DEBUG("  Y: %d", attribs.y);
744 	IM_JA_DEBUG("  WIDTH: %d", attribs.width);
745 	IM_JA_DEBUG("  HEIGHT: %d\n", attribs.height);
746 
747 	gdk_window = gdk_window_foreign_new(ic->client_window);
748 	if (gdk_window != NULL) {
749 		gdk_window_add_filter(gdk_window, im_ja_xim_ic_preedit_event_filter, (gpointer)ic);
750 		g_object_unref(gdk_window);
751 	}
752 
753 }
754 
755 
print_xim_styles(XIMStyle style)756 static void print_xim_styles(XIMStyle style) {
757 
758 	IM_JA_DEBUG(" Supported styles:\n");
759 	if (style & XIMPreeditCallbacks) IM_JA_DEBUG("  XIMPreeditCallbacks\n");
760 	if (style & XIMPreeditPosition) IM_JA_DEBUG("  XIMPreeditPosition\n");
761 	if (style & XIMPreeditArea) IM_JA_DEBUG("  XIMPreeditArea\n");
762 	if (style & XIMPreeditNothing) IM_JA_DEBUG("  XIMPreeditNothing\n");
763 
764 	if (style & XIMStatusCallbacks) IM_JA_DEBUG("  XIMStatusCallbacks\n");
765 	if (style & XIMStatusArea) IM_JA_DEBUG("  XIMStatusArea\n");
766 	if (style & XIMStatusNothing) IM_JA_DEBUG("  XIMStatusNothing\n");
767 }
768 
769 
im_ja_xim_ic_set_values(IMJAContext * ic,IMChangeICStruct * data)770 void im_ja_xim_ic_set_values(IMJAContext *ic, IMChangeICStruct *data) {
771 
772 	XICAttribute *ic_attr = data->ic_attr;
773 	XICAttribute *preedit_attr = data->preedit_attr;
774 	XICAttribute *status_attr = data->status_attr;
775 	CARD16 i;
776 
777 	IM_JA_DEBUG("im_ja_xim_ic_set_values\n");
778 
779 	if (ic == NULL) return;
780 
781 	for (i = 0; i < data->ic_attr_num; i++, ic_attr++) {
782 		IM_JA_DEBUG(" ic attribute: %s\n", ic_attr->name);
783 		if (streql(XNInputStyle, ic_attr->name)) {
784 	    ic->input_style = *(INT32*)ic_attr->value;
785 			print_xim_styles(ic->input_style);
786 			if (ic->input_style & XIMPreeditNothing) im_ja_set_use_preedit(ic, TRUE);
787 			im_ja_xim_ic_init_preedit(ic);
788 
789 		}
790 		else if (streql(XNClientWindow, ic_attr->name)) {
791 			im_ja_xim_ic_set_client_window(ic, *(Window*)ic_attr->value);
792 		}
793 		else if (streql(XNFocusWindow, ic_attr->name)) {
794 	    im_ja_xim_ic_set_focus_window(ic, *(Window*)ic_attr->value);
795 		}
796 		else {
797 	    g_error("im_ja_xim: set unknown ic attribute: %s\n", ic_attr->name);
798 		}
799 	}
800 
801 	for (i = 0; i < data->preedit_attr_num; i++, preedit_attr++) {
802 		IM_JA_DEBUG(" preedit attribute: %s\n", preedit_attr->name);
803 		if (streql(XNSpotLocation, preedit_attr->name)) {
804 	    im_ja_xim_ic_set_spot(ic, (XPoint*)preedit_attr->value);
805 		}
806 		else if (streql(XNForeground, preedit_attr->name)) {
807 	    im_ja_xim_ic_set_preedit_foreground(ic, *(unsigned long*)preedit_attr->value);
808 		}
809 		else if (streql(XNBackground, preedit_attr->name)) {
810 	    im_ja_xim_ic_set_preedit_background(ic,	*(unsigned long*)preedit_attr->value);
811 		}
812 		else if (streql(XNArea, preedit_attr->name)) {
813 	    ic->preedit.area = *(XRectangle*)preedit_attr->value;
814 		}
815 		else if (streql(XNLineSpace, preedit_attr->name)) {
816 	    ic->preedit.line_space = *(CARD32*)preedit_attr->value;
817 		}
818 		else if (streql(XNPreeditState, preedit_attr->name)) {
819 	    ic->preedit.state = *(XIMPreeditState*)preedit_attr->value;
820 		}
821 		else if (streql(XNFontSet, preedit_attr->name)) {
822 	    im_ja_xim_ic_load_preedit_fontset(ic, (char*)preedit_attr->value);
823 		}
824 		else {
825 	    g_print("Im_Ja_Xim: set unknown preedit attribute: %s\n",
826 							preedit_attr->name);
827 		}
828 	}
829 
830 	for (i = 0; i < data->status_attr_num; i++, status_attr++) {
831 		IM_JA_DEBUG(" status attribute: %s\n", status_attr->name);
832 		if (streql(XNArea, status_attr->name)) {
833 			ic->status_attr.area = *(XRectangle*)status_attr->value;
834 		}
835 		else if (streql(XNAreaNeeded, status_attr->name)) {
836 			ic->status_attr.area_needed = *(XRectangle*)status_attr->value;
837 		}
838 		else if (streql(XNForeground, status_attr->name)) {
839 			ic->status_attr.foreground = *(unsigned long*)status_attr->value;
840 		}
841 		else if (streql(XNBackground, status_attr->name)) {
842 			ic->status_attr.background = *(unsigned long*)status_attr->value;
843 		}
844 		else if (streql(XNLineSpace, status_attr->name)) {
845 			ic->status_attr.line_space = *(CARD32*)status_attr->value;
846 		}
847 		else if (streql(XNFontSet, status_attr->name)) {
848 			g_free(ic->status_attr.base_font);
849 			ic->status_attr.base_font = g_strdup((char*)status_attr->value);
850 		}
851 		else {
852 			g_print("Im_Ja_Xim: set unknown status attributes: %s\n",	status_attr->name);
853 		}
854 	}
855 }
856 
857 
im_ja_xim_ic_get_values(IMJAContext * ic,IMChangeICStruct * data)858 void im_ja_xim_ic_get_values(IMJAContext *ic, IMChangeICStruct *data) {
859 	XICAttribute *ic_attr = data->ic_attr;
860 	XICAttribute *preedit_attr = data->preedit_attr;
861 	XICAttribute *status_attr = data->status_attr;
862 	CARD16 i;
863 
864 	IM_JA_DEBUG("im_ja_xim_ic_get_values\n");
865 
866 	if (ic == NULL) return;
867 
868 
869 	for (i = 0; i < data->ic_attr_num; i++, ic_attr++) {
870 		IM_JA_DEBUG(" ic attribute: %s\n", ic_attr->name);
871 		if (streql(XNFilterEvents, ic_attr->name)) {
872 			ic_attr->value = (void *)malloc(sizeof(CARD32));
873 			*(CARD32*)ic_attr->value = KeyPressMask | KeyReleaseMask;
874 			ic_attr->value_length = sizeof(CARD32);
875 		}
876 		else if (streql(XNInputStyle, ic_attr->name)) {
877 			ic_attr->value = (void *)malloc(sizeof(INT32));
878 			*(INT32*)ic_attr->value	= ic->input_style;
879 			ic_attr->value_length = sizeof(INT32);
880 		}
881 		else if (streql(XNSeparatorofNestedList, ic_attr->name)) {
882 			/* FIXME: what do I do here? */
883 				;
884 		}
885 		else {
886 			g_error("im_ja_xim: get unknown ic attribute: %s\n", ic_attr->name);
887 		}
888 	}
889 
890 	for (i = 0; i < data->preedit_attr_num; i++, preedit_attr++) {
891 		IM_JA_DEBUG(" preedit attribute: %s\n", preedit_attr->name);
892 		if (streql(XNArea, preedit_attr->name)) {
893 			preedit_attr->value = (void *)malloc(sizeof(XRectangle));
894 			*(XRectangle*)preedit_attr->value = ic->preedit.area;
895 			preedit_attr->value_length = sizeof(XRectangle);
896 		}
897 		else if (streql(XNAreaNeeded, preedit_attr->name)) {
898 			preedit_attr->value = (void *)malloc(sizeof(XRectangle));
899 			*(XRectangle*)preedit_attr->value = ic->preedit.area_needed;
900 			preedit_attr->value_length = sizeof(XRectangle);
901 		}
902 		else if (streql(XNSpotLocation, preedit_attr->name)) {
903 			preedit_attr->value = (void *)malloc(sizeof(XPoint));
904 			*(XPoint*)preedit_attr->value = ic->preedit.spot;
905 			preedit_attr->value_length = sizeof(XPoint);
906 		}
907 		else if (streql(XNForeground, preedit_attr->name)) {
908 			preedit_attr->value = (void *)malloc(sizeof(long));
909 			*(long*)preedit_attr->value	= ic->preedit.foreground;
910 			preedit_attr->value_length = sizeof(long);
911 		}
912 		else if (streql(XNBackground, preedit_attr->name)) {
913 			preedit_attr->value = (void *)malloc(sizeof(long));
914 			*(long*)preedit_attr->value	= ic->preedit.background;
915 			preedit_attr->value_length = sizeof(long);
916 		}
917 		else if (streql(XNLineSpace, preedit_attr->name)) {
918 			preedit_attr->value = (void *)malloc(sizeof(long));
919 			*(long*)preedit_attr->value	= ic->preedit.line_space;
920 			preedit_attr->value_length = sizeof(long);
921 		}
922 		else if (streql(XNPreeditState, preedit_attr->name)) {
923 			preedit_attr->value = (void *)malloc(sizeof(XIMPreeditState));
924 			*(XIMPreeditState*)preedit_attr->value = ic->preedit.state;
925 			preedit_attr->value_length = sizeof(XIMPreeditState);
926 		}
927 		else if (streql(XNFontSet, preedit_attr->name)) {
928 			CARD16 base_len = (CARD16)strlen(ic->preedit.base_font);
929 			int total_len = sizeof(CARD16) + (CARD16)base_len;
930 			char *p;
931 
932 			preedit_attr->value = (void *)malloc(total_len);
933 			p = (char *)preedit_attr->value;
934 			memmove(p, &base_len, sizeof(CARD16));
935 			p += sizeof(CARD16);
936 			strncpy(p, ic->preedit.base_font, base_len);
937 			preedit_attr->value_length = total_len;
938 		}
939 		else {
940 			g_print("im_ja_xim: get unknown preedit attribute: %s\n", preedit_attr->name);
941 		}
942 	}
943 
944 	for (i = 0; i < data->status_attr_num; i++, status_attr++) {
945 		IM_JA_DEBUG(" status attribute: %s\n", status_attr->name);
946 		if (streql(XNArea, status_attr->name)) {
947 			status_attr->value = (void *)malloc(sizeof(XRectangle));
948 			*(XRectangle*)status_attr->value = ic->status_attr.area;
949 			status_attr->value_length = sizeof(XRectangle);
950 		}
951 		else if (streql(XNAreaNeeded, status_attr->name)) {
952 			status_attr->value = (void *)malloc(sizeof(XRectangle));
953 			*(XRectangle*)status_attr->value = ic->status_attr.area_needed;
954 			status_attr->value_length = sizeof(XRectangle);
955 		}
956 		else if (streql(XNForeground, status_attr->name)) {
957 			status_attr->value = (void *)malloc(sizeof(long));
958 			*(long*)status_attr->value = ic->status_attr.foreground;
959 			status_attr->value_length = sizeof(long);
960 		}
961 		else if (streql(XNBackground, status_attr->name)) {
962 			status_attr->value = (void *)malloc(sizeof(long));
963 			*(long*)status_attr->value = ic->status_attr.background;
964 			status_attr->value_length = sizeof(long);
965 		}
966 		else if (streql(XNLineSpace, status_attr->name)) {
967 			status_attr->value = (void *)malloc(sizeof(long));
968 			*(long*)status_attr->value = ic->status_attr.line_space;
969 			status_attr->value_length = sizeof(long);
970 		}
971 		else if (streql(XNFontSet, status_attr->name)) {
972 			CARD16 base_len = (CARD16)strlen(ic->status_attr.base_font);
973 			int total_len = sizeof(CARD16) + (CARD16)base_len;
974 			char *p;
975 
976 			status_attr->value = (void *)malloc(total_len);
977 			p = (char *)status_attr->value;
978 			memmove(p, &base_len, sizeof(CARD16));
979 			p += sizeof(CARD16);
980 			strncpy(p, ic->status_attr.base_font, base_len);
981 			status_attr->value_length = total_len;
982 		}
983 		else {
984 			g_print("im_ja_xim: get unknown status attribute: %s\n", status_attr->name);
985 		}
986 	}
987 
988 }
989 
990 
991 /*
992 void im_ja_xim_ic_reset(IMJAContext *ic) {
993 	if (!im_ja_xim_ic_is_empty(ic))	im_ja_xim_ic_commit(ic);
994 }
995 */
996 
im_ja_xim_ic_preedit_clear(IMJAContext * ic)997 void im_ja_xim_ic_preedit_clear(IMJAContext *ic) {
998 	XIMText text;
999 	XIMFeedback feedback[4] = { XIMUnderline, 0, 0, 0 };
1000 	IMPreeditCBStruct data;
1001 	XTextProperty tp;
1002 	char *list[2];
1003 	IMCommitStruct commit_data;
1004 	int ret;
1005 
1006 	IM_JA_DEBUG("im_ja_xim_ic_preedit_clear()\n");
1007 
1008 	if (ic->input_style & XIMPreeditCallbacks) {
1009 		data.major_code = XIM_PREEDIT_DRAW;
1010 		data.minor_code = 0;
1011 		data.connect_id = ic->connect_id;
1012 		data.icid = ic->id;
1013 		data.todo.draw.caret = 0;
1014 		data.todo.draw.chg_first = 0;
1015 		data.todo.draw.chg_length = g_utf8_strlen(ic->prev_preedit_buf, -1);
1016 		data.todo.draw.text = &text;
1017 
1018 		text.feedback = feedback;
1019 		text.encoding_is_wchar = False;
1020 		text.string.multi_byte = ""; /*NULL;*/
1021 		text.length = 0;
1022 		IMCallCallback(im_ja_xim_server->xims, (XPointer)&data);
1023 
1024 		/* this commit is needed for kde/qt for some reason */
1025 
1026 		list[0] = "";
1027 		list[1] = 0;
1028 		ret = Xutf8TextListToTextProperty(im_ja_xim_server->display, list, 1,
1029 																			XCompoundTextStyle,
1030 																			&tp);
1031 		commit_data.connect_id = ic->connect_id;
1032 		commit_data.icid = ic->id;
1033 		commit_data.flag = XimLookupChars;
1034 		commit_data.commit_string = (char*) tp.value;
1035 
1036 		IMCommitString(im_ja_xim_server->xims, (XPointer)&commit_data);
1037 		XFree(tp.value);
1038 	}
1039 	else if (ic->input_style & XIMPreeditPosition) {
1040 		if (ic->preedit.window == 0) return;
1041 		XUnmapWindow(im_ja_xim_server->display, ic->preedit.window);
1042 	}
1043 	memset(ic->prev_preedit_buf, 0, BUFFERSIZE);
1044 
1045 }
1046 
im_ja_xim_ic_preedit_start(IMJAContext * ic)1047 void im_ja_xim_ic_preedit_start(IMJAContext *ic) {
1048 
1049 	IM_JA_DEBUG("im_ja_xim_ic_preedit_start\n");
1050 
1051 	if (ic->preedit.start) return;
1052 
1053 	if (im_ja_xim_server->dynamic_event_flow) {
1054 		IMPreeditStateStruct preedit_state;
1055 
1056 		preedit_state.connect_id = ic->connect_id;
1057 		preedit_state.icid = ic->id;
1058 		IMPreeditStart(im_ja_xim_server->xims, (XPointer)&preedit_state);
1059 	}
1060 
1061 	if (ic->input_style & XIMPreeditCallbacks) {
1062 		IMPreeditCBStruct preedit_data;
1063 
1064 		preedit_data.major_code = XIM_PREEDIT_START;
1065 		preedit_data.minor_code = 0;
1066 		preedit_data.connect_id = ic->connect_id;
1067 		preedit_data.icid = ic->id;
1068 		preedit_data.todo.return_value = 0;
1069 		IMCallCallback(im_ja_xim_server->xims, (XPointer)&preedit_data);
1070 	}
1071 	else if (ic->input_style & XIMPreeditPosition) {
1072 		ic->preedit.start = True;
1073 		im_ja_xim_ic_preedit_clear(ic);
1074 
1075 		im_ja_xim_ic_set_preedit_foreground(ic, im_ja_xim_server->preedit_fg);
1076 		im_ja_xim_ic_set_preedit_background(ic, im_ja_xim_server->preedit_bg);
1077 	}
1078 
1079 }
1080 
1081 
1082 /*
1083 void im_ja_xim_ic_preedit_done(IMJAContext *ic) {
1084 	if (!ic->preedit.start) return;
1085 
1086 	if (ic->input_style & XIMPreeditCallbacks) {
1087 		IMPreeditCBStruct preedit_data;
1088 
1089 		preedit_data.major_code = XIM_PREEDIT_DONE;
1090 		preedit_data.minor_code = 0;
1091 		preedit_data.connect_id = ic->connect_id;
1092 		preedit_data.icid = ic->id;
1093 		preedit_data.todo.return_value = 0;
1094 		IMCallCallback(im_ja_xim_server->xims, (XPointer)&preedit_data);
1095 	}
1096 	else if (ic->input_style & XIMPreeditPosition) {
1097 		; // do nothing
1098 	}
1099 
1100 	if (im_ja_xim_server->dynamic_event_flow) {
1101 		IMPreeditStateStruct preedit_state;
1102 
1103 		preedit_state.connect_id = ic->connect_id;
1104 		preedit_state.icid = ic->id;
1105 		IMPreeditEnd(im_ja_xim_server->xims, (XPointer)&preedit_state);
1106 	}
1107 
1108 	ic->preedit.start = False;
1109 }
1110 */
1111 
1112