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