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