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