diff --git a/legacy/ecore/Makefile.am b/legacy/ecore/Makefile.am index ba50633e98..5f1168e45e 100644 --- a/legacy/ecore/Makefile.am +++ b/legacy/ecore/Makefile.am @@ -16,6 +16,7 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ ecore-evas.pc \ ecore-fb.pc \ ecore-file.pc \ + ecore-imf.pc \ ecore-ipc.pc \ ecore-job.pc \ ecore-txt.pc \ @@ -36,6 +37,7 @@ EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN ecore.c.in gendoc ecore.supp \ ecore-evas.pc.in \ ecore-fb.pc.in \ ecore-file.pc.in \ + ecore-imf.pc.in \ ecore-ipc.pc.in \ ecore-job.pc.in \ ecore-txt.pc.in \ @@ -73,6 +75,10 @@ if BUILD_ECORE_DESKTOP pdesktop = ecore-desktop.pc endif +if BUILD_ECORE_IMF +pimf = ecore-imf.pc +endif + if BUILD_ECORE_IPC pipc = ecore-ipc.pc endif @@ -105,5 +111,5 @@ endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = \ ecore.pc $(pcon) $(pconfig) $(pdfb) $(pevas) \ - $(pfb) $(pfile) $(pdesktop) $(pipc) $(pjob) $(ptxt) \ + $(pfb) $(pfile) $(pdesktop) $(pimf) $(pipc) $(pjob) $(ptxt) \ $(px) $(pwin32) $(psdl) diff --git a/legacy/ecore/configure.in b/legacy/ecore/configure.in index 613c8200e0..0c6d9b18a6 100644 --- a/legacy/ecore/configure.in +++ b/legacy/ecore/configure.in @@ -704,6 +704,9 @@ dnl ecore_desktop ECORE_CHECK_MODULE([Desktop], [no], [$have_ecore_file], [requirements_ecore_desktop="ecore-file"]) +dnl ecore_imf +ECORE_CHECK_MODULE([IMF], [yes], [$have_evas]) + dnl requirements AC_SUBST(requirements_ecore_con) AC_SUBST(requirements_ecore_config) @@ -738,6 +741,7 @@ ecore-directfb.pc ecore-evas.pc ecore-fb.pc ecore-file.pc +ecore-imf.pc ecore-ipc.pc ecore-job.pc ecore-txt.pc @@ -755,6 +759,7 @@ src/lib/ecore_fb/Makefile src/lib/ecore_sdl/Makefile src/lib/ecore_evas/Makefile src/lib/ecore_con/Makefile +src/lib/ecore_imf/Makefile src/lib/ecore_ipc/Makefile src/lib/ecore_txt/Makefile src/lib/ecore_config/Makefile @@ -799,6 +804,8 @@ echo " Ecore_Evas Buffer Support....: $have_ecore_evas_buffer" echo " Ecore_File...................: $have_ecore_file (Inotify: $have_inotify) (Poll: $have_poll) (CURL: $have_curl)" echo " Ecore_Desktop................: $have_ecore_desktop" + +echo " Ecore_IMF....................: $have_ecore_imf" echo echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE." echo diff --git a/legacy/ecore/ecore-imf.pc.in b/legacy/ecore/ecore-imf.pc.in new file mode 100644 index 0000000000..83c8b35a66 --- /dev/null +++ b/legacy/ecore/ecore-imf.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-imf +Description: E core library, IMF module +Requires: ecore evas +Version: @VERSION@ +Libs: -L${libdir} -lecore_imf +Cflags: -I${includedir} diff --git a/legacy/ecore/src/lib/Makefile.am b/legacy/ecore/src/lib/Makefile.am index 67273cb508..e63ccdec25 100644 --- a/legacy/ecore/src/lib/Makefile.am +++ b/legacy/ecore/src/lib/Makefile.am @@ -13,4 +13,5 @@ ecore_ipc \ ecore_evas \ ecore_config \ ecore_file \ -ecore_desktop +ecore_desktop \ +ecore_imf diff --git a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h b/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h index f7a2ee94c3..c252b5bd83 100644 --- a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h +++ b/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h @@ -232,6 +232,7 @@ EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, int sticky); EAPI int ecore_evas_sticky_get(Ecore_Evas *ee); EAPI void ecore_evas_ignore_events_set(Ecore_Evas *ee, int ignore); EAPI int ecore_evas_ignore_events_get(Ecore_Evas *ee); +EAPI void *ecore_evas_window_get(Ecore_Evas *ee); #ifdef __cplusplus } diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas.c index a257a32460..5a22e6f9ef 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas.c @@ -1773,6 +1773,20 @@ ecore_evas_ignore_events_get(Ecore_Evas *ee) return ee->ignore_events ? 1 : 0; } +EAPI void * +ecore_evas_window_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_window_get"); + return NULL; + } + + if (ee->engine.func->fn_window_get) return ee->engine.func->fn_window_get(ee); + return NULL; +} + #ifndef _WIN32 /* fps debug calls - for debugging how much time your app actually spends */ /* rendering graphics... :) */ diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c index e318d3565c..ad51f87639 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c @@ -425,6 +425,7 @@ static const Ecore_Evas_Engine_Func _ecore_buffer_engine_func = NULL, NULL, NULL, + NULL, NULL }; #endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c index 0da74d3660..29e106f122 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c @@ -497,8 +497,19 @@ _ecore_evas_directfb_fullscreen_set(Ecore_Evas *ee, int on) if(ee->func.fn_resize) ee->func.fn_resize(ee); } } +#endif +static void * +_ecore_evas_directfb_window_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_DIRECTFB + return ee->engine.directfb.window; +#else + return 0; +#endif +} +#ifdef BUILD_ECORE_EVAS_DIRECTFB static const Ecore_Evas_Engine_Func _ecore_directfb_engine_func = { _ecore_evas_directfb_free, /* free an ecore_evas */ @@ -544,7 +555,8 @@ static const Ecore_Evas_Engine_Func _ecore_directfb_engine_func = NULL, /* withdrawn */ NULL, /* sticky */ NULL, /* ignore events */ - NULL /* alpha */ + NULL, /* alpha */ + _ecore_evas_directfb_window_get /* window_get */ }; #endif @@ -554,15 +566,9 @@ static const Ecore_Evas_Engine_Func _ecore_directfb_engine_func = Ecore_DirectFB_Window * ecore_evas_directfb_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_DIRECTFB - return ee->engine.directfb.window; -#else - ee = NULL; - return NULL; -#endif + return (Ecore_DirectFB_Window *) _ecore_evas_directfb_window_get(ee); } - EAPI Ecore_Evas * ecore_evas_directfb_new(const char *disp_name, int windowed, int x, int y, int w, int h) { diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c index ec4c8d0919..bb2494d691 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c @@ -557,6 +557,7 @@ static const Ecore_Evas_Engine_Func _ecore_fb_engine_func = _ecore_evas_fullscreen_set, NULL, NULL, + NULL, NULL }; #endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h b/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h index f27a635092..969a6dcf1d 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h @@ -124,6 +124,7 @@ struct _Ecore_Evas_Engine_Func void (*fn_sticky_set) (Ecore_Evas *ee, int sticky); void (*fn_ignore_events_set) (Ecore_Evas *ee, int ignore); void (*fn_alpha_set) (Ecore_Evas *ee, int alpha); + void *(*fn_window_get) (Ecore_Evas *ee); }; struct _Ecore_Evas_Engine diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c index 5ac347bfa5..3174a0d64e 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c @@ -419,6 +419,7 @@ static const Ecore_Evas_Engine_Func _ecore_sdl_engine_func = NULL, NULL, NULL, + NULL, NULL }; #endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c index 2a8db64bdd..fdce2684bf 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c @@ -874,8 +874,19 @@ _ecore_evas_win32_fullscreen_set(Ecore_Evas *ee, int on) /* else */ /* _ecore_evas_win32_state_update(ee); */ } +#endif +static void * +_ecore_evas_win32_window_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_WIN32 + return ee->engine.win32.window; +#else + return NULL; +#endif /* BUILD_ECORE_WIN32 */ +} +#ifdef BUILD_ECORE_WIN32 static const Ecore_Evas_Engine_Func _ecore_win32_engine_func = { _ecore_evas_win32_free, @@ -921,7 +932,8 @@ static const Ecore_Evas_Engine_Func _ecore_win32_engine_func = NULL, /* _ecore_evas_x_withdrawn_set */ NULL, /* _ecore_evas_x_sticky_set */ NULL, /* _ecore_evas_x_ignore_events_set */ - NULL /* _ecore_evas_x_alpha_set */ + NULL, /* _ecore_evas_x_alpha_set */ + _ecore_evas_win32_window_get }; #endif /* BUILD_ECORE_WIN32 */ @@ -1037,11 +1049,7 @@ ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent, EAPI Ecore_Win32_Window * ecore_evas_software_ddraw_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_WIN32 - return ee->engine.win32.window; -#else - return NULL; -#endif /* BUILD_ECORE_WIN32 */ + return (Ecore_Win32_Window *) _ecore_evas_win32_window_get(ee); } EAPI Ecore_Evas * @@ -1154,9 +1162,5 @@ ecore_evas_direct3d_new(Ecore_Win32_Window *parent, EAPI Ecore_Win32_Window * ecore_evas_direct3d_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_WIN32 - return ee->engine.win32.window; -#else - return NULL; -#endif /* BUILD_ECORE_WIN32 */ + return (Ecore_Win32_Window *) _ecore_evas_win32_window_get(ee); } diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c index 8d5c5262ef..f161c23d8b 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c @@ -2026,6 +2026,16 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) } } +static void * +_ecore_evas_x_window_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + return (void *) ee->engine.x.win; +#else + return 0; +#endif +} + static void _ecore_evas_x_show(Ecore_Evas *ee) { @@ -2544,7 +2554,8 @@ static const Ecore_Evas_Engine_Func _ecore_x_engine_func = _ecore_evas_x_withdrawn_set, _ecore_evas_x_sticky_set, _ecore_evas_x_ignore_events_set, - _ecore_evas_x_alpha_set + _ecore_evas_x_alpha_set, + _ecore_evas_x_window_get }; #endif @@ -2819,11 +2830,7 @@ ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, EAPI Ecore_X_Window ecore_evas_software_x11_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -2834,11 +2841,7 @@ ecore_evas_software_x11_window_get(Ecore_Evas *ee) EAPI Ecore_X_Window ecore_evas_software_x11_subwindow_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3012,11 +3015,7 @@ ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, EAPI Ecore_X_Window ecore_evas_gl_x11_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3027,11 +3026,7 @@ ecore_evas_gl_x11_window_get(Ecore_Evas *ee) EAPI Ecore_X_Window ecore_evas_gl_x11_subwindow_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3264,11 +3259,7 @@ ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent, EAPI Ecore_X_Window ecore_evas_xrender_x11_window_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3279,11 +3270,7 @@ ecore_evas_xrender_x11_window_get(Ecore_Evas *ee) EAPI Ecore_X_Window ecore_evas_xrender_x11_subwindow_get(Ecore_Evas *ee) { -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3474,11 +3461,7 @@ ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent, EAPI Ecore_X_Window ecore_evas_software_x11_16_window_get(Ecore_Evas *ee) { -#if BUILD_ECORE_EVAS_X11_16 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** @@ -3489,11 +3472,7 @@ ecore_evas_software_x11_16_window_get(Ecore_Evas *ee) EAPI Ecore_X_Window ecore_evas_software_x11_16_subwindow_get(Ecore_Evas *ee) { -#if BUILD_ECORE_EVAS_X11_16 - return ee->engine.x.win; -#else - return 0; -#endif + return (Ecore_X_Window) _ecore_evas_x_window_get(ee); } /** diff --git a/legacy/ecore/src/lib/ecore_imf/.cvsignore b/legacy/ecore/src/lib/ecore_imf/.cvsignore new file mode 100644 index 0000000000..09980ae6ba --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la diff --git a/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h b/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h new file mode 100644 index 0000000000..e640ef43fc --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h @@ -0,0 +1,162 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef _ECORE_IMF_H +#define _ECORE_IMF_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef _MSC_VER +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _Ecore_IMF_Event_Preedit_Start Ecore_IMF_Event_Preedit_Start; + typedef struct _Ecore_IMF_Event_Preedit_End Ecore_IMF_Event_Preedit_End; + typedef struct _Ecore_IMF_Event_Preedit_Changed Ecore_IMF_Event_Preedit_Changed; + typedef struct _Ecore_IMF_Event_Commit Ecore_IMF_Event_Commit; + typedef struct _Ecore_IMF_Event_Delete_Surrounding Ecore_IMF_Event_Delete_Surrounding; + + typedef struct _Ecore_IMF_Context Ecore_IMF_Context; /**< An Input Method Context */ + typedef struct _Ecore_IMF_Context_Class Ecore_IMF_Context_Class; /**< An Input Method Context class */ + typedef struct _Ecore_IMF_Context_Info Ecore_IMF_Context_Info; /**< An Input Method Context info */ + + EAPI extern int ECORE_IMF_EVENT_PREEDIT_START; + EAPI extern int ECORE_IMF_EVENT_PREEDIT_END; + EAPI extern int ECORE_IMF_EVENT_PREEDIT_CHANGED; + EAPI extern int ECORE_IMF_EVENT_COMMIT; + EAPI extern int ECORE_IMF_EVENT_DELETE_SURROUNDIND; + + typedef enum + { + ECORE_IMF_INPUT_MODE_ALPHA = 1 << 0, + ECORE_IMF_INPUT_MODE_NUMERIC = 1 << 1, + ECORE_IMF_INPUT_MODE_SPECIAL = 1 << 2, + ECORE_IMF_INPUT_MODE_HEXA = 1 << 3, + ECORE_IMF_INPUT_MODE_TELE = 1 << 4, + ECORE_IMF_INPUT_MODE_FULL = (ECORE_IMF_INPUT_MODE_ALPHA | ECORE_IMF_INPUT_MODE_NUMERIC | ECORE_IMF_INPUT_MODE_SPECIAL), + ECORE_IMF_INPUT_MODE_INVISIBLE = 1 << 29, + ECORE_IMF_INPUT_MODE_AUTOCAP = 1 << 30 + } Ecore_IMF_Input_Mode; + + struct _Ecore_IMF_Event_Preedit_Start + { + Ecore_IMF_Context *ctx; + }; + + struct _Ecore_IMF_Event_Preedit_End + { + Ecore_IMF_Context *ctx; + }; + + struct _Ecore_IMF_Event_Preedit_Changed + { + Ecore_IMF_Context *ctx; + }; + + struct _Ecore_IMF_Event_Commit + { + Ecore_IMF_Context *ctx; + char *str; + }; + + struct _Ecore_IMF_Event_Delete_Surrounding + { + Ecore_IMF_Context *ctx; + int offset; + int n_chars; + }; + + struct _Ecore_IMF_Context_Class + { + void (*add) (Ecore_IMF_Context *ctx); + void (*del) (Ecore_IMF_Context *ctx); + void (*client_window_set) (Ecore_IMF_Context *ctx, void *window); + void (*show) (Ecore_IMF_Context *ctx); + void (*hide) (Ecore_IMF_Context *ctx); + void (*preedit_string_get) (Ecore_IMF_Context *ctx, char **str, int *cursor_pos); + void (*focus_in) (Ecore_IMF_Context *ctx); + void (*focus_out) (Ecore_IMF_Context *ctx); + void (*reset) (Ecore_IMF_Context *ctx); + void (*cursor_position_set) (Ecore_IMF_Context *ctx, int cursor_pos); + void (*use_preedit_set) (Ecore_IMF_Context *ctx, int use_preedit); + void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); + int (*filter_event) (Ecore_IMF_Context *ctx, Evas_Callback_Type type, void *event_info); + }; + + struct _Ecore_IMF_Context_Info + { + const char *id; /* ID */ + const char *description; /* Human readable description */ + const char *default_locales; /* Languages for which this context is the default, separated by : */ + }; + + EAPI int ecore_imf_init(void); + EAPI int ecore_imf_shutdown(void); + + EAPI Ecore_List *ecore_imf_context_available_ids_get(void); + EAPI const char *ecore_imf_context_default_id_get(void); + EAPI const Ecore_IMF_Context_Info *ecore_imf_context_info_by_id_get(const char *id); + + EAPI Ecore_IMF_Context *ecore_imf_context_add(const char *id); + EAPI void ecore_imf_context_del(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window); + EAPI void ecore_imf_context_show(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_hide(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos); + EAPI void ecore_imf_context_focus_in(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_focus_out(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_reset(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos); + EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, int use_preedit); + EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, int (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data); + EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); + EAPI Ecore_IMF_Input_Mode ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx); + EAPI int ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Evas_Callback_Type type, void *event_info); + + /* plugin specific functions */ + EAPI Ecore_IMF_Context *ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc); + EAPI void ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data); + EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx); + EAPI int ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos); + EAPI void ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx); + EAPI void ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str); + EAPI void ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars); + + /* The following entry points must be exported by each input method module + */ + + /* + * int imf_module_init (const Ecore_IMF_Context_Info **info); + * void imf_module_exit (void); + * Ecore_IMF_Context *imf_module_create (void); + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/legacy/ecore/src/lib/ecore_imf/Makefile.am b/legacy/ecore/src/lib/ecore_imf/Makefile.am new file mode 100644 index 0000000000..f363d2ae01 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/Makefile.am @@ -0,0 +1,31 @@ +MAINTAINERCLEANFILES = Makefile.in + +if BUILD_ECORE_IMF +AM_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/ecore \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +@EVAS_CFLAGS@ + +lib_LTLIBRARIES = libecore_imf.la +include_HEADERS = \ +Ecore_IMF.h + +libecore_imf_la_SOURCES = \ +ecore_imf.c \ +ecore_imf_context.c \ +ecore_imf_module.c \ +ecore_imf_private.h + +libecore_imf_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +@EVAS_LIBS@ + +libecore_imf_la_LDFLAGS = -version-info @version_info@ +endif + +EXTRA_DIST = \ +Ecore_IMF.h \ +ecore_imf.c \ +ecore_imf_context.c \ +ecore_imf_module.c \ +ecore_imf_private.h diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf.c new file mode 100644 index 0000000000..acf7e8d693 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf.c @@ -0,0 +1,64 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#include "config.h" + +#include "Ecore_IMF.h" + +EAPI int ECORE_IMF_EVENT_PREEDIT_START = 0; +EAPI int ECORE_IMF_EVENT_PREEDIT_END = 0; +EAPI int ECORE_IMF_EVENT_PREEDIT_CHANGED = 0; +EAPI int ECORE_IMF_EVENT_COMMIT = 0; +EAPI int ECORE_IMF_EVENT_RETRIEVE_SURROUNDIND = 0; +EAPI int ECORE_IMF_EVENT_DELETE_SURROUNDIND = 0; + +static int init_count = 0; + +/** + * @defgroup Ecore_IMF_Lib_Group Ecore Input Method Library Functions + * + * Utility functions that set up and shut down the Ecore Input Method + * library. + */ + +/** + * Initialises the Ecore_IMF library. + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_IMF_Lib_Group + */ +EAPI int +ecore_imf_init(void) +{ + if (++init_count != 1) return init_count; + + ecore_init(); + ecore_imf_module_init(); + + ECORE_IMF_EVENT_PREEDIT_START = ecore_event_type_new(); + ECORE_IMF_EVENT_PREEDIT_END = ecore_event_type_new(); + ECORE_IMF_EVENT_PREEDIT_CHANGED = ecore_event_type_new(); + ECORE_IMF_EVENT_COMMIT = ecore_event_type_new(); + ECORE_IMF_EVENT_RETRIEVE_SURROUNDIND = ecore_event_type_new(); + ECORE_IMF_EVENT_DELETE_SURROUNDIND = ecore_event_type_new(); + + return init_count; +} + +/** + * Shuts down the Ecore_IMF library. + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_IMF_Lib_Group + */ +EAPI int +ecore_imf_shutdown(void) +{ + if (--init_count != 0) return init_count; + + ecore_shutdown(); + ecore_imf_module_shutdown(); + + return init_count; +} diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c new file mode 100644 index 0000000000..11fbcb4f1e --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c @@ -0,0 +1,740 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#include +#include + +#include "config.h" + +#include "Ecore_IMF.h" +#include "ecore_imf_private.h" + +/** + * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions + * + * Functions that operate on Ecore Input Method Context objects. + */ + +/** + * Get the list of the available Input Method Context ids. + * + * Note that the caller is responsible for freeing the Ecore_List + * when finished with it. There is no need to finish the list strings. + * + * @return Return an Ecore_List of strings; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI Ecore_List * +ecore_imf_context_available_ids_get(void) +{ + return ecore_imf_module_context_ids_get(); +} + +/* + * Match @locale against @against. + * + * 'en_US' against 'en_US' => 4 + * 'en_US' against 'en' => 3 + * 'en', 'en_UK' against 'en_US' => 2 + * all locales, against '*' => 1 + */ +static int +_ecore_imf_context_match_locale(const char *locale, const char *against, int against_len) +{ + if (strcmp(against, "*") == 0) + return 1; + + if (strcasecmp(locale, against) == 0) + return 4; + + if (strncasecmp(locale, against, 2) == 0) + return (against_len == 2) ? 3 : 2; + + return 0; +} + +/** + * Get the id of the default Input Method Context. + * The id may to used to create a new instance of an Input Method + * Context object. + * + * @return Return a string containing the id of the default Input + * Method Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI const char * +ecore_imf_context_default_id_get(void) +{ + const char *id; + Ecore_List *modules; + Ecore_IMF_Module *module; + char *locale; + char *tmp; + int best_goodness = 0; + + id = getenv("ECORE_IMF_MODULE"); + if (id && ecore_imf_module_get(id)) return id; + + modules = ecore_imf_module_available_get(); + if (!modules) return NULL; + + locale = setlocale(LC_CTYPE, NULL); + if (!locale) return NULL; + + locale = strdup(locale); + + tmp = strchr(locale, '.'); + if (tmp) *tmp = '\0'; + tmp = strchr(locale, '@'); + if (tmp) *tmp = '\0'; + + id = NULL; + + ecore_list_first_goto(modules); + while ((module = ecore_list_next(modules))) + { + const char *p = module->info->default_locales; + while (p) + { + const char *q = strchr(p, ':'); + int goodness = _ecore_imf_context_match_locale(locale, p, q ? q - p : strlen (p)); + + if (goodness > best_goodness) + { + id = module->info->id; + best_goodness = goodness; + } + + p = q ? q + 1 : NULL; + } + } + ecore_list_destroy(modules); + + free(locale); + return id; +} + +/** + * Retrieve the info for the Input Method Context with @p id. + * + * @param id The Input Method Context id to query for. + * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI const Ecore_IMF_Context_Info * +ecore_imf_context_info_by_id_get(const char *id) +{ + Ecore_IMF_Module *module; + + if (!id) return NULL; + module = ecore_imf_module_get(id); + if (!module) return NULL; + return module->info; +} + +/** + * Create a new Input Method Context defined by the given id. + * + * @param id The Input Method Context id. + * @return A newly allocated Input Method Context; + * on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI Ecore_IMF_Context * +ecore_imf_context_add(const char *id) +{ + Ecore_IMF_Context *ctx; + + if (!id) return NULL; + ctx = ecore_imf_module_context_create(id); + if (!ctx || !ctx->klass) return NULL; + if (ctx->klass->add) ctx->klass->add(ctx); + /* default use_preedit is 1, so let's make sure it's + * set on the immodule */ + ecore_imf_context_use_preedit_set(ctx, 1); + /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's + * set on the immodule */ + ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL); + return ctx; +} + +/** + * Delete the given Input Method Context and free its memory. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_del(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_del"); + return; + } + if (ctx->klass->del) ctx->klass->del(ctx); + ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE); + free(ctx); +} + +/** + * Set the client window for the Input Method Context; this is the + * window returned by ecore_evas_window_get() in which the input appears. + * This window is used in order to correctly position status windows, and may + * also be used for purposes internal to the Input Method Context. + * + * @param ctx An #Ecore_IMF_Context. + * @param window The client window. This may be NULL to indicate + * that the previous client window no longer exists. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_client_window_set"); + return; + } + if (ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window); +} + +/** + * Ask the Input Method Context to show itself. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_show(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_show"); + return; + } + if (ctx->klass->show) ctx->klass->show(ctx); +} + +/** + * Ask the Input Method Context to hide itself. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_hide(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_hide"); + return; + } + if (ctx->klass->hide) ctx->klass->hide(ctx); +} + +/* + * Retrieve the current preedit string and cursor position + * for the Input Method Context. + * + * @param ctx An #Ecore_IMF_Context. + * @param str Location to store the retrieved string. The + * string retrieved must be freed with free(). + * @param cursor_pos Location to store position of cursor (in characters) + * within the preedit string. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_preedit_string_get"); + return; + } + if (ctx->klass->preedit_string_get) + ctx->klass->preedit_string_get(ctx, str, cursor_pos); + else + { + if (str) *str = strdup(""); + if (cursor_pos) *cursor_pos = 0; + } +} + +/** + * Notify the Input Method Context that the widget to which its + * correspond has gained focus. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_focus_in(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_focus_in"); + return; + } + if (ctx->klass->focus_in) ctx->klass->focus_in(ctx); +} + +/** + * Notify the Input Method Context that the widget to which its + * correspond has lost focus. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_focus_out(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_focus_out"); + return; + } + if (ctx->klass->focus_out) ctx->klass->focus_out(ctx); +} + +/** + * Notify the Input Method Context that a change such as a + * change in cursor position has been made. This will typically + * cause the Input Method Context to clear the preedit state. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_reset(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_reset"); + return; + } + if (ctx->klass->reset) ctx->klass->reset(ctx); +} + +/** + * Notify the Input Method Context that a change in the cursor + * position has been made. + * + * @param ctx An #Ecore_IMF_Context. + * @param cursor_pos New cursor position in characters. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_cursor_position_set"); + return; + } + if (ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos); +} + +/** + * Set whether the IM context should use the preedit string + * to display feedback. If @use_preedit is 0 (default + * is 1), then the IM context may use some other method to display + * feedback, such as displaying it in a child of the root window. + * + * @param ctx An #Ecore_IMF_Context. + * @param use_preedit Whether the IM context should use the preedit string. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, int use_preedit) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_use_preedit_set"); + return; + } + if (ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit); +} + +/** + * Set the callback to be used on get_surrounding request. + * + * This callback will be called when the Input Method Context + * module requests the surrounding context. + * + * @param ctx An #Ecore_IMF_Context. + * @param func The callback to be called. + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, int (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_retrieve_surrounding_callback_set"); + return; + } + + ctx->retrieve_surrounding_func = func; + ctx->retrieve_surrounding_data = (void *) data; +} + +/** + * Set the input mode used by the Ecore Input Context. + * + * The input mode can be one of the input modes defined in + * #Ecore_IMF_Input_Mode. The default input mode is + * ECORE_IMF_INPUT_MODE_FULL. + * + * @param ctx An #Ecore_IMF_Context. + * @param input_mode The input mode to be used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_mode_set"); + return; + } + if (ctx->klass->input_mode_set) ctx->klass->input_mode_set(ctx, input_mode); + ctx->input_mode = input_mode; +} + +/** + * Get the input mode being used by the Ecore Input Context. + * + * See @ref ecore_imf_context_input_mode_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return The input mode being used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI Ecore_IMF_Input_Mode +ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_mode_set"); + return 0; + } + return ctx->input_mode; +} + +/** + * Allow an Ecore Input Context to internally handle an event. + * If this function returns 1, then no further processing + * should be done for this event. + * + * Input methods must be able to accept all types of events (simply + * returning 0 if the event was not handled), but there is no + * obligation of any events to be submitted to this function. + * + * @param ctx An #Ecore_IMF_Context. + * @param type The type of event defined in #Evas_Callback_Type + * @param event_info The event itself; This should be one of + * Evas_Event_* types or NULL for some event types as + * EVAS_CALLBACK_SHOW/HIDE for example. + * @return 1 if the event was handled; otherwise 0. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI int +ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Evas_Callback_Type type, void *event_info) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_filter_event"); + return 0; + } + if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event_info); + return 0; +} + +/** + * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions + * + * Functions that should be used by Ecore Input Method Context modules. + */ + +/** + * Creates a new Input Method Context with klass specified by @p ctxc. + * + * This method should be used by modules implementing the Input + * Method Context interface. + * + * @param ctxc An #Ecore_IMF_Context_Class. + * @return A new #Ecore_IMF_Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI Ecore_IMF_Context * +ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc) +{ + Ecore_IMF_Context *ctx; + + if (!ctx) return NULL; + ctx = malloc(sizeof(Ecore_IMF_Context)); + if (!ctx) return NULL; + ECORE_MAGIC_SET(ctx, ECORE_MAGIC_CONTEXT); + ctx->klass = ctxc; + ctx->data = NULL; + ctx->retrieve_surrounding_func = NULL; + ctx->retrieve_surrounding_data = NULL; + return ctx; +} + +/** + * Set the Input Method Context specific data. + * + * Note that this method should be used by modules to set + * the Input Method Context specific data and it's not meant to + * be used by applications to store application specific data. + * + * @param ctx An #Ecore_IMF_Context. + * @param data The Input Method Context specific data. + * @return A new #Ecore_IMF_Context; on failure it returns NULL. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_data_set"); + return; + } + ctx->data = data; +} + +/** + * Get the Input Method Context specific data. + * + * See @ref ecore_imf_context_data_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return The Input Method Context specific data. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_data_get"); + return; + } + return ctx->data; +} + +/** + * Retrieve context around insertion point. + * + * This function is implemented by calling the + * Ecore_IMF_Context::retrieve_surrounding_func ( + * set using #ecore_imf_context_retrieve_surrounding_callback_set). + * + * There is no obligation for a widget to respond to the + * ::retrieve_surrounding_func, so input methods must be prepared + * to function without context. + * + * @param ctx An #Ecore_IMF_Context. + * @param text Location to store a UTF-8 encoded string of text + * holding context around the insertion point. + * If the function returns 1, then you must free + * the result stored in this location with free(). + * @param cursor_pos Location to store the position in characters of + * the insertion cursor within @text. + * @return 1 if surrounding text was provided; otherwise 0. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI int +ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos) +{ + int result = 0; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_surrounding_get"); + return 0; + } + + if (ctx->retrieve_surrounding_func) + { + result = ctx->retrieve_surrounding_func(ctx->retrieve_surrounding_data, ctx, text, cursor_pos); + if (!result) + { + if (text) *text = NULL; + if (cursor_pos) *cursor_pos = 0; + } + } + return result; +} + +static void +_ecore_imf_event_free_preedit(void *data __UNUSED__, void *event) +{ + free(event); +} + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Event_Commit *ev; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_preedit_start_event_add"); + return; + } + + ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Start)); + ev->ctx = ctx; + ecore_event_add(ECORE_IMF_EVENT_PREEDIT_START, + ev, _ecore_imf_event_free_preedit, NULL); +} + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Event_Commit *ev; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_preedit_end_event_add"); + return; + } + + ev = malloc(sizeof(Ecore_IMF_Event_Preedit_End)); + ev->ctx = ctx; + ecore_event_add(ECORE_IMF_EVENT_PREEDIT_END, + ev, _ecore_imf_event_free_preedit, NULL); +} + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Event_Commit *ev; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_preedit_changed_event_add"); + return; + } + + ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Changed)); + ev->ctx = ctx; + ecore_event_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, + ev, _ecore_imf_event_free_preedit, NULL); +} + +static void +_ecore_imf_event_free_commit(void *data __UNUSED__, void *event) +{ + Ecore_IMF_Event_Commit *ev; + + ev = event; + if (ev->str) free(ev->str); + free(ev); +} + +/** + * Adds ECORE_IMF_EVENT_COMMIT to the event queue. + * + * @param ctx An #Ecore_IMF_Context. + * @param str The committed string. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str) +{ + Ecore_IMF_Event_Commit *ev; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_commit_event_add"); + return; + } + + ev = malloc(sizeof(Ecore_IMF_Event_Commit)); + ev->ctx = ctx; + ev->str = str ? strdup(str) : NULL; + ecore_event_add(ECORE_IMF_EVENT_COMMIT, + ev, _ecore_imf_event_free_commit, NULL); + +} + +static void +_ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event) +{ + free(event); +} + +/** + * Adds ECORE_IMF_EVENT_DELETE_SURROUNDIND to the event queue. + * + * @param ctx An #Ecore_IMF_Context. + * @param offset The start offset of surrounding to be deleted. + * @param n_chars The number of characters to be deleted. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI void +ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars) +{ + Ecore_IMF_Event_Delete_Surrounding *ev; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_delete_surrounding_event_add"); + return; + } + + ev = malloc(sizeof(Ecore_IMF_Event_Delete_Surrounding)); + ev->ctx = ctx; + ev->offset = offset; + ev->n_chars = n_chars; + ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDIND, + ev, _ecore_imf_event_free_delete_surrounding, NULL); +} diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c new file mode 100644 index 0000000000..739ac7fe77 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c @@ -0,0 +1,207 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#include +#include +#include + +#include "config.h" + +#include "ecore_imf_private.h" + +static void _ecore_imf_module_load_all(void); +static void _ecore_imf_module_append(Ecore_Plugin *plugin, const Ecore_IMF_Context_Info *info, Ecore_IMF_Context *(*imf_module_create)(void)); +static void _ecore_imf_module_free(Ecore_IMF_Module *module); +static int _ecore_imf_modules_exists(const char *ctx_id); + +static Ecore_Path_Group *ecore_imf_modules_path = NULL; +static Ecore_Hash *modules = NULL; + +void +ecore_imf_module_init(void) +{ + char pathname[PATH_MAX]; + const char *homedir; + + ecore_imf_modules_path = ecore_path_group_new(); + snprintf(pathname, sizeof(pathname), "%s/ecore/immodules/", + PACKAGE_LIB_DIR); + ecore_path_group_add(ecore_imf_modules_path, pathname); + + homedir = getenv("HOME"); + if (homedir) + { + snprintf(pathname, sizeof(pathname), "%s/.ecore/immodules/", + homedir); + ecore_path_group_add(ecore_imf_modules_path, pathname); + } + + modules = NULL; + _ecore_imf_module_load_all(); +} + +void +ecore_imf_module_shutdown(void) +{ + if (modules) + { + ecore_hash_destroy(modules); + modules = NULL; + } + + ecore_path_group_del(ecore_imf_modules_path); + ecore_imf_modules_path = NULL; +} + +Ecore_List * +ecore_imf_module_available_get(void) +{ + Ecore_List *values; + unsigned int i = 0; + + if (!modules) return NULL; + + /* ecore_hash_values() */ + values = ecore_list_new(); + while (i < ecore_prime_table[modules->size]) + { + if (modules->buckets[i]) + { + Ecore_Hash_Node *node; + + for (node = modules->buckets[i]; node; node = node->next) + ecore_list_append(values, node->value); + } + i++; + } + ecore_list_first_goto(values); + + return values; +} + +Ecore_IMF_Module * +ecore_imf_module_get(const char *ctx_id) +{ + if (!modules) return NULL; + return ecore_hash_get(modules, ctx_id); +} + +Ecore_IMF_Context * +ecore_imf_module_context_create(const char *ctx_id) +{ + Ecore_IMF_Module *module; + + if (!modules) return NULL; + module = ecore_hash_get(modules, ctx_id); + if (module) return module->create(); + return NULL; +} + +Ecore_List * +ecore_imf_module_context_ids_get(void) +{ + if (!modules) return NULL; + return ecore_hash_keys(modules); +} + +static void +_ecore_imf_module_load_all(void) +{ + Ecore_List *avail; + char *filename; + Ecore_Plugin *plugin; + const Ecore_IMF_Context_Info *info = NULL; + int (*imf_module_init)(const Ecore_IMF_Context_Info **info); + Ecore_IMF_Context *(*imf_module_create)(void); + Ecore_IMF_Module *module; + + avail = ecore_plugin_available_get(ecore_imf_modules_path); + if (!avail) return; + + ecore_list_first_goto(avail); + while (filename = ecore_list_next(avail)) + { + plugin = ecore_plugin_load(ecore_imf_modules_path, filename, NULL); + if (!plugin) + { + fprintf(stderr, "** ecore_imf: Error loading input method plugin %s!\n", + filename); + continue; + } + + imf_module_init = ecore_plugin_symbol_get(plugin, "imf_module_init"); + if (!imf_module_init || !imf_module_init(&info) || !info) + { + fprintf(stderr, "** ecore_imf: Error initializing input method plugin %s! " + "'imf_module_init' is missing or failed to run!", + filename); + ecore_plugin_unload(plugin); + continue; + } + + if (_ecore_imf_modules_exists(info->id)) + { + fprintf(stderr, "** ecore_imf: Error loading input method plugin %s! " + "Plugin with id='%s' already exists!", + info->id); + ecore_plugin_unload(plugin); + continue; + } + + imf_module_create = ecore_plugin_symbol_get(plugin, "imf_module_create"); + if (!imf_module_create) + { + fprintf(stderr, "** ecore_imf: Error setting up input method plugin %s! " + "'imf_module_create' is missing!", + filename); + ecore_plugin_unload(plugin); + continue; + } + + _ecore_imf_module_append(plugin, info, imf_module_create); + } + + ecore_list_destroy(avail); +} + +static void +_ecore_imf_module_append(Ecore_Plugin *plugin, + const Ecore_IMF_Context_Info *info, + Ecore_IMF_Context *(*imf_module_create)(void)) +{ + Ecore_IMF_Module *module; + + if (!modules) + { + modules = ecore_hash_new(ecore_str_hash, ecore_str_compare); + ecore_hash_free_key_cb_set(modules, free); + ecore_hash_free_value_cb_set(modules, (Ecore_Free_Cb) _ecore_imf_module_free); + } + + module = malloc(sizeof(Ecore_IMF_Module)); + module->plugin = plugin; + module->info = info; + /* cache imf_module_create as it may be used several times */ + module->create = imf_module_create; + + ecore_hash_set(modules, strdup(info->id), module); +} + +static void +_ecore_imf_module_free(Ecore_IMF_Module *module) +{ + int (*imf_module_exit)(void); + + imf_module_exit = ecore_plugin_symbol_get(module->plugin, "imf_module_exit"); + if (imf_module_exit) imf_module_exit(); + ecore_plugin_unload(module->plugin); + free(module); +} + +static int +_ecore_imf_modules_exists(const char *ctx_id) +{ + if (!modules) return 0; + return (ecore_hash_get(modules, ctx_id) != NULL); +} diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h b/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h new file mode 100644 index 0000000000..8980172fda --- /dev/null +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h @@ -0,0 +1,36 @@ +#ifndef _ECORE_IMF_PRIVATE_H +#define _ECORE_IMF_PRIVATE_H + +#include "Ecore_IMF.h" + +#include "ecore_private.h" + +#define ECORE_MAGIC_CONTEXT 0x56c1b39a + +typedef struct _Ecore_IMF_Module Ecore_IMF_Module; + +struct _Ecore_IMF_Context +{ + ECORE_MAGIC; + const Ecore_IMF_Context_Class *klass; + void *data; + int input_mode; + int (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); + void *retrieve_surrounding_data; +}; + +struct _Ecore_IMF_Module +{ + Ecore_Plugin *plugin; + const Ecore_IMF_Context_Info *info; + Ecore_IMF_Context *(*create)(void); +}; + +void ecore_imf_module_init(void); +void ecore_imf_module_shutdown(void); +Ecore_List *ecore_imf_module_available_get(void); +Ecore_IMF_Module *ecore_imf_module_get(const char *ctx_id); +Ecore_IMF_Context *ecore_imf_module_context_create(const char *ctx_id); +Ecore_List *ecore_imf_module_context_ids_get(void); + +#endif