4 #include "e_kbd_send.h"
5 #include "e_mod_config.h"
17 static Evas_Object *_theme_obj_new(Evas *e, const char *custom_dir, const char *group);
19 static void _e_kbd_int_layout_next(E_Kbd_Int *ki);
20 static void _e_kbd_int_zoomkey_down(E_Kbd_Int *ki);
21 static void _e_kbd_int_matches_update(void *data);
22 static void _e_kbd_int_dictlist_down(E_Kbd_Int *ki);
23 static void _e_kbd_int_matchlist_down(E_Kbd_Int *ki);
24 static Eina_Bool _e_kbd_int_cb_border_move(void *data, int type, void *event);
28 _e_kbd_int_str_unquote(const char *str)
33 snprintf(buf, sizeof(buf), "%s", str + 1);
34 p = strrchr(buf, '"');
39 static E_Kbd_Int_Key *
40 _e_kbd_int_at_coord_get(E_Kbd_Int *ki, Evas_Coord x, Evas_Coord y)
45 E_Kbd_Int_Key *closest_ky = NULL;
47 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
48 if ((x >= ky->x) && (y >= ky->y) &&
49 (x < (ky->x + ky->w)) && (y < (ky->y + ky->h)))
52 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
56 dx = x - (ky->x + (ky->w / 2));
57 dy = y - (ky->y + (ky->h / 2));
58 dx = (dx * dx) + (dy * dy);
68 static E_Kbd_Int_Key_State *
69 _e_kbd_int_key_state_get(E_Kbd_Int *ki, E_Kbd_Int_Key *ky)
71 E_Kbd_Int_Key_State *found = NULL;
72 E_Kbd_Int_Key_State *st;
75 EINA_LIST_FOREACH(ky->states, l, st)
77 if (st->state & ki->layout.state) return st;
78 if (!found && st->state == NORMAL) found = st;
84 _e_kbd_int_layout_buf_update(E_Kbd_Int *ki)
89 e_kbd_buf_layout_clear(ki->kbuf);
90 e_kbd_buf_layout_size_set(ki->kbuf, ki->layout.w, ki->layout.h);
91 e_kbd_buf_layout_fuzz_set(ki->kbuf, ki->layout.fuzz);
92 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
94 E_Kbd_Int_Key_State *st;
95 const char *out, *out_shift, *out_capslock, *out_altgr;
102 EINA_LIST_FOREACH(ky->states, l2, st)
104 if (st->state == NORMAL)
106 else if (st->state == SHIFT)
108 else if (st->state == CAPSLOCK)
109 out_capslock = st->out;
110 else if (st->state == ALTGR)
115 char *s1 = NULL, *s2 = NULL, *s3 = NULL;
117 if ((out) && (out[0] == '"'))
118 s1 = strdup(_e_kbd_int_str_unquote(out));
119 if ((out_shift) && (out_shift[0] == '"'))
120 s2 = strdup(_e_kbd_int_str_unquote(out_shift));
121 if ((out_altgr) && (out_altgr[0] == '"'))
122 s2 = strdup(_e_kbd_int_str_unquote(out_altgr));
123 if ((out_capslock) && (out_capslock[0] == '"'))
124 s3 = strdup(_e_kbd_int_str_unquote(out_capslock));
125 e_kbd_buf_layout_key_add(ki->kbuf, s1, s2, s3,
126 ky->x, ky->y, ky->w, ky->h);
135 _e_kbd_int_layout_state_update(E_Kbd_Int *ki)
140 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
142 E_Kbd_Int_Key_State *st;
145 st = _e_kbd_int_key_state_get(ki, ky);
149 edje_object_part_text_set(ky->obj, "e.text.label", st->label);
151 edje_object_part_text_set(ky->obj, "e.text.label", "");
157 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, st->icon);
158 p = strrchr(st->icon, '.');
159 if (!strcmp(p, ".edj"))
160 e_icon_file_edje_set(ky->icon_obj, buf, "icon");
162 e_icon_file_set(ky->icon_obj, buf);
165 e_icon_file_set(ky->icon_obj, NULL);
168 if ((ki->layout.state & SHIFT) && (ky->is_shift)) selected = 1;
169 if ((ki->layout.state & CTRL) && (ky->is_ctrl)) selected = 1;
170 if ((ki->layout.state & ALT) && (ky->is_alt)) selected = 1;
171 if ((ki->layout.state & ALTGR) && (ky->is_altgr)) selected = 1;
172 if ((ki->layout.state & CAPSLOCK) && (ky->is_capslock)) selected = 1;
173 if ((ki->layout.state & (SHIFT | CAPSLOCK)) && (ky->is_multi_shift))
179 edje_object_signal_emit(ky->obj, "e,state,selected", "e");
187 edje_object_signal_emit(ky->obj, "e,state,unselected", "e");
195 _e_kbd_int_string_send(E_Kbd_Int *ki, const char *str)
197 int pos, newpos, glyph;
200 e_kbd_buf_word_use(ki->kbuf, str);
205 newpos = evas_string_char_next_get(str, pos, &glyph);
206 if (glyph <= 0) return;
207 strncpy(buf, str + pos, newpos - pos);
208 buf[newpos - pos] = 0;
209 e_kbd_send_string_press(buf, 0);
215 _e_kbd_int_buf_send(E_Kbd_Int *ki)
217 const char *str = NULL;
218 const Eina_List *matches;
220 matches = e_kbd_buf_string_matches_get(ki->kbuf);
221 if (matches) str = matches->data;
222 else str = e_kbd_buf_actual_string_get(ki->kbuf);
223 if (str) _e_kbd_int_string_send(ki, str);
227 _e_kbd_int_cb_match_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
232 _e_kbd_int_string_send(km->ki, km->str);
233 e_kbd_buf_clear(km->ki->kbuf);
234 e_kbd_send_keysym_press("space", 0);
235 if (km->ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
237 km->ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
238 _e_kbd_int_layout_state_update(km->ki);
240 _e_kbd_int_matches_update(km->ki);
244 _e_kbd_int_matches_add(E_Kbd_Int *ki, const char *str, int num)
250 km = E_NEW(E_Kbd_Int_Match, 1);
252 o = _theme_obj_new(ki->win->evas, ki->themedir,
253 "e/modules/kbd/match/word");
255 km->str = eina_stringshare_add(str);
257 ki->matches = eina_list_append(ki->matches, km);
258 edje_object_part_text_set(o, "e.text.label", str);
259 edje_object_size_min_calc(o, &mw, &mh);
260 if (mw < 32) mw = 32;
261 if (num & 0x1) e_box_pack_start(ki->box_obj, o);
262 else e_box_pack_end(ki->box_obj, o);
263 e_box_pack_options_set(o, 1, 1, 1, 1, 0.5, 0.5, mw, mh, 9999, 9999);
265 edje_object_signal_emit(o, "e,state,selected", "e");
266 edje_object_signal_callback_add(o, "e,action,do,select", "",
267 _e_kbd_int_cb_match_select, km);
272 _e_kbd_int_matches_free(E_Kbd_Int *ki)
276 EINA_LIST_FREE(ki->matches, km)
278 if (km->str) eina_stringshare_del(km->str);
279 evas_object_del(km->obj);
285 _e_kbd_int_matches_update(void *data)
288 const Eina_List *l, *matches;
290 Evas_Coord mw, mh, vw, vh;
292 if (!(ki = data)) return;
293 evas_event_freeze(ki->win->evas);
294 e_box_freeze(ki->box_obj);
295 _e_kbd_int_matches_free(ki);
296 matches = e_kbd_buf_string_matches_get(ki->kbuf);
299 actual = e_kbd_buf_actual_string_get(ki->kbuf);
300 if (actual) _e_kbd_int_matches_add(ki, actual, 0);
306 for (i = 0, l = matches; l; l = l->next, i++)
308 _e_kbd_int_matches_add(ki, l->data, i);
309 e_box_size_min_get(ki->box_obj, &mw, &mh);
310 edje_object_part_geometry_get(ki->base_obj, "e.swallow.label",
311 NULL, NULL, &vw, &vh);
317 actual = e_kbd_buf_actual_string_get(ki->kbuf);
322 EINA_LIST_FOREACH(matches, l, str)
323 if (!strcmp(str, actual)) break;
324 if (!l) _e_kbd_int_matches_add(ki, actual, i);
328 e_box_thaw(ki->box_obj);
329 e_box_size_min_get(ki->box_obj, &mw, &mh);
330 edje_extern_object_min_size_set(ki->box_obj, 0, mh);
331 edje_object_part_swallow(ki->base_obj, "e.swallow.label", ki->box_obj);
332 evas_event_thaw(ki->win->evas);
334 _e_kbd_int_matchlist_down(ki);
338 _e_kbd_int_key_press_handle(E_Kbd_Int *ki, E_Kbd_Int_Key *ky)
340 E_Kbd_Int_Key_State *st;
341 const char *out = NULL;
347 if (ki->layout.state & SHIFT) ki->layout.state &= (~(SHIFT));
348 else ki->layout.state |= SHIFT;
349 _e_kbd_int_layout_state_update(ki);
352 if (ky->is_multi_shift)
354 if (ki->layout.state & SHIFT)
356 ki->layout.state &= (~(SHIFT));
357 ki->layout.state |= CAPSLOCK;
359 else if (ki->layout.state & CAPSLOCK)
360 ki->layout.state &= (~(CAPSLOCK));
362 ki->layout.state |= SHIFT;
363 _e_kbd_int_layout_state_update(ki);
368 if (ki->layout.state & CTRL) ki->layout.state &= (~(CTRL));
369 else ki->layout.state |= CTRL;
370 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
371 e_kbd_buf_clear(ki->kbuf);
372 _e_kbd_int_layout_state_update(ki);
373 _e_kbd_int_matches_update(ki);
378 if (ki->layout.state & ALT) ki->layout.state &= (~(ALT));
379 else ki->layout.state |= ALT;
380 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
381 e_kbd_buf_clear(ki->kbuf);
382 _e_kbd_int_layout_state_update(ki);
383 _e_kbd_int_matches_update(ki);
388 if (ki->layout.state & ALTGR) ki->layout.state &= (~(ALTGR));
389 else ki->layout.state |= ALTGR;
390 _e_kbd_int_layout_state_update(ki);
395 if (ki->layout.state & CAPSLOCK) ki->layout.state &= (~CAPSLOCK);
396 else ki->layout.state |= CAPSLOCK;
397 _e_kbd_int_layout_state_update(ki);
400 st = _e_kbd_int_key_state_get(ki, ky);
401 if (st) out = st->out;
402 if (ki->layout.state & (CTRL | ALT))
408 if (ki->layout.state & CTRL) mods |= KBD_MOD_CTRL;
409 if (ki->layout.state & ALT) mods |= KBD_MOD_ALT;
411 e_kbd_send_string_press(_e_kbd_int_str_unquote(out), mods);
413 e_kbd_send_keysym_press(out, mods);
415 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
416 _e_kbd_int_layout_state_update(ki);
417 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
425 e_kbd_buf_pressed_key_add(ki->kbuf,
426 _e_kbd_int_str_unquote(out),
427 ki->layout.state & SHIFT,
428 ki->layout.state & CAPSLOCK);
430 e_kbd_buf_pressed_point_add(ki->kbuf,
433 ki->layout.state & SHIFT,
434 ki->layout.state & CAPSLOCK);
435 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
439 if (e_kbd_buf_actual_string_get(ki->kbuf))
440 _e_kbd_int_buf_send(ki);
441 e_kbd_buf_clear(ki->kbuf);
442 e_kbd_send_keysym_press(out, 0);
443 _e_kbd_int_matches_update(ki);
446 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
448 printf("CLEARING STATE\n");
449 if (!ky->is_multi_shift)
450 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
451 _e_kbd_int_layout_state_update(ki);
456 _e_kbd_int_stroke_handle(E_Kbd_Int *ki, int dir)
458 /* If the keyboard direction is RTL switch dir 3 and 1
459 * i.e, make forward backwards and the other way around */
460 if (ki->layout.direction == E_KBD_INT_DIRECTION_RTL)
469 _e_kbd_int_layout_next(ki);
470 else if (dir == 3) // left
472 if (e_kbd_buf_actual_string_get(ki->kbuf))
474 e_kbd_buf_backspace(ki->kbuf);
475 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
478 e_kbd_send_keysym_press("BackSpace", 0);
480 else if (dir == 2) // down
482 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
483 e_kbd_buf_clear(ki->kbuf);
484 e_kbd_send_keysym_press("Return", 0);
485 _e_kbd_int_matches_update(ki);
487 else if (dir == 1) // right
489 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
490 e_kbd_buf_clear(ki->kbuf);
491 e_kbd_send_keysym_press("space", 0);
492 _e_kbd_int_matches_update(ki);
494 if (ki->layout.state)
496 ki->layout.state = 0;
497 _e_kbd_int_layout_state_update(ki);
502 _e_kbd_int_zoomkey_down(E_Kbd_Int *ki)
506 if (!ki->zoomkey.popup) return;
507 e_object_del(E_OBJECT(ki->zoomkey.popup));
508 ki->zoomkey.popup = NULL;
509 ki->zoomkey.layout_obj = NULL;
510 ki->zoomkey.sublayout_obj = NULL;
511 for (l = ki->layout.keys; l; l = l->next)
517 ky->zoom_icon_obj = NULL;
522 _e_kbd_int_zoomkey_up(E_Kbd_Int *ki)
526 Evas_Coord mw, mh, vw, vh;
529 if (ki->zoomkey.popup) return;
530 ki->zoomkey.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
531 e_popup_layer_set(ki->zoomkey.popup, 190);
533 o = _theme_obj_new(ki->zoomkey.popup->evas, ki->themedir,
534 "e/modules/kbd/zoom/default");
535 ki->zoomkey.base_obj = o;
537 o = e_layout_add(ki->zoomkey.popup->evas);
538 e_layout_virtual_size_set(o, 100, 100);
539 edje_object_part_swallow(ki->zoomkey.base_obj, "e.swallow.content", o);
541 ki->zoomkey.layout_obj = o;
543 e_layout_virtual_size_get(ki->layout_obj, &vw, &vh);
545 o = e_layout_add(ki->zoomkey.popup->evas);
546 e_layout_virtual_size_set(o, vw, vh);
547 e_layout_pack(ki->zoomkey.layout_obj, o);
548 e_layout_child_move(o, 0, 0);
549 e_layout_child_resize(o,
550 vw * il_kbd_cfg->zoom_level,
551 vh * il_kbd_cfg->zoom_level);
553 ki->zoomkey.sublayout_obj = o;
555 for (l = ki->layout.keys; l; l = l->next)
558 E_Kbd_Int_Key_State *st;
559 const char *label, *icon;
563 o = _theme_obj_new(ki->zoomkey.popup->evas, ki->themedir,
564 "e/modules/kbd/zoomkey/default");
567 st = _e_kbd_int_key_state_get(ki, ky);
574 edje_object_part_text_set(o, "e.text.label", label);
576 o2 = e_icon_add(ki->zoomkey.popup->evas);
577 e_icon_fill_inside_set(o2, 1);
578 // e_icon_scale_up_set(o2, 0);
579 edje_object_part_swallow(o, "e.swallow.content", o2);
580 evas_object_show(o2);
587 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, icon);
588 p = strrchr(icon, '.');
589 if (!strcmp(p, ".edj"))
590 e_icon_file_edje_set(o2, buf, "icon");
592 e_icon_file_set(o2, buf);
595 if ((ki->layout.state & SHIFT) && (ky->is_shift)) selected = 1;
596 if ((ki->layout.state & CTRL) && (ky->is_ctrl)) selected = 1;
597 if ((ki->layout.state & ALT) && (ky->is_alt)) selected = 1;
598 if ((ki->layout.state & ALTGR) && (ky->is_altgr)) selected = 1;
599 if ((ki->layout.state & CAPSLOCK) && (ky->is_capslock)) selected = 1;
600 if ((ki->layout.state & (SHIFT|CAPSLOCK)) && (ky->is_multi_shift))
603 edje_object_signal_emit(o, "e,state,selected", "e");
605 edje_object_signal_emit(o, "e,state,unselected", "e");
606 e_layout_pack(ki->zoomkey.sublayout_obj, o);
607 e_layout_child_move(o, ky->x, ky->y);
608 e_layout_child_resize(o, ky->w, ky->h);
611 ky->zoom_icon_obj = o2;
614 edje_object_size_min_calc(ki->zoomkey.base_obj, &vw, &vh);
615 e_zone_useful_geometry_get(ki->win->border->zone, &sx, &sy, &sw, &sh);
618 if ((vw > 0) && (mw > vw)) mw = vw;
620 if ((vh > 0) && (mh > vh)) mh = vh;
622 e_popup_move_resize(ki->zoomkey.popup,
623 sx + ((sw - mw) / 2), sy + ((sh - mh) / 2), mw, mh);
624 evas_object_resize(ki->zoomkey.base_obj,
625 ki->zoomkey.popup->w, ki->zoomkey.popup->h);
626 evas_object_show(ki->zoomkey.base_obj);
627 e_popup_edje_bg_object_set(ki->zoomkey.popup, ki->zoomkey.base_obj);
628 e_popup_show(ki->zoomkey.popup);
629 e_popup_layer_set(ki->zoomkey.popup, 190);
633 _e_kbd_int_zoomkey_update(E_Kbd_Int *ki)
635 Evas_Coord w, h, ww, hh;
638 evas_object_geometry_get(ki->zoomkey.layout_obj, NULL, NULL, &w, &h);
639 evas_object_geometry_get(ki->layout_obj, NULL, NULL, &ww, &hh);
640 e_layout_virtual_size_set(ki->zoomkey.layout_obj, w, h);
641 e_layout_child_resize(ki->zoomkey.sublayout_obj,
642 ww * il_kbd_cfg->zoom_level,
643 hh * il_kbd_cfg->zoom_level);
644 e_layout_child_move(ki->zoomkey.sublayout_obj,
645 (w / 2) - (ki->down.cx * il_kbd_cfg->zoom_level),
646 (h / 2) - (ki->down.cy * il_kbd_cfg->zoom_level));
647 ky = _e_kbd_int_at_coord_get(ki, ki->down.clx, ki->down.cly);
648 if (ky != ki->zoomkey.pressed)
650 if (ki->zoomkey.pressed)
652 ki->zoomkey.pressed->pressed = 0;
653 edje_object_signal_emit(ki->zoomkey.pressed->zoom_obj,
654 "e,state,released", "e");
655 edje_object_signal_emit(ki->zoomkey.pressed->obj,
656 "e,state,released", "e");
658 ki->zoomkey.pressed = ky;
659 if (ki->zoomkey.pressed)
661 ki->zoomkey.pressed->pressed = 1;
662 e_layout_child_raise(ki->zoomkey.pressed->zoom_obj);
663 edje_object_signal_emit(ki->zoomkey.pressed->zoom_obj,
664 "e,state,pressed", "e");
665 e_layout_child_raise(ki->zoomkey.pressed->obj);
666 e_layout_child_raise(ki->event_obj);
667 edje_object_signal_emit(ki->zoomkey.pressed->obj,
668 "e,state,pressed", "e");
674 _e_kbd_int_cb_hold_timeout(void *data)
679 ki->down.hold_timer = NULL;
681 if (ki->layout.pressed)
683 ki->layout.pressed->pressed = 0;
684 edje_object_signal_emit(ki->layout.pressed->obj,
685 "e,state,released", "e");
686 ki->layout.pressed = NULL;
688 _e_kbd_int_zoomkey_up(ki);
689 _e_kbd_int_zoomkey_update(ki);
690 return ECORE_CALLBACK_CANCEL;
694 _e_kbd_int_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
696 Evas_Event_Mouse_Down *ev;
698 Evas_Coord x, y, w, h;
702 if (ev->button != 1) return;
704 ki->down.x = ev->canvas.x;
705 ki->down.y = ev->canvas.y;
709 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
710 x = ev->canvas.x - x;
711 y = ev->canvas.y - y;
714 x = (x * ki->layout.w) / w;
715 y = (y * ki->layout.h) / h;
722 if (ki->down.hold_timer) ecore_timer_del(ki->down.hold_timer);
723 ki->down.hold_timer = ecore_timer_add(il_kbd_cfg->hold_timer,
724 _e_kbd_int_cb_hold_timeout, ki);
726 ky = _e_kbd_int_at_coord_get(ki, x, y);
727 ki->layout.pressed = ky;
731 e_layout_child_raise(ky->obj);
732 e_layout_child_raise(ki->event_obj);
733 edje_object_signal_emit(ky->obj, "e,state,pressed", "e");
738 _e_kbd_int_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
740 Evas_Event_Mouse_Move *ev;
742 Evas_Coord dx, dy, x, w, y, h;
749 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
750 x = ev->cur.canvas.x - x;
751 y = ev->cur.canvas.y - y;
754 x = (x * ki->layout.w) / w;
755 y = (y * ki->layout.h) / h;
758 _e_kbd_int_zoomkey_update(ki);
761 if (ki->down.stroke) return;
763 dx = ev->cur.canvas.x - ki->down.x;
764 dy = ev->cur.canvas.y - ki->down.y;
765 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
766 dx = (dx * ki->layout.w) / w;
767 dy = (dy * ki->layout.h) / h;
768 if ((dx > 0) && (dx > (ki->layout.w / il_kbd_cfg->slide_dim)))
770 else if ((dx < 0) && (-dx > (ki->layout.w / il_kbd_cfg->slide_dim)))
772 if ((dy > 0) && (dy > (ki->layout.h / il_kbd_cfg->slide_dim)))
774 else if ((dy < 0) && (-dy > (ki->layout.w / il_kbd_cfg->slide_dim)))
776 if ((ki->down.stroke) && (ki->down.hold_timer))
778 ecore_timer_del(ki->down.hold_timer);
779 ki->down.hold_timer = NULL;
784 _e_kbd_int_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
786 Evas_Event_Mouse_Up *ev;
792 if (ev->button != 1) return;
797 ky = _e_kbd_int_at_coord_get(ki, ki->down.clx, ki->down.cly);
798 _e_kbd_int_key_press_handle(ki, ky);
799 _e_kbd_int_zoomkey_down(ki);
802 else if (!ki->down.down)
804 /* case of mouse up event without mouse down when popup appear */
805 Evas_Coord x, y, w, h;
806 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
807 x = ev->canvas.x - x;
808 y = ev->canvas.y - y;
809 x = (x * ki->layout.w) / w;
810 y = (y * ki->layout.h) / h;
811 ky = _e_kbd_int_at_coord_get(ki, x, y);
812 ki->layout.pressed = ky;
813 _e_kbd_int_key_press_handle(ki, ki->layout.pressed);
814 edje_object_signal_emit(ky->obj,
815 "e,state,pressed", "e");
816 edje_object_message_signal_process(ky->obj);
818 else if (!ki->down.stroke)
821 ky = _e_kbd_int_at_coord_get(ki, ki->down.lx, ki->down.ly);
822 _e_kbd_int_key_press_handle(ki, ky);
828 dx = ev->canvas.x - ki->down.x;
829 dy = ev->canvas.y - ki->down.y;
834 if (dx > dy) dir = 1; // right
835 else dir = 2; // down
839 if (dx > -dy) dir = 1; // right
847 if (-dx > dy) dir = 3; // left
848 else dir = 2; // down
852 if (-dx > -dy) dir = 3; // left
858 ky = ki->layout.pressed;
862 edje_object_signal_emit(ky->obj, "e,state,released", "e");
863 ki->layout.pressed = NULL;
865 ky = ki->zoomkey.pressed;
869 edje_object_signal_emit(ky->obj, "e,state,released", "e");
870 ki->zoomkey.pressed = NULL;
875 if (ki->down.hold_timer)
877 ecore_timer_del(ki->down.hold_timer);
878 ki->down.hold_timer = NULL;
881 if (dir > 0) _e_kbd_int_stroke_handle(ki, dir);
884 static E_Kbd_Int_Layout *
885 _e_kbd_int_layouts_list_default_get(E_Kbd_Int *ki)
887 E_Kbd_Int_Layout *kil;
890 EINA_LIST_FOREACH(ki->layouts, l, kil)
891 if (kil->type == il_kbd_cfg->layout)
894 EINA_LIST_FOREACH(ki->layouts, l, kil)
895 if ((!strcmp(ecore_file_file_get(kil->path), "Default.kbd")))
900 static E_Kbd_Int_Layout *
901 _e_kbd_int_layouts_type_get(E_Kbd_Int *ki, int type)
903 E_Kbd_Int_Layout *kil;
906 EINA_LIST_FOREACH(ki->layouts, l, kil)
907 if (kil->type == type) return kil;
912 _e_kbd_int_layout_free(E_Kbd_Int *ki)
916 if (ki->layout.directory) free(ki->layout.directory);
917 if (ki->layout.file) eina_stringshare_del(ki->layout.file);
918 ki->layout.directory = NULL;
919 ki->layout.file = NULL;
920 EINA_LIST_FREE(ki->layout.keys, ky)
922 E_Kbd_Int_Key_State *st;
924 EINA_LIST_FREE(ky->states, st)
926 if (st->label) eina_stringshare_del(st->label);
927 if (st->icon) eina_stringshare_del(st->icon);
928 if (st->out) eina_stringshare_del(st->out);
931 if (ky->obj) evas_object_del(ky->obj);
932 if (ky->icon_obj) evas_object_del(ky->icon_obj);
935 if (ki->event_obj) evas_object_del(ki->event_obj);
936 ki->event_obj = NULL;
940 _e_kbd_int_layout_parse(E_Kbd_Int *ki, const char *layout)
945 E_Kbd_Int_Key *ky = NULL;
946 E_Kbd_Int_Key_State *st = NULL;
948 if (!(f = fopen(layout, "r"))) return;
950 ki->layout.directory = ecore_file_dir_get(layout);
951 ki->layout.file = eina_stringshare_add(layout);
953 /* Make the default direction LTR */
954 ki->layout.direction = E_KBD_INT_DIRECTION_LTR;
956 while (fgets(buf, sizeof(buf), f))
963 if (!strcmp(buf, "##KBDCONF-1.0\n")) isok = 1;
966 if (buf[0] == '#') continue;
970 if (buf[len - 1] == '\n') buf[len - 1] = 0;
972 if (sscanf(buf, "%4000s", str) != 1) continue;
973 if (!strcmp(str, "kbd"))
975 if (sscanf(buf, "%*s %i %i\n", &(ki->layout.w), &(ki->layout.orig_h)) != 2)
978 if (!strcmp(str, "fuzz"))
980 sscanf(buf, "%*s %i\n", &(ki->layout.fuzz));
983 if (!strcmp(str, "direction"))
987 sscanf(buf, "%*s %3s\n", direction);
989 /* If rtl mark as rtl, otherwise make it ltr */
990 if (!strcmp(direction, "rtl"))
991 ki->layout.direction = E_KBD_INT_DIRECTION_RTL;
993 ki->layout.direction = E_KBD_INT_DIRECTION_LTR;
996 if (!strcmp(str, "key"))
998 ky = calloc(1, sizeof(E_Kbd_Int_Key));
1000 if (sscanf(buf, "%*s %i %i %i %i\n", &(ky->x), &(ky->orig_y), &(ky->w), &(ky->orig_h)) != 4)
1006 ki->layout.keys = eina_list_append(ki->layout.keys, ky);
1009 if ((!strcmp(str, "normal")) || (!strcmp(str, "shift")) ||
1010 (!strcmp(str, "capslock")) || (!strcmp(str, "altgr")))
1015 if (sscanf(buf, "%*s %4000s", label) != 1) continue;
1016 st = calloc(1, sizeof(E_Kbd_Int_Key_State));
1018 ky->states = eina_list_append(ky->states, st);
1019 if (!strcmp(str, "normal")) st->state = NORMAL;
1020 if (!strcmp(str, "shift")) st->state = SHIFT;
1021 if (!strcmp(str, "capslock")) st->state = CAPSLOCK;
1022 if (!strcmp(str, "altgr")) st->state = ALTGR;
1023 p = strrchr(label, '.');
1024 if ((p) && (!strcmp(p, ".png")))
1025 st->icon = eina_stringshare_add(label);
1026 else if ((p) && (!strcmp(p, ".edj")))
1027 st->icon = eina_stringshare_add(label);
1029 st->label = eina_stringshare_add(label);
1030 if (sscanf(buf, "%*s %*s %4000s", str) != 1) continue;
1031 st->out = eina_stringshare_add(str);
1033 if (!strcmp(str, "is_shift")) ky->is_shift = 1;
1034 if (!strcmp(str, "is_multi_shift")) ky->is_multi_shift = 1;
1035 if (!strcmp(str, "is_ctrl")) ky->is_ctrl = 1;
1036 if (!strcmp(str, "is_alt")) ky->is_alt = 1;
1037 if (!strcmp(str, "is_altgr")) ky->is_altgr = 1;
1038 if (!strcmp(str, "is_capslock")) ky->is_capslock = 1;
1044 _e_kbd_int_layout_build(E_Kbd_Int *ki)
1047 Evas_Object *o, *o2;
1051 ki->layout.h = ki->layout.orig_h * il_kbd_cfg->scale_height;
1053 evas_event_freeze(ki->win->evas);
1054 e_layout_virtual_size_set(ki->layout_obj, ki->layout.w, ki->layout.h);
1055 edje_extern_object_aspect_set(ki->layout_obj, EDJE_ASPECT_CONTROL_BOTH,
1056 ki->layout.w, ki->layout.h);
1057 edje_object_part_swallow(ki->base_obj, "e.swallow.content", ki->layout_obj);
1058 evas_object_resize(ki->base_obj, ki->win->w, ki->win->h);
1059 edje_object_part_geometry_get(ki->base_obj, "e.swallow.content",
1060 NULL, NULL, &lw, &lh);
1061 lh = (ki->layout.h * lw) / ki->layout.w;
1062 if (lw > ki->win->w) lw = ki->win->w;
1063 if (lh > ki->win->h) lh = ki->win->h;
1064 edje_extern_object_min_size_set(ki->layout_obj, lw, lh);
1065 edje_extern_object_max_size_set(ki->layout_obj, ki->win->w, ki->win->h);
1067 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
1069 E_Kbd_Int_Key_State *st;
1070 const char *label, *icon;
1072 ky->y = ky->orig_y * il_kbd_cfg->scale_height;
1073 ky->h = ky->orig_h * il_kbd_cfg->scale_height;
1075 o = _theme_obj_new(ki->win->evas, ki->themedir,
1076 "e/modules/kbd/key/default");
1080 st = _e_kbd_int_key_state_get(ki, ky);
1087 edje_object_part_text_set(o, "e.text.label", label);
1089 o2 = e_icon_add(ki->win->evas);
1090 e_icon_fill_inside_set(o2, 1);
1091 e_icon_scale_up_set(o2, 0);
1093 edje_object_part_swallow(o, "e.swallow.content", o2);
1094 evas_object_show(o2);
1101 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, icon);
1102 p = strrchr(icon, '.');
1103 if (!strcmp(p, ".edj"))
1104 e_icon_file_edje_set(o2, buf, "icon");
1106 e_icon_file_set(o2, buf);
1108 e_layout_pack(ki->layout_obj, o);
1109 e_layout_child_move(o, ky->x, ky->y);
1110 e_layout_child_resize(o, ky->w, ky->h);
1111 evas_object_show(o);
1114 o = evas_object_rectangle_add(ki->win->evas);
1115 e_layout_pack(ki->layout_obj, o);
1116 e_layout_child_move(o, 0, 0);
1117 e_layout_child_resize(o, ki->layout.w, ki->layout.h);
1118 evas_object_color_set(o, 0, 0, 0, 0);
1119 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
1120 _e_kbd_int_cb_mouse_down, ki);
1121 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
1122 _e_kbd_int_cb_mouse_up, ki);
1123 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE,
1124 _e_kbd_int_cb_mouse_move, ki);
1125 evas_object_show(o);
1127 evas_event_thaw(ki->win->evas);
1128 _e_kbd_int_matchlist_down(ki);
1132 _e_kbd_int_layouts_free(E_Kbd_Int *ki)
1134 E_Kbd_Int_Layout *kil;
1136 EINA_LIST_FREE(ki->layouts, kil)
1138 eina_stringshare_del(kil->path);
1139 eina_stringshare_del(kil->dir);
1140 eina_stringshare_del(kil->icon);
1141 eina_stringshare_del(kil->name);
1147 _e_kbd_int_layouts_list_update(E_Kbd_Int *ki)
1151 char buf[PATH_MAX], *p, *file, *path;
1153 Eina_List *kbs = NULL, *layouts = NULL;
1157 len = e_user_dir_concat_static(buf, "keyboards");
1158 if (len + 2 >= sizeof(buf)) return;
1160 files = ecore_file_ls(buf);
1165 EINA_LIST_FREE(files, file)
1167 p = strrchr(file, '.');
1168 if ((p) && (!strcmp(p, ".kbd")))
1170 if (eina_strlcpy(buf + len, file, sizeof(buf) - len) >= sizeof(buf) - len)
1172 kbs = eina_list_append(kbs, eina_stringshare_add(buf));
1177 len = snprintf(buf, sizeof(buf), "%s/keyboards", ki->syskbds);
1178 if (len + 2 >= sizeof(buf)) return;
1180 files = ecore_file_ls(buf);
1185 EINA_LIST_FREE(files, file)
1187 p = strrchr(file, '.');
1188 if ((p) && (!strcmp(p, ".kbd")))
1191 EINA_LIST_FOREACH(kbs, l, fl)
1193 if (!strcmp(file, fl))
1201 if (eina_strlcpy(buf + len, file, sizeof(buf) - len) >= sizeof(buf) - len)
1203 kbs = eina_list_append(kbs, eina_stringshare_add(buf));
1208 /* Previous loop could break before destroying all items. */
1209 EINA_LIST_FREE(files, file)
1212 EINA_LIST_FREE(kbs, path)
1214 E_Kbd_Int_Layout *kil;
1216 kil = E_NEW(E_Kbd_Int_Layout, 1);
1223 s = strdup(ecore_file_file_get(kil->path));
1226 p = strrchr(s, '.');
1228 kil->name = eina_stringshare_add(s);
1231 s = ecore_file_dir_get(kil->path);
1234 kil->dir = eina_stringshare_add(s);
1237 f = fopen(kil->path, "r");
1242 while (fgets(buf, sizeof(buf), f))
1248 if (!strcmp(buf, "##KBDCONF-1.0\n")) isok = 1;
1251 if (buf[0] == '#') continue;
1255 if (buf[len - 1] == '\n') buf[len - 1] = 0;
1257 if (sscanf(buf, "%4000s", str) != 1) continue;
1258 if (!strcmp(str, "type"))
1260 sscanf(buf, "%*s %4000s\n", str);
1261 if (!strcmp(str, "ALPHA"))
1262 kil->type = E_KBD_INT_TYPE_ALPHA;
1263 else if (!strcmp(str, "NUMERIC"))
1264 kil->type = E_KBD_INT_TYPE_NUMERIC;
1265 else if (!strcmp(str, "PIN"))
1266 kil->type = E_KBD_INT_TYPE_PIN;
1267 else if (!strcmp(str, "PHONE_NUMBER"))
1268 kil->type = E_KBD_INT_TYPE_PHONE_NUMBER;
1269 else if (!strcmp(str, "HEX"))
1270 kil->type = E_KBD_INT_TYPE_HEX;
1271 else if (!strcmp(str, "TERMINAL"))
1272 kil->type = E_KBD_INT_TYPE_TERMINAL;
1273 else if (!strcmp(str, "PASSWORD"))
1274 kil->type = E_KBD_INT_TYPE_PASSWORD;
1275 else if (!strcmp(str, "IP"))
1276 kil->type = E_KBD_INT_TYPE_IP;
1277 else if (!strcmp(str, "HOST"))
1278 kil->type = E_KBD_INT_TYPE_HOST;
1279 else if (!strcmp(str, "FILE"))
1280 kil->type = E_KBD_INT_TYPE_FILE;
1281 else if (!strcmp(str, "URL"))
1282 kil->type = E_KBD_INT_TYPE_URL;
1283 else if (!strcmp(str, "KEYPAD"))
1284 kil->type = E_KBD_INT_TYPE_KEYPAD;
1285 else if (!strcmp(str, "J2ME"))
1286 kil->type = E_KBD_INT_TYPE_J2ME;
1289 if (!strcmp(str, "icon"))
1291 sscanf(buf, "%*s %4000s\n", str);
1292 snprintf(buf, sizeof(buf), "%s/%s", kil->dir, str);
1293 kil->icon = eina_stringshare_add(buf);
1299 layouts = eina_list_append(layouts, kil);
1302 _e_kbd_int_layouts_free(ki);
1303 ki->layouts = layouts;
1307 _e_kbd_int_layout_select(E_Kbd_Int *ki, E_Kbd_Int_Layout *kil)
1309 _e_kbd_int_layout_free(ki);
1310 _e_kbd_int_layout_parse(ki, kil->path);
1311 _e_kbd_int_layout_build(ki);
1312 _e_kbd_int_layout_buf_update(ki);
1313 _e_kbd_int_layout_state_update(ki);
1316 e_icon_file_set(ki->icon_obj, kil->icon);
1321 p = strrchr(kil->icon, '.');
1323 e_icon_file_set(ki->icon_obj, kil->icon);
1326 if (!strcmp(p, ".edj"))
1327 e_icon_file_edje_set(ki->icon_obj, kil->icon, "icon");
1329 e_icon_file_set(ki->icon_obj, kil->icon);
1335 _e_kbd_int_layout_next(E_Kbd_Int *ki)
1337 Eina_List *l, *ln = NULL;
1338 E_Kbd_Int_Layout *kil;
1340 EINA_LIST_FOREACH(ki->layouts, l, kil)
1341 if (!strcmp(kil->path, ki->layout.file))
1346 if (!ln) ln = ki->layouts;
1349 _e_kbd_int_layout_select(ki, kil);
1353 _e_kbd_int_cb_client_message(void *data, __UNUSED__ int type, void *event)
1355 Ecore_X_Event_Client_Message *ev;
1360 if ((ev->win == ki->win->evas_win) &&
1361 (ev->message_type == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE))
1363 E_Kbd_Int_Layout *kil = NULL;
1365 if ((unsigned int)ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF)
1367 _e_kbd_int_zoomkey_down(ki);
1368 _e_kbd_int_dictlist_down(ki);
1369 _e_kbd_int_matchlist_down(ki);
1371 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_ON)
1373 // do nothing - leave kbd as-is
1375 else if ((unsigned int)ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA)
1376 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_ALPHA);
1377 else if ((unsigned int)ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC)
1378 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_NUMERIC);
1379 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN)
1380 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PIN);
1381 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER)
1382 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PHONE_NUMBER);
1383 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX)
1384 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_HEX);
1385 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL)
1386 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_TERMINAL);
1387 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD)
1388 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PASSWORD);
1389 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_IP)
1390 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_IP);
1391 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST)
1392 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_HOST);
1393 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE)
1394 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_FILE);
1395 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_URL)
1396 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_URL);
1397 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD)
1398 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_KEYPAD);
1399 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME)
1400 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_J2ME);
1402 if (kil) _e_kbd_int_layout_select(ki, kil);
1404 return ECORE_CALLBACK_PASS_ON;
1408 _e_kbd_int_dictlist_down(E_Kbd_Int *ki)
1412 if (!ki->dictlist.popup) return;
1413 e_object_del(E_OBJECT(ki->dictlist.popup));
1414 ki->dictlist.popup = NULL;
1415 EINA_LIST_FREE(ki->dictlist.matches, str)
1416 eina_stringshare_del(str);
1420 _e_kbd_int_cb_dictlist_item_sel(void *data)
1427 i = e_widget_ilist_selected_get(ki->dictlist.ilist_obj);
1428 str = eina_list_nth(ki->dictlist.matches, i);
1429 e_kbd_buf_clear(ki->kbuf);
1430 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
1432 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
1433 _e_kbd_int_layout_state_update(ki);
1436 eina_stringshare_replace(&il_kbd_cfg->dict, str);
1437 e_kbd_buf_dict_set(ki->kbuf, il_kbd_cfg->dict);
1438 e_config_save_queue();
1440 _e_kbd_int_dictlist_down(ki);
1444 _e_kbd_int_dictlist_up(E_Kbd_Int *ki)
1447 Evas_Coord mw, mh, sh;
1448 Eina_List *files, *l;
1449 char buf[PATH_MAX], *p, *file, *pp;
1453 if (ki->dictlist.popup) return;
1455 ki->dictlist.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
1456 e_popup_layer_set(ki->dictlist.popup, 190);
1458 o = _theme_obj_new(ki->dictlist.popup->evas, ki->themedir,
1459 "e/modules/kbd/match/default");
1460 ki->dictlist.base_obj = o;
1462 o = e_widget_ilist_add(ki->dictlist.popup->evas,
1463 (32 * e_scale), (32 * e_scale), NULL);
1464 e_widget_ilist_selector_set(o, 1);
1465 e_widget_ilist_freeze(o);
1466 ki->dictlist.ilist_obj = o;
1468 e_user_dir_concat_static(buf, "dicts");
1469 files = ecore_file_ls(buf);
1471 EINA_LIST_FREE(files, file)
1473 p = strrchr(file, '.');
1474 if ((p) && (!strcmp(p, ".dic")))
1479 EINA_LIST_FOREACH(ki->dictlist.matches, l, match)
1480 if (!strcmp(match, file)) used = 1;
1482 if (used) goto next1;
1487 for (pp = p; *pp; pp++)
1489 if (*pp == '_') *pp = ' ';
1491 pp = strrchr(p, '.');
1493 str = eina_stringshare_add(file);
1494 ki->dictlist.matches = eina_list_append(ki->dictlist.matches, str);
1495 e_widget_ilist_append(o, NULL, p, _e_kbd_int_cb_dictlist_item_sel,
1504 snprintf(buf, sizeof(buf), "%s/dicts", ki->sysdicts);
1505 files = ecore_file_ls(buf);
1506 EINA_LIST_FREE(files, file)
1508 p = strrchr(file, '.');
1509 if ((p) && (!strcmp(p, ".dic")))
1514 EINA_LIST_FOREACH(ki->dictlist.matches, l, match)
1515 if (!strcmp(match, file)) used = 1;
1517 if (used) goto next2;
1522 for (pp = p; *pp; pp++)
1524 if (*pp == '_') *pp = ' ';
1526 pp = strrchr(p, '.');
1528 str = eina_stringshare_add(file);
1529 ki->dictlist.matches = eina_list_append(ki->dictlist.matches, str);
1530 e_widget_ilist_append(o, NULL, p, _e_kbd_int_cb_dictlist_item_sel,
1537 e_widget_ilist_thaw(o);
1538 e_widget_ilist_go(o);
1540 e_widget_ilist_preferred_size_get(o, &mw, &mh);
1541 if (mh < (120 *e_scale)) mh = (120 * e_scale);
1543 edje_extern_object_min_size_set(ki->dictlist.ilist_obj, mw, mh);
1544 edje_object_part_swallow(ki->dictlist.base_obj, "e.swallow.content",
1545 ki->dictlist.ilist_obj);
1546 edje_object_size_min_calc(ki->dictlist.base_obj, &mw, &mh);
1548 e_zone_useful_geometry_get(ki->win->border->zone, NULL, NULL, NULL, &sh);
1550 if (mh > (sh - ki->win->h)) mh = (sh - ki->win->h);
1551 e_popup_move_resize(ki->dictlist.popup, 0, ki->win->y - mh, mw, mh);
1553 evas_object_resize(ki->dictlist.base_obj,
1554 ki->dictlist.popup->w, ki->dictlist.popup->h);
1555 evas_object_show(ki->dictlist.base_obj);
1556 e_popup_edje_bg_object_set(ki->dictlist.popup, ki->dictlist.base_obj);
1557 e_popup_show(ki->dictlist.popup);
1558 _e_kbd_int_matchlist_down(ki);
1562 _e_kbd_int_matchlist_down(E_Kbd_Int *ki)
1566 if (!ki->matchlist.popup) return;
1567 e_object_del(E_OBJECT(ki->matchlist.popup));
1568 ki->matchlist.popup = NULL;
1569 EINA_LIST_FREE(ki->matchlist.matches, str)
1570 eina_stringshare_del(str);
1574 _e_kbd_int_cb_matchlist_item_sel(void *data)
1580 str = e_widget_ilist_selected_label_get(ki->matchlist.ilist_obj);
1581 _e_kbd_int_string_send(ki, str);
1582 e_kbd_buf_clear(ki->kbuf);
1583 e_kbd_send_keysym_press("space", 0);
1584 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
1586 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
1587 _e_kbd_int_layout_state_update(ki);
1589 _e_kbd_int_matches_update(ki);
1590 _e_kbd_int_matchlist_down(ki);
1594 _e_kbd_int_matchlist_up(E_Kbd_Int *ki)
1598 Evas_Coord mw, mh, sh;
1600 if (!e_kbd_buf_string_matches_get(ki->kbuf)) return;
1601 if (ki->matchlist.popup) return;
1602 ki->matchlist.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
1603 e_popup_layer_set(ki->matchlist.popup, 190);
1605 o = _theme_obj_new(ki->matchlist.popup->evas, ki->themedir,
1606 "e/modules/kbd/match/default");
1607 ki->matchlist.base_obj = o;
1609 o = e_widget_ilist_add(ki->matchlist.popup->evas,
1610 (32 * e_scale), (32 * e_scale), NULL);
1611 e_widget_ilist_selector_set(o, 1);
1612 ki->matchlist.ilist_obj = o;
1613 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content", o);
1614 evas_object_show(o);
1616 for (l = e_kbd_buf_string_matches_get(ki->kbuf); l; l = l->next)
1622 str = e_kbd_buf_actual_string_get(ki->kbuf);
1625 str = eina_stringshare_add(str);
1626 ki->matchlist.matches = eina_list_append(ki->matchlist.matches, str);
1627 e_widget_ilist_append(o, NULL, str,
1628 _e_kbd_int_cb_matchlist_item_sel,
1633 str = eina_stringshare_add(str);
1634 ki->matchlist.matches = eina_list_append(ki->matchlist.matches, str);
1635 e_widget_ilist_append(o, NULL, str, _e_kbd_int_cb_matchlist_item_sel,
1638 e_widget_ilist_thaw(o);
1639 e_widget_ilist_go(o);
1641 e_widget_ilist_preferred_size_get(o, &mw, &mh);
1642 if (mh < (120 *e_scale)) mh = (120 * e_scale);
1644 edje_extern_object_min_size_set(ki->matchlist.ilist_obj, mw, mh);
1645 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content",
1646 ki->matchlist.ilist_obj);
1647 edje_object_size_min_calc(ki->matchlist.base_obj, &mw, &mh);
1649 edje_extern_object_min_size_set(ki->matchlist.ilist_obj, 0, 0);
1650 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content",
1651 ki->matchlist.ilist_obj);
1652 e_zone_useful_geometry_get(ki->win->border->zone, NULL, NULL, NULL, &sh);
1654 if (mh > (sh - ki->win->h)) mh = (sh - ki->win->h);
1655 e_popup_move_resize(ki->matchlist.popup,
1656 ki->win->x, ki->win->y - mh, mw, mh);
1657 evas_object_resize(ki->matchlist.base_obj,
1658 ki->matchlist.popup->w, ki->matchlist.popup->h);
1659 evas_object_show(ki->matchlist.base_obj);
1660 e_popup_edje_bg_object_set(ki->matchlist.popup, ki->matchlist.base_obj);
1661 e_popup_show(ki->matchlist.popup);
1663 _e_kbd_int_dictlist_down(ki);
1667 _e_kbd_int_cb_matches(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1672 if (ki->dictlist.popup) _e_kbd_int_dictlist_down(ki);
1673 else if (ki->matchlist.popup) _e_kbd_int_matchlist_down(ki);
1676 if (!e_kbd_buf_actual_string_get(ki->kbuf))
1677 _e_kbd_int_dictlist_up(ki);
1679 _e_kbd_int_matchlist_up(ki);
1684 _e_kbd_int_cb_dicts(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1689 if (ki->dictlist.popup) _e_kbd_int_dictlist_down(ki);
1690 else _e_kbd_int_dictlist_up(ki);
1694 _e_kbd_int_cb_layouts(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1699 _e_kbd_int_layout_next(ki);
1703 _e_kbd_int_cb_resize(E_Win *win)
1710 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
1712 if (ky->obj) evas_object_del(ky->obj);
1713 if (ky->icon_obj) evas_object_del(ky->icon_obj);
1715 if (ki->event_obj) evas_object_del(ki->event_obj);
1716 ki->event_obj = NULL;
1718 _e_kbd_int_layout_build(ki);
1719 _e_kbd_int_layout_buf_update(ki);
1720 _e_kbd_int_layout_state_update(ki);
1724 e_kbd_int_new(const char *themedir, const char *syskbds, const char *sysdicts)
1730 E_Kbd_Int_Layout *kil;
1731 Ecore_X_Window_State states[2];
1733 ki = E_NEW(E_Kbd_Int, 1);
1734 if (!ki) return NULL;
1735 if (themedir) ki->themedir = eina_stringshare_add(themedir);
1736 if (syskbds) ki->syskbds = eina_stringshare_add(syskbds);
1737 if (sysdicts) ki->sysdicts = eina_stringshare_add(sysdicts);
1738 zone = e_util_zone_current_get(e_manager_current_get());
1739 ki->win = e_win_new(zone->container);
1740 states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
1741 states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
1742 ecore_x_netwm_window_state_set(ki->win->evas_win, states, 2);
1743 ecore_x_icccm_hints_set(ki->win->evas_win, 0, 0, 0, 0, 0, 0, 0);
1744 e_win_no_remember_set(ki->win, 1);
1750 e_win_resize(ki->win, mw, (mh / 2));
1752 e_win_resize(ki->win, mw, mh);
1754 e_win_resize_callback_set(ki->win, _e_kbd_int_cb_resize);
1755 e_win_borderless_set(ki->win, 1);
1757 e_win_name_class_set(ki->win, "Virtual-Keyboard", "Virtual-Keyboard");
1758 e_win_title_set(ki->win, "Virtual Keyboard");
1760 ki->base_obj = _theme_obj_new(ki->win->evas, ki->themedir,
1761 "e/modules/kbd/base/default");
1762 edje_object_signal_callback_add(ki->base_obj, "e,action,do,matches", "",
1763 _e_kbd_int_cb_matches, ki);
1764 edje_object_signal_callback_add(ki->base_obj, "e,action,do,layouts", "",
1765 _e_kbd_int_cb_layouts, ki);
1766 edje_object_signal_callback_add(ki->base_obj, "e,action,do,dicts", "",
1767 _e_kbd_int_cb_dicts, ki);
1769 o = e_layout_add(ki->win->evas);
1770 edje_object_part_swallow(ki->base_obj, "e.swallow.content", o);
1771 evas_object_show(o);
1774 o = e_icon_add(ki->win->evas);
1775 evas_object_pass_events_set(o, 1);
1776 e_icon_fill_inside_set(o, 1);
1777 e_icon_scale_up_set(o, 0);
1778 edje_object_part_swallow(ki->base_obj, "e.swallow.layout", o);
1779 evas_object_show(o);
1782 o = e_box_add(ki->win->evas);
1783 e_box_orientation_set(o, 1);
1784 e_box_homogenous_set(o, 1);
1785 edje_object_part_swallow(ki->base_obj, "e.swallow.label", o);
1786 evas_object_show(o);
1789 if (il_kbd_cfg->dict)
1790 ki->kbuf = e_kbd_buf_new(ki->sysdicts, il_kbd_cfg->dict);
1792 ki->kbuf = e_kbd_buf_new(ki->sysdicts, "English_US.dic");
1794 _e_kbd_int_layouts_list_update(ki);
1796 kil = _e_kbd_int_layouts_list_default_get(ki);
1797 if ((!kil) && (ki->layouts))
1798 kil = ki->layouts->data;
1800 if (kil) _e_kbd_int_layout_select(ki, kil);
1802 edje_object_size_min_calc(ki->base_obj, &mw, &mh);
1803 if (mw < 48) mw = 48;
1804 if (mh < 48) mh = 48;
1805 evas_object_move(ki->base_obj, 0, 0);
1806 evas_object_resize(ki->base_obj, zone->w, mh);
1807 evas_object_show(ki->base_obj);
1809 e_win_size_min_set(ki->win, mw, mh);
1810 ecore_x_e_virtual_keyboard_set(ki->win->evas_win, 1);
1812 ki->client_message_handler =
1813 ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
1814 _e_kbd_int_cb_client_message, ki);
1816 ecore_event_handler_add(E_EVENT_BORDER_MOVE,
1817 _e_kbd_int_cb_border_move, ki);
1819 e_win_show(ki->win);
1820 ki->win->border->user_skip_winlist = 1;
1821 ki->win->border->lock_focus_in = 1;
1822 ki->win->border->lock_focus_out = 1;
1828 e_kbd_int_free(E_Kbd_Int *ki)
1830 if (ki->themedir) eina_stringshare_del(ki->themedir);
1831 if (ki->syskbds) eina_stringshare_del(ki->syskbds);
1832 if (ki->sysdicts) eina_stringshare_del(ki->sysdicts);
1833 _e_kbd_int_layouts_free(ki);
1834 _e_kbd_int_matches_free(ki);
1835 _e_kbd_int_layout_free(ki);
1836 ecore_event_handler_del(ki->client_message_handler);
1837 ecore_event_handler_del(ki->kbd_move_hdl);
1838 if (ki->down.hold_timer) ecore_timer_del(ki->down.hold_timer);
1839 _e_kbd_int_matchlist_down(ki);
1840 _e_kbd_int_zoomkey_down(ki);
1841 e_kbd_buf_free(ki->kbuf);
1842 e_object_del(E_OBJECT(ki->win));
1846 static Evas_Object *
1847 _theme_obj_new(Evas *e, const char *custom_dir, const char *group)
1851 o = edje_object_add(e);
1852 if (!e_theme_edje_object_set(o, "base/theme/modules/illume", group))
1858 snprintf(buf, sizeof(buf), "%s/e-module-illume-keyboard.edj",
1860 edje_object_file_set(o, buf, group);
1867 _e_kbd_int_cb_border_move(void *data, int type __UNUSED__, void *event)
1869 E_Event_Border_Move *ev;
1873 if (!(ki = data)) return ECORE_CALLBACK_PASS_ON;
1874 if (ki->win->border != ev->border) return ECORE_CALLBACK_PASS_ON;
1875 _e_kbd_int_zoomkey_down(ki);
1876 _e_kbd_int_matchlist_down(ki);
1877 _e_kbd_int_dictlist_down(ki);
1878 return ECORE_CALLBACK_PASS_ON;