cd0df35c19a31df1c4148535a003f116f5ea1bde
[framework/uifw/e17.git] / src / modules / illume2 / e_mod_kbd.c
1 #include "e_illume_private.h"
2 #include "e_mod_kbd.h"
3 #include "e_mod_kbd_device.h"
4
5 /* local function prototypes */
6 static Eina_Bool _e_mod_kbd_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event);
7 static Eina_Bool _e_mod_kbd_cb_border_remove(void *data __UNUSED__, int type __UNUSED__, void *event);
8 static Eina_Bool _e_mod_kbd_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
9 static Eina_Bool _e_mod_kbd_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
10 static Eina_Bool _e_mod_kbd_cb_border_property(void *data __UNUSED__, int type __UNUSED__, void *event);
11 static void _e_mod_kbd_cb_border_pre_post_fetch(void *data __UNUSED__, void *data2);
12 static void _e_mod_kbd_cb_free(E_Illume_Keyboard *kbd);
13 static Eina_Bool _e_mod_kbd_cb_delay_hide(void *data __UNUSED__);
14 static void _e_mod_kbd_hide(void);
15 static void _e_mod_kbd_slide(int visible, double len);
16 static Eina_Bool _e_mod_kbd_cb_animate(void *data __UNUSED__);
17 static E_Illume_Keyboard *_e_mod_kbd_by_border_get(E_Border *bd);
18 static void _e_mod_kbd_border_adopt(E_Border *bd);
19 static void _e_mod_kbd_layout_send(void);
20 static void _e_mod_kbd_geometry_send(void);
21 static void _e_mod_kbd_changes_send(void);
22
23 /* local variables */
24 static Eina_List *_kbd_hdls = NULL;
25 static E_Border_Hook *_kbd_hook = NULL;
26 static Ecore_X_Atom _focused_state = 0;
27 static E_Border *_focused_border = NULL, *_prev_focused_border = NULL;
28
29 int 
30 e_mod_kbd_init(void) 
31 {
32    /* add handlers for events we are interested in */
33    _kbd_hdls = 
34      eina_list_append(_kbd_hdls, 
35                       ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, 
36                                               _e_mod_kbd_cb_client_message, 
37                                               NULL));
38    _kbd_hdls = 
39      eina_list_append(_kbd_hdls, 
40                       ecore_event_handler_add(E_EVENT_BORDER_REMOVE, 
41                                               _e_mod_kbd_cb_border_remove, 
42                                               NULL));
43    _kbd_hdls = 
44      eina_list_append(_kbd_hdls, 
45                       ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN, 
46                                               _e_mod_kbd_cb_border_focus_in, 
47                                               NULL));
48    _kbd_hdls = 
49      eina_list_append(_kbd_hdls, 
50                       ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, 
51                                               _e_mod_kbd_cb_border_focus_out, 
52                                               NULL));
53    _kbd_hdls = 
54      eina_list_append(_kbd_hdls, 
55                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, 
56                                               _e_mod_kbd_cb_border_property, 
57                                               NULL));
58
59    /* add hooks for events we are interested in */
60    _kbd_hook = e_border_hook_add(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, 
61                                  _e_mod_kbd_cb_border_pre_post_fetch, NULL);
62
63    /* initialize the device subsystem */
64    e_mod_kbd_device_init();
65
66    return 1;
67 }
68
69 int 
70 e_mod_kbd_shutdown(void) 
71 {
72    Ecore_Event_Handler *hdl;
73
74    /* shutdown the device subsystem */
75    e_mod_kbd_device_shutdown();
76
77    /* destroy the hook */
78    e_border_hook_del(_kbd_hook);
79
80    /* destroy the handlers and free the list */
81    EINA_LIST_FREE(_kbd_hdls, hdl)
82      ecore_event_handler_del(hdl);
83
84    return 1;
85 }
86
87 E_Illume_Keyboard *
88 e_mod_kbd_new(void) 
89 {
90    E_Illume_Keyboard *kbd;
91
92    /* try to allocate our new keyboard object */
93    kbd = E_OBJECT_ALLOC(E_Illume_Keyboard, E_ILLUME_KBD_TYPE, 
94                         _e_mod_kbd_cb_free);
95    if (!kbd) return NULL;
96
97    /* set default layout on new keyboard */
98    kbd->layout = E_ILLUME_KEYBOARD_LAYOUT_ALPHA;
99    kbd->visible = 0;
100
101    return kbd;
102 }
103
104 void 
105 e_mod_kbd_enable(void) 
106 {
107    /* don't try to enable a keyboard that is already enabled */
108    if (!_e_illume_kbd->disabled) return;
109
110    /* set keyboard to enabled */
111    _e_illume_kbd->disabled = 0;
112
113    /* show it if we need to */
114    if (!_e_illume_kbd->visible) e_mod_kbd_show();
115 }
116
117 void 
118 e_mod_kbd_disable(void) 
119 {
120    /* don't try to disable a keyboard that is already disabled */
121    if (_e_illume_kbd->disabled) return;
122
123    /* hide it if we need to */
124    if (_e_illume_kbd->visible) e_mod_kbd_hide();
125
126    /* set keyboard to disabled */
127    _e_illume_kbd->disabled = 1;
128 }
129
130 void 
131 e_mod_kbd_show(void) 
132 {
133    /* destroy existing timer */
134    if (_e_illume_kbd->timer) ecore_timer_del(_e_illume_kbd->timer);
135    _e_illume_kbd->timer = NULL;
136
137    /* destroy the animator if it exists */
138    if (_e_illume_kbd->animator) ecore_animator_del(_e_illume_kbd->animator);
139    _e_illume_kbd->animator = NULL;
140
141    if ((_focused_border) && (_e_illume_kbd->border))
142      {
143         if (_e_illume_kbd->border->zone != _focused_border->zone) 
144           e_border_zone_set(_e_illume_kbd->border, _focused_border->zone);
145      }
146
147    /* if it's disabled, get out */
148    if (_e_illume_kbd->disabled) return;
149
150 //   _e_mod_kbd_layout_send();
151
152    /* if we are not animating, just show it */
153    if (_e_illume_cfg->animation.vkbd.duration <= 0) 
154      {
155         /* show the border */
156         if (_e_illume_kbd->border) 
157           {
158              e_border_fx_offset(_e_illume_kbd->border, 0, 0);
159              if (!_e_illume_kbd->border->visible) 
160                e_border_show(_e_illume_kbd->border);
161              e_border_raise(_e_illume_kbd->border);
162           }
163         _e_illume_kbd->visible = 1;
164
165         _e_mod_kbd_geometry_send();
166
167         _e_mod_kbd_changes_send();
168      }
169    else 
170      {
171         /* show the border */
172         if (_e_illume_kbd->border) 
173           {
174              if (!_e_illume_kbd->border->visible) 
175                e_border_show(_e_illume_kbd->border);
176              e_border_raise(_e_illume_kbd->border);
177           }
178
179         /* animate it */
180         _e_mod_kbd_slide(1, (double)_e_illume_cfg->animation.vkbd.duration / 1000.0);
181      }
182 }
183
184 void 
185 e_mod_kbd_hide(void) 
186 {
187    /* cannot hide keyboard that is not visible */
188 //   if (!_e_illume_kbd->visible) return;
189
190    /* create new hide timer if it doesn't exist */
191    if (!_e_illume_kbd->timer) 
192      _e_illume_kbd->timer = ecore_timer_add(0.2, _e_mod_kbd_cb_delay_hide, NULL);
193 }
194
195 void 
196 e_mod_kbd_toggle(void) 
197 {
198    if (_e_illume_kbd->visible) e_mod_kbd_hide();
199    else e_mod_kbd_show();
200 }
201
202 void 
203 e_mod_kbd_fullscreen_set(E_Zone *zone, int fullscreen) 
204 {
205    if (!_e_illume_kbd->border) return;
206    if (_e_illume_kbd->border->zone != zone) return;
207    if ((!!fullscreen) != _e_illume_kbd->fullscreen) 
208      _e_illume_kbd->fullscreen = fullscreen;
209 }
210
211 void 
212 e_mod_kbd_layout_set(E_Illume_Keyboard_Layout layout) 
213 {
214    if (!_e_illume_kbd->border) return;
215    _e_illume_kbd->layout = layout;
216    _e_mod_kbd_layout_send();
217 }
218
219 /* local functions */
220 static Eina_Bool
221 _e_mod_kbd_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event) 
222 {
223    Ecore_X_Event_Client_Message *ev;
224
225    ev = event;
226    if (ev->win != ecore_x_window_root_first_get()) 
227      return ECORE_CALLBACK_PASS_ON;
228
229    /* legacy illume 1 code */
230    if ((ev->message_type == ecore_x_atom_get("_MB_IM_INVOKER_COMMAND")) || 
231        (ev->message_type == ecore_x_atom_get("_MTP_IM_INVOKER_COMMAND"))) 
232      {
233         if (ev->data.l[0] == 1) e_mod_kbd_show();
234         else if (ev->data.l[0] == 2) e_mod_kbd_hide();
235         else if (ev->data.l[0] == 3) e_mod_kbd_toggle();
236      }
237    return ECORE_CALLBACK_PASS_ON;
238 }
239
240 static Eina_Bool
241 _e_mod_kbd_cb_border_remove(void *data __UNUSED__, int type __UNUSED__, void *event) 
242 {
243    E_Event_Border_Remove *ev;
244    E_Illume_Keyboard *kbd;
245
246    ev = event;
247
248    /* if we removed the focused border, reset some variables */
249    if ((_prev_focused_border) && (_prev_focused_border == ev->border)) 
250       _prev_focused_border = NULL;
251    if ((_focused_border) && (_focused_border == ev->border)) 
252      {
253         e_mod_kbd_hide();
254         _focused_border = NULL;
255         _focused_state = 0;
256         return ECORE_CALLBACK_PASS_ON;
257      }
258
259    /* try to find the keyboard for this border */
260    if (!(kbd = _e_mod_kbd_by_border_get(ev->border))) 
261      return ECORE_CALLBACK_PASS_ON;
262
263    if ((kbd->border) && (kbd->border == ev->border)) 
264      {
265         kbd->border = NULL;
266         if (kbd->waiting_borders) 
267           {
268              E_Border *bd;
269
270              bd = kbd->waiting_borders->data;
271              kbd->waiting_borders = 
272                eina_list_remove_list(kbd->waiting_borders, kbd->waiting_borders);
273
274              _e_mod_kbd_border_adopt(bd);
275           }
276         if (kbd->visible) 
277           {
278              e_border_hide(ev->border, 2);
279              e_mod_kbd_hide();
280           }
281      }
282    else if (!kbd->border) 
283      kbd->waiting_borders = eina_list_remove(kbd->waiting_borders, ev->border);
284
285    return ECORE_CALLBACK_PASS_ON;
286 }
287
288 static Eina_Bool
289 _e_mod_kbd_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) 
290 {
291    E_Event_Border_Focus_In *ev;
292
293    ev = event;
294    if (_e_mod_kbd_by_border_get(ev->border)) return ECORE_CALLBACK_PASS_ON;
295
296 //   printf("Kbd Focus in: %s\n", ev->border->client.icccm.name);
297
298    /* set focused border for kbd */
299    _focused_border = ev->border;
300    _focused_state = ev->border->client.vkbd.state;
301
302    if (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) 
303      e_mod_kbd_hide();
304    else 
305      e_mod_kbd_show();
306
307    return ECORE_CALLBACK_PASS_ON;
308 }
309
310 static Eina_Bool
311 _e_mod_kbd_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) 
312 {
313    E_Event_Border_Focus_Out *ev;
314
315    ev = event;
316    if (_e_mod_kbd_by_border_get(ev->border)) return ECORE_CALLBACK_PASS_ON;
317
318 //   printf("Kbd Focus Out: %s\n", ev->border->client.icccm.name);
319
320    _prev_focused_border = _focused_border;
321
322    /* hide the keyboard */
323    e_mod_kbd_hide();
324
325    /* tell the focused border it changed so layout gets udpated */
326    if (_prev_focused_border) 
327      {
328         if (!e_illume_border_is_conformant(_prev_focused_border)) 
329           {
330              _prev_focused_border->changes.size = 1;
331              _prev_focused_border->changed = 1;
332           }
333      }
334
335    /* reset some variables */
336    _focused_border = NULL;
337    _focused_state = 0;
338
339    return ECORE_CALLBACK_PASS_ON;
340 }
341
342 static Eina_Bool
343 _e_mod_kbd_cb_border_property(void *data __UNUSED__, int type __UNUSED__, void *event) 
344 {
345    Ecore_X_Event_Window_Property *ev;
346    E_Border *bd;
347    int fullscreen = 0;
348
349    ev = event;
350
351    /* only interested in vkbd state changes here */
352    if (ev->atom != ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE) 
353      return ECORE_CALLBACK_PASS_ON;
354
355    /* make sure we have a border */
356    if (!(bd = e_border_find_by_client_window(ev->win))) 
357      return ECORE_CALLBACK_PASS_ON;
358
359 //   printf("Kbd Border Property Change: %s\n", bd->client.icccm.name);
360
361    /* if it's not focused, we don't care */
362    if ((!bd->focused) || (_e_mod_kbd_by_border_get(bd))) 
363      return ECORE_CALLBACK_PASS_ON;
364
365    /* NB: Not sure why, but we seem to need to fetch kbd state here. This could 
366     * be a result of filtering the container_hook_layout. Not real happy 
367     * with this because it is an X round-trip, but it is here because this 
368     * needs more time to investigate. */
369    e_hints_window_virtual_keyboard_state_get(bd);
370
371    if ((_focused_border) && (_focused_border == bd)) 
372      {
373         /* if focused state is the same, get out */
374         if (_focused_state == bd->client.vkbd.state) 
375           return ECORE_CALLBACK_PASS_ON;
376      }
377
378    /* set our variables */
379    _focused_border = bd;
380    _focused_state = bd->client.vkbd.state;
381
382    /* handle a border needing fullscreen keyboard */
383    if ((bd->need_fullscreen) || (bd->fullscreen)) fullscreen = 1;
384    if (_e_illume_kbd->fullscreen != fullscreen)
385      e_mod_kbd_fullscreen_set(bd->zone, fullscreen);
386
387    if (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) 
388      e_mod_kbd_hide();
389    else 
390      e_mod_kbd_show();
391
392    return ECORE_CALLBACK_PASS_ON;
393 }
394
395 static void 
396 _e_mod_kbd_cb_border_pre_post_fetch(void *data __UNUSED__, void *data2) 
397 {
398    E_Border *bd;
399
400    if (!(bd = data2)) return;
401    if (!bd->new_client) return;
402    if (_e_mod_kbd_by_border_get(bd)) return;
403    if (e_illume_border_is_keyboard(bd)) 
404      {
405         if (!_e_illume_kbd->border) 
406           _e_mod_kbd_border_adopt(bd);
407         else 
408           {
409              _e_illume_kbd->waiting_borders = 
410                eina_list_append(_e_illume_kbd->waiting_borders, bd);
411           }
412         bd->stolen = 1;
413      }
414 }
415
416 static void 
417 _e_mod_kbd_cb_free(E_Illume_Keyboard *kbd) 
418 {
419    E_Border *bd;
420
421    /* destroy the animator if it exists */
422    if (kbd->animator) ecore_animator_del(kbd->animator);
423    kbd->animator = NULL;
424
425    /* destroy the timer if it exists */
426    if (kbd->timer) ecore_timer_del(kbd->timer);
427    kbd->timer = NULL;
428
429    /* free the list of waiting borders */
430    EINA_LIST_FREE(kbd->waiting_borders, bd)
431      bd->stolen = 0;
432
433    /* free the keyboard structure */
434    E_FREE(kbd);
435 }
436
437 static Eina_Bool
438 _e_mod_kbd_cb_delay_hide(void *data __UNUSED__) 
439 {
440    _e_mod_kbd_hide();
441    return ECORE_CALLBACK_CANCEL;
442 }
443
444 static void 
445 _e_mod_kbd_hide(void) 
446 {
447    /* destroy existing timer */
448    if (_e_illume_kbd->timer) ecore_timer_del(_e_illume_kbd->timer);
449    _e_illume_kbd->timer = NULL;
450
451    /* destroy the animator if it exists */
452    if (_e_illume_kbd->animator) ecore_animator_del(_e_illume_kbd->animator);
453    _e_illume_kbd->animator = NULL;
454
455    /* can't hide keyboard if it's disabled */
456    if (_e_illume_kbd->disabled) return;
457
458 //   _e_mod_kbd_layout_send();
459
460    /* if we are not animating, just hide it */
461    if (_e_illume_cfg->animation.vkbd.duration <= 0) 
462      {
463         if (_e_illume_kbd->border) 
464           {
465              e_border_fx_offset(_e_illume_kbd->border, 0, 
466                                 _e_illume_kbd->border->h);
467              e_border_hide(_e_illume_kbd->border, 2);
468           }
469         _e_illume_kbd->visible = 0;
470
471         _e_mod_kbd_geometry_send();
472
473         _e_mod_kbd_changes_send();
474      }
475    else  
476      _e_mod_kbd_slide(0, (double)_e_illume_cfg->animation.vkbd.duration / 1000.0);
477 }
478
479 static void 
480 _e_mod_kbd_slide(int visible, double len) 
481 {
482    _e_illume_kbd->start = ecore_loop_time_get();
483    _e_illume_kbd->len = len;
484    _e_illume_kbd->adjust_start = _e_illume_kbd->adjust;
485    _e_illume_kbd->adjust_end = 0;
486    if ((visible) && (_e_illume_kbd->border)) 
487      _e_illume_kbd->adjust_end = _e_illume_kbd->border->h;
488    if (!_e_illume_kbd->animator) 
489      _e_illume_kbd->animator = ecore_animator_add(_e_mod_kbd_cb_animate, NULL);
490 }
491
492 static Eina_Bool
493 _e_mod_kbd_cb_animate(void *data __UNUSED__) 
494 {
495    double t, v;
496
497    t = (ecore_loop_time_get() - _e_illume_kbd->start);
498    if (t > _e_illume_kbd->len) t = _e_illume_kbd->len;
499    if (_e_illume_kbd->len > 0.0) 
500      {
501         v = (t / _e_illume_kbd->len);
502         v = (1.0 - v);
503         v = (v * v * v * v);
504         v = (1.0 - v);
505      }
506    else 
507      {
508         t = _e_illume_kbd->len;
509         v = 1.0;
510      }
511    _e_illume_kbd->adjust = ((_e_illume_kbd->adjust_end * v) + 
512                             (_e_illume_kbd->adjust_start * (1.0 - v)));
513
514    if (_e_illume_kbd->border) 
515      e_border_fx_offset(_e_illume_kbd->border, 0, 
516                         (_e_illume_kbd->border->h - _e_illume_kbd->adjust));
517
518    if (t == _e_illume_kbd->len) 
519      {
520         _e_illume_kbd->animator = NULL;
521         if (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
522           {
523              if (_e_illume_kbd->border) 
524                e_border_hide(_e_illume_kbd->border, 2);
525              _e_illume_kbd->visible = 0;
526           }
527         else 
528           _e_illume_kbd->visible = 1;
529
530         _e_mod_kbd_geometry_send();
531
532         _e_mod_kbd_changes_send();
533
534         return ECORE_CALLBACK_CANCEL;
535      }
536
537    return ECORE_CALLBACK_RENEW;
538 }
539
540 static E_Illume_Keyboard *
541 _e_mod_kbd_by_border_get(E_Border *bd) 
542 {
543    Eina_List *l;
544    E_Border *over;
545
546    if ((!bd) || (!bd->stolen)) return NULL;
547
548    /* if this border is the one that vkbd is working with, return the kbd */
549    if (_e_illume_kbd->border == bd) return _e_illume_kbd;
550
551    /* loop the waiting borders */
552    EINA_LIST_FOREACH(_e_illume_kbd->waiting_borders, l, over)
553      if (over == bd) return _e_illume_kbd;
554
555    return NULL;
556 }
557
558 static void 
559 _e_mod_kbd_border_adopt(E_Border *bd) 
560 {
561    if ((!_e_illume_kbd) || (!bd)) return;
562
563    _e_illume_kbd->border = bd;
564
565    if (!_e_illume_kbd->visible) 
566      {
567         e_border_fx_offset(bd, 0, bd->h);
568         _e_mod_kbd_layout_send();
569      }
570 }
571
572 static void 
573 _e_mod_kbd_layout_send(void) 
574 {
575    Ecore_X_Virtual_Keyboard_State type;
576
577    type = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
578    if ((!_e_illume_kbd->visible) && (!_e_illume_kbd->disabled)) 
579      {
580         type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ON;
581         if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_DEFAULT) 
582           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ON;
583         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_ALPHA) 
584           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA;
585         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_NUMERIC) 
586           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC;
587         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_PIN) 
588           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN;
589         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_PHONE_NUMBER) 
590           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER;
591         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_HEX) 
592           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX;
593         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_TERMINAL) 
594           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL;
595         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_PASSWORD) 
596           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD;
597         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_IP) 
598           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_IP;
599         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_HOST) 
600           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST;
601         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_FILE) 
602           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE;
603         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_URL) 
604           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_URL;
605         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_KEYPAD) 
606           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD;
607         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_J2ME) 
608           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME;
609         else if (_e_illume_kbd->layout == E_ILLUME_KEYBOARD_LAYOUT_NONE) 
610           type = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
611      }
612    if (_e_illume_kbd->border) 
613      ecore_x_e_virtual_keyboard_state_send(_e_illume_kbd->border->client.win, type);
614 }
615
616 static void 
617 _e_mod_kbd_geometry_send(void) 
618 {
619    E_Zone *zone;
620    int y = 0;
621
622    /* make sure we have a keyboard border */
623    if (!_e_illume_kbd->border) return;
624
625    /* adjust Y for keyboard visibility */
626    if (_e_illume_kbd->border->fx.y <= 0) 
627      y = _e_illume_kbd->border->y;
628
629    if (_focused_border) zone = _focused_border->zone;
630    else zone = _e_illume_kbd->border->zone;
631
632    ecore_x_e_illume_keyboard_geometry_set(zone->black_win, 
633                                           _e_illume_kbd->border->x, y, 
634                                           _e_illume_kbd->border->w, 
635                                           _e_illume_kbd->border->h);
636 }
637
638 static void 
639 _e_mod_kbd_changes_send(void) 
640 {
641    if (((_prev_focused_border) && (_focused_border)) && 
642        (_prev_focused_border != _focused_border))
643      {
644         /* tell previous focused border it changed so layout udpates */
645         if (_prev_focused_border->client.vkbd.state > 
646             ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN)
647           {
648              if (!e_illume_border_is_conformant(_prev_focused_border)) 
649                {
650                   _prev_focused_border->changes.size = 1;
651                   _prev_focused_border->changed = 1;
652                }
653           }
654      }
655
656    /* tell the focused border it changed so layout gets udpated */
657    if ((_focused_border) && 
658        (_focused_border->client.vkbd.state > 
659            ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN))
660      {
661         if (!e_illume_border_is_conformant(_focused_border)) 
662           {
663              _focused_border->changes.size = 1;
664              _focused_border->changed = 1;
665           }
666      }
667 }