tizen 2.4 release
[framework/uifw/e17-mod-tizen-comp.git] / src / e_mod_comp_bg_win.c
1 #include "e_mod_comp_shared_types.h"
2 #include "e_mod_comp.h"
3 #include "e_mod_comp_atoms.h"
4 #include "e_mod_comp_debug.h"
5
6 typedef enum _E_Comp_BG_Win_State
7 {
8    E_COMP_BG_WIN_STATE_NONE = 0,
9    E_COMP_BG_WIN_STATE_PARENT,
10    E_COMP_BG_WIN_STATE_CHILD,
11    E_COMP_BG_WIN_STATE_CHILD_WAIT_FOR_DAMAGE
12 } E_Comp_BG_Win_State;
13
14 struct _E_Comp_BG_Win
15 {
16    E_Comp_BG_Win_State  state;
17    Evas_Object         *obj;
18    int                  x, y, w, h;
19    Eina_Bool            hidden;
20    struct {
21      Ecore_X_Window     parent;
22      Ecore_X_Window     child;
23      Ecore_X_Window     self;
24    } win;
25 };
26
27 /* local subsystem functions */
28 static void      _e_mod_comp_bg_win_fg_free(E_Comp_BG_Win *fg, E_Comp_Win *cw);
29 static void      _e_mod_comp_bg_win_bg_free(E_Comp_BG_Win *bg, E_Comp_Win *cw);
30 static Eina_Bool _e_mod_comp_bg_win_get_prop(Ecore_X_Window win, Ecore_X_Window *wins);
31 static Eina_Bool _e_mod_comp_bg_win_setup(E_Comp_Win *cw, E_Comp_Win *cw2);
32 static Eina_Bool _e_mod_comp_bg_win_obj_set(E_Comp_Win *cw);
33
34 /* externally accessible functions */
35 EAPI E_Comp_BG_Win *
36 e_mod_comp_bg_win_new(void)
37 {
38    E_Comp_BG_Win *bg;
39    bg = E_NEW(E_Comp_BG_Win, 1);
40    return bg;
41 }
42
43 EAPI void
44 e_mod_comp_bg_win_free(E_Comp_BG_Win *bg)
45 {
46    E_Comp_Win *cw;
47    E_CHECK(bg);
48    if (bg->obj) evas_object_del(bg->obj);
49    bg->obj = NULL;
50
51    cw = e_mod_comp_win_find(bg->win.self);
52    switch (bg->state)
53      {
54       case E_COMP_BG_WIN_STATE_PARENT:
55         _e_mod_comp_bg_win_fg_free(bg, cw);
56         break;
57       case E_COMP_BG_WIN_STATE_CHILD:
58       case E_COMP_BG_WIN_STATE_CHILD_WAIT_FOR_DAMAGE:
59         _e_mod_comp_bg_win_bg_free(bg, cw);
60         break;
61       default:
62         break;
63      }
64
65    memset(bg, 0, sizeof(E_Comp_BG_Win));
66    E_FREE(bg);
67 }
68
69 EAPI Eina_Bool
70 e_mod_comp_bg_win_handler_prop(Ecore_X_Event_Window_Property *ev)
71 {
72    Eina_Bool res = EINA_FALSE;
73    E_Comp_Win *cw[2];
74    Ecore_X_Window wins[2];
75    int i;
76
77    res = _e_mod_comp_bg_win_get_prop(ev->win, wins);
78    E_CHECK_RETURN(res, 0);
79
80    for (i = 0; i < 2; i++)
81      {
82         cw[i] = e_mod_comp_win_find(wins[i]);
83         if (!cw[i])
84           {
85              cw[i] = e_mod_comp_border_client_find(wins[i]);
86              E_CHECK_RETURN(cw[i], 0);
87           }
88      }
89
90    res = _e_mod_comp_bg_win_setup(cw[0], cw[1]);
91    E_CHECK_RETURN(res, 0);
92
93    return EINA_TRUE;
94 }
95
96 EAPI Eina_Bool
97 e_mod_comp_bg_win_handler_release(E_Comp_Win *cw)
98 {
99    E_CHECK_RETURN(cw, 0);
100    E_CHECK_RETURN(cw->bgwin, 0);
101    e_mod_comp_bg_win_free(cw->bgwin);
102    cw->bgwin = NULL;
103    return EINA_TRUE;
104 }
105
106 EAPI Eina_Bool
107 e_mod_comp_bg_win_handler_show(E_Comp_Win *cw)
108 {
109    Eina_Bool res = EINA_FALSE;
110    E_Comp_Win *cw2;
111    Ecore_X_Window wins[2];
112
113    res = _e_mod_comp_bg_win_get_prop
114      (e_mod_comp_util_client_xid_get(cw), wins);
115    E_CHECK_RETURN(res, 0);
116
117    cw2 = e_mod_comp_win_find(wins[1]);
118    if (!cw2)
119      {
120         cw2 = e_mod_comp_border_client_find(wins[1]);
121         E_CHECK_RETURN(cw2, 0);
122      }
123
124    res = _e_mod_comp_bg_win_setup(cw, cw2);
125    E_CHECK_RETURN(res, 0);
126
127    return EINA_TRUE;
128 }
129
130 EAPI Eina_Bool
131 e_mod_comp_bg_win_handler_update(E_Comp_Win *cw)
132 {
133    E_Comp_Win *fgcw;
134    Eina_Bool res;
135    E_CHECK_RETURN(cw, 0);
136    E_CHECK_RETURN(cw->bgwin, 0);
137    E_CHECK_RETURN(cw->bgwin->win.parent, 0);
138    if (cw->bgwin->state != E_COMP_BG_WIN_STATE_CHILD_WAIT_FOR_DAMAGE)
139      {
140         return EINA_FALSE;
141      }
142
143    fgcw = e_mod_comp_win_find(cw->bgwin->win.parent);
144    E_CHECK_RETURN(fgcw, 0);
145
146    res = _e_mod_comp_bg_win_obj_set(fgcw);
147    E_CHECK_RETURN(res, 0);
148
149    cw->bgwin->state = E_COMP_BG_WIN_STATE_CHILD;
150
151    return EINA_TRUE;
152 }
153
154 /* local subsystem functions */
155 static void
156 _e_mod_comp_bg_win_fg_free(E_Comp_BG_Win *fg,
157                            E_Comp_Win    *cw)
158 {
159    E_Comp_BG_Win *bg;
160    E_Comp_Win *bgcw, *fgcw;
161    E_CHECK(fg->win.child);
162
163    bgcw = e_mod_comp_win_find(fg->win.child);
164    E_CHECK(bgcw);
165
166    bg = bgcw->bgwin;
167    E_CHECK(bg);
168    E_CHECK(bg->win.parent);
169
170    fgcw = e_mod_comp_win_find(bg->win.parent);
171    E_CHECK(fgcw);
172
173    E_CHECK(fgcw == cw);
174
175    bg->win.parent = 0;
176 }
177
178 static void
179 _e_mod_comp_bg_win_bg_free(E_Comp_BG_Win *bg,
180                            E_Comp_Win    *cw)
181 {
182    E_Comp_BG_Win *fg;
183    E_Comp_Win *fgcw, *bgcw;
184    E_CHECK(bg->win.parent);
185
186    fgcw = e_mod_comp_win_find(bg->win.parent);
187    E_CHECK(fgcw);
188
189    fg = fgcw->bgwin;
190    E_CHECK(fg);
191    E_CHECK(fg->win.child);
192
193    bgcw = e_mod_comp_win_find(fg->win.child);
194    E_CHECK(bgcw);
195
196    E_CHECK(bgcw == cw);
197
198    fg->win.child = 0;
199
200    e_mod_comp_bg_win_free(fg);
201 }
202
203 static Eina_Bool
204 _e_mod_comp_bg_win_get_prop(Ecore_X_Window  win,
205                             Ecore_X_Window *wins)
206 {
207    Eina_Bool res = EINA_FALSE;
208    int ret, cnt;
209    unsigned char *data = NULL;
210    ret = ecore_x_window_prop_property_get
211            (win, ATOM_NET_CM_WINDOW_BACKGROUND,
212            ECORE_X_ATOM_CARDINAL, 32, &data, &cnt);
213    E_CHECK_GOTO((ret > 0), cleanup);
214    E_CHECK_GOTO((data && (cnt == 2)), cleanup);
215
216    memcpy(wins, data, sizeof(Ecore_X_Window) * cnt);
217
218    res = EINA_TRUE;
219
220 cleanup:
221    if (data) E_FREE(data);
222    return res;
223 }
224
225 static Eina_Bool
226 _e_mod_comp_bg_win_setup(E_Comp_Win *cw,
227                          E_Comp_Win *cw2)
228 {
229    Eina_Bool res = EINA_FALSE;
230
231    if (TYPE_BG_CHECK(cw) ||
232        !TYPE_BG_CHECK(cw2) ||
233        (cw == cw2))
234      {
235         return EINA_FALSE;
236      }
237
238    if (cw->bgwin)
239      e_mod_comp_bg_win_free(cw->bgwin);
240
241    cw->bgwin = e_mod_comp_bg_win_new();
242    E_CHECK_GOTO(cw->bgwin, cleanup);
243    cw->bgwin->state = E_COMP_BG_WIN_STATE_PARENT;
244
245    if (!cw2->bgwin)
246      {
247         cw2->bgwin = e_mod_comp_bg_win_new();
248         E_CHECK_GOTO(cw2->bgwin, cleanup);
249
250         e_mod_comp_src_hidden_set_func
251           (NULL, NULL, (E_Manager_Comp_Source *)cw2, 1);
252
253         cw2->bgwin->hidden = EINA_TRUE;
254      }
255
256    cw->bgwin->win.child = cw2->win;
257    cw2->bgwin->win.parent = cw->win;
258    if (cw2->dmg_updates <= 1)
259      {
260         cw2->bgwin->state = E_COMP_BG_WIN_STATE_CHILD_WAIT_FOR_DAMAGE;
261         res = EINA_TRUE;
262         goto cleanup;
263      }
264
265    cw2->bgwin->state = E_COMP_BG_WIN_STATE_CHILD;
266
267    res = _e_mod_comp_bg_win_obj_set(cw);
268    E_CHECK_GOTO(res, cleanup);
269
270    res = EINA_TRUE;
271
272 cleanup:
273    if (!res && cw->bgwin)
274      {
275         e_mod_comp_bg_win_free(cw->bgwin);
276         cw->bgwin = NULL;
277      }
278    return res;
279 }
280
281 static Eina_Bool
282 _e_mod_comp_bg_win_obj_set(E_Comp_Win *cw)
283 {
284    Eina_List *l;
285    E_Comp_Object *co;
286    E_Comp_Win *cw2;
287    Evas *evas;
288    Eina_Bool res = EINA_FALSE, set = EINA_FALSE;
289    E_CHECK_RETURN(cw->bgwin, 0);
290
291    cw2 = e_mod_comp_win_find(cw->bgwin->win.child);
292    E_CHECK_RETURN(cw2, 0);
293
294    cw->bgwin->x = 0;
295    cw->bgwin->y = 0;
296    cw->bgwin->w = cw2->pw;
297    cw->bgwin->h = cw2->ph;
298    cw->bgwin->obj = e_mod_comp_win_mirror_add(cw2);
299    E_CHECK_GOTO(cw->bgwin->obj, finish);
300
301    evas = evas_object_evas_get(cw->bgwin->obj);
302    E_CHECK_GOTO(evas, finish);
303    EINA_LIST_FOREACH(cw->objs, l, co)
304      {
305         if (!co) continue;
306         if (evas == evas_object_evas_get(co->shadow))
307           {
308              res = edje_object_part_swallow
309                 (co->shadow, "e.swallow.bgcontent",
310                 cw->bgwin->obj);
311              E_CHECK_GOTO(res, finish);
312              set = EINA_TRUE;
313           }
314      }
315    E_CHECK_GOTO(set, finish);
316
317    if (cw2->bgwin &&
318        !cw2->bgwin->hidden)
319      {
320         e_mod_comp_src_hidden_set_func
321           (NULL, NULL, (E_Manager_Comp_Source *)cw2, 1);
322         cw2->bgwin->hidden = EINA_TRUE;
323      }
324
325    e_mod_comp_win_render_queue(cw);
326
327    res = EINA_TRUE;
328
329 finish:
330    return res;
331 }