elm can now set vsync for gl windows/clients
[framework/uifw/elementary.git] / src / lib / elm_win.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Win Win
6  *
7  * The window class of Elementary.  Contains functions to manipulate
8  * windows.
9  *
10  * Signals that you can add callbacks for are:
11  *
12  * "delete,request" - the user requested to delete the window
13  * "focus,in" - window got focus
14  * "focus,out" - window lost focus
15  * "moved" - window that holds the canvas was moved
16  */
17
18 typedef struct _Elm_Win Elm_Win;
19
20 struct _Elm_Win
21 {
22    Ecore_Evas *ee;
23    Evas *evas;
24    Evas_Object *parent, *win_obj, *img_obj, *frame_obj;
25    Eina_List *subobjs;
26 #ifdef HAVE_ELEMENTARY_X
27    Ecore_X_Window xwin;
28    Ecore_Event_Handler *client_message_handler;
29 #endif
30    Ecore_Job *deferred_resize_job;
31    Ecore_Job *deferred_child_eval_job;
32
33    Elm_Win_Type type;
34    Elm_Win_Keyboard_Mode kbdmode;
35    struct {
36       const char *info;
37       Ecore_Timer *timer;
38    } shot;
39    Eina_Bool autodel : 1;
40    int *autodel_clear, rot;
41    struct {
42       int x, y;
43    } screen;
44
45    struct {
46       Evas_Object *top;
47
48       struct {
49          Evas_Object *target;
50          Eina_Bool visible : 1;
51          Eina_Bool handled : 1;
52       } cur, prev;
53
54       const char *style;
55       Ecore_Job *reconf_job;
56
57       Eina_Bool enabled : 1;
58       Eina_Bool changed_theme : 1;
59       Eina_Bool top_animate : 1;
60       Eina_Bool geometry_changed : 1;
61    } focus_highlight;
62 };
63
64 static const char *widtype = NULL;
65 static void _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
66 static void _elm_win_obj_callback_img_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
67 static void _elm_win_obj_callback_parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
68 static void _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
69 static void _elm_win_obj_intercept_show(void *data, Evas_Object *obj);
70 static void _elm_win_move(Ecore_Evas *ee);
71 static void _elm_win_resize(Ecore_Evas *ee);
72 static void _elm_win_delete_request(Ecore_Evas *ee);
73 static void _elm_win_resize_job(void *data);
74 #ifdef HAVE_ELEMENTARY_X
75 static void _elm_win_xwin_update(Elm_Win *win);
76 #endif
77 static void _elm_win_eval_subobjs(Evas_Object *obj);
78 static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
79 static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
80 static void _elm_win_focus_highlight_init(Elm_Win *win);
81 static void _elm_win_focus_highlight_shutdown(Elm_Win *win);
82 static void _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible);
83 static void _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win);
84 static void _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win);
85 static void _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission, const char *source);
86 static void _elm_win_focus_highlight_reconfigure(Elm_Win *win);
87
88 static const char SIG_DELETE_REQUEST[] = "delete,request";
89 static const char SIG_FOCUS_OUT[] = "focus,in";
90 static const char SIG_FOCUS_IN[] = "focus,out";
91 static const char SIG_MOVED[] = "moved";
92
93 static const Evas_Smart_Cb_Description _signals[] = {
94    {SIG_DELETE_REQUEST, ""},
95    {SIG_FOCUS_OUT, ""},
96    {SIG_FOCUS_IN, ""},
97    {SIG_MOVED, ""},
98    {NULL, NULL}
99 };
100
101
102
103 Eina_List *_elm_win_list = NULL;
104 int _elm_win_deferred_free = 0;
105
106 // exmaple shot spec (wait 0.1 sec then save as my-window.png):
107 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
108
109 static double
110 _shot_delay_get(Elm_Win *win)
111 {
112    char *p, *pd;
113    char *d = strdup(win->shot.info);
114
115    if (!d) return 0.5;
116    for (p = (char *)win->shot.info; *p; p++)
117      {
118         if (!strncmp(p, "delay=", 6))
119           {
120              double v;
121
122              for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
123                {
124                   *pd = *p;
125                }
126              *pd = 0;
127              v = atof(d);
128              free(d);
129              return v;
130           }
131      }
132    free(d);
133    return 0.5;
134 }
135
136 static char *
137 _shot_file_get(Elm_Win *win)
138 {
139    char *p;
140    char *tmp = strdup(win->shot.info);
141
142    if (!tmp) return NULL;
143    for (p = (char *)win->shot.info; *p; p++)
144      {
145         if (!strncmp(p, "file=", 5))
146           {
147              strcpy(tmp, p + 5);
148              return tmp;
149           }
150      }
151    free(tmp);
152    return strdup("out.png");
153 }
154
155 static char *
156 _shot_key_get(Elm_Win *win __UNUSED__)
157 {
158    return NULL;
159 }
160
161 static char *
162 _shot_flags_get(Elm_Win *win __UNUSED__)
163 {
164    return NULL;
165 }
166
167 static void
168 _shot_do(Elm_Win *win)
169 {
170    Ecore_Evas *ee;
171    Evas_Object *o;
172    unsigned int *pixels;
173    int w, h;
174    char *file, *key, *flags;
175
176    ecore_evas_manual_render(win->ee);
177    pixels = (void *)ecore_evas_buffer_pixels_get(win->ee);
178    if (!pixels) return;
179    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
180    if ((w < 1) || (h < 1)) return;
181    file = _shot_file_get(win);
182    if (!file) return;
183    key = _shot_key_get(win);
184    flags = _shot_flags_get(win);
185    ee = ecore_evas_buffer_new(1, 1);
186    o = evas_object_image_add(ecore_evas_get(ee));
187    evas_object_image_alpha_set(o, ecore_evas_alpha_get(win->ee));
188    evas_object_image_size_set(o, w, h);
189    evas_object_image_data_set(o, pixels);
190    if (!evas_object_image_save(o, file, key, flags))
191      {
192         ERR("Cannot save window to '%s' (key '%s', flags '%s')",
193             file, key, flags);
194      }
195    free(file);
196    if (key) free(key);
197    if (flags) free(flags);
198    ecore_evas_free(ee);
199 }
200
201 static Eina_Bool
202 _shot_delay(void *data)
203 {
204    Elm_Win *win = data;
205    _shot_do(win);
206    win->shot.timer = NULL;
207    elm_exit();
208    return EINA_FALSE;
209 }
210
211 static void
212 _shot_handle(Elm_Win *win)
213 {
214    if (!win->shot.info) return;
215    win->shot.timer = ecore_timer_add(_shot_delay_get(win), _shot_delay, win);
216 }
217
218 static void
219 _elm_win_move(Ecore_Evas *ee)
220 {
221    Evas_Object *obj = ecore_evas_object_associate_get(ee);
222    Elm_Win *win;
223    int x, y;
224
225    if (!obj) return;
226    win = elm_widget_data_get(obj);
227    if (!win) return;
228    ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
229    win->screen.x = x;
230    win->screen.y = y;
231    evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
232 }
233
234 static void
235 _elm_win_resize(Ecore_Evas *ee)
236 {
237    Evas_Object *obj = ecore_evas_object_associate_get(ee);
238    Elm_Win *win;
239
240    if (!obj) return;
241    win = elm_widget_data_get(obj);
242    if (!win) return;
243    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
244    win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win);
245 }
246
247 static void
248 _elm_win_focus_in(Ecore_Evas *ee)
249 {
250    Evas_Object *obj = ecore_evas_object_associate_get(ee);
251    Elm_Win *win;
252
253    if (!obj) return;
254    win = elm_widget_data_get(obj);
255    if (!win) return;
256    /*NB: Why two different "focus signals" here ??? */
257    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_IN, NULL); // FIXME: remove me
258    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_IN, NULL);
259    win->focus_highlight.cur.visible = EINA_TRUE;
260    _elm_win_focus_highlight_reconfigure_job_start(win);
261    if (win->frame_obj)
262      {
263      }
264    else if (win->img_obj)
265      {
266         /* do nothing */
267      }
268 }
269
270 static void
271 _elm_win_focus_out(Ecore_Evas *ee)
272 {
273    Evas_Object *obj = ecore_evas_object_associate_get(ee);
274    Elm_Win *win;
275
276    if (!obj) return;
277    win = elm_widget_data_get(obj);
278    if (!win) return;
279    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_OUT, NULL); // FIXME: remove me
280    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_OUT, NULL);
281    win->focus_highlight.cur.visible = EINA_FALSE;
282    _elm_win_focus_highlight_reconfigure_job_start(win);
283    if (win->frame_obj)
284      {
285      }
286    else if (win->img_obj)
287      {
288         /* do nothing */
289      }
290 }
291
292 static Eina_Bool
293 _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
294 {
295    Elm_Win *wd = elm_widget_data_get(obj);
296    const Eina_List *items;
297    void *(*list_data_get) (const Eina_List *list);
298
299    if (!wd)
300      return EINA_FALSE;
301
302    /* Focus chain */
303    if (wd->subobjs)
304      {
305         if (!(items = elm_widget_focus_custom_chain_get(obj)))
306           {
307              items = wd->subobjs;
308              if (!items)
309                return EINA_FALSE;
310           }
311         list_data_get = eina_list_data_get;
312
313         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
314
315         if (*next)
316           return EINA_TRUE;
317      }
318
319    *next = (Evas_Object *)obj;
320    return EINA_FALSE;
321 }
322
323 static void
324 _elm_win_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
325 {
326    Elm_Win *win = elm_widget_data_get(obj);
327    if (!win) return;
328
329    if (win->img_obj)
330       evas_object_focus_set(win->img_obj, elm_widget_focus_get(obj));
331    else
332       evas_object_focus_set(obj, elm_widget_focus_get(obj));
333 }
334
335 static Eina_Bool
336 _elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
337 {
338    if (type == EVAS_CALLBACK_KEY_DOWN)
339      {
340         Evas_Event_Key_Down *ev = event_info;
341         if (!strcmp(ev->keyname, "Tab"))
342           {
343              if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
344                elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
345              else
346                elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
347              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
348              return EINA_TRUE;
349           }
350      }
351
352    return EINA_FALSE;
353 }
354
355 static void
356 _deferred_ecore_evas_free(void *data)
357 {
358    ecore_evas_free(data);
359    _elm_win_deferred_free--;
360 }
361
362 static void
363 _elm_win_obj_callback_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
364 {
365    Elm_Win *win = data;
366
367    elm_object_focus(obj);
368    if (win->shot.info) _shot_handle(win);
369 }
370
371 static void
372 _elm_win_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
373 {
374    Elm_Win *win = data;
375
376    if (win->frame_obj)
377      {
378      }
379    else if (win->img_obj)
380      {
381         evas_object_hide(win->img_obj);
382      }
383 }
384
385 static void
386 _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
387 {
388    Elm_Win *win = data;
389    Evas_Object *child;
390
391    if (win->parent)
392      {
393         evas_object_event_callback_del_full(win->parent, EVAS_CALLBACK_DEL,
394                                             _elm_win_obj_callback_parent_del, win);
395         win->parent = NULL;
396      }
397    if (win->autodel_clear) *(win->autodel_clear) = -1;
398    _elm_win_list = eina_list_remove(_elm_win_list, win->win_obj);
399    while (win->subobjs) elm_win_resize_object_del(obj, win->subobjs->data);
400    if (win->ee)
401      {
402         ecore_evas_callback_delete_request_set(win->ee, NULL);
403         ecore_evas_callback_resize_set(win->ee, NULL);
404      }
405    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
406    if (win->deferred_child_eval_job) ecore_job_del(win->deferred_child_eval_job);
407    if (win->shot.info) eina_stringshare_del(win->shot.info);
408    if (win->shot.timer) ecore_timer_del(win->shot.timer);
409    while (((child = evas_object_bottom_get(win->evas))) &&
410           (child != obj))
411      {
412         evas_object_del(child);
413      }
414    while (((child = evas_object_top_get(win->evas))) &&
415           (child != obj))
416      {
417         evas_object_del(child);
418      }
419 #ifdef HAVE_ELEMENTARY_X
420    if (win->client_message_handler)
421      ecore_event_handler_del(win->client_message_handler);
422 #endif
423    // FIXME: Why are we flushing edje on every window destroy ??
424    //   edje_file_cache_flush();
425    //   edje_collection_cache_flush();
426    //   evas_image_cache_flush(win->evas);
427    //   evas_font_cache_flush(win->evas);
428    // FIXME: we are in the del handler for the object and delete the canvas
429    // that lives under it from the handler... nasty. deferring doesn't help either
430
431    if (win->img_obj)
432      {
433         win->img_obj = NULL;
434      }
435    else
436      {
437         if (win->ee)
438           {
439              ecore_job_add(_deferred_ecore_evas_free, win->ee);
440              _elm_win_deferred_free++;
441           }
442      }
443
444    _elm_win_focus_highlight_shutdown(win);
445    eina_stringshare_del(win->focus_highlight.style);
446
447    free(win);
448
449    if ((!_elm_win_list) &&
450        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
451      {
452         edje_file_cache_flush();
453         edje_collection_cache_flush();
454         evas_image_cache_flush(e);
455         evas_font_cache_flush(e);
456         elm_exit();
457      }
458 }
459
460 static void
461 _elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
462 {
463    Elm_Win *win = data;
464    if (!win->img_obj) return;
465    evas_object_event_callback_del_full
466       (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win);
467    evas_object_del(win->img_obj);
468 }
469
470 static void
471 _elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
472 {
473    Elm_Win *win = data;
474    if (obj == win->parent) win->parent = NULL;
475 }
476
477 static void
478 _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
479 {
480    Elm_Win *win = data;
481
482    if (win->img_obj)
483      {
484         if ((x != win->screen.x) || (y != win->screen.y))
485           {
486              win->screen.x = x;
487              win->screen.y = y;
488              evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
489           }
490      }
491    else
492      {
493         evas_object_move(obj, x, y);
494      }
495 }
496
497 static void
498 _elm_win_obj_intercept_show(void *data, Evas_Object *obj)
499 {
500    Elm_Win *win = data;
501    // this is called to make sure all smart containers have calculated their
502    // sizes BEFORE we show the window to make sure it initially appears at
503    // our desired size (ie min size is known first)
504    evas_smart_objects_calculate(evas_object_evas_get(obj));
505    evas_object_show(obj);
506    if (win->frame_obj)
507      {
508      }
509    else if (win->img_obj)
510      {
511         evas_object_show(win->img_obj);
512      }
513 }
514
515 static void
516 _elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
517 {
518    Elm_Win *win = data;
519
520    if (ecore_evas_override_get(win->ee))
521      {
522         Evas_Coord x, y;
523
524         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
525         win->screen.x = x;
526         win->screen.y = y;
527         evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
528      }
529    if (win->frame_obj)
530      {
531      }
532    else if (win->img_obj)
533      {
534         Evas_Coord x, y;
535
536         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
537         win->screen.x = x;
538         win->screen.y = y;
539 //        evas_object_move(win->img_obj, x, y);
540      }
541 }
542
543 static void
544 _elm_win_obj_callback_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
545 {
546    Elm_Win *win = data;
547
548    if (win->frame_obj)
549      {
550      }
551    else if (win->img_obj)
552      {
553         Evas_Coord w = 1, h = 1;
554
555         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
556         if (w < 1) w = 1;
557         if (h < 1) h = 1;
558         evas_object_image_size_set(win->img_obj, w, h);
559      }
560 }
561
562 static void
563 _elm_win_delete_request(Ecore_Evas *ee)
564 {
565    Evas_Object *obj = ecore_evas_object_associate_get(ee);
566    Elm_Win *win;
567    if (strcmp(elm_widget_type_get(obj), "win")) return;
568
569    win = elm_widget_data_get(obj);
570    if (!win) return;
571    int autodel = win->autodel;
572    win->autodel_clear = &autodel;
573    evas_object_smart_callback_call(win->win_obj, SIG_DELETE_REQUEST, NULL); // FIXME: remove me.
574    evas_object_smart_callback_call(win->win_obj, SIG_DELETE_REQUEST, NULL);
575    // FIXME: if above callback deletes - then the below will be invalid
576    if (autodel) evas_object_del(win->win_obj);
577    else win->autodel_clear = NULL;
578 }
579
580 static void
581 _elm_win_resize_job(void *data)
582 {
583    Elm_Win *win = data;
584    const Eina_List *l;
585    Evas_Object *obj;
586    int w, h;
587
588    win->deferred_resize_job = NULL;
589    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
590    evas_object_resize(win->win_obj, w, h);
591    if (win->frame_obj)
592      {
593      }
594    else if (win->img_obj)
595      {
596      }
597    EINA_LIST_FOREACH(win->subobjs, l, obj)
598      {
599         evas_object_move(obj, 0, 0);
600         evas_object_resize(obj, w, h);
601      }
602 }
603
604 #ifdef HAVE_ELEMENTARY_X
605 static void
606 _elm_win_xwindow_get(Elm_Win *win)
607 {
608    win->xwin = 0;
609
610 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
611    if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
612      {
613        if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
614      }
615    else if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
616             ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
617             ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
618             ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
619             ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
620             ENGINE_COMPARE(ELM_OPENGL_SDL))
621      {
622      }
623    else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
624      {
625         if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee);
626      }
627    else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
628      {
629         if (win->ee) win->xwin = ecore_evas_software_x11_8_window_get(win->ee);
630      }
631 /* killed
632    else if (ENGINE_COMPARE(ELM_XRENDER_X11))
633      {
634         if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee);
635      }
636  */
637    else if (ENGINE_COMPARE(ELM_OPENGL_X11))
638      {
639         if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee);
640      }
641    else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
642      {
643         if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee);
644      }
645 #undef ENGINE_COMPARE
646 }
647 #endif
648
649 #ifdef HAVE_ELEMENTARY_X
650 static void
651 _elm_win_xwin_update(Elm_Win *win)
652 {
653    _elm_win_xwindow_get(win);
654    if (win->parent)
655      {
656         Elm_Win *win2;
657
658         win2 = elm_widget_data_get(win->parent);
659         if (win2)
660           {
661              if (win->xwin)
662                ecore_x_icccm_transient_for_set(win->xwin, win2->xwin);
663           }
664      }
665
666    if (!win->xwin) return; /* nothing more to do */
667
668    switch (win->type)
669      {
670       case ELM_WIN_BASIC:
671          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NORMAL);
672          break;
673       case ELM_WIN_DIALOG_BASIC:
674          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DIALOG);
675          break;
676       case ELM_WIN_DESKTOP:
677          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
678          break;
679       case ELM_WIN_DOCK:
680          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DOCK);
681          break;
682       case ELM_WIN_TOOLBAR:
683          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
684          break;
685       case ELM_WIN_MENU:
686          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_MENU);
687          break;
688       case ELM_WIN_UTILITY:
689          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_UTILITY);
690          break;
691       case ELM_WIN_SPLASH:
692          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_SPLASH);
693          break;
694       case ELM_WIN_DROPDOWN_MENU:
695          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
696          break;
697       case ELM_WIN_POPUP_MENU:
698          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
699          break;
700       case ELM_WIN_TOOLTIP:
701          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
702          break;
703       case ELM_WIN_NOTIFICATION:
704          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
705          break;
706       case ELM_WIN_COMBO:
707          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_COMBO);
708          break;
709       case ELM_WIN_DND:
710          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DND);
711          break;
712       default:
713          break;
714      }
715    ecore_x_e_virtual_keyboard_state_set
716       (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
717 }
718 #endif
719
720 static void
721 _elm_win_eval_subobjs(Evas_Object *obj)
722 {
723    const Eina_List *l;
724    const Evas_Object *child;
725
726    Elm_Win *win = elm_widget_data_get(obj);
727    Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
728    int xx = 1, xy = 1;
729    double wx, wy;
730
731    EINA_LIST_FOREACH(win->subobjs, l, child)
732      {
733         evas_object_size_hint_weight_get(child, &wx, &wy);
734         if (wx == 0.0) xx = 0;
735         if (wy == 0.0) xy = 0;
736
737         evas_object_size_hint_min_get(child, &w, &h);
738         if (w < 1) w = -1;
739         if (h < 1) h = -1;
740         if (w > minw) minw = w;
741         if (h > minh) minh = h;
742
743         evas_object_size_hint_max_get(child, &w, &h);
744         if (w < 1) w = -1;
745         if (h < 1) h = -1;
746         if (maxw == -1) maxw = w;
747         else if ((w > 0) && (w < maxw)) maxw = w;
748         if (maxh == -1) maxh = h;
749         else if ((h > 0) && (h < maxh)) maxh = h;
750      }
751    if (!xx) maxw = minw;
752    else maxw = 32767;
753    if (!xy) maxh = minh;
754    else maxh = 32767;
755    evas_object_size_hint_min_set(obj, minw, minh);
756    evas_object_size_hint_max_set(obj, maxw, maxh);
757    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
758    if (w < minw) w = minw;
759    if (h < minh) h = minh;
760    if ((maxw >= 0) && (w > maxw)) w = maxw;
761    if ((maxh >= 0) && (h > maxh)) h = maxh;
762    evas_object_resize(obj, w, h);
763 }
764
765 static void
766 _elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
767 {
768    Elm_Win *win = elm_widget_data_get(data);
769    win->subobjs = eina_list_remove(win->subobjs, obj);
770    _elm_win_eval_subobjs(win->win_obj);
771 }
772
773 static void
774 _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
775 {
776    _elm_win_eval_subobjs(data);
777 }
778
779 void
780 _elm_win_shutdown(void)
781 {
782    while (_elm_win_list)
783      evas_object_del(_elm_win_list->data);
784 }
785
786 void
787 _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme)
788 {
789    const Eina_List *l;
790    Evas_Object *obj;
791
792    if (!use_theme)
793      {
794         EINA_LIST_FOREACH(_elm_win_list, l, obj)
795           elm_widget_theme(obj);
796      }
797    else
798      {
799         EINA_LIST_FOREACH(_elm_win_list, l, obj)
800           elm_widget_theme_specific(obj, th, EINA_FALSE);
801      }
802 }
803
804 #ifdef HAVE_ELEMENTARY_X
805 static Eina_Bool
806 _elm_win_client_message(void *data, int type __UNUSED__, void *event)
807 {
808    Elm_Win *win = data;
809    Ecore_X_Event_Client_Message *e = event;
810
811    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
812    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
813      {
814         if ((unsigned)e->data.l[0] == win->xwin)
815           {
816              Evas *evas = evas_object_evas_get(win->win_obj);
817              if (evas)
818                {
819                   edje_file_cache_flush();
820                   edje_collection_cache_flush();
821                   evas_image_cache_flush(evas);
822                   evas_font_cache_flush(evas);
823                }
824           }
825      }
826    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
827      {
828         if ((unsigned)e->data.l[0] == win->xwin)
829           {
830              Evas *evas = evas_object_evas_get(win->win_obj);
831              if (evas)
832                {
833                   edje_file_cache_flush();
834                   edje_collection_cache_flush();
835                   evas_image_cache_flush(evas);
836                   evas_font_cache_flush(evas);
837                   evas_render_dump(evas);
838                }
839           }
840      }
841    return ECORE_CALLBACK_PASS_ON;
842 }
843 #endif
844
845 static void
846 _elm_win_focus_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
847 {
848    Elm_Win *win = data;
849
850    win->focus_highlight.geometry_changed = EINA_TRUE;
851    _elm_win_focus_highlight_reconfigure_job_start(win);
852 }
853
854 static void
855 _elm_win_focus_target_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
856 {
857    Elm_Win *win = data;
858
859    win->focus_highlight.geometry_changed = EINA_TRUE;
860    _elm_win_focus_highlight_reconfigure_job_start(win);
861 }
862
863 static void
864 _elm_win_focus_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
865 {
866    Elm_Win *win = data;
867
868    win->focus_highlight.cur.target = NULL;
869
870    _elm_win_focus_highlight_reconfigure_job_start(win);
871 }
872
873 static void
874 _elm_win_focus_target_callbacks_add(Elm_Win *win)
875 {
876    Evas_Object *obj = win->focus_highlight.cur.target;
877
878    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
879                                   _elm_win_focus_target_move, win);
880    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
881                                   _elm_win_focus_target_resize, win);
882    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
883                                   _elm_win_focus_target_del, win);
884 }
885
886 static void
887 _elm_win_focus_target_callbacks_del(Elm_Win *win)
888 {
889    Evas_Object *obj = win->focus_highlight.cur.target;
890
891    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
892                                        _elm_win_focus_target_move, win);
893    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
894                                        _elm_win_focus_target_resize, win);
895    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
896                                        _elm_win_focus_target_del, win);
897 }
898
899 static Evas_Object *
900 _elm_win_focus_target_get(Evas_Object *obj)
901 {
902    Evas_Object *o = obj;
903
904    do
905      {
906         if (elm_widget_is(o))
907           {
908              if (!elm_widget_highlight_ignore_get(o))
909                break;
910              o = elm_widget_parent_get(o);
911              if (!o)
912                o = evas_object_smart_parent_get(o);
913           }
914         else
915           {
916              o = elm_widget_parent_widget_get(o);
917              if (!o)
918                o = evas_object_smart_parent_get(o);
919           }
920      }
921    while (o);
922
923    return o;
924 }
925
926 static void
927 _elm_win_object_focus_in(void *data, Evas *e __UNUSED__, void *event_info)
928 {
929    Evas_Object *obj = event_info, *target;
930    Elm_Win *win = data;
931
932    if (win->focus_highlight.cur.target == obj)
933      return;
934
935    target = _elm_win_focus_target_get(obj);
936    win->focus_highlight.cur.target = target;
937    if (elm_widget_highlight_in_theme_get(target))
938      win->focus_highlight.cur.handled = EINA_TRUE;
939    else
940      _elm_win_focus_target_callbacks_add(win);
941
942    _elm_win_focus_highlight_reconfigure_job_start(win);
943 }
944
945 static void
946 _elm_win_object_focus_out(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
947 {
948    Elm_Win *win = data;
949
950    if (!win->focus_highlight.cur.target)
951      return;
952
953    if (!win->focus_highlight.cur.handled)
954      _elm_win_focus_target_callbacks_del(win);
955    win->focus_highlight.cur.target = NULL;
956    win->focus_highlight.cur.handled = EINA_FALSE;
957
958    _elm_win_focus_highlight_reconfigure_job_start(win);
959 }
960
961 static void
962 _elm_win_focus_highlight_hide(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
963 {
964    evas_object_hide(obj);
965 }
966
967 static void
968 _elm_win_focus_highlight_init(Elm_Win *win)
969 {
970    evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
971                            _elm_win_object_focus_in, win);
972    evas_event_callback_add(win->evas,
973                            EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
974                            _elm_win_object_focus_out, win);
975
976    win->focus_highlight.cur.target = evas_focus_get(win->evas);
977
978    win->focus_highlight.top = edje_object_add(win->evas);
979    win->focus_highlight.changed_theme = EINA_TRUE;
980    edje_object_signal_callback_add(win->focus_highlight.top,
981                                    "elm,action,focus,hide,end", "",
982                                    _elm_win_focus_highlight_hide, NULL);
983    edje_object_signal_callback_add(win->focus_highlight.top,
984                                    "elm,action,focus,anim,end", "",
985                                    _elm_win_focus_highlight_anim_end, win);
986    _elm_win_focus_highlight_reconfigure_job_start(win);
987 }
988
989 static void
990 _elm_win_focus_highlight_shutdown(Elm_Win *win)
991 {
992    _elm_win_focus_highlight_reconfigure_job_stop(win);
993    if (win->focus_highlight.cur.target)
994      {
995         _elm_win_focus_target_callbacks_del(win);
996         win->focus_highlight.cur.target = NULL;
997      }
998    if (win->focus_highlight.top)
999      {
1000         evas_object_del(win->focus_highlight.top);
1001         win->focus_highlight.top = NULL;
1002      }
1003
1004    evas_event_callback_del_full(win->evas,
1005                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1006                                 _elm_win_object_focus_in, win);
1007    evas_event_callback_del_full(win->evas,
1008                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1009                                 _elm_win_object_focus_out, win);
1010 }
1011
1012 static void
1013 _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible)
1014 {
1015    Evas_Object *top;
1016
1017    top = win->focus_highlight.top;
1018    if (visible)
1019      {
1020         if (top)
1021           {
1022              evas_object_show(top);
1023              edje_object_signal_emit(top, "elm,action,focus,show", "elm");
1024           }
1025      }
1026    else
1027      {
1028         if (top)
1029           edje_object_signal_emit(top, "elm,action,focus,hide", "elm");
1030      }
1031 }
1032
1033 static void
1034 _elm_win_focus_highlight_reconfigure_job(void *data)
1035 {
1036    _elm_win_focus_highlight_reconfigure((Elm_Win *)data);
1037 }
1038
1039 static void
1040 _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win)
1041 {
1042    if (win->focus_highlight.reconf_job)
1043      ecore_job_del(win->focus_highlight.reconf_job);
1044    win->focus_highlight.reconf_job = ecore_job_add(
1045       _elm_win_focus_highlight_reconfigure_job, win);
1046 }
1047
1048 static void
1049 _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win)
1050 {
1051    if (win->focus_highlight.reconf_job)
1052      ecore_job_del(win->focus_highlight.reconf_job);
1053    win->focus_highlight.reconf_job = NULL;
1054 }
1055
1056 static void
1057 _elm_win_focus_highlight_simple_setup(Elm_Win *win, Evas_Object *obj)
1058 {
1059    Evas_Object *clip, *target = win->focus_highlight.cur.target;
1060    Evas_Coord x, y, w, h;
1061
1062    clip = evas_object_clip_get(target);
1063    evas_object_geometry_get(target, &x, &y, &w, &h);
1064
1065    evas_object_move(obj, x, y);
1066    evas_object_resize(obj, w, h);
1067    evas_object_clip_set(obj, clip);
1068 }
1069
1070 static void
1071 _elm_win_focus_highlight_anim_setup(Elm_Win *win, Evas_Object *obj)
1072 {
1073    Evas_Coord tx, ty, tw, th;
1074    Evas_Coord w, h, px, py, pw, ph;
1075    Edje_Message_Int_Set *m;
1076    Evas_Object *previous = win->focus_highlight.prev.target;
1077    Evas_Object *target = win->focus_highlight.cur.target;
1078
1079    evas_object_geometry_get(win->win_obj, NULL, NULL, &w, &h);
1080    evas_object_geometry_get(target, &tx, &ty, &tw, &th);
1081    evas_object_geometry_get(previous, &px, &py, &pw, &ph);
1082    evas_object_move(obj, 0, 0);
1083    evas_object_resize(obj, tw, th);
1084    evas_object_clip_unset(obj);
1085
1086    m = alloca(sizeof(*m) + (sizeof(int) * 8));
1087    m->count = 8;
1088    m->val[0] = px;
1089    m->val[1] = py;
1090    m->val[2] = pw;
1091    m->val[3] = ph;
1092    m->val[4] = tx;
1093    m->val[5] = ty;
1094    m->val[6] = tw;
1095    m->val[7] = th;
1096    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
1097 }
1098
1099 static void
1100 _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
1101 {
1102    Elm_Win *win = data;
1103    _elm_win_focus_highlight_simple_setup(win, obj);
1104 }
1105
1106 static void
1107 _elm_win_focus_highlight_reconfigure(Elm_Win *win)
1108 {
1109    Evas_Object *target = win->focus_highlight.cur.target;
1110    Evas_Object *previous = win->focus_highlight.prev.target;
1111    Evas_Object *top = win->focus_highlight.top;
1112    Eina_Bool visible_changed;
1113    Eina_Bool common_visible;
1114    const char *sig = NULL;
1115
1116    _elm_win_focus_highlight_reconfigure_job_stop(win);
1117
1118    visible_changed = (win->focus_highlight.cur.visible !=
1119                       win->focus_highlight.prev.visible);
1120
1121    if ((target == previous) && (!visible_changed) &&
1122        (!win->focus_highlight.geometry_changed))
1123      return;
1124
1125    if ((previous) && (win->focus_highlight.prev.handled))
1126      elm_widget_signal_emit(previous, "elm,action,focus_highlight,hide", "elm");
1127
1128    if (!target)
1129      common_visible = EINA_FALSE;
1130    else if (win->focus_highlight.cur.handled)
1131      {
1132         common_visible = EINA_FALSE;
1133         if (win->focus_highlight.cur.visible)
1134           sig = "elm,action,focus_highlight,show";
1135         else
1136           sig = "elm,action,focus_highlight,hide";
1137      }
1138    else
1139      common_visible = win->focus_highlight.cur.visible;
1140
1141    _elm_win_focus_highlight_visible_set(win, common_visible);
1142    if (sig)
1143      elm_widget_signal_emit(target, sig, "elm");
1144
1145    if ((!target) || (!common_visible) || (win->focus_highlight.cur.handled))
1146      goto the_end;
1147
1148    if (win->focus_highlight.changed_theme)
1149      {
1150         const char *str;
1151         if (win->focus_highlight.style)
1152           str = win->focus_highlight.style;
1153         else
1154           str = "default";
1155         _elm_theme_object_set(win->win_obj, top, "focus_highlight", "top",
1156                               str);
1157         win->focus_highlight.changed_theme = EINA_FALSE;
1158
1159         if (_elm_config->focus_highlight_animate)
1160           {
1161              str = edje_object_data_get(win->focus_highlight.top, "animate");
1162              win->focus_highlight.top_animate = ((str) && (!strcmp(str, "on")));
1163           }
1164      }
1165
1166    if ((win->focus_highlight.top_animate) && (previous) &&
1167        (!win->focus_highlight.prev.handled))
1168      _elm_win_focus_highlight_anim_setup(win, top);
1169    else
1170      _elm_win_focus_highlight_simple_setup(win, top);
1171    evas_object_raise(top);
1172
1173 the_end:
1174    win->focus_highlight.geometry_changed = EINA_FALSE;
1175    win->focus_highlight.prev = win->focus_highlight.cur;
1176 }
1177
1178 #ifdef ELM_DEBUG
1179 static void
1180 _debug_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
1181 {
1182    Evas_Event_Key_Down *ev = event_info;
1183
1184    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1185      return;
1186
1187
1188    if ((strcmp(ev->keyname, "F12")) ||
1189        (!evas_key_modifier_is_set(ev->modifiers, "Control")))
1190      return;
1191
1192    printf("Tree graph generated.\n");
1193    elm_object_tree_dot_dump(obj, "./dump.dot");
1194 }
1195 #endif
1196
1197 static void
1198 _win_img_hide(void        *data,
1199               Evas        *e __UNUSED__,
1200               Evas_Object *obj __UNUSED__,
1201               void        *event_info __UNUSED__)
1202 {
1203    Elm_Win *win = data;
1204
1205    elm_widget_focus_hide_handle(win->win_obj);
1206 }
1207
1208 static void
1209 _win_img_mouse_down(void        *data,
1210                     Evas        *e __UNUSED__,
1211                     Evas_Object *obj __UNUSED__,
1212                     void        *event_info __UNUSED__)
1213 {
1214    Elm_Win *win = data;
1215    elm_widget_focus_mouse_down_handle(win->win_obj);
1216 }
1217
1218 static void
1219 _win_img_focus_in(void        *data,
1220                   Evas        *e __UNUSED__,
1221                   Evas_Object *obj __UNUSED__,
1222                   void        *event_info __UNUSED__)
1223 {
1224    Elm_Win *win = data;
1225    elm_widget_focus_steal(win->win_obj);
1226 }
1227
1228 static void
1229 _win_img_focus_out(void        *data,
1230                    Evas        *e __UNUSED__,
1231                    Evas_Object *obj __UNUSED__,
1232                    void        *event_info __UNUSED__)
1233 {
1234    Elm_Win *win = data;
1235    elm_widget_focused_object_clear(win->win_obj);
1236 }
1237
1238 static void
1239 _win_inlined_image_set(Elm_Win *win)
1240 {
1241    evas_object_image_alpha_set(win->img_obj, EINA_FALSE);
1242    evas_object_image_filled_set(win->img_obj, EINA_TRUE);
1243    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_DEL,
1244                                   _elm_win_obj_callback_img_obj_del, win);
1245
1246    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_HIDE,
1247                                   _win_img_hide, win);
1248    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_MOUSE_DOWN,
1249                                   _win_img_mouse_down, win);
1250    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_IN,
1251                                   _win_img_focus_in, win);
1252    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_OUT,
1253                                   _win_img_focus_out, win);
1254 }
1255
1256 /**
1257  * Adds a window object. If this is the first window created, pass NULL as
1258  * @p parent.
1259  *
1260  * @param parent Parent object to add the window to, or NULL
1261  * @param name The name of the window
1262  * @param type The window type, one of the following:
1263  * ELM_WIN_BASIC
1264  * ELM_WIN_DIALOG_BASIC
1265  * ELM_WIN_DESKTOP
1266  * ELM_WIN_DOCK
1267  * ELM_WIN_TOOLBAR
1268  * ELM_WIN_MENU
1269  * ELM_WIN_UTILITY
1270  * ELM_WIN_SPLASH
1271  *
1272  * @return The created object, or NULL on failure
1273  *
1274  * @ingroup Win
1275  */
1276 EAPI Evas_Object *
1277 elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
1278 {
1279    Elm_Win *win;
1280    const Eina_List *l;
1281    const char *fontpath;
1282
1283    win = ELM_NEW(Elm_Win);
1284
1285 #define FALLBACK_TRY(engine)                                            \
1286    if (!win->ee)                                                        \
1287    do {                                                               \
1288         CRITICAL(engine " engine creation failed. Trying software X11."); \
1289         win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);      \
1290    } while (0)
1291 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1292
1293    switch (type)
1294      {
1295       case ELM_WIN_INLINED_IMAGE:
1296           {
1297              if (parent)
1298                {
1299                   Evas *e = evas_object_evas_get(parent);
1300                   if (e)
1301                     {
1302                        Ecore_Evas *ee = ecore_evas_ecore_evas_get(e);
1303                        if (ee)
1304                          {
1305                             win->img_obj = ecore_evas_object_image_new(ee);
1306                             if (win->img_obj)
1307                               {
1308                                  win->ee = ecore_evas_object_ecore_evas_get(win->img_obj);
1309                                  if (win->ee)
1310                                    {
1311                                       _win_inlined_image_set(win);
1312                                    }
1313                                  else
1314                                    {
1315                                       evas_object_del(win->img_obj);
1316                                       win->img_obj = NULL;
1317                                    }
1318                               }
1319                          }
1320                     }
1321                }
1322           }
1323         break;
1324       default:
1325         if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
1326           {
1327              win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
1328 #ifdef HAVE_ELEMENTARY_X
1329              win->client_message_handler = ecore_event_handler_add
1330                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1331 #endif
1332           }
1333         else if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1334           {
1335              win->ee = ecore_evas_fb_new(NULL, 0, 1, 1);
1336              FALLBACK_TRY("Sofware FB");
1337           }
1338         else if (ENGINE_COMPARE(ELM_SOFTWARE_DIRECTFB))
1339           {
1340              win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1);
1341              FALLBACK_TRY("Sofware DirectFB");
1342           }
1343         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
1344           {
1345              win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1);
1346              FALLBACK_TRY("Sofware-16");
1347 #ifdef HAVE_ELEMENTARY_X
1348              win->client_message_handler = ecore_event_handler_add
1349                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1350 #endif
1351      }
1352         else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
1353           {
1354              win->ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1);
1355              FALLBACK_TRY("Sofware-8");
1356 #ifdef HAVE_ELEMENTARY_X
1357              win->client_message_handler = ecore_event_handler_add
1358                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1359 #endif
1360           }
1361 /* killed
1362         else if (ENGINE_COMPARE(ELM_XRENDER_X11))
1363           {
1364              win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1);
1365              FALLBACK_TRY("XRender");
1366 #ifdef HAVE_ELEMENTARY_X
1367              win->client_message_handler = ecore_event_handler_add
1368                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1369 #endif
1370           }
1371  */
1372         else if (ENGINE_COMPARE(ELM_OPENGL_X11))
1373           {
1374              int opt[10];
1375              int opt_i = 0;
1376              
1377              if (_elm_config->vsync)
1378                {
1379                   opt[opt_i] = ECORE_EVAS_GL_X11_OPT_VSYNC;
1380                   opt_i++;
1381                   opt[opt_i] = 1;
1382                   opt_i++;
1383                }
1384              if (opt_i > 0)
1385                 win->ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt);
1386              else
1387                 win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
1388              FALLBACK_TRY("OpenGL");
1389 #ifdef HAVE_ELEMENTARY_X
1390              win->client_message_handler = ecore_event_handler_add
1391                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1392 #endif
1393           }
1394         else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
1395           {
1396              win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
1397              FALLBACK_TRY("Sofware Win32");
1398           }
1399         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1400           {
1401              win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1);
1402              FALLBACK_TRY("Sofware-16-WinCE");
1403           }
1404         else if (ENGINE_COMPARE(ELM_SOFTWARE_SDL))
1405           {
1406              win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
1407              FALLBACK_TRY("Sofware SDL");
1408           }
1409         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_SDL))
1410           {
1411              win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1);
1412              FALLBACK_TRY("Sofware-16-SDL");
1413           }
1414         else if (ENGINE_COMPARE(ELM_OPENGL_SDL))
1415           {
1416              win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
1417              FALLBACK_TRY("OpenGL SDL");
1418           }
1419         else if (!strncmp(_elm_config->engine, "shot:", 5))
1420           {
1421              win->ee = ecore_evas_buffer_new(1, 1);
1422              ecore_evas_manual_render_set(win->ee, EINA_TRUE);
1423              win->shot.info = eina_stringshare_add(_elm_config->engine + 5);
1424           }
1425 #undef FALLBACK_TRY
1426         break;
1427      }
1428
1429    if (!win->ee)
1430      {
1431         ERR("Cannot create window.");
1432         free(win);
1433         return NULL;
1434      }
1435 #ifdef HAVE_ELEMENTARY_X
1436    _elm_win_xwindow_get(win);
1437 #endif
1438    if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
1439      ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
1440    // bg pixmap done by x - has other issues like can be redrawn by x before it
1441    // is filled/ready by app
1442    //     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
1443
1444    win->type = type;
1445    win->parent = parent;
1446    if (win->parent)
1447      evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL,
1448                                     _elm_win_obj_callback_parent_del, win);
1449
1450    win->evas = ecore_evas_get(win->ee);
1451    win->win_obj = elm_widget_add(win->evas);
1452    elm_widget_type_set(win->win_obj, "win");
1453    ELM_SET_WIDTYPE(widtype, "win");
1454    elm_widget_data_set(win->win_obj, win);
1455    elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb);
1456    elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL);
1457    elm_widget_can_focus_set(win->win_obj, EINA_TRUE);
1458    elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE);
1459    elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook);
1460    evas_object_color_set(win->win_obj, 0, 0, 0, 0);
1461    evas_object_move(win->win_obj, 0, 0);
1462    evas_object_resize(win->win_obj, 1, 1);
1463    evas_object_layer_set(win->win_obj, 50);
1464    evas_object_pass_events_set(win->win_obj, EINA_TRUE);
1465
1466    ecore_evas_object_associate(win->ee, win->win_obj,
1467                                ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
1468                                ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
1469                                ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
1470    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW,
1471                                   _elm_win_obj_callback_show, win);
1472    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_HIDE,
1473                                   _elm_win_obj_callback_hide, win);
1474    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
1475                                   _elm_win_obj_callback_del, win);
1476    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_MOVE,
1477                                   _elm_win_obj_callback_move, win);
1478    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_RESIZE,
1479                                   _elm_win_obj_callback_resize, win);
1480    if (win->img_obj)
1481       evas_object_intercept_move_callback_add(win->win_obj,
1482                                               _elm_win_obj_intercept_move, win);
1483    evas_object_intercept_show_callback_add(win->win_obj,
1484                                            _elm_win_obj_intercept_show, win);
1485
1486    ecore_evas_name_class_set(win->ee, name, _elm_appname);
1487    ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request);
1488    ecore_evas_callback_resize_set(win->ee, _elm_win_resize);
1489    ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in);
1490    ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out);
1491    ecore_evas_callback_move_set(win->ee, _elm_win_move);
1492    evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024));
1493    evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
1494    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
1495       evas_font_path_append(win->evas, fontpath);
1496    if (!_elm_config->font_hinting)
1497      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
1498    else if (_elm_config->font_hinting == 1)
1499      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
1500    else if (_elm_config->font_hinting == 2)
1501      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE);
1502
1503 #ifdef HAVE_ELEMENTARY_X
1504    _elm_win_xwin_update(win);
1505 #endif
1506
1507    _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
1508
1509    if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1510      {
1511         ecore_evas_fullscreen_set(win->ee, 1);
1512      }
1513 #undef ENGINE_COMPARE
1514
1515    if (_elm_config->focus_highlight_enable)
1516      elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE);
1517
1518 #ifdef ELM_DEBUG
1519    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control");
1520    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN,
1521                                   _debug_key_down, win);
1522
1523    Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0,
1524                                         EINA_TRUE);
1525    printf("Key F12 exclusive for dot tree generation. (%d)\n", ret);
1526 #endif
1527
1528    evas_object_smart_callbacks_descriptions_set(win->win_obj, _signals);
1529
1530    return win->win_obj;
1531 }
1532
1533 /**
1534  * Add @p subobj as a resize object of window @p obj.
1535  *
1536  * @param obj The window object
1537  * @param subobj The resize object to add
1538  *
1539  * @ingroup Win
1540  */
1541 EAPI void
1542 elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj)
1543 {
1544    Evas_Coord w, h;
1545    Elm_Win *win;
1546    ELM_CHECK_WIDTYPE(obj, widtype);
1547    win = elm_widget_data_get(obj);
1548    if (!win) return;
1549    win->subobjs = eina_list_append(win->subobjs, subobj);
1550    elm_widget_sub_object_add(obj, subobj);
1551    evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL,
1552                                   _elm_win_subobj_callback_del, obj);
1553    evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1554                                   _elm_win_subobj_callback_changed_size_hints,
1555                                   obj);
1556    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
1557    evas_object_move(subobj, 0, 0);
1558    evas_object_resize(subobj, w, h);
1559    _elm_win_eval_subobjs(obj);
1560 }
1561
1562 /**
1563  * Delete @p subobj as a resize object of window @p obj.
1564  *
1565  * @param obj The window object
1566  * @param subobj The resize object to add
1567  *
1568  * @ingroup Win
1569  */
1570 EAPI void
1571 elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj)
1572 {
1573    Elm_Win *win;
1574    ELM_CHECK_WIDTYPE(obj, widtype);
1575    win = elm_widget_data_get(obj);
1576    if (!win) return;
1577    evas_object_event_callback_del_full(subobj,
1578                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1579                                        _elm_win_subobj_callback_changed_size_hints,
1580                                        obj);
1581    evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
1582                                        _elm_win_subobj_callback_del, obj);
1583    win->subobjs = eina_list_remove(win->subobjs, subobj);
1584    elm_widget_sub_object_del(obj, subobj);
1585    _elm_win_eval_subobjs(obj);
1586 }
1587
1588 /**
1589  * Set the title of the window
1590  *
1591  * @param obj The window object
1592  * @param title The title to set
1593  *
1594  * @ingroup Win
1595  */
1596 EAPI void
1597 elm_win_title_set(Evas_Object *obj, const char *title)
1598 {
1599    Elm_Win *win;
1600    ELM_CHECK_WIDTYPE(obj, widtype);
1601    win = elm_widget_data_get(obj);
1602    if (!win) return;
1603    ecore_evas_title_set(win->ee, title);
1604 }
1605
1606 /**
1607  * Get the title of the window
1608  *
1609  * @param obj The window object
1610  * @return The title
1611  *
1612  * @ingroup Win
1613  */
1614 EAPI const char *
1615 elm_win_title_get(const Evas_Object *obj)
1616 {
1617    Elm_Win *win;
1618    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1619    win = elm_widget_data_get(obj);
1620    if (!win) return NULL;
1621    return ecore_evas_title_get(win->ee);
1622 }
1623
1624 /**
1625  * Set the window's autodel state.
1626  *
1627  * @param obj The window object
1628  * @param autodel If true, the window will automatically delete itself when closed
1629  *
1630  * @ingroup Win
1631  */
1632 EAPI void
1633 elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
1634 {
1635    Elm_Win *win;
1636    ELM_CHECK_WIDTYPE(obj, widtype);
1637    win = elm_widget_data_get(obj);
1638    if (!win) return;
1639    win->autodel = autodel;
1640 }
1641
1642 /**
1643  * Get the window's autodel state.
1644  *
1645  * @param obj The window object
1646  * @return If the window will automatically delete itself when closed
1647  *
1648  * @ingroup Win
1649  */
1650 EAPI Eina_Bool
1651 elm_win_autodel_get(const Evas_Object *obj)
1652 {
1653    Elm_Win *win;
1654    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1655    win = elm_widget_data_get(obj);
1656    if (!win) return EINA_FALSE;
1657    return win->autodel;
1658 }
1659
1660 /**
1661  * Activate a window object.
1662  *
1663  * @param obj The window object
1664  *
1665  * @ingroup Win
1666  */
1667 EAPI void
1668 elm_win_activate(Evas_Object *obj)
1669 {
1670    Elm_Win *win;
1671    ELM_CHECK_WIDTYPE(obj, widtype);
1672    win = elm_widget_data_get(obj);
1673    if (!win) return;
1674    ecore_evas_activate(win->ee);
1675 }
1676
1677 /**
1678  * Lower a window object.
1679  *
1680  * @param obj The window object
1681  *
1682  * @ingroup Win
1683  */
1684 EAPI void
1685 elm_win_lower(Evas_Object *obj)
1686 {
1687    Elm_Win *win;
1688    ELM_CHECK_WIDTYPE(obj, widtype);
1689    win = elm_widget_data_get(obj);
1690    if (!win) return;
1691    ecore_evas_lower(win->ee);
1692 }
1693
1694 /**
1695  * Raise a window object.
1696  *
1697  * @param obj The window object
1698  *
1699  * @ingroup Win
1700  */
1701 EAPI void
1702 elm_win_raise(Evas_Object *obj)
1703 {
1704    Elm_Win *win;
1705    ELM_CHECK_WIDTYPE(obj, widtype);
1706    win = elm_widget_data_get(obj);
1707    if (!win) return;
1708    ecore_evas_raise(win->ee);
1709 }
1710
1711 /**
1712  * Set the borderless state of a window.
1713  *
1714  * @param obj The window object
1715  * @param borderless If true, the window is borderless
1716  *
1717  * @ingroup Win
1718  */
1719 EAPI void
1720 elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
1721 {
1722    Elm_Win *win;
1723    ELM_CHECK_WIDTYPE(obj, widtype);
1724    win = elm_widget_data_get(obj);
1725    if (!win) return;
1726    ecore_evas_borderless_set(win->ee, borderless);
1727 #ifdef HAVE_ELEMENTARY_X
1728    _elm_win_xwin_update(win);
1729 #endif
1730 }
1731
1732 /**
1733  * Get the borderless state of a window.
1734  *
1735  * @param obj The window object
1736  * @return If true, the window is borderless
1737  *
1738  * @ingroup Win
1739  */
1740 EAPI Eina_Bool
1741 elm_win_borderless_get(const Evas_Object *obj)
1742 {
1743    Elm_Win *win;
1744    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1745    win = elm_widget_data_get(obj);
1746    if (!win) return EINA_FALSE;
1747    return ecore_evas_borderless_get(win->ee);
1748 }
1749
1750 /**
1751  * Set the shaped state of a window.
1752  *
1753  * @param obj The window object
1754  * @param shaped If true, the window is shaped
1755  *
1756  * @ingroup Win
1757  */
1758 EAPI void
1759 elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
1760 {
1761    Elm_Win *win;
1762    ELM_CHECK_WIDTYPE(obj, widtype);
1763    win = elm_widget_data_get(obj);
1764    if (!win) return;
1765    ecore_evas_shaped_set(win->ee, shaped);
1766 #ifdef HAVE_ELEMENTARY_X
1767    _elm_win_xwin_update(win);
1768 #endif
1769 }
1770
1771 /**
1772  * Get the shaped state of a window.
1773  *
1774  * @param obj The window object
1775  * @return If true, the window is shaped
1776  *
1777  * @ingroup Win
1778  */
1779 EAPI Eina_Bool
1780 elm_win_shaped_get(const Evas_Object *obj)
1781 {
1782    Elm_Win *win;
1783    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1784    win = elm_widget_data_get(obj);
1785    if (!win) return EINA_FALSE;
1786    return ecore_evas_shaped_get(win->ee);
1787 }
1788
1789 /**
1790  * Set the alpha channel state of a window.
1791  *
1792  * @param obj The window object
1793  * @param alpha If true, the window has an alpha channel
1794  *
1795  * @ingroup Win
1796  */
1797 EAPI void
1798 elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
1799 {
1800    Elm_Win *win;
1801    ELM_CHECK_WIDTYPE(obj, widtype);
1802    win = elm_widget_data_get(obj);
1803    if (!win) return;
1804    if (win->frame_obj)
1805      {
1806      }
1807    else if (win->img_obj)
1808      {
1809         evas_object_image_alpha_set(win->img_obj, alpha);
1810      }
1811    else
1812      {
1813 #ifdef HAVE_ELEMENTARY_X
1814         if (win->xwin)
1815           {
1816              if (alpha)
1817                {
1818                   if (!_elm_config->compositing)
1819                      elm_win_shaped_set(obj, alpha);
1820                   else
1821                      ecore_evas_alpha_set(win->ee, alpha);
1822                }
1823              else
1824                 ecore_evas_alpha_set(win->ee, alpha);
1825              _elm_win_xwin_update(win);
1826           }
1827         else
1828 #endif
1829            ecore_evas_alpha_set(win->ee, alpha);
1830      }
1831 }
1832
1833 /**
1834  * Get the alpha channel state of a window.
1835  *
1836  * @param obj The window object
1837  * @return If true, the window has an alpha channel
1838  *
1839  * @ingroup Win
1840  */
1841 EAPI Eina_Bool
1842 elm_win_alpha_get(const Evas_Object *obj)
1843 {
1844    Elm_Win *win;
1845    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1846    win = elm_widget_data_get(obj);
1847    if (!win) return EINA_FALSE;
1848    return ecore_evas_alpha_get(win->ee);
1849 }
1850
1851 /**
1852  * Set the transparency state of a window.
1853  *
1854  * @param obj The window object
1855  * @param transparent If true, the window is transparent
1856  *
1857  * @ingroup Win
1858  */
1859 EAPI void
1860 elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
1861 {
1862    Elm_Win *win;
1863    ELM_CHECK_WIDTYPE(obj, widtype);
1864    win = elm_widget_data_get(obj);
1865    if (!win) return;
1866
1867    if (win->frame_obj)
1868      {
1869      }
1870    else if (win->img_obj)
1871      {
1872         evas_object_image_alpha_set(win->img_obj, transparent);
1873      }
1874    else
1875      {
1876 #ifdef HAVE_ELEMENTARY_X
1877         if (win->xwin)
1878           {
1879              ecore_evas_transparent_set(win->ee, transparent);
1880              _elm_win_xwin_update(win);
1881           }
1882         else
1883 #endif
1884            ecore_evas_transparent_set(win->ee, transparent);
1885      }
1886 }
1887
1888 /**
1889  * Get the transparency state of a window.
1890  *
1891  * @param obj The window object
1892  * @return If true, the window is transparent
1893  *
1894  * @ingroup Win
1895  */
1896 EAPI Eina_Bool
1897 elm_win_transparent_get(const Evas_Object *obj)
1898 {
1899    Elm_Win *win;
1900    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1901    win = elm_widget_data_get(obj);
1902    if (!win) return EINA_FALSE;
1903
1904    return ecore_evas_transparent_get(win->ee);
1905 }
1906
1907 /**
1908  * Set the override state of a window.
1909  *
1910  * @param obj The window object
1911  * @param override If true, the window is overridden
1912  *
1913  * @ingroup Win
1914  */
1915 EAPI void
1916 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
1917 {
1918    Elm_Win *win;
1919    ELM_CHECK_WIDTYPE(obj, widtype);
1920    win = elm_widget_data_get(obj);
1921    if (!win) return;
1922    ecore_evas_override_set(win->ee, override);
1923 #ifdef HAVE_ELEMENTARY_X
1924    _elm_win_xwin_update(win);
1925 #endif
1926 }
1927
1928 /**
1929  * Get the override state of a window.
1930  *
1931  * @param obj The window object
1932  * @return If true, the window is overridden
1933  *
1934  * @ingroup Win
1935  */
1936 EAPI Eina_Bool
1937 elm_win_override_get(const Evas_Object *obj)
1938 {
1939    Elm_Win *win;
1940    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1941    win = elm_widget_data_get(obj);
1942    if (!win) return EINA_FALSE;
1943    return ecore_evas_override_get(win->ee);
1944 }
1945
1946 /**
1947  * Set the fullscreen state of a window.
1948  *
1949  * @param obj The window object
1950  * @param fullscreen If true, the window is fullscreen
1951  *
1952  * @ingroup Win
1953  */
1954 EAPI void
1955 elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
1956 {
1957    Elm_Win *win;
1958    ELM_CHECK_WIDTYPE(obj, widtype);
1959    win = elm_widget_data_get(obj);
1960    if (!win) return;
1961
1962    // YYY: handle if win->img_obj
1963 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1964    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
1965        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1966      {
1967         // these engines... can ONLY be fullscreen
1968         return;
1969      }
1970    else
1971      {
1972         ecore_evas_fullscreen_set(win->ee, fullscreen);
1973 #ifdef HAVE_ELEMENTARY_X
1974         _elm_win_xwin_update(win);
1975 #endif
1976      }
1977 #undef ENGINE_COMPARE
1978 }
1979
1980 /**
1981  * Get the fullscreen state of a window.
1982  *
1983  * @param obj The window object
1984  * @return If true, the window is fullscreen
1985  *
1986  * @ingroup Win
1987  */
1988 EAPI Eina_Bool
1989 elm_win_fullscreen_get(const Evas_Object *obj)
1990 {
1991    Elm_Win *win;
1992    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1993    win = elm_widget_data_get(obj);
1994    if (!win) return EINA_FALSE;
1995
1996 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1997    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
1998        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1999      {
2000         // these engines... can ONLY be fullscreen
2001         return EINA_TRUE;
2002      }
2003    else
2004      {
2005         return ecore_evas_fullscreen_get(win->ee);
2006      }
2007 #undef ENGINE_COMPARE
2008 }
2009
2010 /**
2011  * Set the maximized state of a window.
2012  *
2013  * @param obj The window object
2014  * @param maximized If true, the window is maximized
2015  *
2016  * @ingroup Win
2017  */
2018 EAPI void
2019 elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
2020 {
2021    Elm_Win *win;
2022    ELM_CHECK_WIDTYPE(obj, widtype);
2023    win = elm_widget_data_get(obj);
2024    if (!win) return;
2025    // YYY: handle if win->img_obj
2026    ecore_evas_maximized_set(win->ee, maximized);
2027 #ifdef HAVE_ELEMENTARY_X
2028    _elm_win_xwin_update(win);
2029 #endif
2030 }
2031
2032 /**
2033  * Get the maximized state of a window.
2034  *
2035  * @param obj The window object
2036  * @return If true, the window is maximized
2037  *
2038  * @ingroup Win
2039  */
2040 EAPI Eina_Bool
2041 elm_win_maximized_get(const Evas_Object *obj)
2042 {
2043    Elm_Win *win;
2044    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2045    win = elm_widget_data_get(obj);
2046    if (!win) return EINA_FALSE;
2047    return ecore_evas_maximized_get(win->ee);
2048 }
2049
2050 /**
2051  * Set the iconified state of a window.
2052  *
2053  * @param obj The window object
2054  * @param iconified If true, the window is iconified
2055  *
2056  * @ingroup Win
2057  */
2058 EAPI void
2059 elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
2060 {
2061    Elm_Win *win;
2062    ELM_CHECK_WIDTYPE(obj, widtype);
2063    win = elm_widget_data_get(obj);
2064    if (!win) return;
2065    ecore_evas_iconified_set(win->ee, iconified);
2066 #ifdef HAVE_ELEMENTARY_X
2067    _elm_win_xwin_update(win);
2068 #endif
2069 }
2070
2071 /**
2072  * Get the iconified state of a window.
2073  *
2074  * @param obj The window object
2075  * @return If true, the window is iconified
2076  *
2077  * @ingroup Win
2078  */
2079 EAPI Eina_Bool
2080 elm_win_iconified_get(const Evas_Object *obj)
2081 {
2082    Elm_Win *win;
2083    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2084    win = elm_widget_data_get(obj);
2085    if (!win) return EINA_FALSE;
2086    return ecore_evas_iconified_get(win->ee);
2087 }
2088
2089 /**
2090  * Set the layer of the window.
2091  *
2092  * @param obj The window object
2093  * @param layer The layer of the window
2094  *
2095  * @ingroup Win
2096  */
2097 EAPI void
2098 elm_win_layer_set(Evas_Object *obj, int layer)
2099 {
2100    Elm_Win *win;
2101    ELM_CHECK_WIDTYPE(obj, widtype);
2102    win = elm_widget_data_get(obj);
2103    if (!win) return;
2104    ecore_evas_layer_set(win->ee, layer);
2105 #ifdef HAVE_ELEMENTARY_X
2106    _elm_win_xwin_update(win);
2107 #endif
2108 }
2109
2110 /**
2111  * Get the layer of the window.
2112  *
2113  * @param obj The window object
2114  * @return The layer of the window
2115  *
2116  * @ingroup Win
2117  */
2118 EAPI int
2119 elm_win_layer_get(const Evas_Object *obj)
2120 {
2121    Elm_Win *win;
2122    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2123    win = elm_widget_data_get(obj);
2124    if (!win) return -1;
2125    return ecore_evas_layer_get(win->ee);
2126 }
2127
2128 /**
2129  * Set the rotation of the window.
2130  *
2131  * @param obj The window object
2132  * @param rotation The rotation of the window, in degrees (0-360)
2133  *
2134  * @ingroup Win
2135  */
2136 EAPI void
2137 elm_win_rotation_set(Evas_Object *obj, int rotation)
2138 {
2139    Elm_Win *win;
2140    ELM_CHECK_WIDTYPE(obj, widtype);
2141    win = elm_widget_data_get(obj);
2142    if (!win) return;
2143    if (win->rot == rotation) return;
2144    win->rot = rotation;
2145    ecore_evas_rotation_set(win->ee, rotation);
2146    evas_object_size_hint_min_set(obj, -1, -1);
2147    evas_object_size_hint_max_set(obj, -1, -1);
2148    _elm_win_eval_subobjs(obj);
2149 #ifdef HAVE_ELEMENTARY_X
2150    _elm_win_xwin_update(win);
2151 #endif
2152 }
2153
2154 /**
2155  * Rotates the window and resizes it
2156  *
2157  * @param obj The window object
2158  * @param layer The rotation of the window in degrees (0-360)
2159  *
2160  * @ingroup Win
2161  */
2162 EAPI void
2163 elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
2164 {
2165    Elm_Win *win;
2166    ELM_CHECK_WIDTYPE(obj, widtype);
2167    win = elm_widget_data_get(obj);
2168    if (!win) return;
2169    if (win->rot == rotation) return;
2170    win->rot = rotation;
2171    ecore_evas_rotation_with_resize_set(win->ee, rotation);
2172    evas_object_size_hint_min_set(obj, -1, -1);
2173    evas_object_size_hint_max_set(obj, -1, -1);
2174    _elm_win_eval_subobjs(obj);
2175 #ifdef HAVE_ELEMENTARY_X
2176    _elm_win_xwin_update(win);
2177 #endif
2178 }
2179
2180 /**
2181  * Get the rotation of the window.
2182  *
2183  * @param obj The window object
2184  * @return The rotation of the window in degrees (0-360)
2185  *
2186  * @ingroup Win
2187  */
2188 EAPI int
2189 elm_win_rotation_get(const Evas_Object *obj)
2190 {
2191    Elm_Win *win;
2192    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2193    win = elm_widget_data_get(obj);
2194    if (!win) return -1;
2195    return win->rot;
2196 }
2197
2198 /**
2199  * Set the sticky state of the window.
2200  *
2201  * @param obj The window object
2202  * @param sticky If true, the window's sticky state is enabled
2203  *
2204  * @ingroup Win
2205  */
2206 EAPI void
2207 elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
2208 {
2209    Elm_Win *win;
2210    ELM_CHECK_WIDTYPE(obj, widtype);
2211    win = elm_widget_data_get(obj);
2212    if (!win) return;
2213    ecore_evas_sticky_set(win->ee, sticky);
2214 #ifdef HAVE_ELEMENTARY_X
2215    _elm_win_xwin_update(win);
2216 #endif
2217 }
2218
2219 /**
2220  * Get the sticky state of the window.
2221  *
2222  * @param obj The window object
2223  * @return If true, the window's sticky state is enabled
2224  *
2225  * @ingroup Win
2226  */
2227 EAPI Eina_Bool
2228 elm_win_sticky_get(const Evas_Object *obj)
2229 {
2230    Elm_Win *win;
2231    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2232    win = elm_widget_data_get(obj);
2233    if (!win) return EINA_FALSE;
2234    return ecore_evas_sticky_get(win->ee);
2235 }
2236
2237 /**
2238  * Sets the keyboard mode of the window.
2239  *
2240  * @param obj The window object
2241  * @param mode The mode to set; one of:
2242  * ELM_WIN_KEYBOARD_UNKNOWN
2243  * ELM_WIN_KEYBOARD_OFF
2244  * ELM_WIN_KEYBOARD_ON
2245  * ELM_WIN_KEYBOARD_ALPHA
2246  * ELM_WIN_KEYBOARD_NUMERIC
2247  * ELM_WIN_KEYBOARD_PIN
2248  * ELM_WIN_KEYBOARD_PHONE_NUMBER
2249  * ELM_WIN_KEYBOARD_HEX
2250  * ELM_WIN_KEYBOARD_TERMINAL
2251  * ELM_WIN_KEYBOARD_PASSWORD
2252  * ELM_WIN_KEYBOARD_IP
2253  * ELM_WIN_KEYBOARD_HOST
2254  * ELM_WIN_KEYBOARD_FILE
2255  * ELM_WIN_KEYBOARD_URL
2256  * ELM_WIN_KEYBOARD_KEYPAD
2257  * ELM_WIN_KEYBOARD_J2ME
2258  *
2259  * @ingroup Win
2260  */
2261 EAPI void
2262 elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
2263 {
2264    Elm_Win *win;
2265    ELM_CHECK_WIDTYPE(obj, widtype);
2266    win = elm_widget_data_get(obj);
2267    if (!win) return;
2268    if (mode == win->kbdmode) return;
2269 #ifdef HAVE_ELEMENTARY_X
2270    _elm_win_xwindow_get(win);
2271 #endif
2272    win->kbdmode = mode;
2273 #ifdef HAVE_ELEMENTARY_X
2274    if (win->xwin)
2275      ecore_x_e_virtual_keyboard_state_set
2276         (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
2277 #endif
2278 }
2279
2280 /**
2281  * Gets the keyboard mode of the window.
2282  *
2283  * @param obj The window object
2284  * @return The mode; one of:
2285  * ELM_WIN_KEYBOARD_UNKNOWN
2286  * ELM_WIN_KEYBOARD_OFF
2287  * ELM_WIN_KEYBOARD_ON
2288  * ELM_WIN_KEYBOARD_ALPHA
2289  * ELM_WIN_KEYBOARD_NUMERIC
2290  * ELM_WIN_KEYBOARD_PIN
2291  * ELM_WIN_KEYBOARD_PHONE_NUMBER
2292  * ELM_WIN_KEYBOARD_HEX
2293  * ELM_WIN_KEYBOARD_TERMINAL
2294  * ELM_WIN_KEYBOARD_PASSWORD
2295  * ELM_WIN_KEYBOARD_IP
2296  * ELM_WIN_KEYBOARD_HOST
2297  * ELM_WIN_KEYBOARD_FILE
2298  * ELM_WIN_KEYBOARD_URL
2299  * ELM_WIN_KEYBOARD_KEYPAD
2300  * ELM_WIN_KEYBOARD_J2ME
2301  *
2302  * @ingroup Win
2303  */
2304 EAPI Elm_Win_Keyboard_Mode
2305 elm_win_keyboard_mode_get(const Evas_Object *obj)
2306 {
2307    Elm_Win *win;
2308    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN;
2309    win = elm_widget_data_get(obj);
2310    if (!win) return ELM_WIN_KEYBOARD_UNKNOWN;
2311    return win->kbdmode;
2312 }
2313
2314 /**
2315  * Sets whether the window is a keyboard.
2316  *
2317  * @param obj The window object
2318  * @param is_keyboard If true, the window is a virtual keyboard
2319  *
2320  * @ingroup Win
2321  */
2322 EAPI void
2323 elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
2324 {
2325    Elm_Win *win;
2326    ELM_CHECK_WIDTYPE(obj, widtype);
2327    win = elm_widget_data_get(obj);
2328    if (!win) return;
2329 #ifdef HAVE_ELEMENTARY_X
2330    _elm_win_xwindow_get(win);
2331    if (win->xwin)
2332      ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard);
2333 #endif
2334 }
2335
2336 /**
2337  * Gets whether the window is a keyboard.
2338  *
2339  * @param obj The window object
2340  * @return If the window is a virtual keyboard
2341  *
2342  * @ingroup Win
2343  */
2344 EAPI Eina_Bool
2345 elm_win_keyboard_win_get(const Evas_Object *obj)
2346 {
2347    Elm_Win *win;
2348    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2349    win = elm_widget_data_get(obj);
2350    if (!win) return EINA_FALSE;
2351 #ifdef HAVE_ELEMENTARY_X
2352    _elm_win_xwindow_get(win);
2353    if (win->xwin)
2354      return ecore_x_e_virtual_keyboard_get(win->xwin);
2355 #endif
2356    return EINA_FALSE;
2357 }
2358
2359 /**
2360  * Get the screen position of a window.
2361  *
2362  * @param obj The window object
2363  * @param x The int to store the x coordinate to
2364  * @param y The int to store the y coordinate to
2365  *
2366  * @ingroup Win
2367  */
2368 EAPI void
2369 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
2370 {
2371    Elm_Win *win;
2372    ELM_CHECK_WIDTYPE(obj, widtype);
2373    win = elm_widget_data_get(obj);
2374    if (!win) return;
2375    if (x) *x = win->screen.x;
2376    if (y) *y = win->screen.y;
2377 }
2378
2379 /**
2380  * Set if this window is an illume conformant window
2381  *
2382  * @param obj The window object
2383  * @param conformant The conformant flag (1 = conformant, 0 = non-conformant)
2384  *
2385  * @ingroup Win
2386  */
2387 EAPI void
2388 elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
2389 {
2390    Elm_Win *win;
2391    ELM_CHECK_WIDTYPE(obj, widtype);
2392    win = elm_widget_data_get(obj);
2393    if (!win) return;
2394 #ifdef HAVE_ELEMENTARY_X
2395    _elm_win_xwindow_get(win);
2396    if (win->xwin)
2397      ecore_x_e_illume_conformant_set(win->xwin, conformant);
2398 #endif
2399 }
2400
2401 /**
2402  * Get if this window is an illume conformant window
2403  *
2404  * @param obj The window object
2405  * @return A boolean if this window is illume conformant or not
2406  *
2407  * @ingroup Win
2408  */
2409 EAPI Eina_Bool
2410 elm_win_conformant_get(const Evas_Object *obj)
2411 {
2412    Elm_Win *win;
2413    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2414    win = elm_widget_data_get(obj);
2415    if (!win) return EINA_FALSE;
2416 #ifdef HAVE_ELEMENTARY_X
2417    _elm_win_xwindow_get(win);
2418    if (win->xwin)
2419      return ecore_x_e_illume_conformant_get(win->xwin);
2420 #endif
2421    return EINA_FALSE;
2422 }
2423
2424 /**
2425  * Set a window to be an illume quickpanel window
2426  *
2427  * By default window objects are not quickpanel windows.
2428  *
2429  * @param obj The window object
2430  * @param quickpanel The quickpanel flag (1 = quickpanel, 0 = normal window)
2431  *
2432  * @ingroup Win
2433  */
2434 EAPI void
2435 elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
2436 {
2437    Elm_Win *win;
2438    ELM_CHECK_WIDTYPE(obj, widtype);
2439    win = elm_widget_data_get(obj);
2440    if (!win) return;
2441 #ifdef HAVE_ELEMENTARY_X
2442    _elm_win_xwindow_get(win);
2443    if (win->xwin)
2444      {
2445         ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel);
2446         if (quickpanel)
2447           {
2448              Ecore_X_Window_State states[2];
2449
2450              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2451              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2452              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2453              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2454           }
2455      }
2456 #endif
2457 }
2458
2459 /**
2460  * Get if this window is a quickpanel or not
2461  *
2462  * @param obj The window object
2463  * @return A boolean if this window is a quickpanel or not
2464  *
2465  * @ingroup Win
2466  */
2467 EAPI Eina_Bool
2468 elm_win_quickpanel_get(const Evas_Object *obj)
2469 {
2470    Elm_Win *win;
2471    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2472    win = elm_widget_data_get(obj);
2473    if (!win) return EINA_FALSE;
2474 #ifdef HAVE_ELEMENTARY_X
2475    _elm_win_xwindow_get(win);
2476    if (win->xwin)
2477      return ecore_x_e_illume_quickpanel_get(win->xwin);
2478 #endif
2479    return EINA_FALSE;
2480 }
2481
2482 /**
2483  * Set the major priority of a quickpanel window
2484  *
2485  * @param obj The window object
2486  * @param priority The major priority for this quickpanel
2487  *
2488  * @ingroup Win
2489  */
2490 EAPI void
2491 elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
2492 {
2493    Elm_Win *win;
2494    ELM_CHECK_WIDTYPE(obj, widtype);
2495    win = elm_widget_data_get(obj);
2496    if (!win) return;
2497 #ifdef HAVE_ELEMENTARY_X
2498    _elm_win_xwindow_get(win);
2499    if (win->xwin)
2500      ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority);
2501 #endif
2502 }
2503
2504 /**
2505  * Get the major priority of a quickpanel window
2506  *
2507  * @param obj The window object
2508  * @return The major priority of this quickpanel
2509  *
2510  * @ingroup Win
2511  */
2512 EAPI int
2513 elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
2514 {
2515    Elm_Win *win;
2516    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2517    win = elm_widget_data_get(obj);
2518    if (!win) return -1;
2519 #ifdef HAVE_ELEMENTARY_X
2520    _elm_win_xwindow_get(win);
2521    if (win->xwin)
2522      return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin);
2523 #endif
2524    return -1;
2525 }
2526
2527 /**
2528  * Set the minor priority of a quickpanel window
2529  *
2530  * @param obj The window object
2531  * @param priority The minor priority for this quickpanel
2532  *
2533  * @ingroup Win
2534  */
2535 EAPI void
2536 elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
2537 {
2538    Elm_Win *win;
2539    ELM_CHECK_WIDTYPE(obj, widtype);
2540    win = elm_widget_data_get(obj);
2541    if (!win) return;
2542 #ifdef HAVE_ELEMENTARY_X
2543    _elm_win_xwindow_get(win);
2544    if (win->xwin)
2545      ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority);
2546 #endif
2547 }
2548
2549 /**
2550  * Get the minor priority of a quickpanel window
2551  *
2552  * @param obj The window object
2553  * @return The minor priority of this quickpanel
2554  *
2555  * @ingroup Win
2556  */
2557 EAPI int
2558 elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
2559 {
2560    Elm_Win *win;
2561    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2562    win = elm_widget_data_get(obj);
2563    if (!win) return -1;
2564 #ifdef HAVE_ELEMENTARY_X
2565    _elm_win_xwindow_get(win);
2566    if (win->xwin)
2567      return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin);
2568 #endif
2569    return -1;
2570 }
2571
2572 /**
2573  * Set which zone this quickpanel should appear in
2574  *
2575  * @param obj The window object
2576  * @param zone The requested zone for this quickpanel
2577  *
2578  * @ingroup Win
2579  */
2580 EAPI void
2581 elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
2582 {
2583    Elm_Win *win;
2584    ELM_CHECK_WIDTYPE(obj, widtype);
2585    win = elm_widget_data_get(obj);
2586    if (!win) return;
2587 #ifdef HAVE_ELEMENTARY_X
2588    _elm_win_xwindow_get(win);
2589    if (win->xwin)
2590      ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone);
2591 #endif
2592 }
2593
2594 /**
2595  * Get which zone this quickpanel should appear in
2596  *
2597  * @param obj The window object
2598  * @return The requested zone for this quickpanel
2599  *
2600  * @ingroup Win
2601  */
2602 EAPI int
2603 elm_win_quickpanel_zone_get(const Evas_Object *obj)
2604 {
2605    Elm_Win *win;
2606    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2607    win = elm_widget_data_get(obj);
2608    if (!win) return 0;
2609 #ifdef HAVE_ELEMENTARY_X
2610    _elm_win_xwindow_get(win);
2611    if (win->xwin)
2612      return ecore_x_e_illume_quickpanel_zone_get(win->xwin);
2613 #endif
2614    return 0;
2615 }
2616
2617 /**
2618  * Set the window to be skipped by keyboard focus
2619  *
2620  * This sets the window to be skipped by normal keyboard input. This means
2621  * a window manager will be asked to not focus this window as well as omit
2622  * it from things like the taskbar, pager, "alt-tab" list etc. etc.
2623  *
2624  * Call this and enable it on a window BEFORE you show it for the first time,
2625  * otherwise it may have no effect.
2626  *
2627  * Use this for windows that have only output information or might only be
2628  * interacted with by the mouse or fingers, and never for typing input.
2629  * Be careful that this may have side-effects like making the window
2630  * non-accessible in some cases unless the window is specially handled. Use
2631  * this with care.
2632  *
2633  * @param obj The window object
2634  * @param skip The skip flag state (EINA_TRUE if it is to be skipped)
2635  *
2636  * @ingroup Win
2637  */
2638 EAPI void
2639 elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip)
2640 {
2641    Elm_Win *win;
2642    ELM_CHECK_WIDTYPE(obj, widtype);
2643    win = elm_widget_data_get(obj);
2644    if (!win) return;
2645 #ifdef HAVE_ELEMENTARY_X
2646    _elm_win_xwindow_get(win);
2647    if (skip)
2648      {
2649         if (win->xwin)
2650           {
2651              Ecore_X_Window_State states[2];
2652
2653              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2654              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2655              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2656              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2657           }
2658      }
2659 #endif
2660 }
2661
2662 /**
2663  * Send a command to the windowing environment
2664  *
2665  * This is intended to work in touchscreen or small screen device environments
2666  * where there is a more simplistic window management policy in place. This
2667  * uses the window object indicated to select which part of the environment
2668  * to control (the part that this window lives in), and provides a command
2669  * and an optional parameter structure (use NULL for this if not needed).
2670  *
2671  * @param obj The window object that lives in the environment to control
2672  * @param command The command to send
2673  * @param params Optional parameters for the command
2674  *
2675  * @ingroup Win
2676  */
2677 EAPI void
2678 elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params __UNUSED__)
2679 {
2680    Elm_Win *win;
2681    ELM_CHECK_WIDTYPE(obj, widtype);
2682    win = elm_widget_data_get(obj);
2683    if (!win) return;
2684 #ifdef HAVE_ELEMENTARY_X
2685    _elm_win_xwindow_get(win);
2686    if (win->xwin)
2687      {
2688         switch (command)
2689           {
2690            case ELM_ILLUME_COMMAND_FOCUS_BACK:
2691               ecore_x_e_illume_focus_back_send(win->xwin);
2692               break;
2693            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
2694               ecore_x_e_illume_focus_forward_send(win->xwin);
2695               break;
2696            case ELM_ILLUME_COMMAND_FOCUS_HOME:
2697               ecore_x_e_illume_focus_home_send(win->xwin);
2698               break;
2699            case ELM_ILLUME_COMMAND_CLOSE:
2700               ecore_x_e_illume_close_send(win->xwin);
2701               break;
2702            default:
2703               break;
2704           }
2705      }
2706 #endif
2707 }
2708
2709 /**
2710  * Get the inlined image object handle
2711  *
2712  * When you create a window with elm_win_add() of type ELM_WIN_INLINED_IMAGE,
2713  * then the window is in fact an evas image object inlined in the parent
2714  * canvas. You can get this object (be careful to not manipulate it as it
2715  * is under control of elementary), and use it to do things like get pixel
2716  * data, save the image to a file, etc.
2717  *
2718  * @param obj The window object to get the inlined image from
2719  * @return The inlined image object, or NULL if none exists
2720  *
2721  * @ingroup Win
2722  */
2723 EAPI Evas_Object *
2724 elm_win_inlined_image_object_get(Evas_Object *obj)
2725 {
2726    Elm_Win *win;
2727    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2728    win = elm_widget_data_get(obj);
2729    if (!win) return NULL;
2730    return win->img_obj;
2731 }
2732
2733 /**
2734  * Set the enabled status for the focus highlight in a window
2735  *
2736  * This function will enable or disable the focus highlight only for the
2737  * given window, regardless of the global setting for it
2738  *
2739  * @param obj The window where to enable the highlight
2740  * @param enabled The enabled value for the highlight
2741  *
2742  * @ingroup Win
2743  */
2744 EAPI void
2745 elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled)
2746 {
2747    Elm_Win *win;
2748
2749    ELM_CHECK_WIDTYPE(obj, widtype);
2750
2751    win = elm_widget_data_get(obj);
2752    enabled = !!enabled;
2753    if (win->focus_highlight.enabled == enabled)
2754      return;
2755
2756    win->focus_highlight.enabled = enabled;
2757
2758    if (win->focus_highlight.enabled)
2759      _elm_win_focus_highlight_init(win);
2760    else
2761      _elm_win_focus_highlight_shutdown(win);
2762 }
2763
2764 /**
2765  * Get the enabled value of the focus highlight for this window
2766  *
2767  * @param obj The window in which to check if the focus highlight is enabled
2768  *
2769  * @return EINA_TRUE if enabled, EINA_FALSE otherwise
2770  *
2771  * @ingroup Win
2772  */
2773 EAPI Eina_Bool
2774 elm_win_focus_highlight_enabled_get(const Evas_Object *obj)
2775 {
2776    Elm_Win *win;
2777
2778    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2779
2780    win = elm_widget_data_get(obj);
2781    return win->focus_highlight.enabled;
2782 }
2783
2784 /**
2785  * Set the style for the focus highlight on this window
2786  *
2787  * Sets the style to use for theming the highlight of focused objects on
2788  * the given window. If @p style is NULL, the default will be used.
2789  *
2790  * @param obj The window where to set the style
2791  * @param style The style to set
2792  *
2793  * @ingroup Win
2794  */
2795 EAPI void
2796 elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style)
2797 {
2798    Elm_Win *win;
2799
2800    ELM_CHECK_WIDTYPE(obj, widtype);
2801
2802    win = elm_widget_data_get(obj);
2803    eina_stringshare_replace(&win->focus_highlight.style, style);
2804    win->focus_highlight.changed_theme = EINA_TRUE;
2805    _elm_win_focus_highlight_reconfigure_job_start(win);
2806 }
2807
2808 /**
2809  * Get the style set for the focus highlight object
2810  *
2811  * Gets the style set for this windows highilght object, or NULL if none
2812  * is set.
2813  *
2814  * @param obj The window to retrieve the highlights style from
2815  *
2816  * @return The style set or NULL if none was. Default is used in that case.
2817  *
2818  * @ingroup Win
2819  */
2820 EAPI const char *
2821 elm_win_focus_highlight_style_get(const Evas_Object *obj)
2822 {
2823    Elm_Win *win;
2824
2825    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2826
2827    win = elm_widget_data_get(obj);
2828    return win->focus_highlight.style;
2829 }
2830
2831 typedef struct _Widget_Data Widget_Data;
2832
2833 struct _Widget_Data
2834 {
2835    Evas_Object *frm;
2836    Evas_Object *content;
2837 };
2838
2839 static void _del_hook(Evas_Object *obj);
2840 static void _theme_hook(Evas_Object *obj);
2841 static void _sizing_eval(Evas_Object *obj);
2842 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
2843 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
2844
2845 static const char *widtype2 = NULL;
2846
2847 static void
2848 _del_hook(Evas_Object *obj)
2849 {
2850    Widget_Data *wd = elm_widget_data_get(obj);
2851    if (!wd) return;
2852    free(wd);
2853 }
2854
2855 static void
2856 _theme_hook(Evas_Object *obj)
2857 {
2858    Widget_Data *wd = elm_widget_data_get(obj);
2859    _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
2860    if (wd->content)
2861      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
2862    _sizing_eval(obj);
2863 }
2864
2865 static Eina_Bool
2866 _elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
2867 {
2868    Widget_Data *wd = elm_widget_data_get(obj);
2869
2870    if (!wd)
2871      return EINA_FALSE;
2872
2873    /* Try Focus cycle in subitem */
2874    if (wd->content)
2875      {
2876         elm_widget_focus_next_get(wd->content, dir, next);
2877         if (*next)
2878           return EINA_TRUE;
2879      }
2880
2881    *next = (Evas_Object *)obj;
2882    return EINA_FALSE;
2883 }
2884
2885 static void
2886 _sizing_eval(Evas_Object *obj)
2887 {
2888    Widget_Data *wd = elm_widget_data_get(obj);
2889    Evas_Coord minw = -1, minh = -1;
2890
2891    evas_object_size_hint_min_get(wd->content, &minw, &minh);
2892    edje_object_size_min_calc(wd->frm, &minw, &minh);
2893    evas_object_size_hint_min_set(obj, minw, minh);
2894    evas_object_size_hint_max_set(obj, -1, -1);
2895 }
2896
2897 static void
2898 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2899 {
2900    _sizing_eval(data);
2901 }
2902
2903 static void
2904 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
2905 {
2906    Widget_Data *wd = elm_widget_data_get(obj);
2907    Evas_Object *sub = event_info;
2908    if (sub == wd->content)
2909      {
2910         evas_object_event_callback_del_full
2911            (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
2912         wd->content = NULL;
2913         _sizing_eval(obj);
2914      }
2915 }
2916
2917 /**
2918  * @defgroup Inwin Inwin
2919  *
2920  * An inwin is a window inside a window that is useful for a quick popup.  It does not hover.
2921  */
2922 EAPI Evas_Object *
2923 elm_win_inwin_add(Evas_Object *obj)
2924 {
2925    Evas_Object *obj2;
2926    Widget_Data *wd;
2927    Elm_Win *win;
2928
2929    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2930    win = elm_widget_data_get(obj);
2931    if (!win) return NULL;
2932    wd = ELM_NEW(Widget_Data);
2933    obj2 = elm_widget_add(win->evas);
2934    elm_widget_type_set(obj2, "inwin");
2935    ELM_SET_WIDTYPE(widtype2, "inwin");
2936    elm_widget_sub_object_add(obj, obj2);
2937    evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2938    evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL);
2939    elm_win_resize_object_add(obj, obj2);
2940
2941    elm_widget_data_set(obj2, wd);
2942    elm_widget_del_hook_set(obj2, _del_hook);
2943    elm_widget_theme_hook_set(obj2, _theme_hook);
2944    elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook);
2945    elm_widget_can_focus_set(obj2, EINA_TRUE);
2946    elm_widget_highlight_ignore_set(obj2, EINA_TRUE);
2947
2948    wd->frm = edje_object_add(win->evas);
2949    _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
2950    elm_widget_resize_object_set(obj2, wd->frm);
2951
2952    evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
2953
2954    _sizing_eval(obj2);
2955    return obj2;
2956 }
2957
2958 /**
2959  * Activates an inwin object
2960  *
2961  * @param obj The inwin to activate
2962  *
2963  * @ingroup Inwin
2964  */
2965 EAPI void
2966 elm_win_inwin_activate(Evas_Object *obj)
2967 {
2968    ELM_CHECK_WIDTYPE(obj, widtype2);
2969    Widget_Data *wd = elm_widget_data_get(obj);
2970    if (!wd) return;
2971    evas_object_raise(obj);
2972    evas_object_show(obj);
2973    edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
2974    elm_object_focus(obj);
2975 }
2976
2977 /**
2978  * Set the content of an inwin object.
2979  *
2980  * Once the content object is set, a previously set one will be deleted.
2981  * If you want to keep that old content object, use the
2982  * elm_win_inwin_content_unset() function.
2983  *
2984  * @param obj The inwin object
2985  * @param content The object to set as content
2986  *
2987  * @ingroup Inwin
2988  */
2989 EAPI void
2990 elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
2991 {
2992    ELM_CHECK_WIDTYPE(obj, widtype2);
2993    Widget_Data *wd = elm_widget_data_get(obj);
2994    if (!wd) return;
2995    if (wd->content == content) return;
2996    if (wd->content) evas_object_del(wd->content);
2997    wd->content = content;
2998    if (content)
2999      {
3000         elm_widget_sub_object_add(obj, content);
3001         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3002                                        _changed_size_hints, obj);
3003         edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
3004      }
3005    _sizing_eval(obj);
3006 }
3007
3008 /**
3009  * Get the content of an inwin object.
3010  *
3011  * Return the content object which is set for this widget.
3012  *
3013  * @param obj The inwin object
3014  * @return The content that is being used
3015  *
3016  * @ingroup Inwin
3017  */
3018 EAPI Evas_Object *
3019 elm_win_inwin_content_get(const Evas_Object *obj)
3020 {
3021    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
3022    Widget_Data *wd = elm_widget_data_get(obj);
3023    if (!wd) return NULL;
3024    return wd->content;
3025 }
3026
3027 /**
3028  * Unset the content of an inwin object.
3029  *
3030  * Unparent and return the content object which was set for this widget.
3031  *
3032  * @param obj The inwin object
3033  * @return The content that was being used
3034  *
3035  * @ingroup Inwin
3036  */
3037 EAPI Evas_Object *
3038 elm_win_inwin_content_unset(Evas_Object *obj)
3039 {
3040    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
3041    Widget_Data *wd = elm_widget_data_get(obj);
3042    if (!wd) return NULL;
3043    if (!wd->content) return NULL;
3044    Evas_Object *content = wd->content;
3045    elm_widget_sub_object_del(obj, wd->content);
3046    edje_object_part_unswallow(wd->frm, wd->content);
3047    wd->content = NULL;
3048    return content;
3049 }
3050
3051 /* windowing spcific calls - shall we do this differently? */
3052
3053 static Ecore_X_Window
3054 _elm_ee_win_get(const Evas_Object *obj)
3055 {
3056    if (!obj) return 0;
3057 #ifdef HAVE_ELEMENTARY_X
3058    Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
3059    if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee);
3060 #endif
3061    return 0;
3062 }
3063
3064 /**
3065  * Get the Ecore_X_Window of an Evas_Object
3066  *
3067  * @param obj The object
3068  *
3069  * @return The Ecore_X_Window of @p obj
3070  *
3071  * @ingroup Win
3072  */
3073 EAPI Ecore_X_Window
3074 elm_win_xwindow_get(const Evas_Object *obj)
3075 {
3076    Ecore_X_Window xwin = 0;
3077    Elm_Win *win;
3078    const char *type;
3079
3080    if (!obj) return 0;
3081    type = elm_widget_type_get(obj);
3082    if (!type) return 0;
3083    if (type != widtype) return _elm_ee_win_get(obj);
3084 #ifdef HAVE_ELEMENTARY_X
3085    win = elm_widget_data_get(obj);
3086    if (!win) return xwin;
3087    if (win->xwin) return win->xwin;
3088    if (win->parent) return elm_win_xwindow_get(win->parent);
3089 #endif
3090    return xwin;
3091    win = NULL;
3092 }