From 7722f624e0d29049cd0e6bc444071886b872532c Mon Sep 17 00:00:00 2001 From: raster Date: Thu, 7 Jul 2011 06:23:46 +0000 Subject: [PATCH] From: Jihoon Kim Subject: [E-devel] [PATCH] add ecore_imf_context_cursor_location_set API In this patch, it will add ecore_imf_context_cursor_location_set API in Ecore_IMF. The cursor location can be used to determine the position of candidate word window in immodule. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@61105 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- ChangeLog | 4 ++ src/lib/ecore/ecore_pipe.c | 87 +++++++++++++++++++++++++++++------ src/lib/ecore_imf/Ecore_IMF.h | 2 + src/lib/ecore_imf/ecore_imf_context.c | 23 +++++++++ 4 files changed, 102 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 483c9d7..0b152c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -256,3 +256,7 @@ * Fix epoll delete fd handling in child process - #796 +2011-07-07 Jihoon Kim + + * Ecore_IMF: Added ecore_imf_context_cursor_location_set API + diff --git a/src/lib/ecore/ecore_pipe.c b/src/lib/ecore/ecore_pipe.c index ab6ce57..ab0f55b 100644 --- a/src/lib/ecore/ecore_pipe.c +++ b/src/lib/ecore/ecore_pipe.c @@ -482,13 +482,9 @@ _ecore_pipe_unhandle(Ecore_Pipe *p) static Eina_Bool _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) { - Ecore_Pipe *p; - double start_time; + Ecore_Pipe *p = (Ecore_Pipe *)data; int i; - p = (Ecore_Pipe *)data; - start_time = ecore_time_get(); - p->handling++; for (i = 0; i < 16; i++) { @@ -503,20 +499,28 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) ret = pipe_read(p->fd_read, &p->len, sizeof(p->len)); /* catch the non error case first */ + /* read amount ok - nothing more to do */ if (ret == sizeof(p->len)) ; else if (ret > 0) { - /* XXX What should we do here? */ - ERR("Only read %zd bytes from the pipe, although" - " we need to read %zd bytes.", ret, sizeof(p->len)); + /* we got more data than we asked for - definite error */ + ERR("Only read %i bytes from the pipe, although" + " we need to read %i bytes.", + (int)ret, (int)sizeof(p->len)); _ecore_pipe_unhandle(p); return ECORE_CALLBACK_CANCEL; } else if (ret == 0) { + /* we got no data even though we had data to read */ if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + p->handler((void *)p->data, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; pipe_close(p->fd_read); p->fd_read = PIPE_FD_INVALID; p->fd_handler = NULL; @@ -532,9 +536,9 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) } else { - ERR("An unhandled error (ret: %zd errno: %d [%s])" + ERR("An unhandled error (ret: %i errno: %i [%s])" "occurred while reading from the pipe the length", - ret, errno, strerror(errno)); + (int)ret, errno, strerror(errno)); _ecore_pipe_unhandle(p); return ECORE_CALLBACK_RENEW; } @@ -545,6 +549,11 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) { if (!p->delete_me) p->handler((void *)p->data, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; pipe_close(p->fd_read); p->fd_read = PIPE_FD_INVALID; p->fd_handler = NULL; @@ -555,8 +564,42 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) #endif } + /* if somehow we got less than or equal to 0 we got an errnoneous + * messages so call callback with null and len we got */ + if (p->len <= 0) + { + if (!p->delete_me) + p->handler((void *)p->data, NULL, p->len); + /* reset all values to 0 */ + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } + + /* we dont have a buffer to hold the data, so alloc it */ if (!p->passed_data) - p->passed_data = malloc(p->len); + { + p->passed_data = malloc(p->len); + /* alloc failed - error case */ + if (!p->passed_data) + { + if (!p->delete_me) + p->handler((void *)p->data, NULL, 0); + /* close the pipe */ + p->already_read = 0; + p->len = 0; + p->message++; + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + p->fd_handler = NULL; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + } /* and read the passed data */ ret = pipe_read(p->fd_read, @@ -564,6 +607,7 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) p->len - p->already_read); /* catch the non error case first */ + /* if we read enough data to finish the message/buffer */ if (ret == (ssize_t)(p->len - p->already_read)) { if (!p->delete_me) @@ -575,16 +619,23 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) p->len = 0; p->message++; } - else if (ret >= 0) + else if (ret > 0) { + /* more data left to read */ p->already_read += ret; _ecore_pipe_unhandle(p); return ECORE_CALLBACK_RENEW; } else if (ret == 0) { + /* 0 bytes available when woken up to handle read - error */ if (!p->delete_me) p->handler((void *)p->data, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; pipe_close(p->fd_read); p->fd_read = PIPE_FD_INVALID; p->fd_handler = NULL; @@ -594,7 +645,10 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) #ifndef _WIN32 else if ((ret == PIPE_FD_ERROR) && ((errno == EINTR) || (errno == EAGAIN))) - return ECORE_CALLBACK_RENEW; + { + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } else { ERR("An unhandled error (ret: %zd errno: %d)" @@ -610,6 +664,11 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) { if (!p->delete_me) p->handler((void *)p->data, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; pipe_close(p->fd_read); p->fd_read = PIPE_FD_INVALID; p->fd_handler = NULL; diff --git a/src/lib/ecore_imf/Ecore_IMF.h b/src/lib/ecore_imf/Ecore_IMF.h index 7afee2c..21df2a0 100644 --- a/src/lib/ecore_imf/Ecore_IMF.h +++ b/src/lib/ecore_imf/Ecore_IMF.h @@ -330,6 +330,7 @@ struct _Ecore_IMF_Context_Class Ecore_IMF_Input_Panel_Layout (*input_panel_layout_get) (Ecore_IMF_Context *ctx); void (*input_panel_language_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); Ecore_IMF_Input_Panel_Lang (*input_panel_language_get) (Ecore_IMF_Context *ctx); + void (*cursor_location_set) (Ecore_IMF_Context *ctx, int x, int y, int w, int h); }; struct _Ecore_IMF_Context_Info @@ -367,6 +368,7 @@ EAPI void ecore_imf_context_focus_in(Ecore_IMF_Context 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_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h); EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit); EAPI void ecore_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); EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); diff --git a/src/lib/ecore_imf/ecore_imf_context.c b/src/lib/ecore_imf/ecore_imf_context.c index 382bf6a..c1ecd1e 100644 --- a/src/lib/ecore_imf/ecore_imf_context.c +++ b/src/lib/ecore_imf/ecore_imf_context.c @@ -504,6 +504,29 @@ ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) } /** + * Notify the Input Method Context that a change in the cursor + * location has been made. The location is relative to the canvas. + * + * @param ctx An #Ecore_IMF_Context. + * @param x cursor x position. + * @param x cursor y position. + * @param w cursor width. + * @param h cursor height. + * @ingroup Ecore_IMF_Context_Group + */ +EAPI void +ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) +{ + 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_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h); +} + +/** * Set whether the IM context should use the preedit string * to display feedback. If @use_preedit is EINA_FALSE (default * is EINA_TRUE), then the IM context may use some other method to display -- 2.7.4