aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c')
-rw-r--r--libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c1718
1 files changed, 0 insertions, 1718 deletions
diff --git a/libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c b/libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c
deleted file mode 100644
index 423c461..0000000
--- a/libraries/ecore/src/lib/ecore_imf/ecore_imf_context.c
+++ /dev/null
@@ -1,1718 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6#include <string.h>
7#include <locale.h>
8
9#include <Ecore.h>
10#include <ecore_private.h>
11
12#include "Ecore_IMF.h"
13#include "ecore_imf_private.h"
14
15/**
16 * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions
17 *
18 * Functions that operate on Ecore Input Method Context objects.
19 */
20
21/**
22 * Get the list of the available Input Method Context ids.
23 *
24 * Note that the caller is responsible for freeing the Eina_List
25 * when finished with it. There is no need to finish the list strings.
26 *
27 * @return Return an Eina_List of strings;
28 * on failure it returns NULL.
29 * @ingroup Ecore_IMF_Context_Group
30 */
31EAPI Eina_List *
32ecore_imf_context_available_ids_get(void)
33{
34 return ecore_imf_module_context_ids_get();
35}
36
37EAPI Eina_List *
38ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type)
39{
40 return ecore_imf_module_context_ids_by_canvas_type_get(canvas_type);
41}
42
43/*
44 * Match @locale against @against.
45 *
46 * 'en_US' against 'en_US' => 4
47 * 'en_US' against 'en' => 3
48 * 'en', 'en_UK' against 'en_US' => 2
49 * all locales, against '*' => 1
50 */
51static int
52_ecore_imf_context_match_locale(const char *locale, const char *against, int against_len)
53{
54 if (strcmp(against, "*") == 0)
55 return 1;
56
57 if (strcasecmp(locale, against) == 0)
58 return 4;
59
60 if (strncasecmp(locale, against, 2) == 0)
61 return (against_len == 2) ? 3 : 2;
62
63 return 0;
64}
65
66/**
67 * Get the id of the default Input Method Context.
68 * The id may to used to create a new instance of an Input Method
69 * Context object.
70 *
71 * @return Return a string containing the id of the default Input
72 * Method Context; on failure it returns NULL.
73 * @ingroup Ecore_IMF_Context_Group
74 */
75EAPI const char *
76ecore_imf_context_default_id_get(void)
77{
78 return ecore_imf_context_default_id_by_canvas_type_get(NULL);
79}
80
81EAPI const char *
82ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type)
83{
84 const char *id;
85 Eina_List *modules;
86 Ecore_IMF_Module *module;
87 char *locale;
88 char *tmp;
89 int best_goodness = 0;
90
91 id = getenv("ECORE_IMF_MODULE");
92 if (id)
93 {
94 if (strcmp(id, "none") == 0) return NULL;
95 if (ecore_imf_module_get(id)) return id;
96 }
97
98 modules = ecore_imf_module_available_get();
99 if (!modules) return NULL;
100
101 locale = setlocale(LC_CTYPE, NULL);
102 if (!locale) return NULL;
103
104 locale = strdup(locale);
105
106 tmp = strchr(locale, '.');
107 if (tmp) *tmp = '\0';
108 tmp = strchr(locale, '@');
109 if (tmp) *tmp = '\0';
110
111 id = NULL;
112
113 EINA_LIST_FREE(modules, module)
114 {
115 if (canvas_type &&
116 strcmp(module->info->canvas_type, canvas_type) == 0)
117 continue;
118
119 const char *p = module->info->default_locales;
120 while (p)
121 {
122 const char *q = strchr(p, ':');
123 int goodness = _ecore_imf_context_match_locale(locale, p, q ? (size_t)(q - p) : strlen (p));
124
125 if (goodness > best_goodness)
126 {
127 id = module->info->id;
128 best_goodness = goodness;
129 }
130
131 p = q ? q + 1 : NULL;
132 }
133 }
134
135 free(locale);
136 return id;
137}
138
139/**
140 * Retrieve the info for the Input Method Context with @p id.
141 *
142 * @param id The Input Method Context id to query for.
143 * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id;
144 * on failure it returns NULL.
145 * @ingroup Ecore_IMF_Context_Group
146 *
147 * Example
148 * @code
149 *
150 * const char *ctx_id;
151 * const Ecore_IMF_Context_Info *ctx_info;
152 * Ecore_IMF_Context *imf_context;
153 * ctx_id = ecore_imf_context_default_id_get();
154 * if (ctx_id)
155 * {
156 * ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
157 * if (!ctx_info->canvas_type ||
158 * strcmp(ctx_info->canvas_type, "evas") == 0)
159 * {
160 * imf_context = ecore_imf_context_add(ctx_id);
161 * }
162 * else
163 * {
164 * ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
165 * if (ctx_id)
166 * {
167 * imf_context = ecore_imf_context_add(ctx_id);
168 * }
169 * }
170 * }
171 * @endcode
172 */
173EAPI const Ecore_IMF_Context_Info *
174ecore_imf_context_info_by_id_get(const char *id)
175{
176 Ecore_IMF_Module *module;
177
178 if (!id) return NULL;
179 module = ecore_imf_module_get(id);
180 if (!module) return NULL;
181 return module->info;
182}
183
184/**
185 * Create a new Input Method Context defined by the given id.
186 *
187 * @param id The Input Method Context id.
188 * @return A newly allocated Input Method Context;
189 * on failure it returns NULL.
190 * @ingroup Ecore_IMF_Context_Group
191 */
192EAPI Ecore_IMF_Context *
193ecore_imf_context_add(const char *id)
194{
195 Ecore_IMF_Context *ctx;
196
197 if (!id) return NULL;
198 ctx = ecore_imf_module_context_create(id);
199 if (!ctx || !ctx->klass) return NULL;
200 if (ctx->klass->add) ctx->klass->add(ctx);
201 /* default use_preedit is EINA_TRUE, so let's make sure it's
202 * set on the immodule */
203 ecore_imf_context_use_preedit_set(ctx, EINA_TRUE);
204
205 /* default prediction is EINA_TRUE, so let's make sure it's
206 * set on the immodule */
207 ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE);
208
209 /* default autocapital type is SENTENCE type, so let's make sure it's
210 * set on the immodule */
211 ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE);
212
213 /* default input panel enabled status is EINA_TRUE, so let's make sure it's
214 * set on the immodule */
215 ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE);
216
217 /* default input panel layout type is NORMAL type, so let's make sure it's
218 * set on the immodule */
219 ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
220
221 /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's
222 * set on the immodule */
223 ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL);
224 return ctx;
225}
226
227/**
228 * Retrieve the info for the given Input Method Context.
229 *
230 * @param ctx An #Ecore_IMF_Context.
231 * @return Return a #Ecore_IMF_Context_Info for the given Input Method Context;
232 * on failure it returns NULL.
233 * @ingroup Ecore_IMF_Context_Group
234 */
235EAPI const Ecore_IMF_Context_Info *
236ecore_imf_context_info_get(Ecore_IMF_Context *ctx)
237{
238 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
239 {
240 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
241 "ecore_imf_context_info_get");
242 return NULL;
243 }
244 return ctx->module->info;
245}
246
247/**
248 * Delete the given Input Method Context and free its memory.
249 *
250 * @param ctx An #Ecore_IMF_Context.
251 * @ingroup Ecore_IMF_Context_Group
252 */
253EAPI void
254ecore_imf_context_del(Ecore_IMF_Context *ctx)
255{
256 Ecore_IMF_Func_Node *fn;
257
258 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
259 {
260 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
261 "ecore_imf_context_del");
262 return;
263 }
264 if (ctx->klass->del) ctx->klass->del(ctx);
265
266 if (ctx->callbacks)
267 {
268 EINA_LIST_FREE(ctx->callbacks, fn)
269 free(fn);
270 }
271
272 ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE);
273 free(ctx);
274}
275
276/**
277 * Set the client window for the Input Method Context; this is the
278 * Ecore_X_Window when using X11, Ecore_Win32_Window when using Win32, etc.
279 * This window is used in order to correctly position status windows, and may
280 * also be used for purposes internal to the Input Method Context.
281 *
282 * @param ctx An #Ecore_IMF_Context.
283 * @param window The client window. This may be NULL to indicate
284 * that the previous client window no longer exists.
285 * @ingroup Ecore_IMF_Context_Group
286 */
287EAPI void
288ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
289{
290 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
291 {
292 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
293 "ecore_imf_context_client_window_set");
294 return;
295 }
296 if (ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window);
297 ctx->window = window;
298}
299
300/**
301 * Get the client window of the Input Method Context
302 *
303 * See @ref ecore_imf_context_client_window_set for more details.
304 *
305 * @param ctx An #Ecore_IMF_Context.
306 * @return Return the client window.
307 * @ingroup Ecore_IMF_Context_Group
308 * @since 1.1.0
309 */
310EAPI void *
311ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx)
312{
313 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
314 {
315 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
316 "ecore_imf_context_client_window_get");
317 return NULL;
318 }
319 return ctx->window;
320}
321
322/**
323 * Set the client canvas for the Input Method Context; this is the
324 * canvas in which the input appears.
325 * The canvas type can be determined by using the context canvas type.
326 * Actually only canvas with type "evas" (Evas *) is supported.
327 * This canvas may be used in order to correctly position status windows, and may
328 * also be used for purposes internal to the Input Method Context.
329 *
330 * @param ctx An #Ecore_IMF_Context.
331 * @param canvas The client canvas. This may be NULL to indicate
332 * that the previous client canvas no longer exists.
333 * @ingroup Ecore_IMF_Context_Group
334 */
335EAPI void
336ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
337{
338 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
339 {
340 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
341 "ecore_imf_context_client_canvas_set");
342 return;
343 }
344 if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas);
345 ctx->client_canvas = canvas;
346}
347
348/**
349 * Get the client canvas of the Input Method Context.
350 *
351 * See @ref ecore_imf_context_client_canvas_set for more details.
352 *
353 * @param ctx An #Ecore_IMF_Context.
354 * @return Return the client canvas.
355 * @ingroup Ecore_IMF_Context_Group
356 * @since 1.1.0
357 */
358EAPI void *
359ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx)
360{
361 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
362 {
363 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
364 "ecore_imf_context_client_canvas_get");
365 return NULL;
366 }
367 return ctx->client_canvas;
368}
369
370/**
371 * Ask the Input Method Context to show itself.
372 *
373 * @param ctx An #Ecore_IMF_Context.
374 * @ingroup Ecore_IMF_Context_Group
375 */
376EAPI void
377ecore_imf_context_show(Ecore_IMF_Context *ctx)
378{
379 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
380 {
381 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
382 "ecore_imf_context_show");
383 return;
384 }
385 if (ctx->klass->show) ctx->klass->show(ctx);
386}
387
388/**
389 * Ask the Input Method Context to hide itself.
390 *
391 * @param ctx An #Ecore_IMF_Context.
392 * @ingroup Ecore_IMF_Context_Group
393 */
394EAPI void
395ecore_imf_context_hide(Ecore_IMF_Context *ctx)
396{
397 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
398 {
399 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
400 "ecore_imf_context_hide");
401 return;
402 }
403 if (ctx->klass->hide) ctx->klass->hide(ctx);
404}
405
406/**
407 * Retrieve the current preedit string and cursor position
408 * for the Input Method Context.
409 *
410 * @param ctx An #Ecore_IMF_Context.
411 * @param str Location to store the retrieved string. The
412 * string retrieved must be freed with free().
413 * @param cursor_pos Location to store position of cursor (in characters)
414 * within the preedit string.
415 * @ingroup Ecore_IMF_Context_Group
416 */
417EAPI void
418ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos)
419{
420 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
421 {
422 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
423 "ecore_imf_context_preedit_string_get");
424 return;
425 }
426 if (ctx->klass->preedit_string_get)
427 ctx->klass->preedit_string_get(ctx, str, cursor_pos);
428 else
429 {
430 if (str) *str = strdup("");
431 if (cursor_pos) *cursor_pos = 0;
432 }
433}
434
435/**
436 * Retrieve the current preedit string, attributes and
437 * cursor position for the Input Method Context.
438 *
439 * @param ctx An #Ecore_IMF_Context.
440 * @param str Location to store the retrieved string. The
441 * string retrieved must be freed with free().
442 * @param attrs an Eina_List of attributes
443 * @param cursor_pos Location to store position of cursor (in characters)
444 * within the preedit string.
445 * @ingroup Ecore_IMF_Context_Group
446 *
447 * Example
448 * @code
449 * char *preedit_string;
450 * int cursor_pos;
451 * Eina_List *attrs = NULL, *l = NULL;
452 * Ecore_IMF_Preedit_Attr *attr;
453 *
454 * ecore_imf_context_preedit_string_with_attributes_get(imf_context,
455 * &preedit_string,
456 * &attrs, &cursor_pos);
457 * if (!preedit_string) return;
458 *
459 * if (strlen(preedit_string) > 0)
460 * {
461 * if (attrs)
462 * {
463 * EINA_LIST_FOREACH(attrs, l, attr)
464 * {
465 * if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
466 * {
467 * // Something to do
468 * }
469 * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2)
470 * {
471 * // Something to do
472 * }
473 * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
474 * {
475 * // Something to do
476 * }
477 * }
478 * }
479 * }
480 *
481 * // delete attribute list
482 * if (attrs)
483 * {
484 * EINA_LIST_FREE(attrs, attr) free(attr);
485 * }
486 *
487 * free(preedit_string);
488 * @endcode
489 * @since 1.1.0
490 */
491EAPI void
492ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos)
493{
494 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
495 {
496 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
497 "ecore_imf_context_preedit_string_with_attributes_get");
498 return;
499 }
500 if (ctx->klass->preedit_string_with_attributes_get)
501 ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos);
502 else
503 {
504 if (str) *str = strdup("");
505 if (attrs) *attrs = NULL;
506 if (cursor_pos) *cursor_pos = 0;
507 }
508}
509
510/**
511 * Notify the Input Method Context that the widget to which its
512 * correspond has gained focus.
513 *
514 * @param ctx An #Ecore_IMF_Context.
515 * @ingroup Ecore_IMF_Context_Group
516 *
517 * Example
518 * @code
519 * static void
520 * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source)
521 * {
522 * ecore_imf_context_reset(imf_context);
523 * ecore_imf_context_focus_in(imf_context);
524 * }
525 *
526 * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed);
527 * @endcode
528 */
529EAPI void
530ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
531{
532 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
533 {
534 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
535 "ecore_imf_context_focus_in");
536 return;
537 }
538 if (ctx->klass->focus_in) ctx->klass->focus_in(ctx);
539}
540
541/**
542 * Notify the Input Method Context that the widget to which its
543 * correspond has lost focus.
544 *
545 * @param ctx An #Ecore_IMF_Context.
546 * @ingroup Ecore_IMF_Context_Group
547 *
548 * Example
549 * @code
550 * static void
551 * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
552 * {
553 * ecore_imf_context_reset(imf_context);
554 * ecore_imf_context_focus_out(imf_context);
555 * }
556 *
557 * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
558 * @endcode
559 */
560EAPI void
561ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
562{
563 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
564 {
565 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
566 "ecore_imf_context_focus_out");
567 return;
568 }
569 if (ctx->klass->focus_out) ctx->klass->focus_out(ctx);
570}
571
572/**
573 * Notify the Input Method Context that a change such as a
574 * change in cursor position has been made. This will typically
575 * cause the Input Method Context to clear the preedit state.
576 *
577 * @param ctx An #Ecore_IMF_Context.
578 * @ingroup Ecore_IMF_Context_Group
579 *
580 * Example
581 * @code
582 * static void
583 * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
584 * {
585 * ecore_imf_context_reset(imf_context);
586 * ecore_imf_context_focus_out(imf_context);
587 * }
588 *
589 * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
590 * @endcode
591 */
592EAPI void
593ecore_imf_context_reset(Ecore_IMF_Context *ctx)
594{
595 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
596 {
597 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
598 "ecore_imf_context_reset");
599 return;
600 }
601 if (ctx->klass->reset) ctx->klass->reset(ctx);
602}
603
604/**
605 * Notify the Input Method Context that a change in the cursor
606 * position has been made.
607 *
608 * @param ctx An #Ecore_IMF_Context.
609 * @param cursor_pos New cursor position in characters.
610 * @ingroup Ecore_IMF_Context_Group
611 */
612EAPI void
613ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
614{
615 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
616 {
617 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
618 "ecore_imf_context_cursor_position_set");
619 return;
620 }
621 if (ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos);
622}
623
624/**
625 * Notify the Input Method Context that a change in the cursor
626 * location has been made. The location is relative to the canvas.
627 * The cursor location can be used to determine the position of
628 * candidate word window in the immodule.
629 *
630 * @param ctx An #Ecore_IMF_Context.
631 * @param x cursor x position.
632 * @param y cursor y position.
633 * @param w cursor width.
634 * @param h cursor height.
635 * @ingroup Ecore_IMF_Context_Group
636 * @since 1.1.0
637 */
638EAPI void
639ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
640{
641 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
642 {
643 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
644 "ecore_imf_context_cursor_location_set");
645 return;
646 }
647 if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h);
648}
649
650/**
651 * Set whether the IM context should use the preedit string
652 * to display feedback. If @c use_preedit is EINA_FALSE (default
653 * is EINA_TRUE), then the IM context may use some other method to display
654 * feedback, such as displaying it in a child of the root window.
655 *
656 * @param ctx An #Ecore_IMF_Context.
657 * @param use_preedit Whether the IM context should use the preedit string.
658 * @ingroup Ecore_IMF_Context_Group
659 */
660EAPI void
661ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
662{
663 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
664 {
665 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
666 "ecore_imf_context_use_preedit_set");
667 return;
668 }
669 if (ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit);
670}
671
672/**
673 * Set whether the IM context should allow to use the text prediction.
674 * If @c prediction is EINA_FALSE (default is EINA_TRUE), then the IM context will not display the text prediction window.
675 *
676 * @param ctx An #Ecore_IMF_Context.
677 * @param prediction Whether the IM context should allow to use the text prediction.
678 * @ingroup Ecore_IMF_Context_Group
679 * @since 1.1.0
680 */
681EAPI void
682ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction)
683{
684 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
685 {
686 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
687 "ecore_imf_context_prediction_allow_set");
688 return;
689 }
690
691 ctx->allow_prediction = prediction;
692
693 if (ctx->klass->prediction_allow_set)
694 ctx->klass->prediction_allow_set(ctx, prediction);
695}
696
697/**
698 * Get whether the IM context should allow to use the text prediction.
699 *
700 * @param ctx An #Ecore_IMF_Context.
701 * @return EINA_TRUE if it allows to use the text prediction, otherwise EINA_FALSE.
702 * @ingroup Ecore_IMF_Context_Group
703 * @since 1.1.0
704 */
705EAPI Eina_Bool
706ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx)
707{
708 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
709 {
710 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
711 "ecore_imf_context_prediction_allow_get");
712 return EINA_FALSE;
713 }
714
715 return ctx->allow_prediction;
716}
717
718/**
719 * Set the autocapitalization type on the immodule.
720 *
721 * @param ctx An #Ecore_IMF_Context.
722 * @param autocapital_type the autocapitalization type.
723 * @ingroup Ecore_IMF_Context_Group
724 * @since 1.1.0
725 */
726EAPI void
727ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type)
728{
729 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
730 {
731 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
732 "ecore_imf_context_autocapital_type_set");
733 return;
734 }
735
736 ctx->autocapital_type = autocapital_type;
737
738 if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type);
739}
740
741/**
742 * Get the autocapitalization type.
743 *
744 * @param ctx An #Ecore_IMF_Context.
745 * @return The autocapital type being used by @p ctx.
746 * @ingroup Ecore_IMF_Context_Group
747 * @since 1.1.0
748 */
749EAPI Ecore_IMF_Autocapital_Type
750ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx)
751{
752 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
753 {
754 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
755 "ecore_imf_context_autocapital_allow_get");
756 return ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
757 }
758
759 return ctx->autocapital_type;
760}
761
762/**
763 * Set the callback to be used on get_surrounding request.
764 *
765 * This callback will be called when the Input Method Context
766 * module requests the surrounding context.
767 *
768 * @param ctx An #Ecore_IMF_Context.
769 * @param func The callback to be called.
770 * @param data The data pointer to be passed to @p func
771 * @ingroup Ecore_IMF_Context_Group
772 */
773EAPI void
774ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data)
775{
776 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
777 {
778 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
779 "ecore_imf_context_retrieve_surrounding_callback_set");
780 return;
781 }
782
783 ctx->retrieve_surrounding_func = func;
784 ctx->retrieve_surrounding_data = (void *) data;
785}
786
787/**
788 * Set the input mode used by the Ecore Input Context.
789 *
790 * The input mode can be one of the input modes defined in
791 * #Ecore_IMF_Input_Mode. The default input mode is
792 * ECORE_IMF_INPUT_MODE_FULL.
793 *
794 * @param ctx An #Ecore_IMF_Context.
795 * @param input_mode The input mode to be used by @p ctx.
796 * @ingroup Ecore_IMF_Context_Group
797 */
798EAPI void
799ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
800{
801 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
802 {
803 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
804 "ecore_imf_context_input_mode_set");
805 return;
806 }
807 if (ctx->klass->input_mode_set) ctx->klass->input_mode_set(ctx, input_mode);
808 ctx->input_mode = input_mode;
809}
810
811/**
812 * Get the input mode being used by the Ecore Input Context.
813 *
814 * See @ref ecore_imf_context_input_mode_set for more details.
815 *
816 * @param ctx An #Ecore_IMF_Context.
817 * @return The input mode being used by @p ctx.
818 * @ingroup Ecore_IMF_Context_Group
819 */
820EAPI Ecore_IMF_Input_Mode
821ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx)
822{
823 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
824 {
825 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
826 "ecore_imf_context_input_mode_set");
827 return 0;
828 }
829 return ctx->input_mode;
830}
831
832/**
833 * Allow an Ecore Input Context to internally handle an event.
834 * If this function returns EINA_TRUE, then no further processing
835 * should be done for this event.
836 *
837 * Input methods must be able to accept all types of events (simply
838 * returning EINA_FALSE if the event was not handled), but there is no
839 * obligation of any events to be submitted to this function.
840 *
841 * @param ctx An #Ecore_IMF_Context.
842 * @param type The type of event defined by #Ecore_IMF_Event_Type.
843 * @param event The event itself.
844 * @return EINA_TRUE if the event was handled; otherwise EINA_FALSE.
845 * @ingroup Ecore_IMF_Context_Group
846 *
847 * Example
848 * @code
849 * static void
850 * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
851 * {
852 * Evas_Event_Key_Down *ev = event_info;
853 * if (!ev->keyname) return;
854 *
855 * if (imf_context)
856 * {
857 * Ecore_IMF_Event_Key_Down ecore_ev;
858 * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
859 * if (ecore_imf_context_filter_event(imf_context,
860 * ECORE_IMF_EVENT_KEY_DOWN,
861 * (Ecore_IMF_Event *)&ecore_ev))
862 * return;
863 * }
864 * }
865 *
866 * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data);
867 * @endcode
868 */
869EAPI Eina_Bool
870ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
871{
872 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
873 {
874 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
875 "ecore_imf_context_filter_event");
876 return EINA_FALSE;
877 }
878 if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event);
879 return EINA_FALSE;
880}
881
882/**
883 * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions
884 *
885 * Functions that should be used by Ecore Input Method Context modules.
886 */
887
888/**
889 * Creates a new Input Method Context with klass specified by @p ctxc.
890 *
891 * This method should be used by modules implementing the Input
892 * Method Context interface.
893 *
894 * @param ctxc An #Ecore_IMF_Context_Class.
895 * @return A new #Ecore_IMF_Context; on failure it returns NULL.
896 * @ingroup Ecore_IMF_Context_Module_Group
897 */
898EAPI Ecore_IMF_Context *
899ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc)
900{
901 Ecore_IMF_Context *ctx;
902
903 if (!ctxc) return NULL;
904 ctx = calloc(1, sizeof(Ecore_IMF_Context));
905 if (!ctx) return NULL;
906 ECORE_MAGIC_SET(ctx, ECORE_MAGIC_CONTEXT);
907 ctx->klass = ctxc;
908 ctx->data = NULL;
909 ctx->retrieve_surrounding_func = NULL;
910 ctx->retrieve_surrounding_data = NULL;
911 return ctx;
912}
913
914/**
915 * Set the Input Method Context specific data.
916 *
917 * Note that this method should be used by modules to set
918 * the Input Method Context specific data and it's not meant to
919 * be used by applications to store application specific data.
920 *
921 * @param ctx An #Ecore_IMF_Context.
922 * @param data The Input Method Context specific data.
923 * @return A new #Ecore_IMF_Context; on failure it returns NULL.
924 * @ingroup Ecore_IMF_Context_Module_Group
925 */
926EAPI void
927ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data)
928{
929 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
930 {
931 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
932 "ecore_imf_context_data_set");
933 return;
934 }
935 ctx->data = data;
936}
937
938/**
939 * Get the Input Method Context specific data.
940 *
941 * See @ref ecore_imf_context_data_set for more details.
942 *
943 * @param ctx An #Ecore_IMF_Context.
944 * @return The Input Method Context specific data.
945 * @ingroup Ecore_IMF_Context_Module_Group
946 */
947EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx)
948{
949 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
950 {
951 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
952 "ecore_imf_context_data_get");
953 return NULL;
954 }
955 return ctx->data;
956}
957
958/**
959 * Retrieve context around insertion point.
960 *
961 * This function is implemented by calling the
962 * Ecore_IMF_Context::retrieve_surrounding_func (
963 * set using #ecore_imf_context_retrieve_surrounding_callback_set).
964 *
965 * There is no obligation for a widget to respond to the
966 * ::retrieve_surrounding_func, so input methods must be prepared
967 * to function without context.
968 *
969 * @param ctx An #Ecore_IMF_Context.
970 * @param text Location to store a UTF-8 encoded string of text
971 * holding context around the insertion point.
972 * If the function returns EINA_TRUE, then you must free
973 * the result stored in this location with free().
974 * @param cursor_pos Location to store the position in characters of
975 * the insertion cursor within @p text.
976 * @return EINA_TRUE if surrounding text was provided; otherwise EINA_FALSE.
977 * @ingroup Ecore_IMF_Context_Module_Group
978 */
979EAPI Eina_Bool
980ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos)
981{
982 int result = EINA_FALSE;
983
984 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
985 {
986 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
987 "ecore_imf_context_surrounding_get");
988 return EINA_FALSE;
989 }
990
991 if (ctx->retrieve_surrounding_func)
992 {
993 result = ctx->retrieve_surrounding_func(ctx->retrieve_surrounding_data, ctx, text, cursor_pos);
994 if (!result)
995 {
996 if (text) *text = NULL;
997 if (cursor_pos) *cursor_pos = 0;
998 }
999 }
1000 return result;
1001}
1002
1003static void
1004_ecore_imf_event_free_preedit(void *data __UNUSED__, void *event)
1005{
1006 free(event);
1007}
1008
1009/**
1010 * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue.
1011 *
1012 * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts.
1013 * It's asynchronous method to put event to the event queue.
1014 * ecore_imf_context_event_callback_call() can be used as synchronous method.
1015 *
1016 * @param ctx An #Ecore_IMF_Context.
1017 * @ingroup Ecore_IMF_Context_Module_Group
1018 */
1019EAPI void
1020ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx)
1021{
1022 Ecore_IMF_Event_Commit *ev;
1023
1024 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1025 {
1026 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1027 "ecore_imf_context_preedit_start_event_add");
1028 return;
1029 }
1030
1031 ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Start));
1032 ev->ctx = ctx;
1033 ecore_event_add(ECORE_IMF_EVENT_PREEDIT_START,
1034 ev, _ecore_imf_event_free_preedit, NULL);
1035}
1036
1037/**
1038 * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue.
1039 *
1040 * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled.
1041 * It's asynchronous method to put event to the event queue.
1042 * ecore_imf_context_event_callback_call() can be used as synchronous method.
1043 *
1044 * @param ctx An #Ecore_IMF_Context.
1045 * @ingroup Ecore_IMF_Context_Module_Group
1046 */
1047EAPI void
1048ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx)
1049{
1050 Ecore_IMF_Event_Commit *ev;
1051
1052 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1053 {
1054 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1055 "ecore_imf_context_preedit_end_event_add");
1056 return;
1057 }
1058
1059 ev = malloc(sizeof(Ecore_IMF_Event_Preedit_End));
1060 ev->ctx = ctx;
1061 ecore_event_add(ECORE_IMF_EVENT_PREEDIT_END,
1062 ev, _ecore_imf_event_free_preedit, NULL);
1063}
1064
1065/**
1066 * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue.
1067 *
1068 * It's asynchronous method to put event to the event queue.
1069 * ecore_imf_context_event_callback_call() can be used as synchronous method.
1070 *
1071 * @param ctx An #Ecore_IMF_Context.
1072 * @ingroup Ecore_IMF_Context_Module_Group
1073 */
1074EAPI void
1075ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx)
1076{
1077 Ecore_IMF_Event_Commit *ev;
1078
1079 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1080 {
1081 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1082 "ecore_imf_context_preedit_changed_event_add");
1083 return;
1084 }
1085
1086 ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Changed));
1087 ev->ctx = ctx;
1088 ecore_event_add(ECORE_IMF_EVENT_PREEDIT_CHANGED,
1089 ev, _ecore_imf_event_free_preedit, NULL);
1090}
1091
1092static void
1093_ecore_imf_event_free_commit(void *data __UNUSED__, void *event)
1094{
1095 Ecore_IMF_Event_Commit *ev;
1096
1097 ev = event;
1098 if (ev->str) free(ev->str);
1099 free(ev);
1100}
1101
1102/**
1103 * Adds ECORE_IMF_EVENT_COMMIT to the event queue.
1104 *
1105 * It's asynchronous method to put event to the event queue.
1106 * ecore_imf_context_event_callback_call() can be used as synchronous method.
1107 *
1108 * @param ctx An #Ecore_IMF_Context.
1109 * @param str The committed string.
1110 * @ingroup Ecore_IMF_Context_Module_Group
1111 */
1112EAPI void
1113ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str)
1114{
1115 Ecore_IMF_Event_Commit *ev;
1116
1117 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1118 {
1119 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1120 "ecore_imf_context_commit_event_add");
1121 return;
1122 }
1123
1124 ev = malloc(sizeof(Ecore_IMF_Event_Commit));
1125 ev->ctx = ctx;
1126 ev->str = str ? strdup(str) : NULL;
1127 ecore_event_add(ECORE_IMF_EVENT_COMMIT,
1128 ev, _ecore_imf_event_free_commit, NULL);
1129
1130}
1131
1132static void
1133_ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event)
1134{
1135 free(event);
1136}
1137
1138/**
1139 * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
1140 *
1141 * Asks the widget that the input context is attached to to delete characters around the cursor position
1142 * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
1143 * Note that offset and n_chars are in characters not in bytes.
1144 *
1145 * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue.
1146 * ecore_imf_context_event_callback_call() can be used as synchronous method.
1147 *
1148 * @param ctx An #Ecore_IMF_Context.
1149 * @param offset The start offset of surrounding to be deleted.
1150 * @param n_chars The number of characters to be deleted.
1151 * @ingroup Ecore_IMF_Context_Module_Group
1152 */
1153EAPI void
1154ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars)
1155{
1156 Ecore_IMF_Event_Delete_Surrounding *ev;
1157
1158 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1159 {
1160 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1161 "ecore_imf_context_delete_surrounding_event_add");
1162 return;
1163 }
1164
1165 ev = malloc(sizeof(Ecore_IMF_Event_Delete_Surrounding));
1166 ev->ctx = ctx;
1167 ev->offset = offset;
1168 ev->n_chars = n_chars;
1169 ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
1170 ev, _ecore_imf_event_free_delete_surrounding, NULL);
1171}
1172
1173/**
1174 * Add (register) a callback function to a given context event.
1175 *
1176 * This function adds a function callback to the context @p ctx when the
1177 * event of type @p type occurs on it. The function pointer is @p
1178 * func.
1179 *
1180 * The event type @p type to trigger the function may be one of
1181 * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END,
1182 * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and
1183 * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING.
1184 *
1185 * @param ctx Ecore_IMF_Context to attach a callback to.
1186 * @param type The type of event that will trigger the callback
1187 * @param func The (callback) function to be called when the event is
1188 * triggered
1189 * @param data The data pointer to be passed to @p func
1190 * @ingroup Ecore_IMF_Context_Group
1191 * @since 1.2.0
1192 *
1193 * Example
1194 * @code
1195 * static void
1196 * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info)
1197 * {
1198 * char *commit_str = event_info;
1199 * // something to do
1200 * }
1201 *
1202 * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data);
1203 * @endcode
1204 */
1205EAPI void
1206ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data)
1207{
1208 Ecore_IMF_Func_Node *fn = NULL;
1209
1210 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1211 {
1212 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1213 "ecore_imf_context_event_callback_add");
1214 return;
1215 }
1216
1217 if (!func) return;
1218
1219 fn = calloc(1, sizeof (Ecore_IMF_Func_Node));
1220 if (!fn) return;
1221
1222 fn->func = func;
1223 fn->data = data;
1224 fn->type = type;
1225
1226 ctx->callbacks = eina_list_append(ctx->callbacks, fn);
1227}
1228
1229/**
1230 * Delete (unregister) a callback function registered to a given
1231 * context event.
1232 *
1233 * This function removes a function callback from the context @p ctx when the
1234 * event of type @p type occurs on it. The function pointer is @p
1235 * func.
1236 *
1237 * @see ecore_imf_context_event_callback_add() for more details
1238 *
1239 * @param ctx Ecore_IMF_Context to remove a callback from.
1240 * @param type The type of event that was triggering the callback
1241 * @param func The (callback) function that was to be called when the event was triggered
1242 * @return the data pointer
1243 * @ingroup Ecore_IMF_Context_Group
1244 * @since 1.2.0
1245 */
1246EAPI void *
1247ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func)
1248{
1249 Eina_List *l = NULL;
1250 Eina_List *l_next = NULL;
1251 Ecore_IMF_Func_Node *fn = NULL;
1252
1253 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1254 {
1255 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1256 "ecore_imf_context_event_callback_del");
1257 return NULL;
1258 }
1259
1260 if (!func) return NULL;
1261 if (!ctx->callbacks) return NULL;
1262
1263 EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn)
1264 {
1265 if ((fn) && (fn->func == func) && (fn->type == type))
1266 {
1267 void *tmp = (void *)fn->data;
1268 free(fn);
1269 ctx->callbacks = eina_list_remove_list(ctx->callbacks, l);
1270 return tmp;
1271 }
1272 }
1273 return NULL;
1274}
1275
1276/**
1277 * Call a given callback on the context @p ctx.
1278 *
1279 * ecore_imf_context_preedit_start_event_add, ecore_imf_context_preedit_end_event_add,
1280 * ecore_imf_context_preedit_changed_event_add, ecore_imf_context_commit_event_add and
1281 * ecore_imf_context_delete_surrounding_event_add APIs are asynchronous
1282 * because those API adds each event to the event queue.
1283 *
1284 * This API provides the way to call each callback function immediately.
1285 *
1286 * @param ctx Ecore_IMF_Context.
1287 * @param type The type of event that will trigger the callback
1288 * @param event_info The pointer to event specific struct or information to
1289 * pass to the callback functions registered on this event
1290 * @ingroup Ecore_IMF_Context_Module_Group
1291 * @since 1.2.0
1292 */
1293EAPI void
1294ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info)
1295{
1296 Ecore_IMF_Func_Node *fn = NULL;
1297 Eina_List *l = NULL;
1298
1299 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1300 {
1301 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1302 "ecore_imf_context_event_callback_call");
1303 return;
1304 }
1305
1306 EINA_LIST_FOREACH(ctx->callbacks, l, fn)
1307 {
1308 if ((fn) && (fn->type == type) && (fn->func))
1309 fn->func(fn->data, ctx, event_info);
1310 }
1311}
1312
1313/**
1314 * Ask the Input Method Context to show the control panel of using Input Method.
1315 *
1316 * @param ctx An #Ecore_IMF_Context.
1317 * @ingroup Ecore_IMF_Context_Group
1318 * @since 1.1.0
1319 */
1320EAPI void
1321ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx)
1322{
1323 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1324 {
1325 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1326 "ecore_imf_context_control_panel_show");
1327 return;
1328 }
1329
1330 if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx);
1331}
1332
1333/**
1334 * Ask the Input Method Context to hide the control panel of using Input Method.
1335 *
1336 * @param ctx An #Ecore_IMF_Context.
1337 * @ingroup Ecore_IMF_Context_Group
1338 * @since 1.1.0
1339 */
1340EAPI void
1341ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx)
1342{
1343 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1344 {
1345 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1346 "ecore_imf_context_control_panel_hide");
1347 return;
1348 }
1349
1350 if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx);
1351}
1352
1353/**
1354 * Ask the Input Method Context to show the input panel (virtual keyboard).
1355 *
1356 * @param ctx An #Ecore_IMF_Context.
1357 * @ingroup Ecore_IMF_Context_Group
1358 * @since 1.1.0
1359 */
1360EAPI void
1361ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
1362{
1363 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1364 {
1365 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1366 "ecore_imf_context_input_panel_show");
1367 return;
1368 }
1369
1370 if (ctx->klass->show) ctx->klass->show(ctx);
1371}
1372
1373/**
1374 * Ask the Input Method Context to hide the input panel.
1375 *
1376 * @param ctx An #Ecore_IMF_Context.
1377 * @ingroup Ecore_IMF_Context_Group
1378 * @since 1.1.0
1379 */
1380EAPI void
1381ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
1382{
1383 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1384 {
1385 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1386 "ecore_imf_context_input_panel_hide");
1387 return;
1388 }
1389
1390 if (ctx->klass->hide) ctx->klass->hide(ctx);
1391}
1392
1393/**
1394 * Set the layout of the input panel.
1395 *
1396 * @param ctx An #Ecore_IMF_Context.
1397 * @param layout see #Ecore_IMF_Input_Panel_Layout
1398 * @ingroup Ecore_IMF_Context_Group
1399 * @since 1.1.0
1400 */
1401EAPI void
1402ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout)
1403{
1404 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1405 {
1406 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1407 "ecore_imf_context_input_panel_layout_set");
1408 return;
1409 }
1410
1411 if (ctx->klass->input_panel_layout_set)
1412 ctx->klass->input_panel_layout_set(ctx, layout);
1413
1414 ctx->input_panel_layout = layout;
1415}
1416
1417/**
1418 * Get the layout of the current active input panel.
1419 *
1420 * @param ctx An #Ecore_IMF_Context.
1421 * @return layout see #Ecore_IMF_Input_Panel_Layout
1422 * @ingroup Ecore_IMF_Context_Group
1423 * @since 1.1.0
1424 */
1425EAPI Ecore_IMF_Input_Panel_Layout
1426ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
1427{
1428 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1429 {
1430 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1431 "ecore_imf_context_input_panel_layout_get");
1432 return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
1433 }
1434
1435 if (ctx->klass->input_panel_layout_get)
1436 return ctx->input_panel_layout;
1437 else
1438 return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
1439}
1440
1441/**
1442 * Set the language of the input panel.
1443 * This API can be used when you want to show the English keyboard.
1444 *
1445 * @param ctx An #Ecore_IMF_Context.
1446 * @param lang the language to be set to the input panel.
1447 * @ingroup Ecore_IMF_Context_Group
1448 * @since 1.1.0
1449 */
1450EAPI void
1451ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang)
1452{
1453 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1454 {
1455 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1456 "ecore_imf_context_input_panel_language_set");
1457 return;
1458 }
1459
1460 if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang);
1461 ctx->input_panel_lang = lang;
1462}
1463
1464/**
1465 * Get the language of the input panel.
1466 *
1467 * See @ref ecore_imf_context_input_panel_language_set for more details.
1468 *
1469 * @param ctx An #Ecore_IMF_Context.
1470 * @return Ecore_IMF_Input_Panel_Lang
1471 * @ingroup Ecore_IMF_Context_Group
1472 * @since 1.1.0
1473 */
1474EAPI Ecore_IMF_Input_Panel_Lang
1475ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx)
1476{
1477 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1478 {
1479 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1480 "ecore_imf_context_input_panel_language_get");
1481 return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
1482 }
1483
1484 return ctx->input_panel_lang;
1485}
1486
1487/**
1488 * Set whether the Input Method Context should request to show the input panel automatically
1489 * when the widget has focus.
1490 *
1491 * @param ctx An #Ecore_IMF_Context.
1492 * @param enabled If true, the input panel will be shown when the widget is clicked or has focus.
1493 * @ingroup Ecore_IMF_Context_Group
1494 * @since 1.1.0
1495 */
1496EAPI void
1497ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx,
1498 Eina_Bool enabled)
1499{
1500 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1501 {
1502 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1503 "ecore_imf_context_input_panel_enabled_set");
1504 return;
1505 }
1506
1507 ctx->input_panel_enabled = enabled;
1508}
1509
1510/**
1511 * Get whether the Input Method Context requests to show the input panel automatically.
1512 *
1513 * @param ctx An #Ecore_IMF_Context.
1514 * @return Return the attribute to show the input panel automatically
1515 * @ingroup Ecore_IMF_Context_Group
1516 * @since 1.1.0
1517 */
1518EAPI Eina_Bool
1519ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx)
1520{
1521 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1522 {
1523 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1524 "ecore_imf_context_input_panel_enabled_get");
1525 return EINA_FALSE;
1526 }
1527
1528 return ctx->input_panel_enabled;
1529}
1530
1531/**
1532 * Set the input panel-specific data to deliver to the input panel.
1533 * This API is used by applications to deliver specific data to the input panel.
1534 * The data format MUST be negotiated by both application and the input panel.
1535 * The size and format of data are defined by the input panel.
1536 *
1537 * @param ctx An #Ecore_IMF_Context.
1538 * @param data The specific data to be set to the input panel.
1539 * @param len the length of data, in bytes, to send to the input panel
1540 * @ingroup Ecore_IMF_Context_Group
1541 * @since 1.2.0
1542 */
1543EAPI void
1544ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len)
1545{
1546 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1547 {
1548 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1549 "ecore_imf_context_input_panel_imdata_set");
1550 return;
1551 }
1552
1553 if (!data) return;
1554
1555 if (ctx->klass->input_panel_imdata_set)
1556 ctx->klass->input_panel_imdata_set(ctx, data, len);
1557}
1558
1559/**
1560 * Get the specific data of the current active input panel.
1561 *
1562 * @param ctx An #Ecore_IMF_Context.
1563 * @param data The specific data to be got from the input panel
1564 * @param len The length of data
1565 * @ingroup Ecore_IMF_Context_Group
1566 * @since 1.2.0
1567 */
1568EAPI void
1569ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len)
1570{
1571 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1572 {
1573 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1574 "ecore_imf_context_input_panel_imdata_get");
1575 return;
1576 }
1577
1578 if (!data) return;
1579
1580 if (ctx->klass->input_panel_imdata_get)
1581 ctx->klass->input_panel_imdata_get(ctx, data, len);
1582}
1583
1584/**
1585 * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel.
1586 *
1587 * An input panel displays the string or icon associated with this type
1588 *
1589 * @param ctx An #Ecore_IMF_Context.
1590 * @param return_key_type The type of "return" key on the input panel
1591 * @ingroup Ecore_IMF_Context_Group
1592 * @since 1.2.0
1593 */
1594EAPI void
1595ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
1596{
1597 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1598 {
1599 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1600 "ecore_imf_context_input_panel_return_key_type_set");
1601 return;
1602 }
1603
1604 ctx->input_panel_return_key_type = return_key_type;
1605 if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type);
1606}
1607
1608/**
1609 * Get the "return" key type.
1610 *
1611 * @see ecore_imf_context_input_panel_return_key_type_set() for more details
1612 *
1613 * @param ctx An #Ecore_IMF_Context.
1614 * @return The type of "return" key on the input panel
1615 * @ingroup Ecore_IMF_Context_Group
1616 * @since 1.2.0
1617 */
1618EAPI Ecore_IMF_Input_Panel_Return_Key_Type
1619ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx)
1620{
1621 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1622 {
1623 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1624 "ecore_imf_context_input_panel_return_key_type_get");
1625 return EINA_FALSE;
1626 }
1627
1628 return ctx->input_panel_return_key_type;
1629}
1630
1631/**
1632 * Set the return key on the input panel to be disabled.
1633 *
1634 * @param ctx An #Ecore_IMF_Context.
1635 * @param disabled The state
1636 * @ingroup Ecore_IMF_Context_Group
1637 * @since 1.2.0
1638 */
1639EAPI void
1640ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled)
1641{
1642 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1643 {
1644 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1645 "ecore_imf_context_input_panel_return_key_disabled_set");
1646 return;
1647 }
1648
1649 ctx->input_panel_return_key_disabled = disabled;
1650 if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled);
1651}
1652
1653/**
1654 * Get whether the return key on the input panel should be disabled or not.
1655 *
1656 * @param ctx An #Ecore_IMF_Context.
1657 * @return EINA_TRUE if it should be disabled
1658 * @ingroup Ecore_IMF_Context_Group
1659 * @since 1.2.0
1660 */
1661EAPI Eina_Bool
1662ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx)
1663{
1664 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1665 {
1666 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1667 "ecore_imf_context_input_panel_return_key_disabled_get");
1668 return EINA_FALSE;
1669 }
1670
1671 return ctx->input_panel_return_key_disabled;
1672}
1673
1674/**
1675 * Set the caps lock mode on the input panel.
1676 *
1677 * @param ctx An #Ecore_IMF_Context.
1678 * @param mode Turn on caps lock on the input panel if EINA_TRUE
1679 * @ingroup Ecore_IMF_Context_Group
1680 * @since 1.2.0
1681 */
1682EAPI void
1683ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode)
1684{
1685 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1686 {
1687 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1688 "ecore_imf_context_input_panel_caps_lock_mode_set");
1689 return;
1690 }
1691
1692 if (ctx->klass->input_panel_caps_lock_mode_set)
1693 ctx->klass->input_panel_caps_lock_mode_set(ctx, mode);
1694
1695 ctx->input_panel_caps_lock_mode = mode;
1696}
1697
1698/**
1699 * Get the caps lock mode on the input panel.
1700 *
1701 * @param ctx An #Ecore_IMF_Context.
1702 * @return EINA_TRUE if the caps lock is turned on.
1703 * @ingroup Ecore_IMF_Context_Group
1704 * @since 1.2.0
1705 */
1706EAPI Eina_Bool
1707ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx)
1708{
1709 if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1710 {
1711 ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1712 "ecore_imf_context_input_panel_caps_lock_mode_get");
1713 return EINA_FALSE;
1714 }
1715
1716 return ctx->input_panel_caps_lock_mode;
1717}
1718