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