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