diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/modules/immodules/xim/ecore_imf_xim.c | 614 |
1 files changed, 398 insertions, 216 deletions
diff --git a/libraries/ecore/src/modules/immodules/xim/ecore_imf_xim.c b/libraries/ecore/src/modules/immodules/xim/ecore_imf_xim.c index 7c40606..ea7ee7f 100644 --- a/libraries/ecore/src/modules/immodules/xim/ecore_imf_xim.c +++ b/libraries/ecore/src/modules/immodules/xim/ecore_imf_xim.c | |||
@@ -1,3 +1,7 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
1 | #include <Eina.h> | 5 | #include <Eina.h> |
2 | #include <Ecore.h> | 6 | #include <Ecore.h> |
3 | #include <Ecore_Input.h> | 7 | #include <Ecore_Input.h> |
@@ -12,9 +16,6 @@ | |||
12 | #include <string.h> | 16 | #include <string.h> |
13 | #include <langinfo.h> | 17 | #include <langinfo.h> |
14 | #include <assert.h> | 18 | #include <assert.h> |
15 | #ifdef HAVE_CONFIG_H | ||
16 | # include <config.h> | ||
17 | #endif | ||
18 | 19 | ||
19 | #define CLAMP(x, low, high) (x > high) ? high : (x < low) ? low : x | 20 | #define CLAMP(x, low, high) (x > high) ? high : (x < low) ? low : x |
20 | #define _(x) x | 21 | #define _(x) x |
@@ -23,6 +24,8 @@ | |||
23 | static Eina_List *open_ims = NULL; | 24 | static Eina_List *open_ims = NULL; |
24 | #endif | 25 | #endif |
25 | 26 | ||
27 | #define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight) | ||
28 | |||
26 | typedef struct _XIM_Im_Info XIM_Im_Info; | 29 | typedef struct _XIM_Im_Info XIM_Im_Info; |
27 | struct _XIM_Im_Info | 30 | struct _XIM_Im_Info |
28 | { | 31 | { |
@@ -51,6 +54,7 @@ struct _Ecore_IMF_Context_Data | |||
51 | Eina_Bool finalizing; | 54 | Eina_Bool finalizing; |
52 | Eina_Bool has_focus; | 55 | Eina_Bool has_focus; |
53 | Eina_Bool in_toplevel; | 56 | Eina_Bool in_toplevel; |
57 | XIMFeedback *feedbacks; | ||
54 | 58 | ||
55 | XIMCallback preedit_start_cb; | 59 | XIMCallback preedit_start_cb; |
56 | XIMCallback preedit_done_cb; | 60 | XIMCallback preedit_done_cb; |
@@ -63,40 +67,62 @@ Ecore_IMF_Context_Data *imf_context_data_new(); | |||
63 | void imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data); | 67 | void imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data); |
64 | 68 | ||
65 | #ifdef ENABLE_XIM | 69 | #ifdef ENABLE_XIM |
66 | static void reinitialize_ic(Ecore_IMF_Context *ctx); | 70 | static void add_feedback_attr(Eina_List **attrs, |
67 | static void reinitialize_all_ics(XIM_Im_Info *info); | 71 | const char *str, |
68 | static void set_ic_client_window(Ecore_IMF_Context *ctx, | 72 | XIMFeedback feedback, |
69 | Ecore_X_Window window); | 73 | int start_pos, |
70 | static int preedit_start_callback(XIC xic, | 74 | int end_pos); |
71 | XPointer client_data, | 75 | |
72 | XPointer call_data); | 76 | static void reinitialize_ic(Ecore_IMF_Context *ctx); |
73 | static void preedit_done_callback(XIC xic, | 77 | static void reinitialize_all_ics(XIM_Im_Info *info); |
74 | XPointer client_data, | 78 | static void set_ic_client_window(Ecore_IMF_Context *ctx, |
75 | XPointer call_data); | 79 | Ecore_X_Window window); |
76 | static int xim_text_to_utf8(Ecore_IMF_Context *ctx, | 80 | static int preedit_start_callback(XIC xic, |
77 | XIMText *xim_text, | 81 | XPointer client_data, |
78 | char **text); | 82 | XPointer call_data); |
79 | static void preedit_draw_callback(XIC xic, | 83 | static void preedit_done_callback(XIC xic, |
80 | XPointer client_data, | 84 | XPointer client_data, |
81 | XIMPreeditDrawCallbackStruct *call_data); | 85 | XPointer call_data); |
82 | static void preedit_caret_callback(XIC xic, | 86 | static int xim_text_to_utf8(Ecore_IMF_Context *ctx, |
83 | XPointer client_data, | 87 | XIMText *xim_text, |
84 | XIMPreeditCaretCallbackStruct *call_data); | 88 | char **text); |
89 | static void preedit_draw_callback(XIC xic, | ||
90 | XPointer client_data, | ||
91 | XIMPreeditDrawCallbackStruct *call_data); | ||
92 | static void preedit_caret_callback(XIC xic, | ||
93 | XPointer client_data, | ||
94 | XIMPreeditCaretCallbackStruct *call_data); | ||
85 | static XVaNestedList preedit_callback_set(Ecore_IMF_Context *ctx); | 95 | static XVaNestedList preedit_callback_set(Ecore_IMF_Context *ctx); |
86 | static XIC get_ic(Ecore_IMF_Context *ctx); | 96 | static XIC get_ic(Ecore_IMF_Context *ctx); |
87 | static XIM_Im_Info *get_im(Ecore_X_Window window, | 97 | static XIM_Im_Info *get_im(Ecore_X_Window window, |
88 | char *locale); | 98 | char *locale); |
89 | static void xim_info_try_im(XIM_Im_Info *info); | 99 | static void xim_info_try_im(XIM_Im_Info *info); |
90 | static void xim_info_display_closed(Ecore_X_Display *display, | 100 | static void xim_info_display_closed(Ecore_X_Display *display, |
91 | int is_error, | 101 | int is_error, |
92 | XIM_Im_Info *info); | 102 | XIM_Im_Info *info); |
93 | static void xim_instantiate_callback(Display *display, | 103 | static void xim_instantiate_callback(Display *display, |
94 | XPointer client_data, | 104 | XPointer client_data, |
95 | XPointer call_data); | 105 | XPointer call_data); |
96 | static void setup_im(XIM_Im_Info *info); | 106 | static void setup_im(XIM_Im_Info *info); |
97 | static void xim_destroy_callback(XIM xim, | 107 | static void xim_destroy_callback(XIM xim, |
98 | XPointer client_data, | 108 | XPointer client_data, |
99 | XPointer call_data); | 109 | XPointer call_data); |
110 | #endif | ||
111 | |||
112 | #ifdef ENABLE_XIM | ||
113 | static unsigned int | ||
114 | utf8_offset_to_index(const char *str, int offset) | ||
115 | { | ||
116 | int index = 0; | ||
117 | int i; | ||
118 | for (i = 0; i < offset; i++) | ||
119 | { | ||
120 | eina_unicode_utf8_get_next(str, &index); | ||
121 | } | ||
122 | |||
123 | return index; | ||
124 | } | ||
125 | |||
100 | #endif | 126 | #endif |
101 | 127 | ||
102 | static void | 128 | static void |
@@ -107,7 +133,7 @@ _ecore_imf_context_xim_add(Ecore_IMF_Context *ctx) | |||
107 | Ecore_IMF_Context_Data *imf_context_data = NULL; | 133 | Ecore_IMF_Context_Data *imf_context_data = NULL; |
108 | 134 | ||
109 | imf_context_data = imf_context_data_new(); | 135 | imf_context_data = imf_context_data_new(); |
110 | if(!imf_context_data) return; | 136 | if (!imf_context_data) return; |
111 | 137 | ||
112 | imf_context_data->use_preedit = EINA_TRUE; | 138 | imf_context_data->use_preedit = EINA_TRUE; |
113 | imf_context_data->finalizing = EINA_FALSE; | 139 | imf_context_data->finalizing = EINA_FALSE; |
@@ -115,6 +141,8 @@ _ecore_imf_context_xim_add(Ecore_IMF_Context *ctx) | |||
115 | imf_context_data->in_toplevel = EINA_FALSE; | 141 | imf_context_data->in_toplevel = EINA_FALSE; |
116 | 142 | ||
117 | ecore_imf_context_data_set(ctx, imf_context_data); | 143 | ecore_imf_context_data_set(ctx, imf_context_data); |
144 | #else | ||
145 | (void)ctx; | ||
118 | #endif | 146 | #endif |
119 | } | 147 | } |
120 | 148 | ||
@@ -127,48 +155,53 @@ _ecore_imf_context_xim_del(Ecore_IMF_Context *ctx) | |||
127 | imf_context_data = ecore_imf_context_data_get(ctx); | 155 | imf_context_data = ecore_imf_context_data_get(ctx); |
128 | 156 | ||
129 | imf_context_data->finalizing = EINA_TRUE; | 157 | imf_context_data->finalizing = EINA_TRUE; |
130 | if(imf_context_data->im_info && !imf_context_data->im_info->ics->next) | 158 | if (imf_context_data->im_info && !imf_context_data->im_info->ics->next) |
131 | { | 159 | { |
132 | if(imf_context_data->im_info->reconnecting == EINA_TRUE) | 160 | if (imf_context_data->im_info->reconnecting == EINA_TRUE) |
133 | { | 161 | { |
134 | Ecore_X_Display *dsp; | 162 | Ecore_X_Display *dsp; |
135 | dsp = ecore_x_display_get(); | 163 | dsp = ecore_x_display_get(); |
136 | XUnregisterIMInstantiateCallback (dsp, | 164 | XUnregisterIMInstantiateCallback(dsp, |
137 | NULL, NULL, NULL, | 165 | NULL, NULL, NULL, |
138 | xim_instantiate_callback, | 166 | xim_instantiate_callback, |
139 | (XPointer)imf_context_data->im_info); | 167 | (XPointer)imf_context_data->im_info); |
140 | } | 168 | } |
141 | else if(imf_context_data->im_info->im) | 169 | else if (imf_context_data->im_info->im) |
142 | { | 170 | { |
143 | XIMCallback im_destroy_callback; | 171 | XIMCallback im_destroy_callback; |
144 | im_destroy_callback.client_data = NULL; | 172 | im_destroy_callback.client_data = NULL; |
145 | im_destroy_callback.callback = NULL; | 173 | im_destroy_callback.callback = NULL; |
146 | XSetIMValues (imf_context_data->im_info->im, | 174 | XSetIMValues(imf_context_data->im_info->im, |
147 | XNDestroyCallback, &im_destroy_callback, | 175 | XNDestroyCallback, &im_destroy_callback, |
148 | NULL); | 176 | NULL); |
149 | } | 177 | } |
150 | } | 178 | } |
151 | 179 | ||
152 | set_ic_client_window(ctx, 0); | 180 | set_ic_client_window(ctx, 0); |
153 | 181 | ||
154 | imf_context_data_destroy(imf_context_data); | 182 | imf_context_data_destroy(imf_context_data); |
183 | #else | ||
184 | (void)ctx; | ||
155 | #endif | 185 | #endif |
156 | } | 186 | } |
157 | 187 | ||
158 | static void | 188 | static void |
159 | _ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx, | 189 | _ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx, |
160 | void *window) | 190 | void *window) |
161 | { | 191 | { |
162 | EINA_LOG_DBG("in"); | 192 | EINA_LOG_DBG("in"); |
163 | #ifdef ENABLE_XIM | 193 | #ifdef ENABLE_XIM |
164 | set_ic_client_window(ctx, (Ecore_X_Window)((Ecore_Window)window)); | 194 | set_ic_client_window(ctx, (Ecore_X_Window)((Ecore_Window)window)); |
195 | #else | ||
196 | (void)ctx; | ||
197 | (void)window; | ||
165 | #endif | 198 | #endif |
166 | } | 199 | } |
167 | 200 | ||
168 | static void | 201 | static void |
169 | _ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, | 202 | _ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, |
170 | char **str, | 203 | char **str, |
171 | int *cursor_pos) | 204 | int *cursor_pos) |
172 | { | 205 | { |
173 | EINA_LOG_DBG("in"); | 206 | EINA_LOG_DBG("in"); |
174 | #ifdef ENABLE_XIM | 207 | #ifdef ENABLE_XIM |
@@ -180,25 +213,73 @@ _ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, | |||
180 | { | 213 | { |
181 | utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars, | 214 | utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars, |
182 | &len); | 215 | &len); |
183 | if(str) | 216 | if (str) |
184 | *str = utf8; | 217 | *str = utf8; |
185 | else | 218 | else |
186 | free(utf8); | 219 | free(utf8); |
187 | } | 220 | } |
188 | else | 221 | else |
189 | { | 222 | { |
190 | if(str) | 223 | if (str) |
191 | *str = NULL; | 224 | *str = NULL; |
192 | if(cursor_pos) | 225 | if (cursor_pos) |
193 | *cursor_pos = 0; | 226 | *cursor_pos = 0; |
194 | } | 227 | } |
195 | 228 | ||
196 | if(cursor_pos) | 229 | if (cursor_pos) |
197 | *cursor_pos = imf_context_data->preedit_cursor; | 230 | *cursor_pos = imf_context_data->preedit_cursor; |
198 | #else | 231 | #else |
199 | if(str) | 232 | (void)ctx; |
233 | if (str) | ||
234 | *str = NULL; | ||
235 | if (cursor_pos) | ||
236 | *cursor_pos = 0; | ||
237 | #endif | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | _ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, | ||
242 | char **str, | ||
243 | Eina_List **attrs, | ||
244 | int *cursor_pos) | ||
245 | { | ||
246 | EINA_LOG_DBG("in"); | ||
247 | |||
248 | #ifdef ENABLE_XIM | ||
249 | Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); | ||
250 | |||
251 | _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos); | ||
252 | |||
253 | if (!attrs) return; | ||
254 | if (!imf_context_data || !imf_context_data->feedbacks) return; | ||
255 | |||
256 | int i = 0; | ||
257 | XIMFeedback last_feedback = 0; | ||
258 | int start = -1; | ||
259 | |||
260 | for (i = 0; i < imf_context_data->preedit_length; i++) | ||
261 | { | ||
262 | XIMFeedback new_feedback = imf_context_data->feedbacks[i] & FEEDBACK_MASK; | ||
263 | |||
264 | if (new_feedback != last_feedback) | ||
265 | { | ||
266 | if (start >= 0) | ||
267 | add_feedback_attr(attrs, *str, last_feedback, start, i); | ||
268 | |||
269 | last_feedback = new_feedback; | ||
270 | start = i; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | if (start >= 0) | ||
275 | add_feedback_attr(attrs, *str, last_feedback, start, i); | ||
276 | #else | ||
277 | (void)ctx; | ||
278 | if (str) | ||
200 | *str = NULL; | 279 | *str = NULL; |
201 | if(cursor_pos) | 280 | if (attrs) |
281 | *attrs = NULL; | ||
282 | if (cursor_pos) | ||
202 | *cursor_pos = 0; | 283 | *cursor_pos = 0; |
203 | #endif | 284 | #endif |
204 | } | 285 | } |
@@ -213,7 +294,7 @@ _ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx) | |||
213 | imf_context_data = ecore_imf_context_data_get(ctx); | 294 | imf_context_data = ecore_imf_context_data_get(ctx); |
214 | ic = imf_context_data->ic; | 295 | ic = imf_context_data->ic; |
215 | imf_context_data->has_focus = EINA_TRUE; | 296 | imf_context_data->has_focus = EINA_TRUE; |
216 | if(ic) | 297 | if (ic) |
217 | { | 298 | { |
218 | char *str; | 299 | char *str; |
219 | 300 | ||
@@ -226,6 +307,8 @@ _ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx) | |||
226 | 307 | ||
227 | XSetICFocus(ic); | 308 | XSetICFocus(ic); |
228 | } | 309 | } |
310 | #else | ||
311 | (void)ctx; | ||
229 | #endif | 312 | #endif |
230 | } | 313 | } |
231 | 314 | ||
@@ -237,13 +320,15 @@ _ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx) | |||
237 | XIC ic; | 320 | XIC ic; |
238 | Ecore_IMF_Context_Data *imf_context_data; | 321 | Ecore_IMF_Context_Data *imf_context_data; |
239 | imf_context_data = ecore_imf_context_data_get(ctx); | 322 | imf_context_data = ecore_imf_context_data_get(ctx); |
240 | if(imf_context_data->has_focus == EINA_TRUE) | 323 | if (imf_context_data->has_focus == EINA_TRUE) |
241 | { | 324 | { |
242 | imf_context_data->has_focus = EINA_FALSE; | 325 | imf_context_data->has_focus = EINA_FALSE; |
243 | ic = imf_context_data->ic; | 326 | ic = imf_context_data->ic; |
244 | if(ic) | 327 | if (ic) |
245 | XUnsetICFocus(ic); | 328 | XUnsetICFocus(ic); |
246 | } | 329 | } |
330 | #else | ||
331 | (void)ctx; | ||
247 | #endif | 332 | #endif |
248 | } | 333 | } |
249 | 334 | ||
@@ -263,18 +348,18 @@ _ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) | |||
263 | 348 | ||
264 | imf_context_data = ecore_imf_context_data_get(ctx); | 349 | imf_context_data = ecore_imf_context_data_get(ctx); |
265 | ic = imf_context_data->ic; | 350 | ic = imf_context_data->ic; |
266 | if(!ic) | 351 | if (!ic) |
267 | return; | 352 | return; |
268 | 353 | ||
269 | if(imf_context_data->preedit_length == 0) | 354 | if (imf_context_data->preedit_length == 0) |
270 | return; | 355 | return; |
271 | 356 | ||
272 | preedit_attr = XVaCreateNestedList(0, | 357 | preedit_attr = XVaCreateNestedList(0, |
273 | XNPreeditState, &preedit_state, | 358 | XNPreeditState, &preedit_state, |
274 | NULL); | 359 | NULL); |
275 | if(!XGetICValues(ic, | 360 | if (!XGetICValues(ic, |
276 | XNPreeditAttributes, preedit_attr, | 361 | XNPreeditAttributes, preedit_attr, |
277 | NULL)) | 362 | NULL)) |
278 | have_preedit_state = EINA_TRUE; | 363 | have_preedit_state = EINA_TRUE; |
279 | 364 | ||
280 | XFree(preedit_attr); | 365 | XFree(preedit_attr); |
@@ -284,38 +369,49 @@ _ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) | |||
284 | preedit_attr = XVaCreateNestedList(0, | 369 | preedit_attr = XVaCreateNestedList(0, |
285 | XNPreeditState, preedit_state, | 370 | XNPreeditState, preedit_state, |
286 | NULL); | 371 | NULL); |
287 | if(have_preedit_state) | 372 | if (have_preedit_state) |
288 | XSetICValues(ic, | 373 | XSetICValues(ic, |
289 | XNPreeditAttributes, preedit_attr, | 374 | XNPreeditAttributes, preedit_attr, |
290 | NULL); | 375 | NULL); |
291 | 376 | ||
292 | XFree(preedit_attr); | 377 | XFree(preedit_attr); |
293 | 378 | ||
294 | if(imf_context_data->preedit_length) | 379 | if (imf_context_data->feedbacks) |
380 | { | ||
381 | free(imf_context_data->feedbacks); | ||
382 | imf_context_data->feedbacks = NULL; | ||
383 | } | ||
384 | |||
385 | if (imf_context_data->preedit_length) | ||
295 | { | 386 | { |
296 | imf_context_data->preedit_length = 0; | 387 | imf_context_data->preedit_length = 0; |
297 | free(imf_context_data->preedit_chars); | 388 | free(imf_context_data->preedit_chars); |
298 | imf_context_data->preedit_chars = NULL; | 389 | imf_context_data->preedit_chars = NULL; |
390 | |||
299 | ecore_imf_context_preedit_changed_event_add(ctx); | 391 | ecore_imf_context_preedit_changed_event_add(ctx); |
392 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); | ||
300 | } | 393 | } |
301 | 394 | ||
302 | if(result) | 395 | if (result) |
303 | { | 396 | { |
304 | char *result_utf8 = strdup(result); | 397 | char *result_utf8 = strdup(result); |
305 | if(result_utf8) | 398 | if (result_utf8) |
306 | { | 399 | { |
307 | ecore_imf_context_commit_event_add(ctx, result_utf8); | 400 | ecore_imf_context_commit_event_add(ctx, result_utf8); |
308 | free(result_utf8); | 401 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8); |
309 | } | 402 | free(result_utf8); |
403 | } | ||
310 | } | 404 | } |
311 | 405 | ||
312 | XFree (result); | 406 | XFree(result); |
407 | #else | ||
408 | (void)ctx; | ||
313 | #endif | 409 | #endif |
314 | } | 410 | } |
315 | 411 | ||
316 | static void | 412 | static void |
317 | _ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx, | 413 | _ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx, |
318 | Eina_Bool use_preedit) | 414 | Eina_Bool use_preedit) |
319 | { | 415 | { |
320 | EINA_LOG_DBG("in"); | 416 | EINA_LOG_DBG("in"); |
321 | #ifdef ENABLE_XIM | 417 | #ifdef ENABLE_XIM |
@@ -324,17 +420,53 @@ _ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx, | |||
324 | 420 | ||
325 | use_preedit = use_preedit != EINA_FALSE; | 421 | use_preedit = use_preedit != EINA_FALSE; |
326 | 422 | ||
327 | if(imf_context_data->use_preedit != use_preedit) | 423 | if (imf_context_data->use_preedit != use_preedit) |
328 | { | 424 | { |
329 | imf_context_data->use_preedit = use_preedit; | 425 | imf_context_data->use_preedit = use_preedit; |
330 | reinitialize_ic(ctx); | 426 | reinitialize_ic(ctx); |
331 | } | 427 | } |
428 | #else | ||
429 | (void)ctx; | ||
430 | (void)use_preedit; | ||
332 | #endif | 431 | #endif |
333 | } | 432 | } |
334 | 433 | ||
434 | #ifdef ENABLE_XIM | ||
435 | static void | ||
436 | add_feedback_attr(Eina_List **attrs, | ||
437 | const char *str, | ||
438 | XIMFeedback feedback, | ||
439 | int start_pos, | ||
440 | int end_pos) | ||
441 | { | ||
442 | Ecore_IMF_Preedit_Attr *attr = NULL; | ||
443 | |||
444 | unsigned int start_index = utf8_offset_to_index(str, start_pos); | ||
445 | unsigned int end_index = utf8_offset_to_index(str, end_pos); | ||
446 | |||
447 | if (feedback & FEEDBACK_MASK) | ||
448 | { | ||
449 | attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); | ||
450 | attr->start_index = start_index; | ||
451 | attr->end_index = end_index; | ||
452 | *attrs = eina_list_append(*attrs, (void *)attr); | ||
453 | } | ||
454 | |||
455 | if (feedback & XIMUnderline) | ||
456 | attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; | ||
457 | |||
458 | if (feedback & XIMReverse) | ||
459 | attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; | ||
460 | |||
461 | if (feedback & XIMHighlight) | ||
462 | attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; | ||
463 | } | ||
464 | |||
465 | #endif | ||
466 | |||
335 | static void | 467 | static void |
336 | _ecore_imf_context_xim_cursor_location_set (Ecore_IMF_Context *ctx, | 468 | _ecore_imf_context_xim_cursor_location_set(Ecore_IMF_Context *ctx, |
337 | int x, int y, int w, int h) | 469 | int x, int y, int w, int h) |
338 | { | 470 | { |
339 | EINA_LOG_DBG("%s in", __FUNCTION__); | 471 | EINA_LOG_DBG("%s in", __FUNCTION__); |
340 | 472 | ||
@@ -342,7 +474,7 @@ _ecore_imf_context_xim_cursor_location_set (Ecore_IMF_Context *ctx, | |||
342 | Ecore_IMF_Context_Data *imf_context_data; | 474 | Ecore_IMF_Context_Data *imf_context_data; |
343 | XIC ic; | 475 | XIC ic; |
344 | XVaNestedList preedit_attr; | 476 | XVaNestedList preedit_attr; |
345 | XPoint spot; | 477 | XPoint spot; |
346 | 478 | ||
347 | imf_context_data = ecore_imf_context_data_get(ctx); | 479 | imf_context_data = ecore_imf_context_data_get(ctx); |
348 | ic = imf_context_data->ic; | 480 | ic = imf_context_data->ic; |
@@ -351,15 +483,20 @@ _ecore_imf_context_xim_cursor_location_set (Ecore_IMF_Context *ctx, | |||
351 | 483 | ||
352 | spot.x = x; | 484 | spot.x = x; |
353 | spot.y = y + h; | 485 | spot.y = y + h; |
354 | 486 | ||
355 | preedit_attr = XVaCreateNestedList (0, | 487 | preedit_attr = XVaCreateNestedList(0, |
356 | XNSpotLocation, &spot, | 488 | XNSpotLocation, &spot, |
357 | NULL); | 489 | NULL); |
358 | XSetICValues (ic, | 490 | XSetICValues(ic, |
359 | XNPreeditAttributes, preedit_attr, | 491 | XNPreeditAttributes, preedit_attr, |
360 | NULL); | 492 | NULL); |
361 | 493 | ||
362 | XFree(preedit_attr); | 494 | XFree(preedit_attr); |
495 | #else | ||
496 | (void)ctx; | ||
497 | (void)x; | ||
498 | (void)y; | ||
499 | (void)h; | ||
363 | #endif | 500 | #endif |
364 | (void)(w); // yes w is unused, but only a bi-product of the algorithm | 501 | (void)(w); // yes w is unused, but only a bi-product of the algorithm |
365 | } | 502 | } |
@@ -371,19 +508,19 @@ _ecore_x_event_reverse_modifiers(unsigned int state) | |||
371 | unsigned int modifiers = 0; | 508 | unsigned int modifiers = 0; |
372 | 509 | ||
373 | /**< "Control" is pressed */ | 510 | /**< "Control" is pressed */ |
374 | if(state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) | 511 | if (state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) |
375 | modifiers |= ControlMask; | 512 | modifiers |= ControlMask; |
376 | 513 | ||
377 | /**< "Alt" is pressed */ | 514 | /**< "Alt" is pressed */ |
378 | if(state & ECORE_IMF_KEYBOARD_MODIFIER_ALT) | 515 | if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALT) |
379 | modifiers |= Mod1Mask; | 516 | modifiers |= Mod1Mask; |
380 | 517 | ||
381 | /**< "Shift" is pressed */ | 518 | /**< "Shift" is pressed */ |
382 | if(state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) | 519 | if (state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) |
383 | modifiers |= ShiftMask; | 520 | modifiers |= ShiftMask; |
384 | 521 | ||
385 | /**< "Win" (between "Ctrl" and "A */ | 522 | /**< "Win" (between "Ctrl" and "A */ |
386 | if(state & ECORE_IMF_KEYBOARD_MODIFIER_WIN) | 523 | if (state & ECORE_IMF_KEYBOARD_MODIFIER_WIN) |
387 | modifiers |= Mod5Mask; | 524 | modifiers |= Mod5Mask; |
388 | 525 | ||
389 | return modifiers; | 526 | return modifiers; |
@@ -395,14 +532,14 @@ _ecore_x_event_reverse_locks(unsigned int state) | |||
395 | unsigned int locks = 0; | 532 | unsigned int locks = 0; |
396 | 533 | ||
397 | /**< "Num" lock is active */ | 534 | /**< "Num" lock is active */ |
398 | if(state & ECORE_IMF_KEYBOARD_LOCK_NUM) | 535 | if (state & ECORE_IMF_KEYBOARD_LOCK_NUM) |
399 | locks |= Mod3Mask; | 536 | locks |= Mod3Mask; |
400 | 537 | ||
401 | if(state & ECORE_IMF_KEYBOARD_LOCK_CAPS) | 538 | if (state & ECORE_IMF_KEYBOARD_LOCK_CAPS) |
402 | locks |= LockMask; | 539 | locks |= LockMask; |
403 | 540 | ||
404 | #if 0 /* FIXME: add mask. */ | 541 | #if 0 /* FIXME: add mask. */ |
405 | if(state & ECORE_IMF_KEYBOARD_LOCK_SCROLL) | 542 | if (state & ECORE_IMF_KEYBOARD_LOCK_SCROLL) |
406 | ; | 543 | ; |
407 | #endif | 544 | #endif |
408 | 545 | ||
@@ -411,12 +548,12 @@ _ecore_x_event_reverse_locks(unsigned int state) | |||
411 | 548 | ||
412 | static KeyCode | 549 | static KeyCode |
413 | _keycode_get(Ecore_X_Display *dsp, | 550 | _keycode_get(Ecore_X_Display *dsp, |
414 | const char *keyname) | 551 | const char *keyname) |
415 | { | 552 | { |
416 | KeyCode keycode; | 553 | KeyCode keycode; |
417 | 554 | ||
418 | // EINA_LOG_DBG("keyname:%s keysym:%lu", keyname, XStringToKeysym(keyname)); | 555 | // EINA_LOG_DBG("keyname:%s keysym:%lu", keyname, XStringToKeysym(keyname)); |
419 | if(strcmp(keyname, "Keycode-0") == 0) | 556 | if (strcmp(keyname, "Keycode-0") == 0) |
420 | { | 557 | { |
421 | keycode = 0; | 558 | keycode = 0; |
422 | } | 559 | } |
@@ -430,9 +567,9 @@ _keycode_get(Ecore_X_Display *dsp, | |||
430 | #endif | 567 | #endif |
431 | 568 | ||
432 | static Eina_Bool | 569 | static Eina_Bool |
433 | _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, | 570 | _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, |
434 | Ecore_IMF_Event_Type type, | 571 | Ecore_IMF_Event_Type type, |
435 | Ecore_IMF_Event *event) | 572 | Ecore_IMF_Event *event) |
436 | { | 573 | { |
437 | EINA_LOG_DBG("%s in", __FUNCTION__); | 574 | EINA_LOG_DBG("%s in", __FUNCTION__); |
438 | #ifdef ENABLE_XIM | 575 | #ifdef ENABLE_XIM |
@@ -451,12 +588,12 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, | |||
451 | 588 | ||
452 | imf_context_data = ecore_imf_context_data_get(ctx); | 589 | imf_context_data = ecore_imf_context_data_get(ctx); |
453 | ic = imf_context_data->ic; | 590 | ic = imf_context_data->ic; |
454 | if(!ic) | 591 | if (!ic) |
455 | { | 592 | { |
456 | ic = get_ic(ctx); | 593 | ic = get_ic(ctx); |
457 | } | 594 | } |
458 | 595 | ||
459 | if(type == ECORE_IMF_EVENT_KEY_DOWN) | 596 | if (type == ECORE_IMF_EVENT_KEY_DOWN) |
460 | { | 597 | { |
461 | XKeyPressedEvent xev; | 598 | XKeyPressedEvent xev; |
462 | Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; | 599 | Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; |
@@ -481,7 +618,7 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, | |||
481 | xev.keycode = _keycode_get(dsp, ev->keyname); | 618 | xev.keycode = _keycode_get(dsp, ev->keyname); |
482 | xev.same_screen = True; | 619 | xev.same_screen = True; |
483 | 620 | ||
484 | if(ic) | 621 | if (ic) |
485 | { | 622 | { |
486 | Status mbstatus; | 623 | Status mbstatus; |
487 | #ifdef X_HAVE_UTF8_STRING | 624 | #ifdef X_HAVE_UTF8_STRING |
@@ -563,15 +700,16 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, | |||
563 | } | 700 | } |
564 | } | 701 | } |
565 | 702 | ||
566 | if(compose) | 703 | if (compose) |
567 | { | 704 | { |
568 | Eina_Unicode *unicode; | 705 | Eina_Unicode *unicode; |
569 | int len; | 706 | int len; |
570 | unicode = eina_unicode_utf8_to_unicode(compose, &len); | 707 | unicode = eina_unicode_utf8_to_unicode(compose, &len); |
571 | if(!unicode) abort(); | 708 | if (!unicode) abort(); |
572 | if(unicode[0] >= 0x20 && unicode[0] != 0x7f) | 709 | if (unicode[0] >= 0x20 && unicode[0] != 0x7f) |
573 | { | 710 | { |
574 | ecore_imf_context_commit_event_add(ctx, compose); | 711 | ecore_imf_context_commit_event_add(ctx, compose); |
712 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose); | ||
575 | result = EINA_TRUE; | 713 | result = EINA_TRUE; |
576 | } | 714 | } |
577 | free(compose); | 715 | free(compose); |
@@ -581,6 +719,9 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, | |||
581 | 719 | ||
582 | return result; | 720 | return result; |
583 | #else | 721 | #else |
722 | (void)ctx; | ||
723 | (void)type; | ||
724 | (void)event; | ||
584 | return EINA_FALSE; | 725 | return EINA_FALSE; |
585 | #endif | 726 | #endif |
586 | } | 727 | } |
@@ -608,7 +749,7 @@ static Ecore_IMF_Context_Class xim_class = { | |||
608 | .use_preedit_set = _ecore_imf_context_xim_use_preedit_set, | 749 | .use_preedit_set = _ecore_imf_context_xim_use_preedit_set, |
609 | .input_mode_set = NULL, | 750 | .input_mode_set = NULL, |
610 | .filter_event = _ecore_imf_context_xim_filter_event, | 751 | .filter_event = _ecore_imf_context_xim_filter_event, |
611 | .preedit_string_with_attributes_get = NULL, | 752 | .preedit_string_with_attributes_get = _ecore_imf_context_xim_preedit_string_with_attributes_get, |
612 | .prediction_allow_set = NULL, | 753 | .prediction_allow_set = NULL, |
613 | .autocapital_type_set = NULL, | 754 | .autocapital_type_set = NULL, |
614 | .control_panel_show = NULL, | 755 | .control_panel_show = NULL, |
@@ -627,7 +768,7 @@ xim_imf_module_create(void) | |||
627 | Ecore_IMF_Context *ctx = NULL; | 768 | Ecore_IMF_Context *ctx = NULL; |
628 | 769 | ||
629 | ctx = ecore_imf_context_new(&xim_class); | 770 | ctx = ecore_imf_context_new(&xim_class); |
630 | if(!ctx) | 771 | if (!ctx) |
631 | goto error; | 772 | goto error; |
632 | 773 | ||
633 | return ctx; | 774 | return ctx; |
@@ -686,15 +827,15 @@ imf_context_data_new() | |||
686 | char *locale; | 827 | char *locale; |
687 | 828 | ||
688 | locale = setlocale(LC_CTYPE, ""); | 829 | locale = setlocale(LC_CTYPE, ""); |
689 | if(!locale) return NULL; | 830 | if (!locale) return NULL; |
690 | 831 | ||
691 | if(!XSupportsLocale()) return NULL; | 832 | if (!XSupportsLocale()) return NULL; |
692 | 833 | ||
693 | imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data)); | 834 | imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data)); |
694 | if(!imf_context_data) return NULL; | 835 | if (!imf_context_data) return NULL; |
695 | 836 | ||
696 | imf_context_data->locale = strdup(locale); | 837 | imf_context_data->locale = strdup(locale); |
697 | if(!imf_context_data->locale) goto error; | 838 | if (!imf_context_data->locale) goto error; |
698 | 839 | ||
699 | return imf_context_data; | 840 | return imf_context_data; |
700 | error: | 841 | error: |
@@ -705,19 +846,26 @@ error: | |||
705 | void | 846 | void |
706 | imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data) | 847 | imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data) |
707 | { | 848 | { |
708 | if(!imf_context_data) | 849 | if (!imf_context_data) |
709 | return; | 850 | return; |
710 | 851 | ||
711 | if(imf_context_data->ic) | 852 | if (imf_context_data->ic) |
712 | XDestroyIC(imf_context_data->ic); | 853 | XDestroyIC(imf_context_data->ic); |
713 | 854 | ||
714 | free(imf_context_data->preedit_chars); | 855 | free(imf_context_data->preedit_chars); |
856 | |||
857 | if (imf_context_data->feedbacks) | ||
858 | { | ||
859 | free(imf_context_data->feedbacks); | ||
860 | imf_context_data->feedbacks = NULL; | ||
861 | } | ||
862 | |||
715 | free(imf_context_data->locale); | 863 | free(imf_context_data->locale); |
716 | free(imf_context_data); | 864 | free(imf_context_data); |
717 | } | 865 | } |
718 | 866 | ||
719 | static int | 867 | static int |
720 | preedit_start_callback(XIC xic __UNUSED__, | 868 | preedit_start_callback(XIC xic __UNUSED__, |
721 | XPointer client_data, | 869 | XPointer client_data, |
722 | XPointer call_data __UNUSED__) | 870 | XPointer call_data __UNUSED__) |
723 | { | 871 | { |
@@ -726,14 +874,16 @@ preedit_start_callback(XIC xic __UNUSED__, | |||
726 | Ecore_IMF_Context_Data *imf_context_data; | 874 | Ecore_IMF_Context_Data *imf_context_data; |
727 | imf_context_data = ecore_imf_context_data_get(ctx); | 875 | imf_context_data = ecore_imf_context_data_get(ctx); |
728 | 876 | ||
729 | if(imf_context_data->finalizing == EINA_FALSE) | 877 | if (imf_context_data->finalizing == EINA_FALSE) |
730 | ecore_imf_context_preedit_start_event_add(ctx); | 878 | { |
731 | 879 | ecore_imf_context_preedit_start_event_add(ctx); | |
880 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); | ||
881 | } | ||
732 | return -1; | 882 | return -1; |
733 | } | 883 | } |
734 | 884 | ||
735 | static void | 885 | static void |
736 | preedit_done_callback(XIC xic __UNUSED__, | 886 | preedit_done_callback(XIC xic __UNUSED__, |
737 | XPointer client_data, | 887 | XPointer client_data, |
738 | XPointer call_data __UNUSED__) | 888 | XPointer call_data __UNUSED__) |
739 | { | 889 | { |
@@ -742,30 +892,34 @@ preedit_done_callback(XIC xic __UNUSED__, | |||
742 | Ecore_IMF_Context_Data *imf_context_data; | 892 | Ecore_IMF_Context_Data *imf_context_data; |
743 | imf_context_data = ecore_imf_context_data_get(ctx); | 893 | imf_context_data = ecore_imf_context_data_get(ctx); |
744 | 894 | ||
745 | if(imf_context_data->preedit_length) | 895 | if (imf_context_data->preedit_length) |
746 | { | 896 | { |
747 | imf_context_data->preedit_length = 0; | 897 | imf_context_data->preedit_length = 0; |
748 | free(imf_context_data->preedit_chars); | 898 | free(imf_context_data->preedit_chars); |
749 | imf_context_data->preedit_chars = NULL; | 899 | imf_context_data->preedit_chars = NULL; |
750 | ecore_imf_context_preedit_changed_event_add(ctx); | 900 | ecore_imf_context_preedit_changed_event_add(ctx); |
901 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); | ||
751 | } | 902 | } |
752 | 903 | ||
753 | if(imf_context_data->finalizing == EINA_FALSE) | 904 | if (imf_context_data->finalizing == EINA_FALSE) |
754 | ecore_imf_context_preedit_end_event_add(ctx); | 905 | { |
906 | ecore_imf_context_preedit_end_event_add(ctx); | ||
907 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); | ||
908 | } | ||
755 | } | 909 | } |
756 | 910 | ||
757 | /* FIXME */ | 911 | /* FIXME */ |
758 | static int | 912 | static int |
759 | xim_text_to_utf8(Ecore_IMF_Context *ctx __UNUSED__, | 913 | xim_text_to_utf8(Ecore_IMF_Context *ctx __UNUSED__, |
760 | XIMText *xim_text, | 914 | XIMText *xim_text, |
761 | char **text) | 915 | char **text) |
762 | { | 916 | { |
763 | int text_length = 0; | 917 | int text_length = 0; |
764 | char *result = NULL; | 918 | char *result = NULL; |
765 | 919 | ||
766 | if(xim_text && xim_text->string.multi_byte) | 920 | if (xim_text && xim_text->string.multi_byte) |
767 | { | 921 | { |
768 | if(xim_text->encoding_is_wchar) | 922 | if (xim_text->encoding_is_wchar) |
769 | { | 923 | { |
770 | EINA_LOG_WARN("Wide character return from Xlib not currently supported"); | 924 | EINA_LOG_WARN("Wide character return from Xlib not currently supported"); |
771 | *text = NULL; | 925 | *text = NULL; |
@@ -774,7 +928,7 @@ xim_text_to_utf8(Ecore_IMF_Context *ctx __UNUSED__, | |||
774 | 928 | ||
775 | /* XXX Convert to UTF-8 */ | 929 | /* XXX Convert to UTF-8 */ |
776 | result = strdup(xim_text->string.multi_byte); | 930 | result = strdup(xim_text->string.multi_byte); |
777 | if(result) | 931 | if (result) |
778 | { | 932 | { |
779 | text_length = eina_unicode_utf8_get_len(result); | 933 | text_length = eina_unicode_utf8_get_len(result); |
780 | if (text_length != xim_text->length) | 934 | if (text_length != xim_text->length) |
@@ -798,8 +952,8 @@ xim_text_to_utf8(Ecore_IMF_Context *ctx __UNUSED__, | |||
798 | } | 952 | } |
799 | 953 | ||
800 | static void | 954 | static void |
801 | preedit_draw_callback(XIC xic __UNUSED__, | 955 | preedit_draw_callback(XIC xic __UNUSED__, |
802 | XPointer client_data, | 956 | XPointer client_data, |
803 | XIMPreeditDrawCallbackStruct *call_data) | 957 | XIMPreeditDrawCallbackStruct *call_data) |
804 | { | 958 | { |
805 | EINA_LOG_DBG("in"); | 959 | EINA_LOG_DBG("in"); |
@@ -811,59 +965,83 @@ preedit_draw_callback(XIC xic __UNUSED__, | |||
811 | Eina_Unicode *new_text = NULL; | 965 | Eina_Unicode *new_text = NULL; |
812 | Eina_UStrbuf *preedit_bufs = NULL; | 966 | Eina_UStrbuf *preedit_bufs = NULL; |
813 | int new_text_length; | 967 | int new_text_length; |
968 | int i = 0; | ||
814 | 969 | ||
815 | preedit_bufs = eina_ustrbuf_new(); | 970 | preedit_bufs = eina_ustrbuf_new(); |
816 | if(imf_context_data->preedit_chars) { | 971 | if (imf_context_data->preedit_chars) |
817 | ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars); | 972 | { |
818 | if(ret == EINA_FALSE) goto done; | 973 | ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars); |
819 | } | 974 | if (ret == EINA_FALSE) goto done; |
975 | } | ||
820 | 976 | ||
821 | new_text_length = xim_text_to_utf8(ctx, t, &tmp); | 977 | new_text_length = xim_text_to_utf8(ctx, t, &tmp); |
822 | if(tmp) | 978 | if (tmp) |
823 | { | 979 | { |
824 | int tmp_len; | 980 | int tmp_len; |
825 | new_text = eina_unicode_utf8_to_unicode((const char *)tmp, &tmp_len); | 981 | new_text = eina_unicode_utf8_to_unicode((const char *)tmp, &tmp_len); |
826 | free(tmp); | 982 | free(tmp); |
827 | } | 983 | } |
828 | 984 | ||
829 | if(t == NULL) { | 985 | if (t == NULL) |
830 | /* delete string */ | 986 | { |
831 | ret = eina_ustrbuf_remove(preedit_bufs, | 987 | /* delete string */ |
832 | call_data->chg_first, call_data->chg_length); | 988 | ret = eina_ustrbuf_remove(preedit_bufs, |
833 | } else if(call_data->chg_length == 0) { | 989 | call_data->chg_first, call_data->chg_length); |
834 | /* insert string */ | 990 | } |
835 | ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first); | 991 | else if (call_data->chg_length == 0) |
836 | } else if(call_data->chg_length > 0) { | 992 | { |
837 | /* replace string */ | 993 | /* insert string */ |
838 | ret = eina_ustrbuf_remove(preedit_bufs, | 994 | ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first); |
839 | call_data->chg_first, call_data->chg_length); | 995 | } |
840 | if(ret == EINA_FALSE) goto done; | 996 | else if (call_data->chg_length > 0) |
841 | 997 | { | |
842 | ret = eina_ustrbuf_insert_n(preedit_bufs, new_text, | 998 | /* replace string */ |
843 | new_text_length, call_data->chg_first); | 999 | ret = eina_ustrbuf_remove(preedit_bufs, |
844 | if(ret == EINA_FALSE) goto done; | 1000 | call_data->chg_first, call_data->chg_length); |
845 | } else { | 1001 | if (ret == EINA_FALSE) goto done; |
846 | ret = EINA_FALSE; | 1002 | |
847 | } | 1003 | ret = eina_ustrbuf_insert_n(preedit_bufs, new_text, |
848 | 1004 | new_text_length, call_data->chg_first); | |
849 | done: | 1005 | if (ret == EINA_FALSE) goto done; |
850 | if(ret == EINA_TRUE) { | 1006 | } |
851 | free(imf_context_data->preedit_chars); | 1007 | else { |
852 | imf_context_data->preedit_chars = | 1008 | ret = EINA_FALSE; |
1009 | } | ||
1010 | |||
1011 | done: | ||
1012 | if (ret == EINA_TRUE) | ||
1013 | { | ||
1014 | free(imf_context_data->preedit_chars); | ||
1015 | imf_context_data->preedit_chars = | ||
853 | eina_ustrbuf_string_steal(preedit_bufs); | 1016 | eina_ustrbuf_string_steal(preedit_bufs); |
854 | imf_context_data->preedit_length = | 1017 | imf_context_data->preedit_length = |
855 | eina_unicode_strlen(imf_context_data->preedit_chars); | 1018 | eina_unicode_strlen(imf_context_data->preedit_chars); |
856 | 1019 | ||
857 | ecore_imf_context_preedit_changed_event_add(ctx); | 1020 | if (imf_context_data->feedbacks) |
858 | } | 1021 | { |
1022 | free(imf_context_data->feedbacks); | ||
1023 | imf_context_data->feedbacks = NULL; | ||
1024 | } | ||
1025 | |||
1026 | if (imf_context_data->preedit_length > 0) | ||
1027 | { | ||
1028 | imf_context_data->feedbacks = calloc(imf_context_data->preedit_length, sizeof(XIMFeedback)); | ||
1029 | |||
1030 | for (i = 0; i < imf_context_data->preedit_length; i++) | ||
1031 | imf_context_data->feedbacks[i] = t->feedback[i]; | ||
1032 | } | ||
1033 | |||
1034 | ecore_imf_context_preedit_changed_event_add(ctx); | ||
1035 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); | ||
1036 | } | ||
859 | 1037 | ||
860 | free(new_text); | 1038 | free(new_text); |
861 | eina_ustrbuf_free(preedit_bufs); | 1039 | eina_ustrbuf_free(preedit_bufs); |
862 | } | 1040 | } |
863 | 1041 | ||
864 | static void | 1042 | static void |
865 | preedit_caret_callback(XIC xic __UNUSED__, | 1043 | preedit_caret_callback(XIC xic __UNUSED__, |
866 | XPointer client_data, | 1044 | XPointer client_data, |
867 | XIMPreeditCaretCallbackStruct *call_data) | 1045 | XIMPreeditCaretCallbackStruct *call_data) |
868 | { | 1046 | { |
869 | EINA_LOG_DBG("in"); | 1047 | EINA_LOG_DBG("in"); |
@@ -871,12 +1049,15 @@ preedit_caret_callback(XIC xic __UNUSED__, | |||
871 | Ecore_IMF_Context_Data *imf_context_data; | 1049 | Ecore_IMF_Context_Data *imf_context_data; |
872 | imf_context_data = ecore_imf_context_data_get(ctx); | 1050 | imf_context_data = ecore_imf_context_data_get(ctx); |
873 | 1051 | ||
874 | if(call_data->direction == XIMAbsolutePosition) | 1052 | if (call_data->direction == XIMAbsolutePosition) |
875 | { | 1053 | { |
876 | // printf("call_data->position:%d\n", call_data->position); | 1054 | // printf("call_data->position:%d\n", call_data->position); |
877 | imf_context_data->preedit_cursor = call_data->position; | 1055 | imf_context_data->preedit_cursor = call_data->position; |
878 | if(imf_context_data->finalizing == EINA_FALSE) | 1056 | if (imf_context_data->finalizing == EINA_FALSE) |
879 | ecore_imf_context_preedit_changed_event_add(ctx); | 1057 | { |
1058 | ecore_imf_context_preedit_changed_event_add(ctx); | ||
1059 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); | ||
1060 | } | ||
880 | } | 1061 | } |
881 | } | 1062 | } |
882 | 1063 | ||
@@ -917,7 +1098,7 @@ get_ic(Ecore_IMF_Context *ctx) | |||
917 | XIC ic; | 1098 | XIC ic; |
918 | imf_context_data = ecore_imf_context_data_get(ctx); | 1099 | imf_context_data = ecore_imf_context_data_get(ctx); |
919 | ic = imf_context_data->ic; | 1100 | ic = imf_context_data->ic; |
920 | if(!ic) | 1101 | if (!ic) |
921 | { | 1102 | { |
922 | XIM_Im_Info *im_info = imf_context_data->im_info; | 1103 | XIM_Im_Info *im_info = imf_context_data->im_info; |
923 | XVaNestedList preedit_attr = NULL; | 1104 | XVaNestedList preedit_attr = NULL; |
@@ -930,7 +1111,7 @@ get_ic(Ecore_IMF_Context *ctx) | |||
930 | EINA_LOG_WARN("Doesn't open XIM."); | 1111 | EINA_LOG_WARN("Doesn't open XIM."); |
931 | return NULL; | 1112 | return NULL; |
932 | } | 1113 | } |
933 | 1114 | ||
934 | // supported styles | 1115 | // supported styles |
935 | #if 0 | 1116 | #if 0 |
936 | int i; | 1117 | int i; |
@@ -940,23 +1121,23 @@ get_ic(Ecore_IMF_Context *ctx) | |||
940 | { | 1121 | { |
941 | printf("%i: ", i); | 1122 | printf("%i: ", i); |
942 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditCallbacks) | 1123 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditCallbacks) |
943 | printf("XIMPreeditCallbacks | "); | 1124 | printf("XIMPreeditCallbacks | "); |
944 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditPosition) | 1125 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditPosition) |
945 | printf("XIMPreeditPosition | "); | 1126 | printf("XIMPreeditPosition | "); |
946 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditArea) | 1127 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditArea) |
947 | printf("XIMPreeditArea | "); | 1128 | printf("XIMPreeditArea | "); |
948 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditNothing) | 1129 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditNothing) |
949 | printf("XIMPreeditNothing | "); | 1130 | printf("XIMPreeditNothing | "); |
950 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditNone) | 1131 | if (im_info->xim_styles->supported_styles[i] & XIMPreeditNone) |
951 | printf("XIMPreeditNone | "); | 1132 | printf("XIMPreeditNone | "); |
952 | if (im_info->xim_styles->supported_styles[i] & XIMStatusArea) | 1133 | if (im_info->xim_styles->supported_styles[i] & XIMStatusArea) |
953 | printf("XIMStatusArea | "); | 1134 | printf("XIMStatusArea | "); |
954 | if (im_info->xim_styles->supported_styles[i] & XIMStatusCallbacks) | 1135 | if (im_info->xim_styles->supported_styles[i] & XIMStatusCallbacks) |
955 | printf("XIMStatusCallbacks | "); | 1136 | printf("XIMStatusCallbacks | "); |
956 | if (im_info->xim_styles->supported_styles[i] & XIMStatusNothing) | 1137 | if (im_info->xim_styles->supported_styles[i] & XIMStatusNothing) |
957 | printf("XIMStatusNothing | "); | 1138 | printf("XIMStatusNothing | "); |
958 | if (im_info->xim_styles->supported_styles[i] & XIMStatusNone) | 1139 | if (im_info->xim_styles->supported_styles[i] & XIMStatusNone) |
959 | printf("XIMStatusNone | "); | 1140 | printf("XIMStatusNone | "); |
960 | printf("\n"); | 1141 | printf("\n"); |
961 | } | 1142 | } |
962 | } | 1143 | } |
@@ -969,12 +1150,12 @@ get_ic(Ecore_IMF_Context *ctx) | |||
969 | { | 1150 | { |
970 | if (im_info->supports_cursor) | 1151 | if (im_info->supports_cursor) |
971 | { | 1152 | { |
972 | // kinput2 DOES do this... | 1153 | // kinput2 DOES do this... |
973 | XFontSet fs; | 1154 | XFontSet fs; |
974 | char **missing_charset_list; | 1155 | char **missing_charset_list; |
975 | int missing_charset_count; | 1156 | int missing_charset_count; |
976 | char *def_string; | 1157 | char *def_string; |
977 | 1158 | ||
978 | im_style |= XIMPreeditPosition; | 1159 | im_style |= XIMPreeditPosition; |
979 | im_style |= XIMStatusNothing; | 1160 | im_style |= XIMStatusNothing; |
980 | fs = XCreateFontSet(ecore_x_display_get(), | 1161 | fs = XCreateFontSet(ecore_x_display_get(), |
@@ -995,7 +1176,7 @@ get_ic(Ecore_IMF_Context *ctx) | |||
995 | } | 1176 | } |
996 | name = XNPreeditAttributes; | 1177 | name = XNPreeditAttributes; |
997 | } | 1178 | } |
998 | else | 1179 | else |
999 | { | 1180 | { |
1000 | im_style |= XIMPreeditNothing; | 1181 | im_style |= XIMPreeditNothing; |
1001 | im_style |= XIMStatusNothing; | 1182 | im_style |= XIMStatusNothing; |
@@ -1009,18 +1190,18 @@ get_ic(Ecore_IMF_Context *ctx) | |||
1009 | name, preedit_attr, NULL); | 1190 | name, preedit_attr, NULL); |
1010 | } | 1191 | } |
1011 | XFree(preedit_attr); | 1192 | XFree(preedit_attr); |
1012 | if(ic) | 1193 | if (ic) |
1013 | { | 1194 | { |
1014 | unsigned long mask = 0xaaaaaaaa; | 1195 | unsigned long mask = 0xaaaaaaaa; |
1015 | XGetICValues (ic, | 1196 | XGetICValues(ic, |
1016 | XNFilterEvents, &mask, | 1197 | XNFilterEvents, &mask, |
1017 | NULL); | 1198 | NULL); |
1018 | imf_context_data->mask = mask; | 1199 | imf_context_data->mask = mask; |
1019 | ecore_x_event_mask_set(imf_context_data->win, mask); | 1200 | ecore_x_event_mask_set(imf_context_data->win, mask); |
1020 | } | 1201 | } |
1021 | 1202 | ||
1022 | imf_context_data->ic = ic; | 1203 | imf_context_data->ic = ic; |
1023 | if(ic && imf_context_data->has_focus == EINA_TRUE) | 1204 | if (ic && imf_context_data->has_focus == EINA_TRUE) |
1024 | XSetICFocus(ic); | 1205 | XSetICFocus(ic); |
1025 | } | 1206 | } |
1026 | 1207 | ||
@@ -1032,16 +1213,17 @@ reinitialize_ic(Ecore_IMF_Context *ctx) | |||
1032 | { | 1213 | { |
1033 | Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); | 1214 | Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); |
1034 | XIC ic = imf_context_data->ic; | 1215 | XIC ic = imf_context_data->ic; |
1035 | if(ic) | 1216 | if (ic) |
1036 | { | 1217 | { |
1037 | XDestroyIC(ic); | 1218 | XDestroyIC(ic); |
1038 | imf_context_data->ic = NULL; | 1219 | imf_context_data->ic = NULL; |
1039 | if(imf_context_data->preedit_length) | 1220 | if (imf_context_data->preedit_length) |
1040 | { | 1221 | { |
1041 | imf_context_data->preedit_length = 0; | 1222 | imf_context_data->preedit_length = 0; |
1042 | free(imf_context_data->preedit_chars); | 1223 | free(imf_context_data->preedit_chars); |
1043 | imf_context_data->preedit_chars = NULL; | 1224 | imf_context_data->preedit_chars = NULL; |
1044 | ecore_imf_context_preedit_changed_event_add(ctx); | 1225 | ecore_imf_context_preedit_changed_event_add(ctx); |
1226 | ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); | ||
1045 | } | 1227 | } |
1046 | } | 1228 | } |
1047 | } | 1229 | } |
@@ -1052,13 +1234,13 @@ reinitialize_all_ics(XIM_Im_Info *info) | |||
1052 | Eina_List *tmp_list; | 1234 | Eina_List *tmp_list; |
1053 | Ecore_IMF_Context *ctx; | 1235 | Ecore_IMF_Context *ctx; |
1054 | 1236 | ||
1055 | EINA_LIST_FOREACH(info->ics, tmp_list, ctx) | 1237 | EINA_LIST_FOREACH (info->ics, tmp_list, ctx) |
1056 | reinitialize_ic(ctx); | 1238 | reinitialize_ic(ctx); |
1057 | } | 1239 | } |
1058 | 1240 | ||
1059 | static void | 1241 | static void |
1060 | set_ic_client_window(Ecore_IMF_Context *ctx, | 1242 | set_ic_client_window(Ecore_IMF_Context *ctx, |
1061 | Ecore_X_Window window) | 1243 | Ecore_X_Window window) |
1062 | { | 1244 | { |
1063 | EINA_LOG_DBG("in"); | 1245 | EINA_LOG_DBG("in"); |
1064 | Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); | 1246 | Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); |
@@ -1069,7 +1251,7 @@ set_ic_client_window(Ecore_IMF_Context *ctx, | |||
1069 | 1251 | ||
1070 | old_win = imf_context_data->win; | 1252 | old_win = imf_context_data->win; |
1071 | EINA_LOG_DBG("old_win:%d window:%d ", old_win, window); | 1253 | EINA_LOG_DBG("old_win:%d window:%d ", old_win, window); |
1072 | if(old_win != 0 && old_win != window) /* XXX how do check window... */ | 1254 | if (old_win != 0 && old_win != window) /* XXX how do check window... */ |
1073 | { | 1255 | { |
1074 | XIM_Im_Info *info; | 1256 | XIM_Im_Info *info; |
1075 | info = imf_context_data->im_info; | 1257 | info = imf_context_data->im_info; |
@@ -1079,7 +1261,7 @@ set_ic_client_window(Ecore_IMF_Context *ctx, | |||
1079 | 1261 | ||
1080 | imf_context_data->win = window; | 1262 | imf_context_data->win = window; |
1081 | 1263 | ||
1082 | if(window) /* XXX */ | 1264 | if (window) /* XXX */ |
1083 | { | 1265 | { |
1084 | XIM_Im_Info *info = NULL; | 1266 | XIM_Im_Info *info = NULL; |
1085 | info = get_im(window, imf_context_data->locale); | 1267 | info = get_im(window, imf_context_data->locale); |
@@ -1092,17 +1274,17 @@ set_ic_client_window(Ecore_IMF_Context *ctx, | |||
1092 | 1274 | ||
1093 | static XIM_Im_Info * | 1275 | static XIM_Im_Info * |
1094 | get_im(Ecore_X_Window window, | 1276 | get_im(Ecore_X_Window window, |
1095 | char *locale) | 1277 | char *locale) |
1096 | { | 1278 | { |
1097 | EINA_LOG_DBG("in"); | 1279 | EINA_LOG_DBG("in"); |
1098 | 1280 | ||
1099 | Eina_List *l; | 1281 | Eina_List *l; |
1100 | XIM_Im_Info *im_info = NULL; | 1282 | XIM_Im_Info *im_info = NULL; |
1101 | XIM_Im_Info *info = NULL; | 1283 | XIM_Im_Info *info = NULL; |
1102 | EINA_LIST_FOREACH(open_ims, l, im_info) { | 1284 | EINA_LIST_FOREACH (open_ims, l, im_info) { |
1103 | if(strcmp(im_info->locale, locale) == 0) | 1285 | if (strcmp(im_info->locale, locale) == 0) |
1104 | { | 1286 | { |
1105 | if(im_info->im) | 1287 | if (im_info->im) |
1106 | { | 1288 | { |
1107 | return im_info; | 1289 | return im_info; |
1108 | } | 1290 | } |
@@ -1113,10 +1295,10 @@ get_im(Ecore_X_Window window, | |||
1113 | } | 1295 | } |
1114 | } | 1296 | } |
1115 | 1297 | ||
1116 | if(!info) | 1298 | if (!info) |
1117 | { | 1299 | { |
1118 | info = calloc(1, sizeof(XIM_Im_Info)); | 1300 | info = calloc(1, sizeof(XIM_Im_Info)); |
1119 | if(!info) return NULL; | 1301 | if (!info) return NULL; |
1120 | open_ims = eina_list_prepend(open_ims, info); | 1302 | open_ims = eina_list_prepend(open_ims, info); |
1121 | info->win = window; | 1303 | info->win = window; |
1122 | info->locale = strdup(locale); | 1304 | info->locale = strdup(locale); |
@@ -1137,13 +1319,13 @@ xim_info_try_im(XIM_Im_Info *info) | |||
1137 | if (info->reconnecting == EINA_TRUE) | 1319 | if (info->reconnecting == EINA_TRUE) |
1138 | return; | 1320 | return; |
1139 | 1321 | ||
1140 | if(XSupportsLocale()) | 1322 | if (XSupportsLocale()) |
1141 | { | 1323 | { |
1142 | if (!XSetLocaleModifiers ("")) | 1324 | if (!XSetLocaleModifiers("")) |
1143 | EINA_LOG_WARN("Unable to set locale modifiers with XSetLocaleModifiers()"); | 1325 | EINA_LOG_WARN("Unable to set locale modifiers with XSetLocaleModifiers()"); |
1144 | dsp = ecore_x_display_get(); | 1326 | dsp = ecore_x_display_get(); |
1145 | info->im = XOpenIM(dsp, NULL, NULL, NULL); | 1327 | info->im = XOpenIM(dsp, NULL, NULL, NULL); |
1146 | if(!info->im) | 1328 | if (!info->im) |
1147 | { | 1329 | { |
1148 | XRegisterIMInstantiateCallback(dsp, | 1330 | XRegisterIMInstantiateCallback(dsp, |
1149 | NULL, NULL, NULL, | 1331 | NULL, NULL, NULL, |
@@ -1158,8 +1340,8 @@ xim_info_try_im(XIM_Im_Info *info) | |||
1158 | 1340 | ||
1159 | static void | 1341 | static void |
1160 | xim_info_display_closed(Ecore_X_Display *display __UNUSED__, | 1342 | xim_info_display_closed(Ecore_X_Display *display __UNUSED__, |
1161 | int is_error __UNUSED__, | 1343 | int is_error __UNUSED__, |
1162 | XIM_Im_Info *info) | 1344 | XIM_Im_Info *info) |
1163 | { | 1345 | { |
1164 | Eina_List *ics, *tmp_list; | 1346 | Eina_List *ics, *tmp_list; |
1165 | Ecore_IMF_Context *ctx; | 1347 | Ecore_IMF_Context *ctx; |
@@ -1169,21 +1351,21 @@ xim_info_display_closed(Ecore_X_Display *display __UNUSED__, | |||
1169 | ics = info->ics; | 1351 | ics = info->ics; |
1170 | info->ics = NULL; | 1352 | info->ics = NULL; |
1171 | 1353 | ||
1172 | EINA_LIST_FOREACH(ics, tmp_list, ctx) | 1354 | EINA_LIST_FOREACH (ics, tmp_list, ctx) |
1173 | set_ic_client_window(ctx, 0); | 1355 | set_ic_client_window(ctx, 0); |
1174 | 1356 | ||
1175 | EINA_LIST_FREE(ics, ctx) { | 1357 | EINA_LIST_FREE (ics, ctx) { |
1176 | Ecore_IMF_Context_Data *imf_context_data; | 1358 | Ecore_IMF_Context_Data *imf_context_data; |
1177 | imf_context_data = ecore_imf_context_data_get(ctx); | 1359 | imf_context_data = ecore_imf_context_data_get(ctx); |
1178 | imf_context_data_destroy(imf_context_data); | 1360 | imf_context_data_destroy(imf_context_data); |
1179 | } | 1361 | } |
1180 | 1362 | ||
1181 | free (info->locale); | 1363 | free(info->locale); |
1182 | 1364 | ||
1183 | if (info->im) | 1365 | if (info->im) |
1184 | XCloseIM (info->im); | 1366 | XCloseIM(info->im); |
1185 | 1367 | ||
1186 | free (info); | 1368 | free(info); |
1187 | } | 1369 | } |
1188 | 1370 | ||
1189 | static void | 1371 | static void |
@@ -1203,11 +1385,11 @@ xim_instantiate_callback(Display *display, | |||
1203 | } | 1385 | } |
1204 | 1386 | ||
1205 | info->im = im; | 1387 | info->im = im; |
1206 | setup_im (info); | 1388 | setup_im(info); |
1207 | 1389 | ||
1208 | XUnregisterIMInstantiateCallback (display, NULL, NULL, NULL, | 1390 | XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, |
1209 | xim_instantiate_callback, | 1391 | xim_instantiate_callback, |
1210 | (XPointer)info); | 1392 | (XPointer)info); |
1211 | info->reconnecting = EINA_FALSE; | 1393 | info->reconnecting = EINA_FALSE; |
1212 | } | 1394 | } |
1213 | 1395 | ||
@@ -1217,7 +1399,7 @@ setup_im(XIM_Im_Info *info) | |||
1217 | XIMValuesList *ic_values = NULL; | 1399 | XIMValuesList *ic_values = NULL; |
1218 | XIMCallback im_destroy_callback; | 1400 | XIMCallback im_destroy_callback; |
1219 | 1401 | ||
1220 | if(!info->im) | 1402 | if (!info->im) |
1221 | return; | 1403 | return; |
1222 | 1404 | ||
1223 | im_destroy_callback.client_data = (XPointer)info; | 1405 | im_destroy_callback.client_data = (XPointer)info; |
@@ -1239,25 +1421,25 @@ setup_im(XIM_Im_Info *info) | |||
1239 | { | 1421 | { |
1240 | if (!strcmp(ic_values->supported_values[i], | 1422 | if (!strcmp(ic_values->supported_values[i], |
1241 | XNStringConversionCallback)) | 1423 | XNStringConversionCallback)) |
1242 | info->supports_string_conversion = EINA_TRUE; | 1424 | info->supports_string_conversion = EINA_TRUE; |
1243 | if (!strcmp(ic_values->supported_values[i], | 1425 | if (!strcmp(ic_values->supported_values[i], |
1244 | XNCursor)) | 1426 | XNCursor)) |
1245 | info->supports_cursor = EINA_TRUE; | 1427 | info->supports_cursor = EINA_TRUE; |
1246 | } | 1428 | } |
1247 | #if 0 | 1429 | #if 0 |
1248 | printf("values........\n"); | 1430 | printf("values........\n"); |
1249 | for (i = 0; i < ic_values->count_values; i++) | 1431 | for (i = 0; i < ic_values->count_values; i++) |
1250 | printf("%s\n", ic_values->supported_values[i]); | 1432 | printf("%s\n", ic_values->supported_values[i]); |
1251 | printf("styles........\n"); | 1433 | printf("styles........\n"); |
1252 | for (i = 0; i < info->xim_styles->count_styles; i++) | 1434 | for (i = 0; i < info->xim_styles->count_styles; i++) |
1253 | printf("%lx\n", info->xim_styles->supported_styles[i]); | 1435 | printf("%lx\n", info->xim_styles->supported_styles[i]); |
1254 | #endif | 1436 | #endif |
1255 | XFree(ic_values); | 1437 | XFree(ic_values); |
1256 | } | 1438 | } |
1257 | } | 1439 | } |
1258 | 1440 | ||
1259 | static void | 1441 | static void |
1260 | xim_destroy_callback(XIM xim __UNUSED__, | 1442 | xim_destroy_callback(XIM xim __UNUSED__, |
1261 | XPointer client_data, | 1443 | XPointer client_data, |
1262 | XPointer call_data __UNUSED__) | 1444 | XPointer call_data __UNUSED__) |
1263 | { | 1445 | { |