Inwin docs. No example.
[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 (ENGINE_COMPARE(ELM_BUFFER))
1531           {
1532              win->ee = ecore_evas_buffer_new(1, 1);
1533           }
1534         else if (!strncmp(_elm_config->engine, "shot:", 5))
1535           {
1536              win->ee = ecore_evas_buffer_new(1, 1);
1537              ecore_evas_manual_render_set(win->ee, EINA_TRUE);
1538              win->shot.info = eina_stringshare_add(_elm_config->engine + 5);
1539              _shot_init(win);
1540           }
1541 #undef FALLBACK_TRY
1542         break;
1543      }
1544
1545    if (!win->ee)
1546      {
1547         ERR("Cannot create window.");
1548         free(win);
1549         return NULL;
1550      }
1551 #ifdef HAVE_ELEMENTARY_X
1552    _elm_win_xwindow_get(win);
1553 #endif
1554    if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
1555      ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
1556    // bg pixmap done by x - has other issues like can be redrawn by x before it
1557    // is filled/ready by app
1558    //     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
1559
1560    win->type = type;
1561    win->parent = parent;
1562    if (win->parent)
1563      evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL,
1564                                     _elm_win_obj_callback_parent_del, win);
1565
1566    win->evas = ecore_evas_get(win->ee);
1567    win->win_obj = elm_widget_add(win->evas);
1568    elm_widget_type_set(win->win_obj, "win");
1569    ELM_SET_WIDTYPE(widtype, "win");
1570    elm_widget_data_set(win->win_obj, win);
1571    elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb);
1572    elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL);
1573    elm_widget_can_focus_set(win->win_obj, EINA_TRUE);
1574    elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE);
1575    elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook);
1576    evas_object_color_set(win->win_obj, 0, 0, 0, 0);
1577    evas_object_move(win->win_obj, 0, 0);
1578    evas_object_resize(win->win_obj, 1, 1);
1579    evas_object_layer_set(win->win_obj, 50);
1580    evas_object_pass_events_set(win->win_obj, EINA_TRUE);
1581
1582    ecore_evas_object_associate(win->ee, win->win_obj,
1583                                ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
1584                                ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
1585                                ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
1586    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW,
1587                                   _elm_win_obj_callback_show, win);
1588    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_HIDE,
1589                                   _elm_win_obj_callback_hide, win);
1590    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
1591                                   _elm_win_obj_callback_del, win);
1592    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_MOVE,
1593                                   _elm_win_obj_callback_move, win);
1594    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_RESIZE,
1595                                   _elm_win_obj_callback_resize, win);
1596    if (win->img_obj)
1597       evas_object_intercept_move_callback_add(win->win_obj,
1598                                               _elm_win_obj_intercept_move, win);
1599    evas_object_intercept_show_callback_add(win->win_obj,
1600                                            _elm_win_obj_intercept_show, win);
1601
1602    ecore_evas_name_class_set(win->ee, name, _elm_appname);
1603    ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request);
1604    ecore_evas_callback_resize_set(win->ee, _elm_win_resize);
1605    ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in);
1606    ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out);
1607    ecore_evas_callback_move_set(win->ee, _elm_win_move);
1608    evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024));
1609    evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
1610    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
1611       evas_font_path_append(win->evas, fontpath);
1612    if (!_elm_config->font_hinting)
1613      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
1614    else if (_elm_config->font_hinting == 1)
1615      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
1616    else if (_elm_config->font_hinting == 2)
1617      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE);
1618
1619 #ifdef HAVE_ELEMENTARY_X
1620    _elm_win_xwin_update(win);
1621 #endif
1622
1623    _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
1624
1625    if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1626      {
1627         ecore_evas_fullscreen_set(win->ee, 1);
1628      }
1629 #undef ENGINE_COMPARE
1630
1631    if (_elm_config->focus_highlight_enable)
1632      elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE);
1633
1634 #ifdef ELM_DEBUG
1635    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control");
1636    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN,
1637                                   _debug_key_down, win);
1638
1639    Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0,
1640                                         EINA_TRUE);
1641    printf("Key F12 exclusive for dot tree generation. (%d)\n", ret);
1642 #endif
1643
1644    evas_object_smart_callbacks_descriptions_set(win->win_obj, _signals);
1645
1646    return win->win_obj;
1647 }
1648
1649 /**
1650  * Add @p subobj as a resize object of window @p obj. Note, do not move and
1651  * resize window and sub object at the same time. It will cause problem.
1652  *
1653  * @param obj The window object
1654  * @param subobj The resize object to add
1655  *
1656  * @ingroup Win
1657  */
1658 EAPI void
1659 elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj)
1660 {
1661    Evas_Coord w, h;
1662    Elm_Win *win;
1663    ELM_CHECK_WIDTYPE(obj, widtype);
1664    win = elm_widget_data_get(obj);
1665    if (!win) return;
1666    if (eina_list_data_find(win->subobjs, subobj)) return;
1667    win->subobjs = eina_list_append(win->subobjs, subobj);
1668    elm_widget_sub_object_add(obj, subobj);
1669    evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL,
1670                                   _elm_win_subobj_callback_del, obj);
1671    evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1672                                   _elm_win_subobj_callback_changed_size_hints,
1673                                   obj);
1674    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
1675    evas_object_move(subobj, 0, 0);
1676    evas_object_resize(subobj, w, h);
1677    _elm_win_eval_subobjs(obj);
1678 }
1679
1680 /**
1681  * Delete @p subobj as a resize object of window @p obj.
1682  *
1683  * @param obj The window object
1684  * @param subobj The resize object to add
1685  *
1686  * @ingroup Win
1687  */
1688 EAPI void
1689 elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj)
1690 {
1691    Elm_Win *win;
1692    ELM_CHECK_WIDTYPE(obj, widtype);
1693    win = elm_widget_data_get(obj);
1694    if (!win) return;
1695    evas_object_event_callback_del_full(subobj,
1696                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1697                                        _elm_win_subobj_callback_changed_size_hints,
1698                                        obj);
1699    evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
1700                                        _elm_win_subobj_callback_del, obj);
1701    win->subobjs = eina_list_remove(win->subobjs, subobj);
1702    elm_widget_sub_object_del(obj, subobj);
1703    _elm_win_eval_subobjs(obj);
1704 }
1705
1706 /**
1707  * Set the title of the window
1708  *
1709  * @param obj The window object
1710  * @param title The title to set
1711  *
1712  * @ingroup Win
1713  */
1714 EAPI void
1715 elm_win_title_set(Evas_Object *obj, const char *title)
1716 {
1717    Elm_Win *win;
1718    ELM_CHECK_WIDTYPE(obj, widtype);
1719    win = elm_widget_data_get(obj);
1720    if (!win) return;
1721    ecore_evas_title_set(win->ee, title);
1722 }
1723
1724 /**
1725  * Get the title of the window
1726  *
1727  * @param obj The window object
1728  * @return The title
1729  *
1730  * @ingroup Win
1731  */
1732 EAPI const char *
1733 elm_win_title_get(const Evas_Object *obj)
1734 {
1735    Elm_Win *win;
1736    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1737    win = elm_widget_data_get(obj);
1738    if (!win) return NULL;
1739    return ecore_evas_title_get(win->ee);
1740 }
1741
1742 /**
1743  * Set the window's autodel state.
1744  *
1745  * @param obj The window object
1746  * @param autodel If true, the window will automatically delete itself when closed
1747  *
1748  * @ingroup Win
1749  */
1750 EAPI void
1751 elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
1752 {
1753    Elm_Win *win;
1754    ELM_CHECK_WIDTYPE(obj, widtype);
1755    win = elm_widget_data_get(obj);
1756    if (!win) return;
1757    win->autodel = autodel;
1758 }
1759
1760 /**
1761  * Get the window's autodel state.
1762  *
1763  * @param obj The window object
1764  * @return If the window will automatically delete itself when closed
1765  *
1766  * @ingroup Win
1767  */
1768 EAPI Eina_Bool
1769 elm_win_autodel_get(const Evas_Object *obj)
1770 {
1771    Elm_Win *win;
1772    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1773    win = elm_widget_data_get(obj);
1774    if (!win) return EINA_FALSE;
1775    return win->autodel;
1776 }
1777
1778 /**
1779  * Activate a window object.
1780  *
1781  * @param obj The window object
1782  *
1783  * @ingroup Win
1784  */
1785 EAPI void
1786 elm_win_activate(Evas_Object *obj)
1787 {
1788    Elm_Win *win;
1789    ELM_CHECK_WIDTYPE(obj, widtype);
1790    win = elm_widget_data_get(obj);
1791    if (!win) return;
1792    ecore_evas_activate(win->ee);
1793 }
1794
1795 /**
1796  * Lower a window object.
1797  *
1798  * @param obj The window object
1799  *
1800  * @ingroup Win
1801  */
1802 EAPI void
1803 elm_win_lower(Evas_Object *obj)
1804 {
1805    Elm_Win *win;
1806    ELM_CHECK_WIDTYPE(obj, widtype);
1807    win = elm_widget_data_get(obj);
1808    if (!win) return;
1809    ecore_evas_lower(win->ee);
1810 }
1811
1812 /**
1813  * Raise a window object.
1814  *
1815  * @param obj The window object
1816  *
1817  * @ingroup Win
1818  */
1819 EAPI void
1820 elm_win_raise(Evas_Object *obj)
1821 {
1822    Elm_Win *win;
1823    ELM_CHECK_WIDTYPE(obj, widtype);
1824    win = elm_widget_data_get(obj);
1825    if (!win) return;
1826    ecore_evas_raise(win->ee);
1827 }
1828
1829 /**
1830  * Set the borderless state of a window.
1831  *
1832  * @param obj The window object
1833  * @param borderless If true, the window is borderless
1834  *
1835  * @ingroup Win
1836  */
1837 EAPI void
1838 elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
1839 {
1840    Elm_Win *win;
1841    ELM_CHECK_WIDTYPE(obj, widtype);
1842    win = elm_widget_data_get(obj);
1843    if (!win) return;
1844    ecore_evas_borderless_set(win->ee, borderless);
1845 #ifdef HAVE_ELEMENTARY_X
1846    _elm_win_xwin_update(win);
1847 #endif
1848 }
1849
1850 /**
1851  * Get the borderless state of a window.
1852  *
1853  * @param obj The window object
1854  * @return If true, the window is borderless
1855  *
1856  * @ingroup Win
1857  */
1858 EAPI Eina_Bool
1859 elm_win_borderless_get(const Evas_Object *obj)
1860 {
1861    Elm_Win *win;
1862    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1863    win = elm_widget_data_get(obj);
1864    if (!win) return EINA_FALSE;
1865    return ecore_evas_borderless_get(win->ee);
1866 }
1867
1868 /**
1869  * Set the shaped state of a window.
1870  *
1871  * @param obj The window object
1872  * @param shaped If true, the window is shaped
1873  *
1874  * @ingroup Win
1875  */
1876 EAPI void
1877 elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
1878 {
1879    Elm_Win *win;
1880    ELM_CHECK_WIDTYPE(obj, widtype);
1881    win = elm_widget_data_get(obj);
1882    if (!win) return;
1883    ecore_evas_shaped_set(win->ee, shaped);
1884 #ifdef HAVE_ELEMENTARY_X
1885    _elm_win_xwin_update(win);
1886 #endif
1887 }
1888
1889 /**
1890  * Get the shaped state of a window.
1891  *
1892  * @param obj The window object
1893  * @return If true, the window is shaped
1894  *
1895  * @ingroup Win
1896  */
1897 EAPI Eina_Bool
1898 elm_win_shaped_get(const Evas_Object *obj)
1899 {
1900    Elm_Win *win;
1901    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1902    win = elm_widget_data_get(obj);
1903    if (!win) return EINA_FALSE;
1904    return ecore_evas_shaped_get(win->ee);
1905 }
1906
1907 /**
1908  * Set the alpha channel state of a window.
1909  *
1910  * @param obj The window object
1911  * @param alpha If true, the window has an alpha channel
1912  *
1913  * @ingroup Win
1914  */
1915 EAPI void
1916 elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
1917 {
1918    Elm_Win *win;
1919    ELM_CHECK_WIDTYPE(obj, widtype);
1920    win = elm_widget_data_get(obj);
1921    if (!win) return;
1922    if (win->frame_obj)
1923      {
1924      }
1925    else if (win->img_obj)
1926      {
1927         evas_object_image_alpha_set(win->img_obj, alpha);
1928      }
1929    else
1930      {
1931 #ifdef HAVE_ELEMENTARY_X
1932         if (win->xwin)
1933           {
1934              if (alpha)
1935                {
1936                   if (!_elm_config->compositing)
1937                      elm_win_shaped_set(obj, alpha);
1938                   else
1939                      ecore_evas_alpha_set(win->ee, alpha);
1940                }
1941              else
1942                 ecore_evas_alpha_set(win->ee, alpha);
1943              _elm_win_xwin_update(win);
1944           }
1945         else
1946 #endif
1947            ecore_evas_alpha_set(win->ee, alpha);
1948      }
1949 }
1950
1951 /**
1952  * Get the alpha channel state of a window.
1953  *
1954  * @param obj The window object
1955  * @return If true, the window has an alpha channel
1956  *
1957  * @ingroup Win
1958  */
1959 EAPI Eina_Bool
1960 elm_win_alpha_get(const Evas_Object *obj)
1961 {
1962    Elm_Win *win;
1963    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1964    win = elm_widget_data_get(obj);
1965    if (!win) return EINA_FALSE;
1966    return ecore_evas_alpha_get(win->ee);
1967 }
1968
1969 /**
1970  * Set the transparency state of a window.
1971  *
1972  * @param obj The window object
1973  * @param transparent If true, the window is transparent
1974  *
1975  * @ingroup Win
1976  */
1977 EAPI void
1978 elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
1979 {
1980    Elm_Win *win;
1981    ELM_CHECK_WIDTYPE(obj, widtype);
1982    win = elm_widget_data_get(obj);
1983    if (!win) return;
1984
1985    if (win->frame_obj)
1986      {
1987      }
1988    else if (win->img_obj)
1989      {
1990         evas_object_image_alpha_set(win->img_obj, transparent);
1991      }
1992    else
1993      {
1994 #ifdef HAVE_ELEMENTARY_X
1995         if (win->xwin)
1996           {
1997              ecore_evas_transparent_set(win->ee, transparent);
1998              _elm_win_xwin_update(win);
1999           }
2000         else
2001 #endif
2002            ecore_evas_transparent_set(win->ee, transparent);
2003      }
2004 }
2005
2006 /**
2007  * Get the transparency state of a window.
2008  *
2009  * @param obj The window object
2010  * @return If true, the window is transparent
2011  *
2012  * @ingroup Win
2013  */
2014 EAPI Eina_Bool
2015 elm_win_transparent_get(const Evas_Object *obj)
2016 {
2017    Elm_Win *win;
2018    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2019    win = elm_widget_data_get(obj);
2020    if (!win) return EINA_FALSE;
2021
2022    return ecore_evas_transparent_get(win->ee);
2023 }
2024
2025 /**
2026  * Set the override state of a window.
2027  *
2028  * @param obj The window object
2029  * @param override If true, the window is overridden
2030  *
2031  * @ingroup Win
2032  */
2033 EAPI void
2034 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
2035 {
2036    Elm_Win *win;
2037    ELM_CHECK_WIDTYPE(obj, widtype);
2038    win = elm_widget_data_get(obj);
2039    if (!win) return;
2040    ecore_evas_override_set(win->ee, override);
2041 #ifdef HAVE_ELEMENTARY_X
2042    _elm_win_xwin_update(win);
2043 #endif
2044 }
2045
2046 /**
2047  * Get the override state of a window.
2048  *
2049  * @param obj The window object
2050  * @return If true, the window is overridden
2051  *
2052  * @ingroup Win
2053  */
2054 EAPI Eina_Bool
2055 elm_win_override_get(const Evas_Object *obj)
2056 {
2057    Elm_Win *win;
2058    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2059    win = elm_widget_data_get(obj);
2060    if (!win) return EINA_FALSE;
2061    return ecore_evas_override_get(win->ee);
2062 }
2063
2064 /**
2065  * Set the fullscreen state of a window.
2066  *
2067  * @param obj The window object
2068  * @param fullscreen If true, the window is fullscreen
2069  *
2070  * @ingroup Win
2071  */
2072 EAPI void
2073 elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
2074 {
2075    Elm_Win *win;
2076    ELM_CHECK_WIDTYPE(obj, widtype);
2077    win = elm_widget_data_get(obj);
2078    if (!win) return;
2079
2080    // YYY: handle if win->img_obj
2081 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2082    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
2083        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
2084      {
2085         // these engines... can ONLY be fullscreen
2086         return;
2087      }
2088    else
2089      {
2090         ecore_evas_fullscreen_set(win->ee, fullscreen);
2091 #ifdef HAVE_ELEMENTARY_X
2092         _elm_win_xwin_update(win);
2093 #endif
2094      }
2095 #undef ENGINE_COMPARE
2096 }
2097
2098 /**
2099  * Get the fullscreen state of a window.
2100  *
2101  * @param obj The window object
2102  * @return If true, the window is fullscreen
2103  *
2104  * @ingroup Win
2105  */
2106 EAPI Eina_Bool
2107 elm_win_fullscreen_get(const Evas_Object *obj)
2108 {
2109    Elm_Win *win;
2110    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2111    win = elm_widget_data_get(obj);
2112    if (!win) return EINA_FALSE;
2113
2114 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2115    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
2116        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
2117      {
2118         // these engines... can ONLY be fullscreen
2119         return EINA_TRUE;
2120      }
2121    else
2122      {
2123         return ecore_evas_fullscreen_get(win->ee);
2124      }
2125 #undef ENGINE_COMPARE
2126 }
2127
2128 /**
2129  * Set the maximized state of a window.
2130  *
2131  * @param obj The window object
2132  * @param maximized If true, the window is maximized
2133  *
2134  * @ingroup Win
2135  */
2136 EAPI void
2137 elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
2138 {
2139    Elm_Win *win;
2140    ELM_CHECK_WIDTYPE(obj, widtype);
2141    win = elm_widget_data_get(obj);
2142    if (!win) return;
2143    // YYY: handle if win->img_obj
2144    ecore_evas_maximized_set(win->ee, maximized);
2145 #ifdef HAVE_ELEMENTARY_X
2146    _elm_win_xwin_update(win);
2147 #endif
2148 }
2149
2150 /**
2151  * Get the maximized state of a window.
2152  *
2153  * @param obj The window object
2154  * @return If true, the window is maximized
2155  *
2156  * @ingroup Win
2157  */
2158 EAPI Eina_Bool
2159 elm_win_maximized_get(const Evas_Object *obj)
2160 {
2161    Elm_Win *win;
2162    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2163    win = elm_widget_data_get(obj);
2164    if (!win) return EINA_FALSE;
2165    return ecore_evas_maximized_get(win->ee);
2166 }
2167
2168 /**
2169  * Set the iconified state of a window.
2170  *
2171  * @param obj The window object
2172  * @param iconified If true, the window is iconified
2173  *
2174  * @ingroup Win
2175  */
2176 EAPI void
2177 elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
2178 {
2179    Elm_Win *win;
2180    ELM_CHECK_WIDTYPE(obj, widtype);
2181    win = elm_widget_data_get(obj);
2182    if (!win) return;
2183    ecore_evas_iconified_set(win->ee, iconified);
2184 #ifdef HAVE_ELEMENTARY_X
2185    _elm_win_xwin_update(win);
2186 #endif
2187 }
2188
2189 /**
2190  * Get the iconified state of a window.
2191  *
2192  * @param obj The window object
2193  * @return If true, the window is iconified
2194  *
2195  * @ingroup Win
2196  */
2197 EAPI Eina_Bool
2198 elm_win_iconified_get(const Evas_Object *obj)
2199 {
2200    Elm_Win *win;
2201    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2202    win = elm_widget_data_get(obj);
2203    if (!win) return EINA_FALSE;
2204    return ecore_evas_iconified_get(win->ee);
2205 }
2206
2207 /**
2208  * Set the layer of the window.
2209  *
2210  * @param obj The window object
2211  * @param layer The layer of the window
2212  *
2213  * @ingroup Win
2214  */
2215 EAPI void
2216 elm_win_layer_set(Evas_Object *obj, int layer)
2217 {
2218    Elm_Win *win;
2219    ELM_CHECK_WIDTYPE(obj, widtype);
2220    win = elm_widget_data_get(obj);
2221    if (!win) return;
2222    ecore_evas_layer_set(win->ee, layer);
2223 #ifdef HAVE_ELEMENTARY_X
2224    _elm_win_xwin_update(win);
2225 #endif
2226 }
2227
2228 /**
2229  * Get the layer of the window.
2230  *
2231  * @param obj The window object
2232  * @return The layer of the window
2233  *
2234  * @ingroup Win
2235  */
2236 EAPI int
2237 elm_win_layer_get(const Evas_Object *obj)
2238 {
2239    Elm_Win *win;
2240    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2241    win = elm_widget_data_get(obj);
2242    if (!win) return -1;
2243    return ecore_evas_layer_get(win->ee);
2244 }
2245
2246 /**
2247  * Set the rotation of the window.
2248  *
2249  * @param obj The window object
2250  * @param rotation The rotation of the window, in degrees (0-360)
2251  *
2252  * @ingroup Win
2253  */
2254 EAPI void
2255 elm_win_rotation_set(Evas_Object *obj, int rotation)
2256 {
2257    Elm_Win *win;
2258    ELM_CHECK_WIDTYPE(obj, widtype);
2259    win = elm_widget_data_get(obj);
2260    if (!win) return;
2261    if (win->rot == rotation) return;
2262    win->rot = rotation;
2263    ecore_evas_rotation_set(win->ee, rotation);
2264    evas_object_size_hint_min_set(obj, -1, -1);
2265    evas_object_size_hint_max_set(obj, -1, -1);
2266    _elm_win_eval_subobjs(obj);
2267 #ifdef HAVE_ELEMENTARY_X
2268    _elm_win_xwin_update(win);
2269 #endif
2270 }
2271
2272 /**
2273  * Rotates the window and resizes it
2274  *
2275  * @param obj The window object
2276  * @param layer The rotation of the window in degrees (0-360)
2277  *
2278  * @ingroup Win
2279  */
2280 EAPI void
2281 elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
2282 {
2283    Elm_Win *win;
2284    ELM_CHECK_WIDTYPE(obj, widtype);
2285    win = elm_widget_data_get(obj);
2286    if (!win) return;
2287    if (win->rot == rotation) return;
2288    win->rot = rotation;
2289    ecore_evas_rotation_with_resize_set(win->ee, rotation);
2290    evas_object_size_hint_min_set(obj, -1, -1);
2291    evas_object_size_hint_max_set(obj, -1, -1);
2292    _elm_win_eval_subobjs(obj);
2293 #ifdef HAVE_ELEMENTARY_X
2294    _elm_win_xwin_update(win);
2295 #endif
2296 }
2297
2298 /**
2299  * Get the rotation of the window.
2300  *
2301  * @param obj The window object
2302  * @return The rotation of the window in degrees (0-360)
2303  *
2304  * @ingroup Win
2305  */
2306 EAPI int
2307 elm_win_rotation_get(const Evas_Object *obj)
2308 {
2309    Elm_Win *win;
2310    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2311    win = elm_widget_data_get(obj);
2312    if (!win) return -1;
2313    return win->rot;
2314 }
2315
2316 /**
2317  * Set the sticky state of the window.
2318  *
2319  * @param obj The window object
2320  * @param sticky If true, the window's sticky state is enabled
2321  *
2322  * @ingroup Win
2323  */
2324 EAPI void
2325 elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
2326 {
2327    Elm_Win *win;
2328    ELM_CHECK_WIDTYPE(obj, widtype);
2329    win = elm_widget_data_get(obj);
2330    if (!win) return;
2331    ecore_evas_sticky_set(win->ee, sticky);
2332 #ifdef HAVE_ELEMENTARY_X
2333    _elm_win_xwin_update(win);
2334 #endif
2335 }
2336
2337 /**
2338  * Get the sticky state of the window.
2339  *
2340  * @param obj The window object
2341  * @return If true, the window's sticky state is enabled
2342  *
2343  * @ingroup Win
2344  */
2345 EAPI Eina_Bool
2346 elm_win_sticky_get(const Evas_Object *obj)
2347 {
2348    Elm_Win *win;
2349    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2350    win = elm_widget_data_get(obj);
2351    if (!win) return EINA_FALSE;
2352    return ecore_evas_sticky_get(win->ee);
2353 }
2354
2355 /**
2356  * Sets the keyboard mode of the window.
2357  *
2358  * @param obj The window object
2359  * @param mode The mode to set; one of:
2360  * ELM_WIN_KEYBOARD_UNKNOWN
2361  * ELM_WIN_KEYBOARD_OFF
2362  * ELM_WIN_KEYBOARD_ON
2363  * ELM_WIN_KEYBOARD_ALPHA
2364  * ELM_WIN_KEYBOARD_NUMERIC
2365  * ELM_WIN_KEYBOARD_PIN
2366  * ELM_WIN_KEYBOARD_PHONE_NUMBER
2367  * ELM_WIN_KEYBOARD_HEX
2368  * ELM_WIN_KEYBOARD_TERMINAL
2369  * ELM_WIN_KEYBOARD_PASSWORD
2370  * ELM_WIN_KEYBOARD_IP
2371  * ELM_WIN_KEYBOARD_HOST
2372  * ELM_WIN_KEYBOARD_FILE
2373  * ELM_WIN_KEYBOARD_URL
2374  * ELM_WIN_KEYBOARD_KEYPAD
2375  * ELM_WIN_KEYBOARD_J2ME
2376  *
2377  * @ingroup Win
2378  */
2379 EAPI void
2380 elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
2381 {
2382    Elm_Win *win;
2383    ELM_CHECK_WIDTYPE(obj, widtype);
2384    win = elm_widget_data_get(obj);
2385    if (!win) return;
2386    if (mode == win->kbdmode) return;
2387 #ifdef HAVE_ELEMENTARY_X
2388    _elm_win_xwindow_get(win);
2389 #endif
2390    win->kbdmode = mode;
2391 #ifdef HAVE_ELEMENTARY_X
2392    if (win->xwin)
2393      ecore_x_e_virtual_keyboard_state_set
2394         (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
2395 #endif
2396 }
2397
2398 /**
2399  * Gets the keyboard mode of the window.
2400  *
2401  * @param obj The window object
2402  * @return The mode; one of:
2403  * ELM_WIN_KEYBOARD_UNKNOWN
2404  * ELM_WIN_KEYBOARD_OFF
2405  * ELM_WIN_KEYBOARD_ON
2406  * ELM_WIN_KEYBOARD_ALPHA
2407  * ELM_WIN_KEYBOARD_NUMERIC
2408  * ELM_WIN_KEYBOARD_PIN
2409  * ELM_WIN_KEYBOARD_PHONE_NUMBER
2410  * ELM_WIN_KEYBOARD_HEX
2411  * ELM_WIN_KEYBOARD_TERMINAL
2412  * ELM_WIN_KEYBOARD_PASSWORD
2413  * ELM_WIN_KEYBOARD_IP
2414  * ELM_WIN_KEYBOARD_HOST
2415  * ELM_WIN_KEYBOARD_FILE
2416  * ELM_WIN_KEYBOARD_URL
2417  * ELM_WIN_KEYBOARD_KEYPAD
2418  * ELM_WIN_KEYBOARD_J2ME
2419  *
2420  * @ingroup Win
2421  */
2422 EAPI Elm_Win_Keyboard_Mode
2423 elm_win_keyboard_mode_get(const Evas_Object *obj)
2424 {
2425    Elm_Win *win;
2426    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN;
2427    win = elm_widget_data_get(obj);
2428    if (!win) return ELM_WIN_KEYBOARD_UNKNOWN;
2429    return win->kbdmode;
2430 }
2431
2432 /**
2433  * Sets whether the window is a keyboard.
2434  *
2435  * @param obj The window object
2436  * @param is_keyboard If true, the window is a virtual keyboard
2437  *
2438  * @ingroup Win
2439  */
2440 EAPI void
2441 elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
2442 {
2443    Elm_Win *win;
2444    ELM_CHECK_WIDTYPE(obj, widtype);
2445    win = elm_widget_data_get(obj);
2446    if (!win) return;
2447 #ifdef HAVE_ELEMENTARY_X
2448    _elm_win_xwindow_get(win);
2449    if (win->xwin)
2450      ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard);
2451 #endif
2452 }
2453
2454 /**
2455  * Gets whether the window is a keyboard.
2456  *
2457  * @param obj The window object
2458  * @return If the window is a virtual keyboard
2459  *
2460  * @ingroup Win
2461  */
2462 EAPI Eina_Bool
2463 elm_win_keyboard_win_get(const Evas_Object *obj)
2464 {
2465    Elm_Win *win;
2466    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2467    win = elm_widget_data_get(obj);
2468    if (!win) return EINA_FALSE;
2469 #ifdef HAVE_ELEMENTARY_X
2470    _elm_win_xwindow_get(win);
2471    if (win->xwin)
2472      return ecore_x_e_virtual_keyboard_get(win->xwin);
2473 #endif
2474    return EINA_FALSE;
2475 }
2476
2477 /**
2478  * Get the screen position of a window.
2479  *
2480  * @param obj The window object
2481  * @param x The int to store the x coordinate to
2482  * @param y The int to store the y coordinate to
2483  *
2484  * @ingroup Win
2485  */
2486 EAPI void
2487 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
2488 {
2489    Elm_Win *win;
2490    ELM_CHECK_WIDTYPE(obj, widtype);
2491    win = elm_widget_data_get(obj);
2492    if (!win) return;
2493    if (x) *x = win->screen.x;
2494    if (y) *y = win->screen.y;
2495 }
2496
2497 /**
2498  * Set if this window is an illume conformant window
2499  *
2500  * @param obj The window object
2501  * @param conformant The conformant flag (1 = conformant, 0 = non-conformant)
2502  *
2503  * @ingroup Win
2504  */
2505 EAPI void
2506 elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
2507 {
2508    Elm_Win *win;
2509    ELM_CHECK_WIDTYPE(obj, widtype);
2510    win = elm_widget_data_get(obj);
2511    if (!win) return;
2512 #ifdef HAVE_ELEMENTARY_X
2513    _elm_win_xwindow_get(win);
2514    if (win->xwin)
2515      ecore_x_e_illume_conformant_set(win->xwin, conformant);
2516 #endif
2517 }
2518
2519 /**
2520  * Get if this window is an illume conformant window
2521  *
2522  * @param obj The window object
2523  * @return A boolean if this window is illume conformant or not
2524  *
2525  * @ingroup Win
2526  */
2527 EAPI Eina_Bool
2528 elm_win_conformant_get(const Evas_Object *obj)
2529 {
2530    Elm_Win *win;
2531    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2532    win = elm_widget_data_get(obj);
2533    if (!win) return EINA_FALSE;
2534 #ifdef HAVE_ELEMENTARY_X
2535    _elm_win_xwindow_get(win);
2536    if (win->xwin)
2537      return ecore_x_e_illume_conformant_get(win->xwin);
2538 #endif
2539    return EINA_FALSE;
2540 }
2541
2542 /**
2543  * Set a window to be an illume quickpanel window
2544  *
2545  * By default window objects are not quickpanel windows.
2546  *
2547  * @param obj The window object
2548  * @param quickpanel The quickpanel flag (1 = quickpanel, 0 = normal window)
2549  *
2550  * @ingroup Win
2551  */
2552 EAPI void
2553 elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
2554 {
2555    Elm_Win *win;
2556    ELM_CHECK_WIDTYPE(obj, widtype);
2557    win = elm_widget_data_get(obj);
2558    if (!win) return;
2559 #ifdef HAVE_ELEMENTARY_X
2560    _elm_win_xwindow_get(win);
2561    if (win->xwin)
2562      {
2563         ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel);
2564         if (quickpanel)
2565           {
2566              Ecore_X_Window_State states[2];
2567
2568              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2569              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2570              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2571              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2572           }
2573      }
2574 #endif
2575 }
2576
2577 /**
2578  * Get if this window is a quickpanel or not
2579  *
2580  * @param obj The window object
2581  * @return A boolean if this window is a quickpanel or not
2582  *
2583  * @ingroup Win
2584  */
2585 EAPI Eina_Bool
2586 elm_win_quickpanel_get(const Evas_Object *obj)
2587 {
2588    Elm_Win *win;
2589    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2590    win = elm_widget_data_get(obj);
2591    if (!win) return EINA_FALSE;
2592 #ifdef HAVE_ELEMENTARY_X
2593    _elm_win_xwindow_get(win);
2594    if (win->xwin)
2595      return ecore_x_e_illume_quickpanel_get(win->xwin);
2596 #endif
2597    return EINA_FALSE;
2598 }
2599
2600 /**
2601  * Set the major priority of a quickpanel window
2602  *
2603  * @param obj The window object
2604  * @param priority The major priority for this quickpanel
2605  *
2606  * @ingroup Win
2607  */
2608 EAPI void
2609 elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
2610 {
2611    Elm_Win *win;
2612    ELM_CHECK_WIDTYPE(obj, widtype);
2613    win = elm_widget_data_get(obj);
2614    if (!win) return;
2615 #ifdef HAVE_ELEMENTARY_X
2616    _elm_win_xwindow_get(win);
2617    if (win->xwin)
2618      ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority);
2619 #endif
2620 }
2621
2622 /**
2623  * Get the major priority of a quickpanel window
2624  *
2625  * @param obj The window object
2626  * @return The major priority of this quickpanel
2627  *
2628  * @ingroup Win
2629  */
2630 EAPI int
2631 elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
2632 {
2633    Elm_Win *win;
2634    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2635    win = elm_widget_data_get(obj);
2636    if (!win) return -1;
2637 #ifdef HAVE_ELEMENTARY_X
2638    _elm_win_xwindow_get(win);
2639    if (win->xwin)
2640      return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin);
2641 #endif
2642    return -1;
2643 }
2644
2645 /**
2646  * Set the minor priority of a quickpanel window
2647  *
2648  * @param obj The window object
2649  * @param priority The minor priority for this quickpanel
2650  *
2651  * @ingroup Win
2652  */
2653 EAPI void
2654 elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
2655 {
2656    Elm_Win *win;
2657    ELM_CHECK_WIDTYPE(obj, widtype);
2658    win = elm_widget_data_get(obj);
2659    if (!win) return;
2660 #ifdef HAVE_ELEMENTARY_X
2661    _elm_win_xwindow_get(win);
2662    if (win->xwin)
2663      ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority);
2664 #endif
2665 }
2666
2667 /**
2668  * Get the minor priority of a quickpanel window
2669  *
2670  * @param obj The window object
2671  * @return The minor priority of this quickpanel
2672  *
2673  * @ingroup Win
2674  */
2675 EAPI int
2676 elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
2677 {
2678    Elm_Win *win;
2679    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2680    win = elm_widget_data_get(obj);
2681    if (!win) return -1;
2682 #ifdef HAVE_ELEMENTARY_X
2683    _elm_win_xwindow_get(win);
2684    if (win->xwin)
2685      return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin);
2686 #endif
2687    return -1;
2688 }
2689
2690 /**
2691  * Set which zone this quickpanel should appear in
2692  *
2693  * @param obj The window object
2694  * @param zone The requested zone for this quickpanel
2695  *
2696  * @ingroup Win
2697  */
2698 EAPI void
2699 elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
2700 {
2701    Elm_Win *win;
2702    ELM_CHECK_WIDTYPE(obj, widtype);
2703    win = elm_widget_data_get(obj);
2704    if (!win) return;
2705 #ifdef HAVE_ELEMENTARY_X
2706    _elm_win_xwindow_get(win);
2707    if (win->xwin)
2708      ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone);
2709 #endif
2710 }
2711
2712 /**
2713  * Get which zone this quickpanel should appear in
2714  *
2715  * @param obj The window object
2716  * @return The requested zone for this quickpanel
2717  *
2718  * @ingroup Win
2719  */
2720 EAPI int
2721 elm_win_quickpanel_zone_get(const Evas_Object *obj)
2722 {
2723    Elm_Win *win;
2724    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2725    win = elm_widget_data_get(obj);
2726    if (!win) return 0;
2727 #ifdef HAVE_ELEMENTARY_X
2728    _elm_win_xwindow_get(win);
2729    if (win->xwin)
2730      return ecore_x_e_illume_quickpanel_zone_get(win->xwin);
2731 #endif
2732    return 0;
2733 }
2734
2735 /**
2736  * Set the window to be skipped by keyboard focus
2737  *
2738  * This sets the window to be skipped by normal keyboard input. This means
2739  * a window manager will be asked to not focus this window as well as omit
2740  * it from things like the taskbar, pager, "alt-tab" list etc. etc.
2741  *
2742  * Call this and enable it on a window BEFORE you show it for the first time,
2743  * otherwise it may have no effect.
2744  *
2745  * Use this for windows that have only output information or might only be
2746  * interacted with by the mouse or fingers, and never for typing input.
2747  * Be careful that this may have side-effects like making the window
2748  * non-accessible in some cases unless the window is specially handled. Use
2749  * this with care.
2750  *
2751  * @param obj The window object
2752  * @param skip The skip flag state (EINA_TRUE if it is to be skipped)
2753  *
2754  * @ingroup Win
2755  */
2756 EAPI void
2757 elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip)
2758 {
2759    Elm_Win *win;
2760    ELM_CHECK_WIDTYPE(obj, widtype);
2761    win = elm_widget_data_get(obj);
2762    if (!win) return;
2763 #ifdef HAVE_ELEMENTARY_X
2764    _elm_win_xwindow_get(win);
2765    if (skip)
2766      {
2767         if (win->xwin)
2768           {
2769              Ecore_X_Window_State states[2];
2770
2771              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2772              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2773              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2774              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2775           }
2776      }
2777 #endif
2778 }
2779
2780 /**
2781  * Send a command to the windowing environment
2782  *
2783  * This is intended to work in touchscreen or small screen device environments
2784  * where there is a more simplistic window management policy in place. This
2785  * uses the window object indicated to select which part of the environment
2786  * to control (the part that this window lives in), and provides a command
2787  * and an optional parameter structure (use NULL for this if not needed).
2788  *
2789  * @param obj The window object that lives in the environment to control
2790  * @param command The command to send
2791  * @param params Optional parameters for the command
2792  *
2793  * @ingroup Win
2794  */
2795 EAPI void
2796 elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params __UNUSED__)
2797 {
2798    Elm_Win *win;
2799    ELM_CHECK_WIDTYPE(obj, widtype);
2800    win = elm_widget_data_get(obj);
2801    if (!win) return;
2802 #ifdef HAVE_ELEMENTARY_X
2803    _elm_win_xwindow_get(win);
2804    if (win->xwin)
2805      {
2806         switch (command)
2807           {
2808            case ELM_ILLUME_COMMAND_FOCUS_BACK:
2809               ecore_x_e_illume_focus_back_send(win->xwin);
2810               break;
2811            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
2812               ecore_x_e_illume_focus_forward_send(win->xwin);
2813               break;
2814            case ELM_ILLUME_COMMAND_FOCUS_HOME:
2815               ecore_x_e_illume_focus_home_send(win->xwin);
2816               break;
2817            case ELM_ILLUME_COMMAND_CLOSE:
2818               ecore_x_e_illume_close_send(win->xwin);
2819               break;
2820            default:
2821               break;
2822           }
2823      }
2824 #endif
2825 }
2826
2827 /**
2828  * Get the inlined image object handle
2829  *
2830  * When you create a window with elm_win_add() of type ELM_WIN_INLINED_IMAGE,
2831  * then the window is in fact an evas image object inlined in the parent
2832  * canvas. You can get this object (be careful to not manipulate it as it
2833  * is under control of elementary), and use it to do things like get pixel
2834  * data, save the image to a file, etc.
2835  *
2836  * @param obj The window object to get the inlined image from
2837  * @return The inlined image object, or NULL if none exists
2838  *
2839  * @ingroup Win
2840  */
2841 EAPI Evas_Object *
2842 elm_win_inlined_image_object_get(Evas_Object *obj)
2843 {
2844    Elm_Win *win;
2845    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2846    win = elm_widget_data_get(obj);
2847    if (!win) return NULL;
2848    return win->img_obj;
2849 }
2850
2851 /**
2852  * Set the enabled status for the focus highlight in a window
2853  *
2854  * This function will enable or disable the focus highlight only for the
2855  * given window, regardless of the global setting for it
2856  *
2857  * @param obj The window where to enable the highlight
2858  * @param enabled The enabled value for the highlight
2859  *
2860  * @ingroup Win
2861  */
2862 EAPI void
2863 elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled)
2864 {
2865    Elm_Win *win;
2866
2867    ELM_CHECK_WIDTYPE(obj, widtype);
2868
2869    win = elm_widget_data_get(obj);
2870    enabled = !!enabled;
2871    if (win->focus_highlight.enabled == enabled)
2872      return;
2873
2874    win->focus_highlight.enabled = enabled;
2875
2876    if (win->focus_highlight.enabled)
2877      _elm_win_focus_highlight_init(win);
2878    else
2879      _elm_win_focus_highlight_shutdown(win);
2880 }
2881
2882 /**
2883  * Get the enabled value of the focus highlight for this window
2884  *
2885  * @param obj The window in which to check if the focus highlight is enabled
2886  *
2887  * @return EINA_TRUE if enabled, EINA_FALSE otherwise
2888  *
2889  * @ingroup Win
2890  */
2891 EAPI Eina_Bool
2892 elm_win_focus_highlight_enabled_get(const Evas_Object *obj)
2893 {
2894    Elm_Win *win;
2895
2896    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2897
2898    win = elm_widget_data_get(obj);
2899    return win->focus_highlight.enabled;
2900 }
2901
2902 /**
2903  * Set the style for the focus highlight on this window
2904  *
2905  * Sets the style to use for theming the highlight of focused objects on
2906  * the given window. If @p style is NULL, the default will be used.
2907  *
2908  * @param obj The window where to set the style
2909  * @param style The style to set
2910  *
2911  * @ingroup Win
2912  */
2913 EAPI void
2914 elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style)
2915 {
2916    Elm_Win *win;
2917
2918    ELM_CHECK_WIDTYPE(obj, widtype);
2919
2920    win = elm_widget_data_get(obj);
2921    eina_stringshare_replace(&win->focus_highlight.style, style);
2922    win->focus_highlight.changed_theme = EINA_TRUE;
2923    _elm_win_focus_highlight_reconfigure_job_start(win);
2924 }
2925
2926 /**
2927  * Get the style set for the focus highlight object
2928  *
2929  * Gets the style set for this windows highilght object, or NULL if none
2930  * is set.
2931  *
2932  * @param obj The window to retrieve the highlights style from
2933  *
2934  * @return The style set or NULL if none was. Default is used in that case.
2935  *
2936  * @ingroup Win
2937  */
2938 EAPI const char *
2939 elm_win_focus_highlight_style_get(const Evas_Object *obj)
2940 {
2941    Elm_Win *win;
2942
2943    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2944
2945    win = elm_widget_data_get(obj);
2946    return win->focus_highlight.style;
2947 }
2948
2949 typedef struct _Widget_Data Widget_Data;
2950
2951 struct _Widget_Data
2952 {
2953    Evas_Object *frm;
2954    Evas_Object *content;
2955 };
2956
2957 static void _del_hook(Evas_Object *obj);
2958 static void _theme_hook(Evas_Object *obj);
2959 static void _sizing_eval(Evas_Object *obj);
2960 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
2961 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
2962
2963 static const char *widtype2 = NULL;
2964
2965 static void
2966 _del_hook(Evas_Object *obj)
2967 {
2968    Widget_Data *wd = elm_widget_data_get(obj);
2969    if (!wd) return;
2970    free(wd);
2971 }
2972
2973 static void
2974 _theme_hook(Evas_Object *obj)
2975 {
2976    Widget_Data *wd = elm_widget_data_get(obj);
2977    _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
2978    if (wd->content)
2979      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
2980    _sizing_eval(obj);
2981 }
2982
2983 static Eina_Bool
2984 _elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
2985 {
2986    Widget_Data *wd = elm_widget_data_get(obj);
2987
2988    if (!wd)
2989      return EINA_FALSE;
2990
2991    /* Try Focus cycle in subitem */
2992    if (wd->content)
2993      {
2994         elm_widget_focus_next_get(wd->content, dir, next);
2995         if (*next)
2996           return EINA_TRUE;
2997      }
2998
2999    *next = (Evas_Object *)obj;
3000    return EINA_FALSE;
3001 }
3002
3003 static void
3004 _sizing_eval(Evas_Object *obj)
3005 {
3006    Widget_Data *wd = elm_widget_data_get(obj);
3007    Evas_Coord minw = -1, minh = -1;
3008
3009    evas_object_size_hint_min_get(wd->content, &minw, &minh);
3010    edje_object_size_min_calc(wd->frm, &minw, &minh);
3011    evas_object_size_hint_min_set(obj, minw, minh);
3012    evas_object_size_hint_max_set(obj, -1, -1);
3013 }
3014
3015 static void
3016 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3017 {
3018    _sizing_eval(data);
3019 }
3020
3021 static void
3022 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
3023 {
3024    Widget_Data *wd = elm_widget_data_get(obj);
3025    Evas_Object *sub = event_info;
3026    if (sub == wd->content)
3027      {
3028         evas_object_event_callback_del_full
3029            (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
3030         wd->content = NULL;
3031         _sizing_eval(obj);
3032      }
3033 }
3034
3035 EAPI Evas_Object *
3036 elm_win_inwin_add(Evas_Object *obj)
3037 {
3038    Evas_Object *obj2;
3039    Widget_Data *wd;
3040    Elm_Win *win;
3041
3042    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3043    win = elm_widget_data_get(obj);
3044    if (!win) return NULL;
3045    wd = ELM_NEW(Widget_Data);
3046    obj2 = elm_widget_add(win->evas);
3047    elm_widget_type_set(obj2, "inwin");
3048    ELM_SET_WIDTYPE(widtype2, "inwin");
3049    elm_widget_sub_object_add(obj, obj2);
3050    evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3051    evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL);
3052    elm_win_resize_object_add(obj, obj2);
3053
3054    elm_widget_data_set(obj2, wd);
3055    elm_widget_del_hook_set(obj2, _del_hook);
3056    elm_widget_theme_hook_set(obj2, _theme_hook);
3057    elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook);
3058    elm_widget_can_focus_set(obj2, EINA_TRUE);
3059    elm_widget_highlight_ignore_set(obj2, EINA_TRUE);
3060
3061    wd->frm = edje_object_add(win->evas);
3062    _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
3063    elm_widget_resize_object_set(obj2, wd->frm);
3064
3065    evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
3066
3067    _sizing_eval(obj2);
3068    return obj2;
3069 }
3070
3071 EAPI void
3072 elm_win_inwin_activate(Evas_Object *obj)
3073 {
3074    ELM_CHECK_WIDTYPE(obj, widtype2);
3075    Widget_Data *wd = elm_widget_data_get(obj);
3076    if (!wd) return;
3077    evas_object_raise(obj);
3078    evas_object_show(obj);
3079    edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
3080    elm_object_focus(obj);
3081 }
3082
3083 EAPI void
3084 elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
3085 {
3086    ELM_CHECK_WIDTYPE(obj, widtype2);
3087    Widget_Data *wd = elm_widget_data_get(obj);
3088    if (!wd) return;
3089    if (wd->content == content) return;
3090    if (wd->content) evas_object_del(wd->content);
3091    wd->content = content;
3092    if (content)
3093      {
3094         elm_widget_sub_object_add(obj, content);
3095         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3096                                        _changed_size_hints, obj);
3097         edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
3098      }
3099    _sizing_eval(obj);
3100 }
3101
3102 EAPI Evas_Object *
3103 elm_win_inwin_content_get(const Evas_Object *obj)
3104 {
3105    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
3106    Widget_Data *wd = elm_widget_data_get(obj);
3107    if (!wd) return NULL;
3108    return wd->content;
3109 }
3110
3111 EAPI Evas_Object *
3112 elm_win_inwin_content_unset(Evas_Object *obj)
3113 {
3114    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
3115    Widget_Data *wd = elm_widget_data_get(obj);
3116    if (!wd) return NULL;
3117    if (!wd->content) return NULL;
3118    Evas_Object *content = wd->content;
3119    elm_widget_sub_object_del(obj, wd->content);
3120    edje_object_part_unswallow(wd->frm, wd->content);
3121    wd->content = NULL;
3122    return content;
3123 }
3124
3125 /* windowing spcific calls - shall we do this differently? */
3126
3127 static Ecore_X_Window
3128 _elm_ee_win_get(const Evas_Object *obj)
3129 {
3130    if (!obj) return 0;
3131 #ifdef HAVE_ELEMENTARY_X
3132    Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
3133    if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee);
3134 #endif
3135    return 0;
3136 }
3137
3138 /**
3139  * Get the Ecore_X_Window of an Evas_Object
3140  *
3141  * @param obj The object
3142  *
3143  * @return The Ecore_X_Window of @p obj
3144  *
3145  * @ingroup Win
3146  */
3147 EAPI Ecore_X_Window
3148 elm_win_xwindow_get(const Evas_Object *obj)
3149 {
3150    Ecore_X_Window xwin = 0;
3151    Elm_Win *win;
3152    const char *type;
3153
3154    if (!obj) return 0;
3155    type = elm_widget_type_get(obj);
3156    if (!type) return 0;
3157    if (type != widtype) return _elm_ee_win_get(obj);
3158 #ifdef HAVE_ELEMENTARY_X
3159    win = elm_widget_data_get(obj);
3160    if (!win) return xwin;
3161    if (win->xwin) return win->xwin;
3162    if (win->parent) return elm_win_xwindow_get(win->parent);
3163 #endif
3164    return xwin;
3165    win = NULL;
3166 }