tizen 2.4 release
[framework/uifw/e17-mod-tizen-comp.git] / src / e_mod_comp_hw_ov_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 struct _E_Comp_Log
7 {
8    E_Comp_Log_Type  type;
9    int              repeat;
10    Evas_Object     *o;
11    Evas_Object     *bg;
12    char             str[256];
13 } E_Comp_Log;
14
15 struct _E_Comp_HW_Ov_Win
16 {
17    Ecore_X_Window  ee_win;
18    Ecore_Evas     *ee;
19    Evas           *evas;
20    Evas_Object    *bg;
21    int             x, y, w, h;
22
23    Ecore_X_Window  root;
24
25    Eina_Bool       on;
26
27    // debugging info
28    struct {
29      int           num;
30      Eina_List    *list;
31    } info;
32 };
33
34 /* local subsystem globals */
35 static E_Comp_HW_Ov_Win *ov_win = NULL;
36
37 /* local subsystem functions */
38 static void      _hw_ov_win_power_set(E_Comp_HW_Ov_Win *ov, Eina_Bool set);
39 static Eina_Bool _hw_ov_win_update(E_Comp_HW_Ov_Win *ov, E_Comp_Win *cw);
40
41 /* externally accessible functions */
42 EAPI E_Comp_HW_Ov_Win *
43 e_mod_comp_hw_ov_win_new(Ecore_X_Window parent,
44                          int            x,
45                          int            y,
46                          int            w,
47                          int            h)
48 {
49    E_Comp_HW_Ov_Win *ov = NULL;
50    Eina_Bool res = EINA_FALSE;
51
52    E_CHECK_GOTO(parent, finish);
53
54    ov = E_NEW(E_Comp_HW_Ov_Win, 1);
55    E_CHECK_GOTO(ov, finish);
56
57    ov->ee = ecore_evas_software_x11_new(NULL, parent, x, y, w, h);
58    E_CHECK_GOTO(ov->ee, finish);
59
60    ov->ee_win = ecore_evas_window_get(ov->ee);;
61    E_CHECK_GOTO(ov->ee_win, finish);
62
63    ov->evas = ecore_evas_get(ov->ee);
64    E_CHECK_GOTO(ov->evas, finish);
65
66    ecore_x_composite_redirect_window(ov->ee_win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
67    ecore_evas_comp_sync_set(ov->ee, 0);
68    ecore_evas_show(ov->ee);
69
70    ov->bg = evas_object_rectangle_add(ov->evas);
71    E_CHECK_GOTO(ov->bg, finish);
72
73    evas_object_render_op_set(ov->bg, EVAS_RENDER_COPY);
74    evas_object_layer_set(ov->bg, EVAS_LAYER_MIN);
75    evas_object_color_set(ov->bg, 0, 0, 0, 0);
76    evas_object_move(ov->bg, 0, 0);
77    evas_object_resize(ov->bg, w, h);
78    evas_object_show(ov->bg);
79    _hw_ov_win_power_set(ov, EINA_FALSE);
80
81    // comp has to unset shape input mask for the H/W overlay window
82    // to receive input event.
83    ecore_x_window_shape_input_rectangle_set(ov->ee_win, -1, -1, 1, 1);
84
85    ov->x = x;
86    ov->y = y;
87    ov->w = w;
88    ov->h = h;
89
90    ov_win = ov;
91
92    res = EINA_TRUE;
93
94 finish:
95    if (!res && ov)
96      {
97         if (ov->ee)
98           {
99              ecore_evas_free(ov->ee);
100              ov->ee = NULL;
101           }
102         E_FREE(ov);
103         ov = NULL;
104      }
105    return ov;
106 }
107
108 EAPI void
109 e_mod_comp_hw_ov_win_msg_config_update(void)
110 {
111    E_Comp_Log *log;
112
113    E_CHECK(ov_win);
114    E_CHECK(_comp_mod->conf->use_hw_ov);
115    E_CHECK(_comp_mod->conf->debug_info_show);
116
117    EINA_LIST_FREE(ov_win->info.list, log)
118      {
119         evas_object_hide(log->o);
120         evas_object_hide(log->bg);
121         evas_object_del(log->o);
122         evas_object_del(log->bg);
123         memset(log, 0, sizeof(E_Comp_Log));
124         E_FREE(log);
125      }
126 }
127
128 #ifdef _LOG_TYPE_CHECK
129 # undef _LOG_TYPE_CHECK
130 #endif
131 # define _LOG_TYPE_CHECK(a, b)          \
132   ((_comp_mod->conf->debug_type_##a) && \
133    (E_COMP_LOG_TYPE_##b == type))
134
135 EAPI void
136 e_mod_comp_hw_ov_win_msg_show(E_Comp_Log_Type  type,
137                               const char      *f,
138                               ...)
139 {
140    E_Comp_Log *log, *prev_log;
141    Evas_Object *bg, *o;
142    Evas_Coord w = 0, h = 0;
143    Eina_List *l;
144    int num, y;
145    char buf[256], str[256];
146    va_list args;
147
148    E_CHECK(ov_win);
149    E_CHECK(_comp_mod->conf->use_hw_ov);
150    E_CHECK(_comp_mod->conf->debug_info_show);
151    E_CHECK(_comp_mod->conf->max_debug_msgs >= 1);
152    E_CHECK(type > E_COMP_LOG_TYPE_DEFAULT);
153    E_CHECK(type < E_COMP_LOG_TYPE_MAX);
154
155    if (!(_LOG_TYPE_CHECK(nocomp, NOCOMP) ||
156          _LOG_TYPE_CHECK(swap, SWAP) ||
157          _LOG_TYPE_CHECK(effect, EFFECT)))
158      {
159         return;
160      }
161
162    va_start(args, f);
163    vsprintf(buf, f, args);
164    va_end(args);
165
166    /* check if previous log is same type, just increment repeat value */
167    num = eina_list_count(ov_win->info.list);
168    if (num >= 1)
169      {
170         log = eina_list_nth(ov_win->info.list, num - 1);
171         if ((log) && (log->type == type) &&
172             (!strcmp(buf, log->str)))
173           {
174              sprintf(str, "%04d|%s %d",
175                      ov_win->info.num++,
176                      log->str,
177                      log->repeat++);
178              evas_object_text_text_set(log->o, str);
179              return;
180           }
181      }
182
183    log = E_NEW(E_Comp_Log, 1);
184    E_CHECK(log);
185
186    log->type = type;
187    strcpy(log->str, buf);
188    sprintf(str, "%04d|%s", ov_win->info.num++, log->str);
189
190    if (num < _comp_mod->conf->max_debug_msgs)
191      {
192         bg = evas_object_rectangle_add(ov_win->evas);
193         evas_object_layer_set(bg, EVAS_LAYER_MAX);
194         evas_object_render_op_set(bg, EVAS_RENDER_COPY);
195         evas_object_color_set(bg, 30, 30, 30, 128);
196         evas_object_show(bg);
197
198         o = evas_object_text_add(ov_win->evas);
199         evas_object_text_font_set(o, "Sans", 28);
200         evas_object_text_text_set(o, str);
201         evas_object_layer_set(o, EVAS_LAYER_MAX);
202         evas_object_render_op_set(o, EVAS_RENDER_COPY);
203         evas_object_color_set(o, 200, 200, 200, 255);
204         evas_object_show(o);
205
206         log->bg = bg;
207         log->o = o;
208      }
209    else
210      {
211         prev_log = eina_list_nth(ov_win->info.list, 0);
212         if (!prev_log)
213           {
214              E_FREE(log);
215              return;
216           }
217         log->bg = prev_log->bg;
218         log->o = prev_log->o;
219         ov_win->info.list = eina_list_remove(ov_win->info.list, prev_log);
220         E_FREE(prev_log);
221
222         evas_object_text_text_set(log->o, str);
223      }
224
225    ov_win->info.list = eina_list_append(ov_win->info.list, log);
226
227    y = ov_win->h - 40;
228    EINA_LIST_REVERSE_FOREACH(ov_win->info.list, l, log)
229      {
230         if (!log) continue;
231         evas_object_geometry_get(log->o, NULL, NULL, &w, &h);
232         evas_object_move(log->bg, 0, y - 1);
233         evas_object_resize(log->bg, w + 2, h + 2);
234         evas_object_move(log->o, 1, y);
235         y -= (h+2);
236      }
237 }
238
239 EAPI void
240 e_mod_comp_hw_ov_win_free(E_Comp_HW_Ov_Win *ov)
241 {
242    E_Comp_Log *log;
243    E_CHECK(ov);
244
245    _hw_ov_win_power_set(ov, EINA_FALSE);
246
247    EINA_LIST_FREE(ov->info.list, log)
248      {
249         evas_object_hide(log->o);
250         evas_object_hide(log->bg);
251         evas_object_del(log->o);
252         evas_object_del(log->bg);
253         memset(log, 0, sizeof(E_Comp_Log));
254         E_FREE(log);
255      }
256    if (ov->bg)
257      {
258         evas_object_del(ov->bg);
259         ov->bg = NULL;
260      }
261    if (ov->ee)
262      {
263         ecore_evas_free(ov->ee);
264         ov->ee = NULL;
265      }
266    memset(ov, 0, sizeof(E_Comp_HW_Ov_Win));
267    E_FREE(ov);
268
269    ov_win = NULL;
270 }
271
272 EAPI void
273 e_mod_comp_hw_ov_win_show(E_Comp_HW_Ov_Win *ov,
274                           E_Comp_Win       *cw)
275 {
276    E_CHECK(ov);
277    E_CHECK(cw);
278    E_CHECK(cw->visible);
279    E_CHECK(cw->dmg_updates >= 1);
280
281    _hw_ov_win_update(ov, cw);
282 }
283
284 EAPI void
285 e_mod_comp_hw_ov_win_hide(E_Comp_HW_Ov_Win *ov,
286                           E_Comp_Win       *cw)
287 {
288    E_CHECK(ov);
289    E_CHECK(cw);
290    E_CHECK(!cw->visible);
291
292    _hw_ov_win_power_set(ov, EINA_FALSE);
293
294    if (cw->ov_obj)
295      {
296         evas_object_hide(cw->ov_obj);
297         evas_object_del(cw->ov_obj);
298         cw->ov_obj = NULL;
299      }
300
301    if (cw->ov_xim)
302      {
303         ecore_x_image_free(cw->ov_xim);
304         cw->ov_xim = NULL;
305      }
306    cw->ov.w = 0;
307    cw->ov.h = 0;
308 }
309
310 EAPI void
311 e_mod_comp_hw_ov_win_obj_show(E_Comp_HW_Ov_Win *ov,
312                               E_Comp_Win       *cw)
313 {
314    Eina_Bool visible;
315
316    if (cw->ov_obj)
317      {
318         visible = evas_object_visible_get(cw->ov_obj);
319         if (!visible)
320           {
321              Eina_Bool res = _hw_ov_win_update(ov, cw);
322              if (res)
323                {
324                   evas_object_show(cw->ov_obj);
325                   _hw_ov_win_power_set(ov, EINA_TRUE);
326                }
327           }
328      }
329 }
330
331 EAPI void
332 e_mod_comp_hw_ov_win_obj_hide(E_Comp_HW_Ov_Win *ov,
333                               E_Comp_Win       *cw)
334 {
335    Eina_Bool visible;
336    if (cw->ov_obj)
337      {
338         visible = evas_object_visible_get(cw->ov_obj);
339         if (visible)
340           {
341              _hw_ov_win_power_set(ov, EINA_FALSE);
342              evas_object_hide(cw->ov_obj);
343           }
344      }
345 }
346
347
348
349 EAPI Eina_Bool
350 e_mod_comp_hw_ov_win_update(E_Comp_HW_Ov_Win *ov,
351                             E_Comp_Win       *cw)
352 {
353    E_CHECK_RETURN(ov, EINA_FALSE);
354    E_CHECK_RETURN(cw, EINA_FALSE);
355
356    Eina_Bool res = _hw_ov_win_update(ov, cw);
357    if (!res)
358      {
359         // we will be trying to get image again at next update.
360         cw->update = 1;
361         cw->c->updates = eina_list_append(cw->c->updates, cw);
362         e_mod_comp_win_render_queue(cw);
363      }
364
365    return res;
366 }
367
368 EAPI void
369 e_mod_comp_hw_ov_win_root_set(E_Comp_HW_Ov_Win *ov,
370                               Ecore_X_Window    root)
371 {
372    E_CHECK(ov);
373    ov->root = root;
374 }
375
376 /* local subsystem functions */
377 static void
378 _hw_ov_win_power_set(E_Comp_HW_Ov_Win *ov,
379                      Eina_Bool         set)
380 {
381    if (set)
382      {
383         if (!ov->on)
384           {
385              // power on
386              e_mod_comp_util_fb_visible_set(set);
387              ov->on = EINA_TRUE;
388           }
389      }
390    else
391      {
392         if (ov->on)
393           {
394              // power off
395              e_mod_comp_util_fb_visible_set(set);
396              ov->on = EINA_FALSE;
397           }
398      }
399 }
400
401 static Eina_Bool
402 _hw_ov_win_update(E_Comp_HW_Ov_Win *ov,
403                   E_Comp_Win       *cw)
404 {
405    Eina_Bool visible = EINA_FALSE;
406    Eina_Bool get = EINA_FALSE;
407    unsigned char *pix = NULL;
408
409    if (!cw->pixmap || cw->pw <= 0 || cw->ph <= 0 || cw->needpix)
410      {
411         cw->ov.w = 0;
412         cw->ov.h = 0;
413         if (cw->ov_xim) ecore_x_image_free(cw->ov_xim);
414         cw->ov_xim = NULL;
415         return EINA_FALSE;
416      }
417
418    if (cw->pixmap && cw->pw > 0 && cw->ph > 0)
419      {
420         if (!cw->ov_xim)
421           {
422              cw->ov_xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth);
423              if (!cw->ov_xim) return EINA_FALSE;
424
425              cw->ov.w = cw->pw;
426              cw->ov.h = cw->ph;
427           }
428         else if (cw->ov.w != cw->pw || cw->ov.h != cw->ph)
429           {
430              if (cw->ov_xim) ecore_x_image_free(cw->ov_xim);
431              cw->ov_xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth);
432              if (!cw->ov_xim)
433                {
434                   cw->ov.w = 0;
435                   cw->ov.h = 0;
436                   return EINA_FALSE;
437                }
438              cw->ov.w = cw->pw;
439              cw->ov.h = cw->ph;
440           }
441      }
442
443    if (cw->pixmap && cw->pw > 0 && cw->ph > 0 && cw->ov_xim &&
444        !cw->ov_obj && cw->visible)
445      {
446         cw->ov_obj = evas_object_image_filled_add(ov->evas);
447         if (!cw->ov_obj) return EINA_FALSE;
448         evas_object_image_content_hint_set(cw->ov_obj, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
449         evas_object_image_colorspace_set(cw->ov_obj, EVAS_COLORSPACE_ARGB8888);
450         evas_object_image_size_set(cw->ov_obj, cw->pw, cw->ph);
451         if (cw->argb) evas_object_image_alpha_set(cw->ov_obj, 1);
452         else evas_object_image_alpha_set(cw->ov_obj, 0);
453         evas_object_image_fill_set(cw->ov_obj, 0, 0, cw->pw, cw->ph);
454         evas_object_resize(cw->ov_obj, cw->pw, cw->ph);
455         evas_object_render_op_set(cw->ov_obj, EVAS_RENDER_COPY);
456         evas_object_color_set(cw->ov_obj, 255, 255, 255, 255);
457         evas_object_show(cw->ov_obj);
458         _hw_ov_win_power_set(ov, EINA_TRUE);
459      }
460
461    if (cw->ov_obj && cw->visible)
462      {
463         visible = evas_object_visible_get(cw->ov_obj);
464         if (!visible)
465           {
466              evas_object_show(cw->ov_obj);
467              _hw_ov_win_power_set(ov, EINA_TRUE);
468           }
469      }
470
471    if (cw->ov_xim && cw->ov_obj && cw->visible)
472      {
473         pix = ecore_x_image_data_get(cw->ov_xim, NULL, NULL, NULL);
474         evas_object_image_data_set(cw->ov_obj, pix);
475         evas_object_image_size_set(cw->ov_obj, cw->pw, cw->ph);
476
477         get = ecore_x_image_get(cw->ov_xim, cw->pixmap,
478                                 0, 0, 0, 0,
479                                 cw->pw, cw->ph);
480
481         if (!get)
482           {
483              e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
484              return EINA_FALSE;
485           }
486
487         evas_object_move(cw->ov_obj, cw->x, cw->y);
488         evas_object_resize(cw->ov_obj, cw->pw, cw->ph);
489
490         int bpl, rows, bpp;
491         pix = ecore_x_image_data_get(cw->ov_xim, &bpl, &rows, &bpp);
492         if (pix)
493           {
494              evas_data_argb_unpremul((unsigned int *)pix,
495                                      (unsigned int)bpl * (unsigned int)rows / bpp);
496              evas_object_image_data_set(cw->ov_obj, pix);
497              evas_object_image_data_update_add(cw->ov_obj, 0, 0, cw->pw, cw->ph);
498           }
499      }
500    return EINA_TRUE;
501 }