summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/keyin.c84
-rw-r--r--src/bin/keyin.h13
-rw-r--r--src/bin/termio.c240
-rw-r--r--src/bin/termio.h6
-rw-r--r--src/bin/termpty.c24
-rw-r--r--src/bin/win.c405
-rw-r--r--src/bin/win.h3
7 files changed, 462 insertions, 313 deletions
diff --git a/src/bin/keyin.c b/src/bin/keyin.c
index 78601af..c5bc7f2 100644
--- a/src/bin/keyin.c
+++ b/src/bin/keyin.c
@@ -102,9 +102,9 @@ keyin_compose_seq_reset(Keys_Handler *khdl)
102 102
103#include "tty_keys.h" 103#include "tty_keys.h"
104 104
105static void 105void
106_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev, 106keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
107 int alt, int shift, int ctrl) 107 const int alt, const int shift, const int ctrl)
108{ 108{
109 if (!ev->key) 109 if (!ev->key)
110 return; 110 return;
@@ -228,92 +228,24 @@ key_binding_lookup(const char *keyname,
228} 228}
229 229
230Eina_Bool 230Eina_Bool
231keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev, 231keyin_handle_key_binding(Evas_Object *termio, const Evas_Event_Key_Down *ev,
232 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift, Eina_Bool win, 232 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift,
233 Eina_Bool meta, Eina_Bool hyper) 233 Eina_Bool win, Eina_Bool meta, Eina_Bool hyper)
234{ 234{
235 235
236 Key_Binding *kb; 236 Key_Binding *kb;
237 kb = key_binding_lookup(ev->keyname, ctrl, alt, shift, win, meta, hyper); 237 kb = key_binding_lookup(ev->keyname, ctrl, alt, shift, win, meta, hyper);
238 if (kb) 238 if (kb)
239 { 239 {
240 if (kb->cb(ty->obj)) 240 if (kb->cb(termio))
241 { 241 {
242 keyin_compose_seq_reset(khdl);
243 return EINA_TRUE; 242 return EINA_TRUE;
244 } 243 }
245 } 244 }
246
247 /* composing */
248 if (khdl->imf)
249 {
250 // EXCEPTION. Don't filter modifiers alt+shift -> breaks emacs
251 // and jed (alt+shift+5 for search/replace for example)
252 // Don't filter modifiers alt, is used by shells
253 if ((!alt) && (!ctrl))
254 {
255 Ecore_IMF_Event_Key_Down imf_ev;
256
257 ecore_imf_evas_event_key_down_wrap((Evas_Event_Key_Down*)ev, &imf_ev);
258 if (!khdl->composing)
259 {
260 if (ecore_imf_context_filter_event
261 (khdl->imf, ECORE_IMF_EVENT_KEY_DOWN, (Ecore_IMF_Event *)&imf_ev))
262 goto end;
263 }
264 }
265 }
266
267 // if term app asked for kbd lock - dont handle here
268 if (ty->termstate.kbd_lock) return EINA_TRUE;
269 // if app asked us to not do autorepeat - ignore press if is it is the same
270 // timestamp as last one
271 if ((ty->termstate.no_autorepeat) &&
272 (ev->timestamp == khdl->last_keyup)) return EINA_TRUE;
273 if (!khdl->composing)
274 {
275 Ecore_Compose_State state;
276 char *compres = NULL;
277
278 keyin_compose_seq_reset(khdl);
279 khdl->seq = eina_list_append(khdl->seq, eina_stringshare_add(ev->key));
280 state = ecore_compose_get(khdl->seq, &compres);
281 if (state == ECORE_COMPOSE_MIDDLE) khdl->composing = EINA_TRUE;
282 else khdl->composing = EINA_FALSE;
283 if (!khdl->composing) keyin_compose_seq_reset(khdl);
284 else goto end;
285 }
286 else
287 {
288 Ecore_Compose_State state;
289 char *compres = NULL;
290
291 if (key_is_modifier(ev->key)) goto end;
292 khdl->seq = eina_list_append(khdl->seq, eina_stringshare_add(ev->key));
293 state = ecore_compose_get(khdl->seq, &compres);
294 if (state == ECORE_COMPOSE_NONE) keyin_compose_seq_reset(khdl);
295 else if (state == ECORE_COMPOSE_DONE)
296 {
297 keyin_compose_seq_reset(khdl);
298 if (compres)
299 {
300 termpty_write(ty, compres, strlen(compres));
301 free(compres);
302 compres = NULL;
303 }
304 goto end;
305 }
306 else goto end;
307 }
308
309
310 _handle_key_to_pty(ty, ev, alt, shift, ctrl);
311
312
313end:
314 return EINA_FALSE; 245 return EINA_FALSE;
315} 246}
316 247
248
317Eina_Bool 249Eina_Bool
318key_is_modifier(const char *key) 250key_is_modifier(const char *key)
319{ 251{
diff --git a/src/bin/keyin.h b/src/bin/keyin.h
index d9127a1..ccfa644 100644
--- a/src/bin/keyin.h
+++ b/src/bin/keyin.h
@@ -11,12 +11,19 @@ struct _Keys_Handler
11 unsigned char composing : 1; 11 unsigned char composing : 1;
12}; 12};
13 13
14void
15keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
16 const int alt, const int shift, const int ctrl);
17Eina_Bool
18termpty_can_handle_key(const Termpty *ty,
19 const Keys_Handler *khdl,
20 const Evas_Event_Key_Down *ev);
14void keyin_compose_seq_reset(Keys_Handler *khdl); 21void keyin_compose_seq_reset(Keys_Handler *khdl);
15Eina_Bool key_is_modifier(const char *key); 22Eina_Bool key_is_modifier(const char *key);
16Eina_Bool 23Eina_Bool
17keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev, 24keyin_handle_key_binding(Evas_Object *termio, const Evas_Event_Key_Down *ev,
18 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift, Eina_Bool win, 25 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift,
19 Eina_Bool meta, Eina_Bool hyper); 26 Eina_Bool win, Eina_Bool meta, Eina_Bool hyper);
20 27
21void keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev); 28void keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev);
22 29
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 01e5227..f7f178e 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -86,12 +86,10 @@ struct _Termio
86 Evas_Object *win, *theme, *glayer; 86 Evas_Object *win, *theme, *glayer;
87 Config *config; 87 Config *config;
88 const char *sel_str; 88 const char *sel_str;
89 const char *preedit_str;
90 Eina_List *cur_chids; 89 Eina_List *cur_chids;
91 Ecore_Job *sel_reset_job; 90 Ecore_Job *sel_reset_job;
92 double set_sel_at; 91 double set_sel_at;
93 Elm_Sel_Type sel_type; 92 Elm_Sel_Type sel_type;
94 Keys_Handler khdl;
95 unsigned char jump_on_change : 1; 93 unsigned char jump_on_change : 1;
96 unsigned char jump_on_keypress : 1; 94 unsigned char jump_on_keypress : 1;
97 unsigned char have_sel : 1; 95 unsigned char have_sel : 1;
@@ -1984,72 +1982,6 @@ _block_obj_del(Termblock *blk)
1984} 1982}
1985 1983
1986/* }}} */ 1984/* }}} */
1987/* {{{ Keys */
1988
1989static void
1990_smart_cb_key_up(void *data,
1991 Evas *_e EINA_UNUSED,
1992 Evas_Object *_obj EINA_UNUSED,
1993 void *event)
1994{
1995 Evas_Event_Key_Up *ev = event;
1996 Termio *sd = evas_object_smart_data_get(data);
1997
1998 EINA_SAFETY_ON_NULL_RETURN(sd);
1999
2000 keyin_handle_up(&sd->khdl, ev);
2001}
2002
2003static void
2004_smart_cb_key_down(void *data,
2005 Evas *_e EINA_UNUSED,
2006 Evas_Object *_obj EINA_UNUSED,
2007 void *event)
2008{
2009 const Evas_Event_Key_Down *ev = event;
2010 Termio *sd = evas_object_smart_data_get(data);
2011 int ctrl, alt, shift, win, meta, hyper;
2012
2013 EINA_SAFETY_ON_NULL_RETURN(sd);
2014 EINA_SAFETY_ON_NULL_RETURN(ev->key);
2015
2016 if (miniview_handle_key(term_miniview_get(sd->term), ev))
2017 return;
2018
2019 if (term_has_popmedia(sd->term) && !strcmp(ev->key, "Escape"))
2020 {
2021 term_popmedia_close(sd->term);
2022 return;
2023 }
2024
2025 ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
2026 alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
2027 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
2028 win = evas_key_modifier_is_set(ev->modifiers, "Super");
2029 meta = evas_key_modifier_is_set(ev->modifiers, "Meta") ||
2030 evas_key_modifier_is_set(ev->modifiers, "AltGr") ||
2031 evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift");
2032 hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper");
2033 ERR("ctrl:%d alt:%d shift:%d win:%d meta:%d hyper:%d",
2034 ctrl, alt, shift, win, meta, hyper);
2035
2036 if (keyin_handle(&sd->khdl, sd->pty, ev, ctrl, alt, shift, win, meta, hyper))
2037 goto end;
2038
2039 if (sd->jump_on_keypress)
2040 {
2041 if (!key_is_modifier(ev->key))
2042 {
2043 sd->scroll = 0;
2044 _smart_update_queue(data, sd);
2045 }
2046 }
2047end:
2048 if (sd->config->flicker_on_key)
2049 edje_object_signal_emit(sd->cursor.obj, "key,down", "terminology");
2050}
2051
2052/* }}} */
2053/* {{{ Selection */ 1985/* {{{ Selection */
2054 1986
2055static Eina_Bool 1987static Eina_Bool
@@ -3496,16 +3428,19 @@ termio_event_feed_mouse_in(Evas_Object *obj)
3496 evas_event_feed_mouse_in(e, 0, NULL); 3428 evas_event_feed_mouse_in(e, 0, NULL);
3497} 3429}
3498 3430
3499static void 3431void
3500_imf_cursor_set(Termio *sd) 3432termio_imf_cursor_set(Evas_Object *obj, Ecore_IMF_Context *imf)
3501{ 3433{
3502 /* TODO */ 3434 Termio *sd = evas_object_smart_data_get(obj);
3503 Evas_Coord cx, cy, cw, ch; 3435 Evas_Coord cx, cy, cw, ch;
3436
3437 if (!imf)
3438 return;
3439
3440 EINA_SAFETY_ON_NULL_RETURN(sd);
3504 evas_object_geometry_get(sd->cursor.obj, &cx, &cy, &cw, &ch); 3441 evas_object_geometry_get(sd->cursor.obj, &cx, &cy, &cw, &ch);
3505 if (sd->khdl.imf) 3442 ecore_imf_context_cursor_location_set(imf, cx, cy, cw, ch);
3506 ecore_imf_context_cursor_location_set(sd->khdl.imf, cx, cy, cw, ch); 3443 ecore_imf_context_cursor_position_set(imf, (sd->cursor.y * sd->grid.w) + sd->cursor.x);
3507 if (sd->khdl.imf) ecore_imf_context_cursor_position_set
3508 (sd->khdl.imf, (sd->cursor.y * sd->grid.w) + sd->cursor.x);
3509 /* 3444 /*
3510 ecore_imf_context_cursor_position_set(sd->imf, 0); // how to get it? 3445 ecore_imf_context_cursor_position_set(sd->imf, 0); // how to get it?
3511 */ 3446 */
@@ -3522,14 +3457,6 @@ termio_focus_in(Evas_Object *termio)
3522 else 3457 else
3523 edje_object_signal_emit(sd->cursor.obj, "focus,in", "terminology"); 3458 edje_object_signal_emit(sd->cursor.obj, "focus,in", "terminology");
3524 if (!sd->win) return; 3459 if (!sd->win) return;
3525 elm_win_keyboard_mode_set(sd->win, ELM_WIN_KEYBOARD_TERMINAL);
3526 if (sd->khdl.imf)
3527 {
3528 ecore_imf_context_input_panel_show(sd->khdl.imf);
3529 ecore_imf_context_reset(sd->khdl.imf);
3530 ecore_imf_context_focus_in(sd->khdl.imf);
3531 _imf_cursor_set(sd);
3532 }
3533} 3460}
3534 3461
3535void 3462void
@@ -3542,14 +3469,6 @@ termio_focus_out(Evas_Object *termio)
3542 edje_object_signal_emit(sd->cursor.obj, "focus,out", "terminology"); 3469 edje_object_signal_emit(sd->cursor.obj, "focus,out", "terminology");
3543 if (!sd->win) return; 3470 if (!sd->win) return;
3544 sd->pty->selection.last_click = 0; 3471 sd->pty->selection.last_click = 0;
3545 elm_win_keyboard_mode_set(sd->win, ELM_WIN_KEYBOARD_OFF);
3546 if (sd->khdl.imf)
3547 {
3548 ecore_imf_context_reset(sd->khdl.imf);
3549 _imf_cursor_set(sd);
3550 ecore_imf_context_focus_out(sd->khdl.imf);
3551 ecore_imf_context_input_panel_hide(sd->khdl.imf);
3552 }
3553 if (!sd->ctxpopup) 3472 if (!sd->ctxpopup)
3554 _remove_links(sd, termio); 3473 _remove_links(sd, termio);
3555 term_unfocus(sd->term); 3474 term_unfocus(sd->term);
@@ -4807,6 +4726,7 @@ _smart_apply(Evas_Object *obj)
4807 Eina_List *l, *ln; 4726 Eina_List *l, *ln;
4808 Termblock *blk; 4727 Termblock *blk;
4809 int x, y, ch1 = 0, ch2 = 0, inv = 0, preedit_x = 0, preedit_y = 0; 4728 int x, y, ch1 = 0, ch2 = 0, inv = 0, preedit_x = 0, preedit_y = 0;
4729 char *preedit_str;
4810 ssize_t w; 4730 ssize_t w;
4811 4731
4812 EINA_SAFETY_ON_NULL_RETURN(sd); 4732 EINA_SAFETY_ON_NULL_RETURN(sd);
@@ -4993,7 +4913,9 @@ _smart_apply(Evas_Object *obj)
4993 evas_object_textgrid_update_add(sd->grid.obj, ch1, y, 4913 evas_object_textgrid_update_add(sd->grid.obj, ch1, y,
4994 ch2 - ch1 + 1, 1); 4914 ch2 - ch1 + 1, 1);
4995 } 4915 }
4996 if (sd->preedit_str && sd->preedit_str[0]) 4916
4917 preedit_str = term_preedit_str_get(sd->term);
4918 if (preedit_str && preedit_str[0])
4997 { 4919 {
4998 Eina_Unicode *uni, g; 4920 Eina_Unicode *uni, g;
4999 int len = 0, i, jump, xx, backx; 4921 int len = 0, i, jump, xx, backx;
@@ -5001,7 +4923,7 @@ _smart_apply(Evas_Object *obj)
5001 Evas_Textgrid_Cell *tc; 4923 Evas_Textgrid_Cell *tc;
5002 x = sd->cursor.x, y = sd->cursor.y; 4924 x = sd->cursor.x, y = sd->cursor.y;
5003 4925
5004 uni = eina_unicode_utf8_to_unicode(sd->preedit_str, &len); 4926 uni = eina_unicode_utf8_to_unicode(preedit_str, &len);
5005 if (uni) 4927 if (uni)
5006 { 4928 {
5007 for (i = 0; i < len; i++) 4929 for (i = 0; i < len; i++)
@@ -5251,52 +5173,8 @@ _cursor_cb_move(void *data,
5251{ 5173{
5252 Termio *sd = evas_object_smart_data_get(data); 5174 Termio *sd = evas_object_smart_data_get(data);
5253 EINA_SAFETY_ON_NULL_RETURN(sd); 5175 EINA_SAFETY_ON_NULL_RETURN(sd);
5254 _imf_cursor_set(sd); 5176 /* TODO: boris */
5255} 5177 //_imf_cursor_set(sd);
5256
5257static void
5258_imf_event_commit_cb(void *data,
5259 Ecore_IMF_Context *_ctx EINA_UNUSED,
5260 void *event)
5261{
5262 Termio *sd = data;
5263 char *str = event;
5264 DBG("IMF committed '%s'", str);
5265 if (!str) return;
5266 termpty_write(sd->pty, str, strlen(str));
5267 if (sd->preedit_str)
5268 {
5269 eina_stringshare_del(sd->preedit_str);
5270 sd->preedit_str = NULL;
5271 }
5272 _smart_update_queue(sd->self, sd);
5273}
5274
5275static void
5276_imf_event_delete_surrounding_cb(void *data,
5277 Ecore_IMF_Context *_ctx EINA_UNUSED,
5278 void *event)
5279{
5280 Termio *sd = data;
5281 Ecore_IMF_Event_Delete_Surrounding *ev = event;
5282 DBG("IMF del surrounding %p %i %i", sd, ev->offset, ev->n_chars);
5283}
5284
5285static void
5286_imf_event_preedit_changed_cb(void *data,
5287 Ecore_IMF_Context *ctx,
5288 void *_event EINA_UNUSED)
5289{
5290 Termio *sd = data;
5291 char *preedit_string;
5292 int cursor_pos;
5293 ecore_imf_context_preedit_string_get(ctx, &preedit_string, &cursor_pos);
5294 if (!preedit_string) return;
5295 DBG("IMF preedit str '%s'", preedit_string);
5296 if (sd->preedit_str) eina_stringshare_del(sd->preedit_str);
5297 sd->preedit_str = eina_stringshare_add(preedit_string);
5298 _smart_update_queue(sd->self, sd);
5299 free(preedit_string);
5300} 5178}
5301 5179
5302 5180
@@ -5370,58 +5248,6 @@ _smart_add(Evas_Object *obj)
5370 5248
5371 sd->link.suspend = 1; 5249 sd->link.suspend = 1;
5372 5250
5373 if (ecore_imf_init())
5374 {
5375 const char *imf_id = ecore_imf_context_default_id_get();
5376 Evas *e;
5377
5378 if (!imf_id) sd->khdl.imf = NULL;
5379 else
5380 {
5381 const Ecore_IMF_Context_Info *imf_info;
5382
5383 imf_info = ecore_imf_context_info_by_id_get(imf_id);
5384 if ((!imf_info->canvas_type) ||
5385 (strcmp(imf_info->canvas_type, "evas") == 0))
5386 sd->khdl.imf = ecore_imf_context_add(imf_id);
5387 else
5388 {
5389 imf_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
5390 if (imf_id) sd->khdl.imf = ecore_imf_context_add(imf_id);
5391 }
5392 }
5393
5394 if (!sd->khdl.imf) goto imf_done;
5395
5396 e = evas_object_evas_get(o);
5397 ecore_imf_context_client_window_set
5398 (sd->khdl.imf, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(e)));
5399 ecore_imf_context_client_canvas_set(sd->khdl.imf, e);
5400
5401 ecore_imf_context_event_callback_add
5402 (sd->khdl.imf, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, sd);
5403 ecore_imf_context_event_callback_add
5404 (sd->khdl.imf, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _imf_event_delete_surrounding_cb, sd);
5405 ecore_imf_context_event_callback_add
5406 (sd->khdl.imf, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _imf_event_preedit_changed_cb, sd);
5407 /* make IMF usable by a terminal - no preedit, prediction... */
5408 ecore_imf_context_prediction_allow_set
5409 (sd->khdl.imf, EINA_FALSE);
5410 ecore_imf_context_autocapital_type_set
5411 (sd->khdl.imf, ECORE_IMF_AUTOCAPITAL_TYPE_NONE);
5412 ecore_imf_context_input_panel_layout_set
5413 (sd->khdl.imf, ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL);
5414 ecore_imf_context_input_mode_set
5415 (sd->khdl.imf, ECORE_IMF_INPUT_MODE_FULL);
5416 ecore_imf_context_input_panel_language_set
5417 (sd->khdl.imf, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
5418 ecore_imf_context_input_panel_return_key_type_set
5419 (sd->khdl.imf, ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT);
5420imf_done:
5421 if (sd->khdl.imf) DBG("Ecore IMF Setup");
5422 else WRN(_("Ecore IMF failed"));
5423
5424 }
5425 terms = eina_list_append(terms, obj); 5251 terms = eina_list_append(terms, obj);
5426} 5252}
5427 5253
@@ -5434,12 +5260,6 @@ _smart_del(Evas_Object *obj)
5434 5260
5435 EINA_SAFETY_ON_NULL_RETURN(sd); 5261 EINA_SAFETY_ON_NULL_RETURN(sd);
5436 terms = eina_list_remove(terms, obj); 5262 terms = eina_list_remove(terms, obj);
5437 if (sd->khdl.imf)
5438 {
5439 ecore_imf_context_event_callback_del
5440 (sd->khdl.imf, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb);
5441 ecore_imf_context_del(sd->khdl.imf);
5442 }
5443 if (sd->cursor.obj) evas_object_del(sd->cursor.obj); 5263 if (sd->cursor.obj) evas_object_del(sd->cursor.obj);
5444 if (sd->event) 5264 if (sd->event)
5445 { 5265 {
@@ -5495,13 +5315,10 @@ _smart_del(Evas_Object *obj)
5495 } 5315 }
5496 sd->sendfile.active = EINA_FALSE; 5316 sd->sendfile.active = EINA_FALSE;
5497 } 5317 }
5498 keyin_compose_seq_reset(&sd->khdl);
5499 if (sd->sel_str) eina_stringshare_del(sd->sel_str); 5318 if (sd->sel_str) eina_stringshare_del(sd->sel_str);
5500 if (sd->preedit_str) eina_stringshare_del(sd->preedit_str);
5501 if (sd->sel_reset_job) ecore_job_del(sd->sel_reset_job); 5319 if (sd->sel_reset_job) ecore_job_del(sd->sel_reset_job);
5502 EINA_LIST_FREE(sd->cur_chids, chid) eina_stringshare_del(chid); 5320 EINA_LIST_FREE(sd->cur_chids, chid) eina_stringshare_del(chid);
5503 sd->sel_str = NULL; 5321 sd->sel_str = NULL;
5504 sd->preedit_str = NULL;
5505 sd->sel_reset_job = NULL; 5322 sd->sel_reset_job = NULL;
5506 sd->link.down.dndobj = NULL; 5323 sd->link.down.dndobj = NULL;
5507 sd->cursor.obj = NULL; 5324 sd->cursor.obj = NULL;
@@ -5513,10 +5330,8 @@ _smart_del(Evas_Object *obj)
5513 sd->delayed_size_timer = NULL; 5330 sd->delayed_size_timer = NULL;
5514 sd->font.name = NULL; 5331 sd->font.name = NULL;
5515 sd->pty = NULL; 5332 sd->pty = NULL;
5516 sd->khdl.imf = NULL;
5517 sd->win = NULL; 5333 sd->win = NULL;
5518 sd->glayer = NULL; 5334 sd->glayer = NULL;
5519 ecore_imf_shutdown();
5520 5335
5521 _parent_sc.del(obj); 5336 _parent_sc.del(obj);
5522} 5337}
@@ -6274,13 +6089,20 @@ termio_add(Evas_Object *win, Config *config,
6274} 6089}
6275 6090
6276void 6091void
6277termio_key_down(Evas_Object *termio, void *event) 6092termio_key_down(Evas_Object *termio,
6093 const Evas_Event_Key_Down *ev)
6278{ 6094{
6279 _smart_cb_key_down(termio, NULL, NULL, event); 6095 Termio *sd = evas_object_smart_data_get(termio);
6280}
6281 6096
6282void 6097 EINA_SAFETY_ON_NULL_RETURN(sd);
6283termio_key_up(Evas_Object *termio, void *event) 6098 if (sd->jump_on_keypress)
6284{ 6099 {
6285 _smart_cb_key_up(termio, NULL, NULL, event); 6100 if (!key_is_modifier(ev->key))
6101 {
6102 sd->scroll = 0;
6103 _smart_update_queue(termio, sd);
6104 }
6105 }
6106 if (sd->config->flicker_on_key)
6107 edje_object_signal_emit(sd->cursor.obj, "key,down", "terminology");
6286} 6108}
diff --git a/src/bin/termio.h b/src/bin/termio.h
index 7ee9c85..5e4a403 100644
--- a/src/bin/termio.h
+++ b/src/bin/termio.h
@@ -49,12 +49,14 @@ Eina_Bool termio_file_send_ok(const Evas_Object *obj, const char *file);
49void termio_file_send_cancel(const Evas_Object *obj); 49void termio_file_send_cancel(const Evas_Object *obj);
50double termio_file_send_progress_get(const Evas_Object *obj); 50double termio_file_send_progress_get(const Evas_Object *obj);
51 51
52void
53termio_imf_cursor_set(Evas_Object *obj, Ecore_IMF_Context *imf);
54
52Termpty *termio_pty_get(const Evas_Object *obj); 55Termpty *termio_pty_get(const Evas_Object *obj);
53Evas_Object * termio_miniview_get(const Evas_Object *obj); 56Evas_Object * termio_miniview_get(const Evas_Object *obj);
54Term* termio_term_get(const Evas_Object *obj); 57Term* termio_term_get(const Evas_Object *obj);
55 58
56void termio_key_down(Evas_Object *termio, void *event); 59void termio_key_down(Evas_Object *termio, const Evas_Event_Key_Down *ev);
57void termio_key_up(Evas_Object *termio, void *event);
58void termio_focus_in(Evas_Object *termio); 60void termio_focus_in(Evas_Object *termio);
59void termio_focus_out(Evas_Object *termio); 61void termio_focus_out(Evas_Object *termio);
60 62
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 4251e8a..e857676 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -1,10 +1,14 @@
1#include "private.h" 1#include "private.h"
2#include <Elementary.h> 2#include <Elementary.h>
3#include <Ecore_Input.h>
4#include <Ecore_IMF.h>
5#include <Ecore_IMF_Evas.h>
3#include "termpty.h" 6#include "termpty.h"
4#include "termptyesc.h" 7#include "termptyesc.h"
5#include "termptyops.h" 8#include "termptyops.h"
6#include "termptysave.h" 9#include "termptysave.h"
7#include "termio.h" 10#include "termio.h"
11#include "keyin.h"
8#include <sys/types.h> 12#include <sys/types.h>
9#include <signal.h> 13#include <signal.h>
10#include <sys/wait.h> 14#include <sys/wait.h>
@@ -54,6 +58,26 @@ termpty_shutdown(void)
54 _termpty_log_dom = -1; 58 _termpty_log_dom = -1;
55} 59}
56 60
61
62Eina_Bool
63termpty_can_handle_key(const Termpty *ty,
64 const Keys_Handler *khdl,
65 const Evas_Event_Key_Down *ev)
66{
67 // if term app asked for kbd lock - dont handle here
68 if (ty->termstate.kbd_lock)
69 return EINA_FALSE;
70 // if app asked us to not do autorepeat - ignore press if is it is the same
71 // timestamp as last one
72 if ((ty->termstate.no_autorepeat) &&
73 (ev->timestamp == khdl->last_keyup))
74 return EINA_FALSE;
75 return EINA_TRUE;
76}
77
78
79
80
57void 81void
58termpty_handle_buf(Termpty *ty, const Eina_Unicode *codepoints, int len) 82termpty_handle_buf(Termpty *ty, const Eina_Unicode *codepoints, int len)
59{ 83{
diff --git a/src/bin/win.c b/src/bin/win.c
index 399d9d5..41e2d21 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -1,5 +1,8 @@
1#include <assert.h> 1#include <assert.h>
2#include <Elementary.h> 2#include <Elementary.h>
3#include <Ecore_Input.h>
4#include <Ecore_IMF.h>
5#include <Ecore_IMF_Evas.h>
3#include "win.h" 6#include "win.h"
4#include "termcmd.h" 7#include "termcmd.h"
5#include "config.h" 8#include "config.h"
@@ -12,6 +15,7 @@
12#include "private.h" 15#include "private.h"
13#include "sel.h" 16#include "sel.h"
14#include "controls.h" 17#include "controls.h"
18#include "keyin.h"
15#include "term_container.h" 19#include "term_container.h"
16 20
17 21
@@ -154,8 +158,10 @@ struct _Split
154 158
155struct _Win 159struct _Win
156{ 160{
157 Term_Container tc; 161 Term_Container tc; /* has to be first field */
158 162
163 Keys_Handler khdl;
164 const char *preedit_str;
159 Term_Container *child; 165 Term_Container *child;
160 Evas_Object *win; 166 Evas_Object *win;
161 Evas_Object *conform; 167 Evas_Object *conform;
@@ -195,6 +201,7 @@ static Tab_Item* tab_item_new(Tabs *tabs, Term_Container *child);
195static void _tabs_refresh(Tabs *tabs); 201static void _tabs_refresh(Tabs *tabs);
196static void _term_tabregion_free(Term *term); 202static void _term_tabregion_free(Term *term);
197static void _set_trans(Config *config, Evas_Object *bg, Evas_Object *base); 203static void _set_trans(Config *config, Evas_Object *bg, Evas_Object *base);
204static void _imf_event_commit_cb(void *data, Ecore_IMF_Context *_ctx EINA_UNUSED, void *event);
198 205
199 206
200/* {{{ Solo */ 207/* {{{ Solo */
@@ -749,8 +756,20 @@ win_free(Win *wn)
749 evas_object_event_callback_del_full(wn->win, EVAS_CALLBACK_DEL, _cb_del, wn); 756 evas_object_event_callback_del_full(wn->win, EVAS_CALLBACK_DEL, _cb_del, wn);
750 evas_object_del(wn->win); 757 evas_object_del(wn->win);
751 } 758 }
752 if (wn->size_job) ecore_job_del(wn->size_job); 759 if (wn->size_job)
753 if (wn->config) config_del(wn->config); 760 ecore_job_del(wn->size_job);
761 if (wn->config)
762 config_del(wn->config);
763 if (wn->preedit_str)
764 eina_stringshare_del(wn->preedit_str);
765 keyin_compose_seq_reset(&wn->khdl);
766 if (wn->khdl.imf)
767 {
768 ecore_imf_context_event_callback_del
769 (wn->khdl.imf, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb);
770 ecore_imf_context_del(wn->khdl.imf);
771 }
772 ecore_imf_shutdown();
754 free(wn); 773 free(wn);
755} 774}
756 775
@@ -958,9 +977,25 @@ _win_focus(Term_Container *tc, Term_Container *relative)
958 DBG("tc:%p tc->is_focused:%d from_child:%d", 977 DBG("tc:%p tc->is_focused:%d from_child:%d",
959 tc, tc->is_focused, wn->child == relative); 978 tc, tc->is_focused, wn->child == relative);
960 if (relative != wn->child) 979 if (relative != wn->child)
961 wn->child->focus(wn->child, tc); 980 {
981 wn->child->focus(wn->child, tc);
982 elm_win_keyboard_mode_set(wn->win, ELM_WIN_KEYBOARD_TERMINAL);
983 if (wn->khdl.imf)
984 {
985 Term *focused;
962 986
963 if (!tc->is_focused) elm_win_urgent_set(wn->win, EINA_FALSE); 987 ecore_imf_context_input_panel_show(wn->khdl.imf);
988 ecore_imf_context_reset(wn->khdl.imf);
989 ecore_imf_context_focus_in(wn->khdl.imf);
990
991 focused = tc->focused_term_get(tc);
992 if (focused)
993 termio_imf_cursor_set(focused->termio, wn->khdl.imf);
994 }
995 }
996
997 if (!tc->is_focused)
998 elm_win_urgent_set(wn->win, EINA_FALSE);
964 tc->is_focused = EINA_TRUE; 999 tc->is_focused = EINA_TRUE;
965} 1000}
966 1001
@@ -974,8 +1009,20 @@ _win_unfocus(Term_Container *tc, Term_Container *relative)
974 1009
975 DBG("tc:%p tc->is_focused:%d from_child:%d", 1010 DBG("tc:%p tc->is_focused:%d from_child:%d",
976 tc, tc->is_focused, wn->child == relative); 1011 tc, tc->is_focused, wn->child == relative);
1012 elm_win_keyboard_mode_set(wn->win, ELM_WIN_KEYBOARD_OFF);
977 if (relative != wn->child && wn->child) 1013 if (relative != wn->child && wn->child)
978 { 1014 {
1015 if (wn->khdl.imf)
1016 {
1017 Term *focused;
1018
1019 ecore_imf_context_reset(wn->khdl.imf);
1020 focused = tc->focused_term_get(tc);
1021 if (focused)
1022 termio_imf_cursor_set(focused->termio, wn->khdl.imf);
1023 ecore_imf_context_focus_out(wn->khdl.imf);
1024 ecore_imf_context_input_panel_hide(wn->khdl.imf);
1025 }
979 tc->is_focused = EINA_FALSE; 1026 tc->is_focused = EINA_FALSE;
980 wn->child->unfocus(wn->child, tc); 1027 wn->child->unfocus(wn->child, tc);
981 1028
@@ -1108,26 +1155,55 @@ static void
1108_cb_win_key_up(void *data, 1155_cb_win_key_up(void *data,
1109 Evas *_e EINA_UNUSED, 1156 Evas *_e EINA_UNUSED,
1110 Evas_Object *_obj EINA_UNUSED, 1157 Evas_Object *_obj EINA_UNUSED,
1111 void *event_info) 1158 void *event)
1112{ 1159{
1113 Win *wn = data; 1160 Win *wn = data;
1114 Eina_List *l; 1161 Evas_Event_Key_Up *ev = event;
1115 Term *term;
1116 const Evas_Event_Key_Up *ev = event_info;
1117
1118 if (wn->on_options)
1119 return;
1120 1162
1121 DBG("GROUP key up (%p) (ctrl:%d)", 1163 DBG("GROUP key up (%p) (ctrl:%d)",
1122 wn, evas_key_modifier_is_set(ev->modifiers, "Control")); 1164 wn, evas_key_modifier_is_set(ev->modifiers, "Control"));
1165 keyin_handle_up(&wn->khdl, ev);
1166}
1167
1168char *
1169term_preedit_str_get(Term *term)
1170{
1171 Win *wn = term->wn;
1172 Term_Container *tc = (Term_Container*) wn;
1173
1174 if (wn->on_options)
1175 return NULL;
1176 tc = (Term_Container*) wn;
1177 term = tc->focused_term_get(tc);
1178 if (term)
1179 {
1180 return wn->preedit_str;
1181 }
1182 return NULL;
1183}
1184
1185static void
1186_imf_event_commit_cb(void *data,
1187 Ecore_IMF_Context *_ctx EINA_UNUSED,
1188 void *event)
1189{
1190 Eina_List *l;
1191 Term *term;
1192 Win *wn = data;
1193 Termpty *ty;
1194 char *str = event;
1195 int len;
1196 DBG("IMF committed '%s'", str);
1197 if (!str)
1198 return;
1199 len = strlen(str);
1123 if (wn->group_input) 1200 if (wn->group_input)
1124 { 1201 {
1125 wn->group_once_handled = EINA_FALSE;
1126 EINA_LIST_FOREACH(wn->terms, l, term) 1202 EINA_LIST_FOREACH(wn->terms, l, term)
1127 { 1203 {
1128 termio_key_up(term->termio, event_info); 1204 ty = termio_pty_get(term->termio);
1129 if (!wn->group_input) 1205 if (ty)
1130 return; 1206 termpty_write(ty, str, len);
1131 } 1207 }
1132 } 1208 }
1133 else 1209 else
@@ -1136,10 +1212,51 @@ _cb_win_key_up(void *data,
1136 1212
1137 term = tc->focused_term_get(tc); 1213 term = tc->focused_term_get(tc);
1138 if (term) 1214 if (term)
1139 termio_key_up(term->termio, event_info); 1215 {
1216 ty = termio_pty_get(term->termio);
1217 if (ty)
1218 termpty_write(ty, str, len);
1219 }
1220 }
1221 if (wn->preedit_str)
1222 {
1223 eina_stringshare_del(wn->preedit_str);
1224 wn->preedit_str = NULL;
1140 } 1225 }
1141} 1226}
1142 1227
1228
1229
1230static void
1231_imf_event_delete_surrounding_cb(void *data,
1232 Ecore_IMF_Context *_ctx EINA_UNUSED,
1233 void *event)
1234{
1235 Win *wn = data;
1236 Ecore_IMF_Event_Delete_Surrounding *ev = event;
1237 DBG("IMF del surrounding %p %i %i", wn, ev->offset, ev->n_chars);
1238}
1239
1240static void
1241_imf_event_preedit_changed_cb(void *data,
1242 Ecore_IMF_Context *ctx,
1243 void *_event EINA_UNUSED)
1244{
1245 Win *wn = data;
1246 char *preedit_string;
1247 int cursor_pos;
1248
1249 ecore_imf_context_preedit_string_get(ctx, &preedit_string, &cursor_pos);
1250 if (!preedit_string)
1251 return;
1252 DBG("IMF preedit str '%s'", preedit_string);
1253 if (wn->preedit_str)
1254 eina_stringshare_del(wn->preedit_str);
1255 wn->preedit_str = eina_stringshare_add(preedit_string);
1256 free(preedit_string);
1257}
1258
1259
1143static void 1260static void
1144_cb_win_key_down(void *data, 1261_cb_win_key_down(void *data,
1145 Evas *_e EINA_UNUSED, 1262 Evas *_e EINA_UNUSED,
@@ -1147,9 +1264,12 @@ _cb_win_key_down(void *data,
1147 void *event_info) 1264 void *event_info)
1148{ 1265{
1149 Win *wn = data; 1266 Win *wn = data;
1150 Eina_List *l; 1267 Eina_List *l = NULL;
1151 Term *term; 1268 Term *term = NULL;
1152 const Evas_Event_Key_Down *ev = event_info; 1269 Termpty *ty = NULL;
1270 Evas_Event_Key_Down *ev = event_info;
1271 Eina_Bool done = EINA_FALSE;
1272 int ctrl, alt, shift, win, meta, hyper;
1153 1273
1154 DBG("GROUP key down (%p) (ctrl:%d)", 1274 DBG("GROUP key down (%p) (ctrl:%d)",
1155 wn, evas_key_modifier_is_set(ev->modifiers, "Control")); 1275 wn, evas_key_modifier_is_set(ev->modifiers, "Control"));
@@ -1157,7 +1277,6 @@ _cb_win_key_down(void *data,
1157 if (wn->on_options) 1277 if (wn->on_options)
1158 return; 1278 return;
1159 1279
1160 int ctrl, alt, shift, win, meta, hyper;
1161 ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); 1280 ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
1162 alt = evas_key_modifier_is_set(ev->modifiers, "Alt"); 1281 alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1163 shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); 1282 shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
@@ -1169,13 +1288,73 @@ _cb_win_key_down(void *data,
1169 DBG("ctrl:%d alt:%d shift:%d win:%d meta:%d hyper:%d", 1288 DBG("ctrl:%d alt:%d shift:%d win:%d meta:%d hyper:%d",
1170 ctrl, alt, shift, win, meta, hyper); 1289 ctrl, alt, shift, win, meta, hyper);
1171 1290
1291 /* 1st/ Miniview */
1292 if (wn->group_input)
1293 {
1294 EINA_LIST_FOREACH(wn->terms, l, term)
1295 {
1296 done = miniview_handle_key(term_miniview_get(term), ev);
1297 if (!wn->group_input)
1298 return;
1299 }
1300 }
1301 else
1302 {
1303 Term_Container *tc = (Term_Container*) wn;
1304
1305 term = tc->focused_term_get(tc);
1306 if (!term)
1307 return;
1308 done = miniview_handle_key(term_miniview_get(term), ev);
1309 }
1310 if (done)
1311 {
1312 keyin_compose_seq_reset(&wn->khdl);
1313 goto end;
1314 }
1315
1172 1316
1317 /* 2nd/ PopMedia */
1318 done = EINA_FALSE;
1319 if (wn->group_input)
1320 {
1321 EINA_LIST_FOREACH(wn->terms, l, term)
1322 {
1323 if (term_has_popmedia(term) && !strcmp(ev->key, "Escape"))
1324 {
1325 term_popmedia_close(term);
1326 done = EINA_TRUE;
1327 }
1328 }
1329 }
1330 else
1331 {
1332 Term_Container *tc = (Term_Container*) wn;
1333
1334 term = tc->focused_term_get(tc);
1335 if (!term)
1336 return;
1337 if (term_has_popmedia(term) && !strcmp(ev->key, "Escape"))
1338 {
1339 term_popmedia_close(term);
1340 done = EINA_TRUE;
1341 }
1342 }
1343 if (done)
1344 {
1345 keyin_compose_seq_reset(&wn->khdl);
1346 goto end;
1347 }
1348
1349 /* 3rd/ Handle key bindings */
1350 done = EINA_FALSE;
1173 if (wn->group_input) 1351 if (wn->group_input)
1174 { 1352 {
1175 wn->group_once_handled = EINA_FALSE; 1353 wn->group_once_handled = EINA_FALSE;
1176 EINA_LIST_FOREACH(wn->terms, l, term) 1354 EINA_LIST_FOREACH(wn->terms, l, term)
1177 { 1355 {
1178 termio_key_down(term->termio, event_info); 1356 done = keyin_handle_key_binding(term->termio, ev, ctrl, alt,
1357 shift, win, meta, hyper);
1179 if (!wn->group_input) 1358 if (!wn->group_input)
1180 return; 1359 return;
1181 } 1360 }
@@ -1185,8 +1364,130 @@ _cb_win_key_down(void *data,
1185 Term_Container *tc = (Term_Container*) wn; 1364 Term_Container *tc = (Term_Container*) wn;
1186 1365
1187 term = tc->focused_term_get(tc); 1366 term = tc->focused_term_get(tc);
1367 if (!term)
1368 return;
1369 done = keyin_handle_key_binding(term->termio, ev, ctrl, alt,
1370 shift, win, meta, hyper);
1371 }
1372 if (done)
1373 {
1374 keyin_compose_seq_reset(&wn->khdl);
1375 goto end;
1376 }
1377 done = EINA_FALSE;
1378
1379 /* 4th/ Composing */
1380 /* composing */
1381 if (&wn->khdl.imf)
1382 {
1383 // EXCEPTION. Don't filter modifiers alt+shift -> breaks emacs
1384 // and jed (alt+shift+5 for search/replace for example)
1385 // Don't filter modifiers alt, is used by shells
1386 if ((!alt) && (!ctrl))
1387 {
1388 Ecore_IMF_Event_Key_Down imf_ev;
1389
1390 ecore_imf_evas_event_key_down_wrap(ev, &imf_ev);
1391 if (!wn->khdl.composing)
1392 {
1393 if (ecore_imf_context_filter_event(wn->khdl.imf,
1394 ECORE_IMF_EVENT_KEY_DOWN,
1395 (Ecore_IMF_Event *)&imf_ev))
1396 goto end;
1397 }
1398 }
1399 }
1400 if (!wn->khdl.composing)
1401 {
1402 Ecore_Compose_State state;
1403 char *compres = NULL;
1404
1405 keyin_compose_seq_reset(&wn->khdl);
1406 wn->khdl.seq = eina_list_append(wn->khdl.seq,
1407 eina_stringshare_add(ev->key));
1408 state = ecore_compose_get(wn->khdl.seq, &compres);
1409 if (state == ECORE_COMPOSE_MIDDLE)
1410 wn->khdl.composing = EINA_TRUE;
1411 else
1412 wn->khdl.composing = EINA_FALSE;
1413 if (!wn->khdl.composing)
1414 keyin_compose_seq_reset(&wn->khdl);
1415 else
1416 goto end;
1417 }
1418 else
1419 {
1420 Ecore_Compose_State state;
1421 char *compres = NULL;
1422
1423 if (key_is_modifier(ev->key))
1424 goto end;
1425 wn->khdl.seq = eina_list_append(wn->khdl.seq,
1426 eina_stringshare_add(ev->key));
1427 state = ecore_compose_get(wn->khdl.seq, &compres);
1428 if (state == ECORE_COMPOSE_NONE)
1429 keyin_compose_seq_reset(&wn->khdl);
1430 else if (state == ECORE_COMPOSE_DONE)
1431 {
1432 keyin_compose_seq_reset(&wn->khdl);
1433 if (compres)
1434 {
1435 int len = strlen(compres);
1436 if (wn->group_input)
1437 {
1438 EINA_LIST_FOREACH(wn->terms, l, term)
1439 {
1440 ty = termio_pty_get(term->termio);
1441 if (ty && termpty_can_handle_key(ty, &wn->khdl, ev))
1442 termpty_write(ty, compres, len);
1443 }
1444 }
1445 else
1446 {
1447 ty = termio_pty_get(term->termio);
1448 if (ty && termpty_can_handle_key(ty, &wn->khdl, ev))
1449 termpty_write(ty, compres, len);
1450 }
1451 free(compres);
1452 compres = NULL;
1453 }
1454 goto end;
1455 }
1456 else
1457 goto end;
1458 }
1459
1460 /* 5th/ send key to pty */
1461 if (wn->group_input)
1462 {
1463 EINA_LIST_FOREACH(wn->terms, l, term)
1464 {
1465 ty = termio_pty_get(term->termio);
1466 if (ty && termpty_can_handle_key(ty, &wn->khdl, ev))
1467 keyin_handle_key_to_pty(ty, ev, alt, shift, ctrl);
1468 }
1469 }
1470 else
1471 {
1472 ty = termio_pty_get(term->termio);
1473 if (ty && termpty_can_handle_key(ty, &wn->khdl, ev))
1474 keyin_handle_key_to_pty(ty, ev, alt, shift, ctrl);
1475 }
1476
1477 /* 6th: specifics: jump on keypress / flicker on key */
1478end:
1479 if (wn->group_input)
1480 {
1481 EINA_LIST_FOREACH(wn->terms, l, term)
1482 {
1483 if (term)
1484 termio_key_down(term->termio, ev);
1485 }
1486 }
1487 else
1488 {
1188 if (term) 1489 if (term)
1189 termio_key_down(term->termio, event_info); 1490 termio_key_down(term->termio, ev);
1190 } 1491 }
1191} 1492}
1192 1493
@@ -1369,6 +1670,64 @@ win_new(const char *name, const char *role, const char *title,
1369 _cb_win_mouse_move, 1670 _cb_win_mouse_move,
1370 wn); 1671 wn);
1371 1672
1673 if (ecore_imf_init())
1674 {
1675 const char *imf_id = ecore_imf_context_default_id_get();
1676 Evas *e;
1677
1678 if (!imf_id)
1679 wn->khdl.imf = NULL;
1680 else
1681 {
1682 const Ecore_IMF_Context_Info *imf_info;
1683
1684 imf_info = ecore_imf_context_info_by_id_get(imf_id);
1685 if ((!imf_info->canvas_type) ||
1686 (strcmp(imf_info->canvas_type, "evas") == 0))
1687 wn->khdl.imf = ecore_imf_context_add(imf_id);
1688 else
1689 {
1690 imf_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1691 if (imf_id)
1692 wn->khdl.imf = ecore_imf_context_add(imf_id);
1693 }
1694 }
1695
1696 if (!wn->khdl.imf)
1697 goto imf_done;
1698
1699 e = evas_object_evas_get(o);
1700 ecore_imf_context_client_window_set
1701 (wn->khdl.imf, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(e)));
1702 ecore_imf_context_client_canvas_set(wn->khdl.imf, e);
1703
1704 ecore_imf_context_event_callback_add
1705 (wn->khdl.imf, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, wn);
1706 ecore_imf_context_event_callback_add
1707 (wn->khdl.imf, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _imf_event_delete_surrounding_cb, wn);
1708 ecore_imf_context_event_callback_add
1709 (wn->khdl.imf, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _imf_event_preedit_changed_cb, wn);
1710 /* make IMF usable by a terminal - no preedit, prediction... */
1711 ecore_imf_context_prediction_allow_set
1712 (wn->khdl.imf, EINA_FALSE);
1713 ecore_imf_context_autocapital_type_set
1714 (wn->khdl.imf, ECORE_IMF_AUTOCAPITAL_TYPE_NONE);
1715 ecore_imf_context_input_panel_layout_set
1716 (wn->khdl.imf, ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL);
1717 ecore_imf_context_input_mode_set
1718 (wn->khdl.imf, ECORE_IMF_INPUT_MODE_FULL);
1719 ecore_imf_context_input_panel_language_set
1720 (wn->khdl.imf, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
1721 ecore_imf_context_input_panel_return_key_type_set
1722 (wn->khdl.imf, ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT);
1723imf_done:
1724 if (wn->khdl.imf)
1725 DBG("Ecore IMF Setup");
1726 else
1727 WRN(_("Ecore IMF failed"));
1728
1729 }
1730
1372 wins = eina_list_append(wins, wn); 1731 wins = eina_list_append(wins, wn);
1373 return wn; 1732 return wn;
1374} 1733}
diff --git a/src/bin/win.h b/src/bin/win.h
index 113ed71..4c7aa7d 100644
--- a/src/bin/win.h
+++ b/src/bin/win.h
@@ -66,6 +66,9 @@ void term_down(Term *term);
66void term_left(Term *term); 66void term_left(Term *term);
67void term_right(Term *term); 67void term_right(Term *term);
68 68
69char *
70term_preedit_str_get(Term *term);
71
69void win_font_size_set(Win *wn, int new_size); 72void win_font_size_set(Win *wn, int new_size);
70void win_font_update(Term *term); 73void win_font_update(Term *term);
71 74