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);
27 _e_kbd_int_cb_resize(E_Win *win)
32 evas_object_resize(ki->base_obj, ki->win->w, ki->win->h);
33 _e_kbd_int_zoomkey_down(ki);
34 _e_kbd_int_dictlist_down(ki);
35 _e_kbd_int_matchlist_down(ki);
39 _e_kbd_int_str_unquote(const char *str)
44 snprintf(buf, sizeof(buf), "%s", str + 1);
45 p = strrchr(buf, '"');
50 static E_Kbd_Int_Key *
51 _e_kbd_int_at_coord_get(E_Kbd_Int *ki, Evas_Coord x, Evas_Coord y)
56 E_Kbd_Int_Key *closest_ky = NULL;
58 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
59 if ((x >= ky->x) && (y >= ky->y) &&
60 (x < (ky->x + ky->w)) && (y < (ky->y + ky->h)))
63 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
67 dx = x - (ky->x + (ky->w / 2));
68 dy = y - (ky->y + (ky->h / 2));
69 dx = (dx * dx) + (dy * dy);
79 static E_Kbd_Int_Key_State *
80 _e_kbd_int_key_state_get(E_Kbd_Int *ki, E_Kbd_Int_Key *ky)
82 E_Kbd_Int_Key_State *found = NULL;
83 E_Kbd_Int_Key_State *st;
86 EINA_LIST_FOREACH(ky->states, l, st)
88 if (st->state & ki->layout.state) return st;
89 if (!found && st->state == NORMAL) found = st;
95 _e_kbd_int_layout_buf_update(E_Kbd_Int *ki)
100 e_kbd_buf_layout_clear(ki->kbuf);
101 e_kbd_buf_layout_size_set(ki->kbuf, ki->layout.w, ki->layout.h);
102 e_kbd_buf_layout_fuzz_set(ki->kbuf, ki->layout.fuzz);
103 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
105 E_Kbd_Int_Key_State *st;
106 const char *out, *out_shift, *out_capslock, *out_altgr;
113 EINA_LIST_FOREACH(ky->states, l2, st)
115 if (st->state == NORMAL)
117 else if (st->state == SHIFT)
119 else if (st->state == CAPSLOCK)
120 out_capslock = st->out;
121 else if (st->state == ALTGR)
126 char *s1 = NULL, *s2 = NULL, *s3 = NULL;
128 if ((out) && (out[0] == '"'))
129 s1 = strdup(_e_kbd_int_str_unquote(out));
130 if ((out_shift) && (out_shift[0] == '"'))
131 s2 = strdup(_e_kbd_int_str_unquote(out_shift));
132 if ((out_altgr) && (out_altgr[0] == '"'))
133 s2 = strdup(_e_kbd_int_str_unquote(out_altgr));
134 if ((out_capslock) && (out_capslock[0] == '"'))
135 s3 = strdup(_e_kbd_int_str_unquote(out_capslock));
136 e_kbd_buf_layout_key_add(ki->kbuf, s1, s2, s3,
137 ky->x, ky->y, ky->w, ky->h);
146 _e_kbd_int_layout_state_update(E_Kbd_Int *ki)
151 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
153 E_Kbd_Int_Key_State *st;
156 st = _e_kbd_int_key_state_get(ki, ky);
160 edje_object_part_text_set(ky->obj, "e.text.label", st->label);
162 edje_object_part_text_set(ky->obj, "e.text.label", "");
168 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, st->icon);
169 p = strrchr(st->icon, '.');
170 if (!strcmp(p, ".edj"))
171 e_icon_file_edje_set(ky->icon_obj, buf, "icon");
173 e_icon_file_set(ky->icon_obj, buf);
176 e_icon_file_set(ky->icon_obj, NULL);
179 if ((ki->layout.state & SHIFT) && (ky->is_shift)) selected = 1;
180 if ((ki->layout.state & CTRL) && (ky->is_ctrl)) selected = 1;
181 if ((ki->layout.state & ALT) && (ky->is_alt)) selected = 1;
182 if ((ki->layout.state & ALTGR) && (ky->is_altgr)) selected = 1;
183 if ((ki->layout.state & CAPSLOCK) && (ky->is_capslock)) selected = 1;
184 if ((ki->layout.state & (SHIFT | CAPSLOCK)) && (ky->is_multi_shift))
190 edje_object_signal_emit(ky->obj, "e,state,selected", "e");
198 edje_object_signal_emit(ky->obj, "e,state,unselected", "e");
206 _e_kbd_int_string_send(E_Kbd_Int *ki, const char *str)
208 int pos, newpos, glyph;
211 e_kbd_buf_word_use(ki->kbuf, str);
216 newpos = evas_string_char_next_get(str, pos, &glyph);
217 if (glyph <= 0) return;
218 strncpy(buf, str + pos, newpos - pos);
219 buf[newpos - pos] = 0;
220 e_kbd_send_string_press(buf, 0);
226 _e_kbd_int_buf_send(E_Kbd_Int *ki)
228 const char *str = NULL;
229 const Eina_List *matches;
231 matches = e_kbd_buf_string_matches_get(ki->kbuf);
232 if (matches) str = matches->data;
233 else str = e_kbd_buf_actual_string_get(ki->kbuf);
234 if (str) _e_kbd_int_string_send(ki, str);
238 _e_kbd_int_cb_match_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
243 _e_kbd_int_string_send(km->ki, km->str);
244 e_kbd_buf_clear(km->ki->kbuf);
245 e_kbd_send_keysym_press("space", 0);
246 if (km->ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
248 km->ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
249 _e_kbd_int_layout_state_update(km->ki);
251 _e_kbd_int_matches_update(km->ki);
255 _e_kbd_int_matches_add(E_Kbd_Int *ki, const char *str, int num)
261 km = E_NEW(E_Kbd_Int_Match, 1);
263 o = _theme_obj_new(ki->win->evas, ki->themedir,
264 "e/modules/kbd/match/word");
266 km->str = eina_stringshare_add(str);
268 ki->matches = eina_list_append(ki->matches, km);
269 edje_object_part_text_set(o, "e.text.label", str);
270 edje_object_size_min_calc(o, &mw, &mh);
271 if (mw < 32) mw = 32;
272 if (num & 0x1) e_box_pack_start(ki->box_obj, o);
273 else e_box_pack_end(ki->box_obj, o);
274 e_box_pack_options_set(o, 1, 1, 1, 1, 0.5, 0.5, mw, mh, 9999, 9999);
276 edje_object_signal_emit(o, "e,state,selected", "e");
277 edje_object_signal_callback_add(o, "e,action,do,select", "",
278 _e_kbd_int_cb_match_select, km);
283 _e_kbd_int_matches_free(E_Kbd_Int *ki)
287 EINA_LIST_FREE(ki->matches, km)
289 if (km->str) eina_stringshare_del(km->str);
290 evas_object_del(km->obj);
296 _e_kbd_int_matches_update(void *data)
299 const Eina_List *l, *matches;
301 Evas_Coord mw, mh, vw, vh;
303 if (!(ki = data)) return;
304 evas_event_freeze(ki->win->evas);
305 e_box_freeze(ki->box_obj);
306 _e_kbd_int_matches_free(ki);
307 matches = e_kbd_buf_string_matches_get(ki->kbuf);
310 actual = e_kbd_buf_actual_string_get(ki->kbuf);
311 if (actual) _e_kbd_int_matches_add(ki, actual, 0);
317 for (i = 0, l = matches; l; l = l->next, i++)
319 _e_kbd_int_matches_add(ki, l->data, i);
320 e_box_size_min_get(ki->box_obj, &mw, &mh);
321 edje_object_part_geometry_get(ki->base_obj, "e.swallow.label",
322 NULL, NULL, &vw, &vh);
328 actual = e_kbd_buf_actual_string_get(ki->kbuf);
333 EINA_LIST_FOREACH(matches, l, str)
334 if (!strcmp(str, actual)) break;
335 if (!l) _e_kbd_int_matches_add(ki, actual, i);
339 e_box_thaw(ki->box_obj);
340 e_box_size_min_get(ki->box_obj, &mw, &mh);
341 edje_extern_object_min_size_set(ki->box_obj, 0, mh);
342 edje_object_part_swallow(ki->base_obj, "e.swallow.label", ki->box_obj);
343 evas_event_thaw(ki->win->evas);
345 _e_kbd_int_matchlist_down(ki);
349 _e_kbd_int_key_press_handle(E_Kbd_Int *ki, E_Kbd_Int_Key *ky)
351 E_Kbd_Int_Key_State *st;
352 const char *out = NULL;
358 if (ki->layout.state & SHIFT) ki->layout.state &= (~(SHIFT));
359 else ki->layout.state |= SHIFT;
360 _e_kbd_int_layout_state_update(ki);
363 if (ky->is_multi_shift)
365 if (ki->layout.state & SHIFT)
367 ki->layout.state &= (~(SHIFT));
368 ki->layout.state |= CAPSLOCK;
370 else if (ki->layout.state & CAPSLOCK)
371 ki->layout.state &= (~(CAPSLOCK));
373 ki->layout.state |= SHIFT;
374 _e_kbd_int_layout_state_update(ki);
379 if (ki->layout.state & CTRL) ki->layout.state &= (~(CTRL));
380 else ki->layout.state |= CTRL;
381 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
382 e_kbd_buf_clear(ki->kbuf);
383 _e_kbd_int_layout_state_update(ki);
384 _e_kbd_int_matches_update(ki);
389 if (ki->layout.state & ALT) ki->layout.state &= (~(ALT));
390 else ki->layout.state |= ALT;
391 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
392 e_kbd_buf_clear(ki->kbuf);
393 _e_kbd_int_layout_state_update(ki);
394 _e_kbd_int_matches_update(ki);
399 if (ki->layout.state & ALTGR) ki->layout.state &= (~(ALTGR));
400 else ki->layout.state |= ALTGR;
401 _e_kbd_int_layout_state_update(ki);
406 if (ki->layout.state & CAPSLOCK) ki->layout.state &= (~CAPSLOCK);
407 else ki->layout.state |= CAPSLOCK;
408 _e_kbd_int_layout_state_update(ki);
411 st = _e_kbd_int_key_state_get(ki, ky);
412 if (st) out = st->out;
413 if (ki->layout.state & (CTRL | ALT))
419 if (ki->layout.state & CTRL) mods |= KBD_MOD_CTRL;
420 if (ki->layout.state & ALT) mods |= KBD_MOD_ALT;
422 e_kbd_send_string_press(_e_kbd_int_str_unquote(out), mods);
424 e_kbd_send_keysym_press(out, mods);
426 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
427 _e_kbd_int_layout_state_update(ki);
428 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
436 e_kbd_buf_pressed_key_add(ki->kbuf,
437 _e_kbd_int_str_unquote(out),
438 ki->layout.state & SHIFT,
439 ki->layout.state & CAPSLOCK);
441 e_kbd_buf_pressed_point_add(ki->kbuf,
444 ki->layout.state & SHIFT,
445 ki->layout.state & CAPSLOCK);
446 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
450 if (e_kbd_buf_actual_string_get(ki->kbuf))
451 _e_kbd_int_buf_send(ki);
452 e_kbd_buf_clear(ki->kbuf);
453 e_kbd_send_keysym_press(out, 0);
454 _e_kbd_int_matches_update(ki);
457 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
459 printf("CLEARING STATE\n");
460 if (!ky->is_multi_shift)
461 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
462 _e_kbd_int_layout_state_update(ki);
467 _e_kbd_int_stroke_handle(E_Kbd_Int *ki, int dir)
469 /* If the keyboard direction is RTL switch dir 3 and 1
470 * i.e, make forward backwards and the other way around */
471 if (ki->layout.direction == E_KBD_INT_DIRECTION_RTL)
480 _e_kbd_int_layout_next(ki);
481 else if (dir == 3) // left
483 if (e_kbd_buf_actual_string_get(ki->kbuf))
485 e_kbd_buf_backspace(ki->kbuf);
486 e_kbd_buf_lookup(ki->kbuf, _e_kbd_int_matches_update, ki);
489 e_kbd_send_keysym_press("BackSpace", 0);
491 else if (dir == 2) // down
493 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
494 e_kbd_buf_clear(ki->kbuf);
495 e_kbd_send_keysym_press("Return", 0);
496 _e_kbd_int_matches_update(ki);
498 else if (dir == 1) // right
500 if (e_kbd_buf_actual_string_get(ki->kbuf)) _e_kbd_int_buf_send(ki);
501 e_kbd_buf_clear(ki->kbuf);
502 e_kbd_send_keysym_press("space", 0);
503 _e_kbd_int_matches_update(ki);
505 if (ki->layout.state)
507 ki->layout.state = 0;
508 _e_kbd_int_layout_state_update(ki);
513 _e_kbd_int_zoomkey_down(E_Kbd_Int *ki)
517 if (!ki->zoomkey.popup) return;
518 e_object_del(E_OBJECT(ki->zoomkey.popup));
519 ki->zoomkey.popup = NULL;
520 ki->zoomkey.layout_obj = NULL;
521 ki->zoomkey.sublayout_obj = NULL;
522 for (l = ki->layout.keys; l; l = l->next)
528 ky->zoom_icon_obj = NULL;
533 _e_kbd_int_zoomkey_up(E_Kbd_Int *ki)
537 Evas_Coord mw, mh, vw, vh;
540 if (ki->zoomkey.popup) return;
541 ki->zoomkey.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
542 e_popup_layer_set(ki->zoomkey.popup, 190);
544 o = _theme_obj_new(ki->zoomkey.popup->evas, ki->themedir,
545 "e/modules/kbd/zoom/default");
546 ki->zoomkey.base_obj = o;
548 o = e_layout_add(ki->zoomkey.popup->evas);
549 e_layout_virtual_size_set(o, 100, 100);
550 edje_object_part_swallow(ki->zoomkey.base_obj, "e.swallow.content", o);
552 ki->zoomkey.layout_obj = o;
554 e_layout_virtual_size_get(ki->layout_obj, &vw, &vh);
556 o = e_layout_add(ki->zoomkey.popup->evas);
557 e_layout_virtual_size_set(o, vw, vh);
558 e_layout_pack(ki->zoomkey.layout_obj, o);
559 e_layout_child_move(o, 0, 0);
560 // FIXME dimension * 4 is a magic number - make config
561 e_layout_child_resize(o, vw * 4, vh * 4);
563 ki->zoomkey.sublayout_obj = o;
565 for (l = ki->layout.keys; l; l = l->next)
568 E_Kbd_Int_Key_State *st;
569 const char *label, *icon;
573 o = _theme_obj_new(ki->zoomkey.popup->evas, ki->themedir,
574 "e/modules/kbd/zoomkey/default");
577 st = _e_kbd_int_key_state_get(ki, ky);
584 edje_object_part_text_set(o, "e.text.label", label);
586 o2 = e_icon_add(ki->zoomkey.popup->evas);
587 e_icon_fill_inside_set(o2, 1);
588 // e_icon_scale_up_set(o2, 0);
589 edje_object_part_swallow(o, "e.swallow.content", o2);
590 evas_object_show(o2);
597 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, icon);
598 p = strrchr(icon, '.');
599 if (!strcmp(p, ".edj"))
600 e_icon_file_edje_set(o2, buf, "icon");
602 e_icon_file_set(o2, buf);
605 if ((ki->layout.state & SHIFT) && (ky->is_shift)) selected = 1;
606 if ((ki->layout.state & CTRL) && (ky->is_ctrl)) selected = 1;
607 if ((ki->layout.state & ALT) && (ky->is_alt)) selected = 1;
608 if ((ki->layout.state & ALTGR) && (ky->is_altgr)) selected = 1;
609 if ((ki->layout.state & CAPSLOCK) && (ky->is_capslock)) selected = 1;
610 if ((ki->layout.state & (SHIFT|CAPSLOCK)) && (ky->is_multi_shift))
613 edje_object_signal_emit(o, "e,state,selected", "e");
615 edje_object_signal_emit(o, "e,state,unselected", "e");
616 e_layout_pack(ki->zoomkey.sublayout_obj, o);
617 e_layout_child_move(o, ky->x, ky->y);
618 e_layout_child_resize(o, ky->w, ky->h);
621 ky->zoom_icon_obj = o2;
624 edje_object_size_min_calc(ki->zoomkey.base_obj, &vw, &vh);
625 e_zone_useful_geometry_get(ki->win->border->zone, &sx, &sy, &sw, &sh);
628 if ((vw > 0) && (mw > vw)) mw = vw;
630 if ((vh > 0) && (mh > vh)) mh = vh;
632 e_popup_move_resize(ki->zoomkey.popup,
633 sx + ((sw - mw) / 2), sy + ((sh - mh) / 2), mw, mh);
634 evas_object_resize(ki->zoomkey.base_obj,
635 ki->zoomkey.popup->w, ki->zoomkey.popup->h);
636 evas_object_show(ki->zoomkey.base_obj);
637 e_popup_edje_bg_object_set(ki->zoomkey.popup, ki->zoomkey.base_obj);
638 e_popup_show(ki->zoomkey.popup);
639 e_popup_layer_set(ki->zoomkey.popup, 190);
643 _e_kbd_int_zoomkey_update(E_Kbd_Int *ki)
645 Evas_Coord w, h, ww, hh;
648 evas_object_geometry_get(ki->zoomkey.layout_obj, NULL, NULL, &w, &h);
649 evas_object_geometry_get(ki->layout_obj, NULL, NULL, &ww, &hh);
650 e_layout_virtual_size_set(ki->zoomkey.layout_obj, w, h);
651 // FIXME dimension * 4 is a magic number - make config
652 e_layout_child_resize(ki->zoomkey.sublayout_obj, ww * 4, hh * 4);
653 e_layout_child_move(ki->zoomkey.sublayout_obj,
654 (w / 2) - (ki->down.cx * 4),
655 (h / 2) - (ki->down.cy * 4));
656 ky = _e_kbd_int_at_coord_get(ki, ki->down.clx, ki->down.cly);
657 if (ky != ki->zoomkey.pressed)
659 if (ki->zoomkey.pressed)
661 ki->zoomkey.pressed->pressed = 0;
662 edje_object_signal_emit(ki->zoomkey.pressed->zoom_obj,
663 "e,state,released", "e");
664 edje_object_signal_emit(ki->zoomkey.pressed->obj,
665 "e,state,released", "e");
667 ki->zoomkey.pressed = ky;
668 if (ki->zoomkey.pressed)
670 ki->zoomkey.pressed->pressed = 1;
671 e_layout_child_raise(ki->zoomkey.pressed->zoom_obj);
672 edje_object_signal_emit(ki->zoomkey.pressed->zoom_obj,
673 "e,state,pressed", "e");
674 e_layout_child_raise(ki->zoomkey.pressed->obj);
675 e_layout_child_raise(ki->event_obj);
676 edje_object_signal_emit(ki->zoomkey.pressed->obj,
677 "e,state,pressed", "e");
683 _e_kbd_int_cb_hold_timeout(void *data)
688 ki->down.hold_timer = NULL;
690 if (ki->layout.pressed)
692 ki->layout.pressed->pressed = 0;
693 edje_object_signal_emit(ki->layout.pressed->obj,
694 "e,state,released", "e");
695 ki->layout.pressed = NULL;
697 _e_kbd_int_zoomkey_up(ki);
698 _e_kbd_int_zoomkey_update(ki);
699 return ECORE_CALLBACK_CANCEL;
703 _e_kbd_int_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
705 Evas_Event_Mouse_Down *ev;
707 Evas_Coord x, y, w, h;
711 if (ev->button != 1) return;
713 ki->down.x = ev->canvas.x;
714 ki->down.y = ev->canvas.y;
718 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
719 x = ev->canvas.x - x;
720 y = ev->canvas.y - y;
723 x = (x * ki->layout.w) / w;
724 y = (y * ki->layout.h) / h;
731 if (ki->down.hold_timer) ecore_timer_del(ki->down.hold_timer);
732 // FIXME 0.25 - magic value. make config.
733 ki->down.hold_timer = ecore_timer_add(0.25, _e_kbd_int_cb_hold_timeout, ki);
735 ky = _e_kbd_int_at_coord_get(ki, x, y);
736 ki->layout.pressed = ky;
740 e_layout_child_raise(ky->obj);
741 e_layout_child_raise(ki->event_obj);
742 edje_object_signal_emit(ky->obj, "e,state,pressed", "e");
747 _e_kbd_int_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
749 Evas_Event_Mouse_Move *ev;
751 Evas_Coord dx, dy, x, w, y, h;
758 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
759 x = ev->cur.canvas.x - x;
760 y = ev->cur.canvas.y - y;
763 x = (x * ki->layout.w) / w;
764 y = (y * ki->layout.h) / h;
767 _e_kbd_int_zoomkey_update(ki);
770 if (ki->down.stroke) return;
772 dx = ev->cur.canvas.x - ki->down.x;
773 dy = ev->cur.canvas.y - ki->down.y;
774 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
775 dx = (dx * ki->layout.w) / w;
776 dy = (dy * ki->layout.h) / h;
777 // FIXME: slide 1/4 of dimension is a magic number - make config
778 if ((dx > 0) && (dx > (ki->layout.w / 4))) ki->down.stroke = 1;
779 else if ((dx < 0) && (-dx > (ki->layout.w / 4))) ki->down.stroke = 1;
780 if ((dy > 0) && (dy > (ki->layout.h / 4))) ki->down.stroke = 1;
781 else if ((dy < 0) && (-dy > (ki->layout.w / 4))) ki->down.stroke = 1;
782 if ((ki->down.stroke) && (ki->down.hold_timer))
784 ecore_timer_del(ki->down.hold_timer);
785 ki->down.hold_timer = NULL;
790 _e_kbd_int_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
792 Evas_Event_Mouse_Up *ev;
798 if (ev->button != 1) return;
803 ky = _e_kbd_int_at_coord_get(ki, ki->down.clx, ki->down.cly);
804 _e_kbd_int_key_press_handle(ki, ky);
805 _e_kbd_int_zoomkey_down(ki);
808 else if (!ki->down.down)
810 /* case of mouse up event without mouse down when popup appear */
811 Evas_Coord x, y, w, h;
812 evas_object_geometry_get(ki->event_obj, &x, &y, &w, &h);
813 x = ev->canvas.x - x;
814 y = ev->canvas.y - y;
815 x = (x * ki->layout.w) / w;
816 y = (y * ki->layout.h) / h;
817 ky = _e_kbd_int_at_coord_get(ki, x, y);
818 ki->layout.pressed = ky;
819 _e_kbd_int_key_press_handle(ki, ki->layout.pressed);
820 edje_object_signal_emit(ky->obj,
821 "e,state,pressed", "e");
822 edje_object_message_signal_process(ky->obj);
824 else if (!ki->down.stroke)
827 ky = _e_kbd_int_at_coord_get(ki, ki->down.lx, ki->down.ly);
828 _e_kbd_int_key_press_handle(ki, ky);
834 dx = ev->canvas.x - ki->down.x;
835 dy = ev->canvas.y - ki->down.y;
840 if (dx > dy) dir = 1; // right
841 else dir = 2; // down
845 if (dx > -dy) dir = 1; // right
853 if (-dx > dy) dir = 3; // left
854 else dir = 2; // down
858 if (-dx > -dy) dir = 3; // left
864 ky = ki->layout.pressed;
868 edje_object_signal_emit(ky->obj, "e,state,released", "e");
869 ki->layout.pressed = NULL;
871 ky = ki->zoomkey.pressed;
875 edje_object_signal_emit(ky->obj, "e,state,released", "e");
876 ki->zoomkey.pressed = NULL;
881 if (ki->down.hold_timer)
883 ecore_timer_del(ki->down.hold_timer);
884 ki->down.hold_timer = NULL;
887 if (dir > 0) _e_kbd_int_stroke_handle(ki, dir);
890 static E_Kbd_Int_Layout *
891 _e_kbd_int_layouts_list_default_get(E_Kbd_Int *ki)
893 E_Kbd_Int_Layout *kil;
896 EINA_LIST_FOREACH(ki->layouts, l, kil)
897 if ((!strcmp(ecore_file_file_get(kil->path), "Default.kbd")))
902 static E_Kbd_Int_Layout *
903 _e_kbd_int_layouts_type_get(E_Kbd_Int *ki, int type)
905 E_Kbd_Int_Layout *kil;
908 EINA_LIST_FOREACH(ki->layouts, l, kil)
909 if (kil->type == type) return kil;
914 _e_kbd_int_layout_free(E_Kbd_Int *ki)
918 if (ki->layout.directory) free(ki->layout.directory);
919 if (ki->layout.file) eina_stringshare_del(ki->layout.file);
920 ki->layout.directory = NULL;
921 ki->layout.file = NULL;
922 EINA_LIST_FREE(ki->layout.keys, ky)
924 E_Kbd_Int_Key_State *st;
926 EINA_LIST_FREE(ky->states, st)
928 if (st->label) eina_stringshare_del(st->label);
929 if (st->icon) eina_stringshare_del(st->icon);
930 if (st->out) eina_stringshare_del(st->out);
933 if (ky->obj) evas_object_del(ky->obj);
934 if (ky->icon_obj) evas_object_del(ky->icon_obj);
937 if (ki->event_obj) evas_object_del(ki->event_obj);
938 ki->event_obj = NULL;
942 _e_kbd_int_layout_parse(E_Kbd_Int *ki, const char *layout)
947 E_Kbd_Int_Key *ky = NULL;
948 E_Kbd_Int_Key_State *st = NULL;
950 if (!(f = fopen(layout, "r"))) return;
952 ki->layout.directory = ecore_file_dir_get(layout);
953 ki->layout.file = eina_stringshare_add(layout);
955 /* Make the default direction LTR */
956 ki->layout.direction = E_KBD_INT_DIRECTION_LTR;
958 while (fgets(buf, sizeof(buf), f))
965 if (!strcmp(buf, "##KBDCONF-1.0\n")) isok = 1;
968 if (buf[0] == '#') continue;
972 if (buf[len - 1] == '\n') buf[len - 1] = 0;
974 if (sscanf(buf, "%4000s", str) != 1) continue;
975 if (!strcmp(str, "kbd"))
977 if (sscanf(buf, "%*s %i %i\n", &(ki->layout.w), &(ki->layout.h)) != 2)
980 if (!strcmp(str, "fuzz"))
982 sscanf(buf, "%*s %i\n", &(ki->layout.fuzz));
985 if (!strcmp(str, "direction"))
989 sscanf(buf, "%*s %3s\n", direction);
991 /* If rtl mark as rtl, otherwise make it ltr */
992 if (!strcmp(direction, "rtl"))
993 ki->layout.direction = E_KBD_INT_DIRECTION_RTL;
995 ki->layout.direction = E_KBD_INT_DIRECTION_LTR;
998 if (!strcmp(str, "key"))
1000 ky = calloc(1, sizeof(E_Kbd_Int_Key));
1002 if (sscanf(buf, "%*s %i %i %i %i\n", &(ky->x), &(ky->y), &(ky->w), &(ky->h)) != 4)
1008 ki->layout.keys = eina_list_append(ki->layout.keys, ky);
1011 if ((!strcmp(str, "normal")) || (!strcmp(str, "shift")) ||
1012 (!strcmp(str, "capslock")) || (!strcmp(str, "altgr")))
1015 char label[PATH_MAX];
1017 if (sscanf(buf, "%*s %4000s", label) != 1) continue;
1018 st = calloc(1, sizeof(E_Kbd_Int_Key_State));
1020 ky->states = eina_list_append(ky->states, st);
1021 if (!strcmp(str, "normal")) st->state = NORMAL;
1022 if (!strcmp(str, "shift")) st->state = SHIFT;
1023 if (!strcmp(str, "capslock")) st->state = CAPSLOCK;
1024 if (!strcmp(str, "altgr")) st->state = ALTGR;
1025 p = strrchr(label, '.');
1026 if ((p) && (!strcmp(p, ".png")))
1027 st->icon = eina_stringshare_add(label);
1028 else if ((p) && (!strcmp(p, ".edj")))
1029 st->icon = eina_stringshare_add(label);
1031 st->label = eina_stringshare_add(label);
1032 if (sscanf(buf, "%*s %*s %4000s", str) != 1) continue;
1033 st->out = eina_stringshare_add(str);
1035 if (!strcmp(str, "is_shift")) ky->is_shift = 1;
1036 if (!strcmp(str, "is_multi_shift")) ky->is_multi_shift = 1;
1037 if (!strcmp(str, "is_ctrl")) ky->is_ctrl = 1;
1038 if (!strcmp(str, "is_alt")) ky->is_alt = 1;
1039 if (!strcmp(str, "is_altgr")) ky->is_altgr = 1;
1040 if (!strcmp(str, "is_capslock")) ky->is_capslock = 1;
1046 _e_kbd_int_layout_build(E_Kbd_Int *ki)
1049 Evas_Object *o, *o2;
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 edje_extern_object_min_size_set(ki->layout_obj, lw, lh);
1063 edje_extern_object_max_size_set(ki->layout_obj, ki->win->w, ki->win->h);
1064 edje_object_part_swallow(ki->base_obj, "e.swallow.content", ki->layout_obj);
1066 EINA_LIST_FOREACH(ki->layout.keys, l, ky)
1068 E_Kbd_Int_Key_State *st;
1069 const char *label, *icon;
1071 o = _theme_obj_new(ki->win->evas, ki->themedir,
1072 "e/modules/kbd/key/default");
1076 st = _e_kbd_int_key_state_get(ki, ky);
1083 edje_object_part_text_set(o, "e.text.label", label);
1085 o2 = e_icon_add(ki->win->evas);
1086 e_icon_fill_inside_set(o2, 1);
1087 e_icon_scale_up_set(o2, 0);
1089 edje_object_part_swallow(o, "e.swallow.content", o2);
1090 evas_object_show(o2);
1097 snprintf(buf, sizeof(buf), "%s/%s", ki->layout.directory, icon);
1098 p = strrchr(icon, '.');
1099 if (!strcmp(p, ".edj"))
1100 e_icon_file_edje_set(o2, buf, "icon");
1102 e_icon_file_set(o2, buf);
1104 e_layout_pack(ki->layout_obj, o);
1105 e_layout_child_move(o, ky->x, ky->y);
1106 e_layout_child_resize(o, ky->w, ky->h);
1107 evas_object_show(o);
1110 o = evas_object_rectangle_add(ki->win->evas);
1111 e_layout_pack(ki->layout_obj, o);
1112 e_layout_child_move(o, 0, 0);
1113 e_layout_child_resize(o, ki->layout.w, ki->layout.h);
1114 evas_object_color_set(o, 0, 0, 0, 0);
1115 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
1116 _e_kbd_int_cb_mouse_down, ki);
1117 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
1118 _e_kbd_int_cb_mouse_up, ki);
1119 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE,
1120 _e_kbd_int_cb_mouse_move, ki);
1121 evas_object_show(o);
1123 evas_event_thaw(ki->win->evas);
1124 _e_kbd_int_matchlist_down(ki);
1128 _e_kbd_int_layouts_free(E_Kbd_Int *ki)
1130 E_Kbd_Int_Layout *kil;
1132 EINA_LIST_FREE(ki->layouts, kil)
1134 eina_stringshare_del(kil->path);
1135 eina_stringshare_del(kil->dir);
1136 eina_stringshare_del(kil->icon);
1137 eina_stringshare_del(kil->name);
1143 _e_kbd_int_layouts_list_update(E_Kbd_Int *ki)
1147 char buf[PATH_MAX], *p, *file, *path;
1149 Eina_List *kbs = NULL, *layouts = NULL;
1153 len = e_user_dir_concat_static(buf, "keyboards");
1154 if (len + 2 >= sizeof(buf)) return;
1156 files = ecore_file_ls(buf);
1161 EINA_LIST_FREE(files, file)
1163 p = strrchr(file, '.');
1164 if ((p) && (!strcmp(p, ".kbd")))
1166 if (eina_strlcpy(buf + len, file, sizeof(buf) - len) >= sizeof(buf) - len)
1168 kbs = eina_list_append(kbs, eina_stringshare_add(buf));
1173 len = snprintf(buf, sizeof(buf), "%s/keyboards", ki->syskbds);
1174 if (len + 2 >= sizeof(buf)) return;
1176 files = ecore_file_ls(buf);
1181 EINA_LIST_FREE(files, file)
1183 p = strrchr(file, '.');
1184 if ((p) && (!strcmp(p, ".kbd")))
1187 EINA_LIST_FOREACH(kbs, l, fl)
1189 if (!strcmp(file, fl))
1197 if (eina_strlcpy(buf + len, file, sizeof(buf) - len) >= sizeof(buf) - len)
1199 kbs = eina_list_append(kbs, eina_stringshare_add(buf));
1204 /* Previous loop could break before destroying all items. */
1205 EINA_LIST_FREE(files, file)
1208 EINA_LIST_FREE(kbs, path)
1210 E_Kbd_Int_Layout *kil;
1212 kil = E_NEW(E_Kbd_Int_Layout, 1);
1219 s = strdup(ecore_file_file_get(kil->path));
1222 p = strrchr(s, '.');
1224 kil->name = eina_stringshare_add(s);
1227 s = ecore_file_dir_get(kil->path);
1230 kil->dir = eina_stringshare_add(s);
1233 f = fopen(kil->path, "r");
1238 while (fgets(buf, sizeof(buf), f))
1245 if (!strcmp(buf, "##KBDCONF-1.0\n")) isok = 1;
1248 if (buf[0] == '#') continue;
1252 if (buf[len - 1] == '\n') buf[len - 1] = 0;
1254 if (sscanf(buf, "%4000s", str) != 1) continue;
1255 if (!strcmp(str, "type"))
1257 sscanf(buf, "%*s %4000s\n", str);
1258 if (!strcmp(str, "ALPHA"))
1259 kil->type = E_KBD_INT_TYPE_ALPHA;
1260 else if (!strcmp(str, "NUMERIC"))
1261 kil->type = E_KBD_INT_TYPE_NUMERIC;
1262 else if (!strcmp(str, "PIN"))
1263 kil->type = E_KBD_INT_TYPE_PIN;
1264 else if (!strcmp(str, "PHONE_NUMBER"))
1265 kil->type = E_KBD_INT_TYPE_PHONE_NUMBER;
1266 else if (!strcmp(str, "HEX"))
1267 kil->type = E_KBD_INT_TYPE_HEX;
1268 else if (!strcmp(str, "TERMINAL"))
1269 kil->type = E_KBD_INT_TYPE_TERMINAL;
1270 else if (!strcmp(str, "PASSWORD"))
1271 kil->type = E_KBD_INT_TYPE_PASSWORD;
1272 else if (!strcmp(str, "IP"))
1273 kil->type = E_KBD_INT_TYPE_IP;
1274 else if (!strcmp(str, "HOST"))
1275 kil->type = E_KBD_INT_TYPE_HOST;
1276 else if (!strcmp(str, "FILE"))
1277 kil->type = E_KBD_INT_TYPE_FILE;
1278 else if (!strcmp(str, "URL"))
1279 kil->type = E_KBD_INT_TYPE_URL;
1280 else if (!strcmp(str, "KEYPAD"))
1281 kil->type = E_KBD_INT_TYPE_KEYPAD;
1282 else if (!strcmp(str, "J2ME"))
1283 kil->type = E_KBD_INT_TYPE_J2ME;
1286 if (!strcmp(str, "icon"))
1288 sscanf(buf, "%*s %4000s\n", str);
1289 snprintf(buf, sizeof(buf), "%s/%s", kil->dir, str);
1290 kil->icon = eina_stringshare_add(buf);
1296 layouts = eina_list_append(layouts, kil);
1299 _e_kbd_int_layouts_free(ki);
1300 ki->layouts = layouts;
1304 _e_kbd_int_layout_select(E_Kbd_Int *ki, E_Kbd_Int_Layout *kil)
1306 _e_kbd_int_layout_free(ki);
1307 _e_kbd_int_layout_parse(ki, kil->path);
1308 _e_kbd_int_layout_build(ki);
1309 _e_kbd_int_layout_buf_update(ki);
1310 _e_kbd_int_layout_state_update(ki);
1313 e_icon_file_set(ki->icon_obj, kil->icon);
1318 p = strrchr(kil->icon, '.');
1320 e_icon_file_set(ki->icon_obj, kil->icon);
1323 if (!strcmp(p, ".edj"))
1324 e_icon_file_edje_set(ki->icon_obj, kil->icon, "icon");
1326 e_icon_file_set(ki->icon_obj, kil->icon);
1332 _e_kbd_int_layout_next(E_Kbd_Int *ki)
1334 Eina_List *l, *ln = NULL;
1335 E_Kbd_Int_Layout *kil;
1337 EINA_LIST_FOREACH(ki->layouts, l, kil)
1338 if (!strcmp(kil->path, ki->layout.file))
1343 if (!ln) ln = ki->layouts;
1346 _e_kbd_int_layout_select(ki, kil);
1350 _e_kbd_int_cb_client_message(void *data, __UNUSED__ int type, void *event)
1352 Ecore_X_Event_Client_Message *ev;
1357 if ((ev->win == ki->win->evas_win) &&
1358 (ev->message_type == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE))
1360 E_Kbd_Int_Layout *kil = NULL;
1362 if (ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF)
1364 _e_kbd_int_zoomkey_down(ki);
1365 _e_kbd_int_dictlist_down(ki);
1366 _e_kbd_int_matchlist_down(ki);
1368 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_ON)
1370 // do nothing - leave kbd as-is
1372 else if (ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA)
1373 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_ALPHA);
1374 else if (ev->data.l[0] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC)
1375 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_NUMERIC);
1376 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN)
1377 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PIN);
1378 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER)
1379 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PHONE_NUMBER);
1380 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX)
1381 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_HEX);
1382 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL)
1383 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_TERMINAL);
1384 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD)
1385 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_PASSWORD);
1386 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_IP)
1387 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_IP);
1388 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST)
1389 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_HOST);
1390 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE)
1391 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_FILE);
1392 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_URL)
1393 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_URL);
1394 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD)
1395 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_KEYPAD);
1396 else if (ev->data.l[0] == ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME)
1397 kil = _e_kbd_int_layouts_type_get(ki, E_KBD_INT_TYPE_J2ME);
1399 if (kil) _e_kbd_int_layout_select(ki, kil);
1401 return ECORE_CALLBACK_PASS_ON;
1405 _e_kbd_int_dictlist_down(E_Kbd_Int *ki)
1409 if (!ki->dictlist.popup) return;
1410 e_object_del(E_OBJECT(ki->dictlist.popup));
1411 ki->dictlist.popup = NULL;
1412 EINA_LIST_FREE(ki->dictlist.matches, str)
1413 eina_stringshare_del(str);
1417 _e_kbd_int_cb_dictlist_item_sel(void *data)
1424 i = e_widget_ilist_selected_get(ki->dictlist.ilist_obj);
1425 str = eina_list_nth(ki->dictlist.matches, i);
1426 e_kbd_buf_clear(ki->kbuf);
1427 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
1429 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
1430 _e_kbd_int_layout_state_update(ki);
1433 eina_stringshare_replace(&il_kbd_cfg->dict, str);
1434 e_kbd_buf_dict_set(ki->kbuf, il_kbd_cfg->dict);
1435 e_config_save_queue();
1437 _e_kbd_int_dictlist_down(ki);
1441 _e_kbd_int_dictlist_up(E_Kbd_Int *ki)
1444 Evas_Coord mw, mh, sh;
1445 Eina_List *files, *l;
1446 char buf[PATH_MAX], *p, *file, *pp;
1450 if (ki->dictlist.popup) return;
1452 ki->dictlist.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
1453 e_popup_layer_set(ki->dictlist.popup, 190);
1455 o = _theme_obj_new(ki->dictlist.popup->evas, ki->themedir,
1456 "e/modules/kbd/match/default");
1457 ki->dictlist.base_obj = o;
1459 o = e_widget_ilist_add(ki->dictlist.popup->evas,
1460 (32 * e_scale), (32 * e_scale), NULL);
1461 e_widget_ilist_selector_set(o, 1);
1462 e_widget_ilist_freeze(o);
1463 ki->dictlist.ilist_obj = o;
1465 e_user_dir_concat_static(buf, "dicts");
1466 files = ecore_file_ls(buf);
1468 EINA_LIST_FREE(files, file)
1470 p = strrchr(file, '.');
1471 if ((p) && (!strcmp(p, ".dic")))
1476 EINA_LIST_FOREACH(ki->dictlist.matches, l, match)
1477 if (!strcmp(match, file)) used = 1;
1479 if (used) goto next1;
1484 for (pp = p; *pp; pp++)
1486 if (*pp == '_') *pp = ' ';
1488 pp = strrchr(p, '.');
1490 str = eina_stringshare_add(file);
1491 ki->dictlist.matches = eina_list_append(ki->dictlist.matches, str);
1492 e_widget_ilist_append(o, NULL, p, _e_kbd_int_cb_dictlist_item_sel,
1501 snprintf(buf, sizeof(buf), "%s/dicts", ki->sysdicts);
1502 files = ecore_file_ls(buf);
1503 EINA_LIST_FREE(files, file)
1505 p = strrchr(file, '.');
1506 if ((p) && (!strcmp(p, ".dic")))
1511 EINA_LIST_FOREACH(ki->dictlist.matches, l, match)
1512 if (!strcmp(match, file)) used = 1;
1514 if (used) goto next2;
1519 for (pp = p; *pp; pp++)
1521 if (*pp == '_') *pp = ' ';
1523 pp = strrchr(p, '.');
1525 str = eina_stringshare_add(file);
1526 ki->dictlist.matches = eina_list_append(ki->dictlist.matches, str);
1527 e_widget_ilist_append(o, NULL, p, _e_kbd_int_cb_dictlist_item_sel,
1534 e_widget_ilist_thaw(o);
1535 e_widget_ilist_go(o);
1537 e_widget_ilist_preferred_size_get(o, &mw, &mh);
1538 if (mh < (120 *e_scale)) mh = (120 * e_scale);
1540 edje_extern_object_min_size_set(ki->dictlist.ilist_obj, mw, mh);
1541 edje_object_part_swallow(ki->dictlist.base_obj, "e.swallow.content",
1542 ki->dictlist.ilist_obj);
1543 edje_object_size_min_calc(ki->dictlist.base_obj, &mw, &mh);
1545 e_zone_useful_geometry_get(ki->win->border->zone, NULL, NULL, NULL, &sh);
1547 if (mh > (sh - ki->win->h)) mh = (sh - ki->win->h);
1548 e_popup_move_resize(ki->dictlist.popup, 0, ki->win->y - mh, mw, mh);
1550 evas_object_resize(ki->dictlist.base_obj,
1551 ki->dictlist.popup->w, ki->dictlist.popup->h);
1552 evas_object_show(ki->dictlist.base_obj);
1553 e_popup_edje_bg_object_set(ki->dictlist.popup, ki->dictlist.base_obj);
1554 e_popup_show(ki->dictlist.popup);
1555 _e_kbd_int_matchlist_down(ki);
1559 _e_kbd_int_matchlist_down(E_Kbd_Int *ki)
1563 if (!ki->matchlist.popup) return;
1564 e_object_del(E_OBJECT(ki->matchlist.popup));
1565 ki->matchlist.popup = NULL;
1566 EINA_LIST_FREE(ki->matchlist.matches, str)
1567 eina_stringshare_del(str);
1571 _e_kbd_int_cb_matchlist_item_sel(void *data)
1577 str = e_widget_ilist_selected_label_get(ki->matchlist.ilist_obj);
1578 _e_kbd_int_string_send(ki, str);
1579 e_kbd_buf_clear(ki->kbuf);
1580 e_kbd_send_keysym_press("space", 0);
1581 if (ki->layout.state & (SHIFT | CTRL | ALT | ALTGR))
1583 ki->layout.state &= (~(SHIFT | CTRL | ALT | ALTGR));
1584 _e_kbd_int_layout_state_update(ki);
1586 _e_kbd_int_matches_update(ki);
1587 _e_kbd_int_matchlist_down(ki);
1591 _e_kbd_int_matchlist_up(E_Kbd_Int *ki)
1595 Evas_Coord mw, mh, sh;
1597 if (!e_kbd_buf_string_matches_get(ki->kbuf)) return;
1598 if (ki->matchlist.popup) return;
1599 ki->matchlist.popup = e_popup_new(ki->win->border->zone, -1, -1, 1, 1);
1600 e_popup_layer_set(ki->matchlist.popup, 190);
1602 o = _theme_obj_new(ki->matchlist.popup->evas, ki->themedir,
1603 "e/modules/kbd/match/default");
1604 ki->matchlist.base_obj = o;
1606 o = e_widget_ilist_add(ki->matchlist.popup->evas,
1607 (32 * e_scale), (32 * e_scale), NULL);
1608 e_widget_ilist_selector_set(o, 1);
1609 ki->matchlist.ilist_obj = o;
1610 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content", o);
1611 evas_object_show(o);
1613 for (l = e_kbd_buf_string_matches_get(ki->kbuf); l; l = l->next)
1619 str = e_kbd_buf_actual_string_get(ki->kbuf);
1622 str = eina_stringshare_add(str);
1623 ki->matchlist.matches = eina_list_append(ki->matchlist.matches, str);
1624 e_widget_ilist_append(o, NULL, str,
1625 _e_kbd_int_cb_matchlist_item_sel,
1630 str = eina_stringshare_add(str);
1631 ki->matchlist.matches = eina_list_append(ki->matchlist.matches, str);
1632 e_widget_ilist_append(o, NULL, str, _e_kbd_int_cb_matchlist_item_sel,
1635 e_widget_ilist_thaw(o);
1636 e_widget_ilist_go(o);
1638 e_widget_ilist_preferred_size_get(o, &mw, &mh);
1639 if (mh < (120 *e_scale)) mh = (120 * e_scale);
1641 edje_extern_object_min_size_set(ki->matchlist.ilist_obj, mw, mh);
1642 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content",
1643 ki->matchlist.ilist_obj);
1644 edje_object_size_min_calc(ki->matchlist.base_obj, &mw, &mh);
1646 edje_extern_object_min_size_set(ki->matchlist.ilist_obj, 0, 0);
1647 edje_object_part_swallow(ki->matchlist.base_obj, "e.swallow.content",
1648 ki->matchlist.ilist_obj);
1649 e_zone_useful_geometry_get(ki->win->border->zone, NULL, NULL, NULL, &sh);
1651 if (mh > (sh - ki->win->h)) mh = (sh - ki->win->h);
1652 e_popup_move_resize(ki->matchlist.popup,
1653 ki->win->x, ki->win->y - mh, mw, mh);
1654 evas_object_resize(ki->matchlist.base_obj,
1655 ki->matchlist.popup->w, ki->matchlist.popup->h);
1656 evas_object_show(ki->matchlist.base_obj);
1657 e_popup_edje_bg_object_set(ki->matchlist.popup, ki->matchlist.base_obj);
1658 e_popup_show(ki->matchlist.popup);
1660 _e_kbd_int_dictlist_down(ki);
1664 _e_kbd_int_cb_matches(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1669 if (ki->dictlist.popup) _e_kbd_int_dictlist_down(ki);
1670 else if (ki->matchlist.popup) _e_kbd_int_matchlist_down(ki);
1673 if (!e_kbd_buf_actual_string_get(ki->kbuf))
1674 _e_kbd_int_dictlist_up(ki);
1676 _e_kbd_int_matchlist_up(ki);
1681 _e_kbd_int_cb_dicts(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1686 if (ki->dictlist.popup) _e_kbd_int_dictlist_down(ki);
1687 else _e_kbd_int_dictlist_up(ki);
1691 _e_kbd_int_cb_layouts(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
1696 _e_kbd_int_layout_next(ki);
1700 e_kbd_int_new(const char *themedir, const char *syskbds, const char *sysdicts)
1706 E_Kbd_Int_Layout *kil;
1707 Ecore_X_Window_State states[2];
1709 ki = E_NEW(E_Kbd_Int, 1);
1710 if (!ki) return NULL;
1711 if (themedir) ki->themedir = eina_stringshare_add(themedir);
1712 if (syskbds) ki->syskbds = eina_stringshare_add(syskbds);
1713 if (sysdicts) ki->sysdicts = eina_stringshare_add(sysdicts);
1714 zone = e_util_zone_current_get(e_manager_current_get());
1715 ki->win = e_win_new(zone->container);
1716 states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
1717 states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
1718 ecore_x_netwm_window_state_set(ki->win->evas_win, states, 2);
1719 ecore_x_icccm_hints_set(ki->win->evas_win, 0, 0, 0, 0, 0, 0, 0);
1720 e_win_no_remember_set(ki->win, 1);
1722 if (zone->w > zone->h)
1723 e_win_resize(ki->win, zone->w, (zone->h / 2));
1725 e_win_resize(ki->win, zone->w, zone->h);
1727 e_win_resize_callback_set(ki->win, _e_kbd_int_cb_resize);
1728 e_win_borderless_set(ki->win, 1);
1730 e_win_name_class_set(ki->win, "Virtual-Keyboard", "Virtual-Keyboard");
1731 e_win_title_set(ki->win, "Virtual Keyboard");
1733 ki->base_obj = _theme_obj_new(ki->win->evas, ki->themedir,
1734 "e/modules/kbd/base/default");
1735 edje_object_signal_callback_add(ki->base_obj, "e,action,do,matches", "",
1736 _e_kbd_int_cb_matches, ki);
1737 edje_object_signal_callback_add(ki->base_obj, "e,action,do,layouts", "",
1738 _e_kbd_int_cb_layouts, ki);
1739 edje_object_signal_callback_add(ki->base_obj, "e,action,do,dicts", "",
1740 _e_kbd_int_cb_dicts, ki);
1742 o = e_layout_add(ki->win->evas);
1743 edje_object_part_swallow(ki->base_obj, "e.swallow.content", o);
1744 evas_object_show(o);
1747 o = e_icon_add(ki->win->evas);
1748 evas_object_pass_events_set(o, 1);
1749 e_icon_fill_inside_set(o, 1);
1750 e_icon_scale_up_set(o, 0);
1751 edje_object_part_swallow(ki->base_obj, "e.swallow.layout", o);
1752 evas_object_show(o);
1755 o = e_box_add(ki->win->evas);
1756 e_box_orientation_set(o, 1);
1757 e_box_homogenous_set(o, 1);
1758 edje_object_part_swallow(ki->base_obj, "e.swallow.label", o);
1759 evas_object_show(o);
1762 if (il_kbd_cfg->dict)
1763 ki->kbuf = e_kbd_buf_new(ki->sysdicts, il_kbd_cfg->dict);
1765 ki->kbuf = e_kbd_buf_new(ki->sysdicts, "English_(US).dic");
1767 _e_kbd_int_layouts_list_update(ki);
1769 kil = _e_kbd_int_layouts_list_default_get(ki);
1770 if ((!kil) && (ki->layouts))
1771 kil = ki->layouts->data;
1773 if (kil) _e_kbd_int_layout_select(ki, kil);
1775 edje_object_size_min_calc(ki->base_obj, &mw, &mh);
1776 if (mw < 48) mw = 48;
1777 if (mh < 48) mh = 48;
1778 evas_object_move(ki->base_obj, 0, 0);
1779 evas_object_resize(ki->base_obj, mw, mh);
1780 evas_object_show(ki->base_obj);
1782 e_win_size_min_set(ki->win, zone->w, mh);
1783 ecore_x_e_virtual_keyboard_set(ki->win->evas_win, 1);
1785 ki->client_message_handler =
1786 ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
1787 _e_kbd_int_cb_client_message, ki);
1789 ecore_event_handler_add(E_EVENT_BORDER_MOVE,
1790 _e_kbd_int_cb_border_move, ki);
1792 e_win_show(ki->win);
1793 ki->win->border->user_skip_winlist = 1;
1799 e_kbd_int_free(E_Kbd_Int *ki)
1801 if (ki->themedir) eina_stringshare_del(ki->themedir);
1802 if (ki->syskbds) eina_stringshare_del(ki->syskbds);
1803 if (ki->sysdicts) eina_stringshare_del(ki->sysdicts);
1804 _e_kbd_int_layouts_free(ki);
1805 _e_kbd_int_matches_free(ki);
1806 _e_kbd_int_layout_free(ki);
1807 ecore_event_handler_del(ki->client_message_handler);
1808 ecore_event_handler_del(ki->kbd_move_hdl);
1809 if (ki->down.hold_timer) ecore_timer_del(ki->down.hold_timer);
1810 _e_kbd_int_matchlist_down(ki);
1811 _e_kbd_int_zoomkey_down(ki);
1812 e_kbd_buf_free(ki->kbuf);
1813 e_object_del(E_OBJECT(ki->win));
1817 static Evas_Object *
1818 _theme_obj_new(Evas *e, const char *custom_dir, const char *group)
1822 o = edje_object_add(e);
1823 if (!e_theme_edje_object_set(o, "base/theme/modules/illume", group))
1829 snprintf(buf, sizeof(buf), "%s/e-module-illume-keyboard.edj",
1831 edje_object_file_set(o, buf, group);
1838 _e_kbd_int_cb_border_move(void *data, int type __UNUSED__, void *event)
1840 E_Event_Border_Move *ev;
1844 if (!(ki = data)) return ECORE_CALLBACK_PASS_ON;
1845 if (ki->win->border != ev->border) return ECORE_CALLBACK_PASS_ON;
1846 _e_kbd_int_zoomkey_down(ki);
1847 _e_kbd_int_matchlist_down(ki);
1848 _e_kbd_int_dictlist_down(ki);
1849 return ECORE_CALLBACK_PASS_ON;