[ILLUME2] Fix bug for handling child window
[framework/uifw/e17-extra-modules.git] / comp-slp / src / e_mod_comp.c
1 #include <dlog.h>
2 #include "e_mod_comp.h"
3 #include "e_mod_comp_atoms.h"
4 #include "e_mod_comp_debug.h"
5
6 #define OVER_FLOW 2
7
8 //////////////////////////////////////////////////////////////////////////
9 //
10 // TODO (no specific order):
11 //   1. abstract evas object and compwin so we can duplicate the object N times
12 //      in N canvases - for winlist, everything, pager etc. too
13 //   2. implement "unmapped composite cache" -> N pixels worth of unmapped
14 //      windows to be fully composited. only the most active/recent.
15 //   3. for unmapped windows - when window goes out of unmapped comp cache
16 //      make a miniature copy (1/4 width+height?) and set property on window
17 //      with pixmap id
18 //   8. obey transparent property
19 //   9. shortcut lots of stuff to draw inside the compositor - shelf,
20 //      wallpaper, efm - hell even menus and anything else in e (this is what
21 //      e18 was mostly about)
22 //  10. fullscreen windows need to be able to bypass compositing *seems buggy*
23 //
24 //////////////////////////////////////////////////////////////////////////
25
26 /* static global variables */
27 static Eina_List *handlers    = NULL;
28 static Eina_List *compositors = NULL;
29 static Eina_Hash *windows     = NULL;
30 static Eina_Hash *borders     = NULL;
31 static Eina_Hash *damages     = NULL;
32
33 /* static functions */
34 static void         _e_mod_comp_render_queue(E_Comp *c);
35 static void         _e_mod_comp_win_damage(E_Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg);
36 static void         _e_mod_comp_win_del(E_Comp_Win *cw);
37 static void         _e_mod_comp_win_real_hide(E_Comp_Win *cw);
38 static void         _e_mod_comp_win_hide(E_Comp_Win *cw);
39 static void         _e_mod_comp_win_configure(E_Comp_Win *cw, int x, int y, int w, int h, int border);
40 static Eina_Bool    _e_mod_comp_win_damage_timeout(void *data);
41 static void         _e_mod_comp_win_raise(E_Comp_Win *cw);
42 static void         _e_mod_comp_win_lower(E_Comp_Win *cw);
43 static E_Comp_Win  *_e_mod_comp_win_find(Ecore_X_Window win);
44 static E_Comp_Win  *_e_mod_comp_border_client_find(Ecore_X_Window win);
45 static Eina_Bool    _e_mod_comp_cb_update(E_Comp *c);
46 static Eina_Bool    _e_mod_comp_win_is_border(E_Comp_Win *cw);
47 static void         _e_mod_comp_cb_pending_after(void *data, E_Manager *man, E_Manager_Comp_Source *src);
48 static E_Comp      *_e_mod_comp_find(Ecore_X_Window root);
49 static void         _e_mod_comp_win_render_queue(E_Comp_Win *cw);
50 static void         _e_mod_comp_x_grab_set(E_Comp *c, Eina_Bool grab);
51 static Evas_Object *_e_mod_comp_win_mirror_add(E_Comp_Win *cw);
52 static void         _e_mod_comp_cb_win_mirror_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
53 static void         _e_mod_comp_src_hidden_set_func(void *data, E_Manager *man, E_Manager_Comp_Source *src, Eina_Bool hidden);
54 static Eina_Bool    _e_mod_comp_prop_window_use_dri2_get(Ecore_X_Window win);
55 static Eina_Bool    _e_mod_comp_prop_use_dri2(Ecore_X_Event_Window_Property *ev);
56
57 ///////////////////////////////////////////////////////////////////////////////////
58
59 EINTERN Eina_Bool
60 e_mod_comp_comp_event_src_visibility_send(E_Comp_Win *cw)
61 {
62    E_CHECK_RETURN(cw, 0);
63    E_CHECK_RETURN(cw->c, 0);
64    E_CHECK_RETURN(cw->c->man, 0);
65
66    cw->pending_count++;
67    e_manager_comp_event_src_visibility_send
68      (cw->c->man, (E_Manager_Comp_Source *)cw,
69      _e_mod_comp_cb_pending_after, cw->c);
70
71    return EINA_TRUE;
72 }
73
74 static void
75 _e_mod_comp_x_grab_set(E_Comp *c,
76                        Eina_Bool grab)
77 {
78    E_CHECK(_comp_mod->conf->grab);
79    E_CHECK(c);
80    E_CHECK((c->grabbed != grab));
81    if (grab)
82      ecore_x_grab();
83    else
84      ecore_x_ungrab();
85    c->grabbed = grab;
86 }
87
88 static Eina_Bool
89 _e_mod_comp_win_is_border(E_Comp_Win *cw)
90 {
91    E_CHECK_RETURN(cw, 0);
92    if (cw->bd) return EINA_TRUE;
93    else return EINA_FALSE;
94 }
95
96 static void
97 _e_mod_comp_fps_update(E_Comp_Canvas *canvas)
98 {
99    char buf[128];
100    double fps = 0.0, t, dt;
101    int i;
102    Evas_Coord x = 0, y = 0, w = 0, h = 0;
103    E_Zone *z;
104
105    if (!_comp_mod->conf->fps_show) return;
106
107    t = ecore_time_get();
108
109    if (_comp_mod->conf->fps_average_range < 1)
110      _comp_mod->conf->fps_average_range = 30;
111    else if (_comp_mod->conf->fps_average_range > 120)
112      _comp_mod->conf->fps_average_range = 120;
113
114    dt = t - canvas->fps.frametimes[_comp_mod->conf->fps_average_range - 1];
115
116    if (dt > 0.0) fps = (double)_comp_mod->conf->fps_average_range / dt;
117    else fps = 0.0;
118
119    if (fps > 0.0) snprintf(buf, sizeof(buf), "FPS: %1.1f", fps);
120    else snprintf(buf, sizeof(buf), "FPS: N/A");
121
122    for (i = 121; i >= 1; i--) canvas->fps.frametimes[i] = canvas->fps.frametimes[i - 1];
123    canvas->fps.frametimes[0] = t;
124    canvas->fps.frameskip++;
125
126    if (canvas->fps.frameskip >= _comp_mod->conf->fps_average_range)
127      {
128         canvas->fps.frameskip = 0;
129         evas_object_text_text_set(canvas->fps.fg, buf);
130      }
131
132    evas_object_geometry_get(canvas->fps.fg, NULL, NULL, &w, &h);
133
134    w += 8;
135    h += 8;
136
137    z = canvas->zone;
138    if (z)
139      {
140         switch (_comp_mod->conf->fps_corner)
141           {
142            case 3: // bottom-right
143               x = z->w - w;
144               y = z->h - h;
145               break;
146            case 2: // bottom-left
147               x = 0;
148               y = z->y + z->h - h;
149               break;
150            case 1: // top-right
151               x = z->w - w;
152               y = z->y;
153               break;
154            default: // 0 // top-left
155               x = 0;
156               y = z->y;
157               break;
158           }
159      }
160    evas_object_move(canvas->fps.bg, x, y);
161    evas_object_resize(canvas->fps.bg, w, h);
162    evas_object_move(canvas->fps.fg, x + 4, y + 4);
163 }
164
165 EINTERN void
166 e_mod_comp_fps_toggle(void)
167 {
168    if (_comp_mod)
169      {
170         Eina_List *l;
171         E_Comp *c;
172
173         if (_comp_mod->conf->fps_show)
174           {
175              _comp_mod->conf->fps_show = 0;
176           }
177         else
178           {
179              _comp_mod->conf->fps_show = 1;
180           }
181         e_config_save_queue();
182         EINA_LIST_FOREACH(compositors, l, c) _e_mod_comp_cb_update(c);
183      }
184 }
185
186 EINTERN Eina_Bool
187 e_mod_comp_win_add_damage(E_Comp_Win *cw,
188                           Ecore_X_Damage dmg)
189 {
190    E_CHECK_RETURN(cw, 0);
191    E_CHECK_RETURN(dmg, 0);
192    return eina_hash_add(damages, e_util_winid_str_get(dmg), cw);
193 }
194
195 EINTERN Eina_Bool
196 e_mod_comp_win_del_damage(E_Comp_Win *cw,
197                           Ecore_X_Damage dmg)
198 {
199    E_CHECK_RETURN(cw, 0);
200    E_CHECK_RETURN(dmg, 0);
201    return eina_hash_del(damages, e_util_winid_str_get(dmg), cw);
202 }
203
204 static void
205 _e_mod_comp_cb_pending_after(void *data __UNUSED__,
206                              E_Manager *man __UNUSED__,
207                              E_Manager_Comp_Source *src)
208 {
209    E_Comp_Win *cw = (E_Comp_Win *)src;
210    cw->pending_count--;
211    if (!cw->delete_pending) return;
212    if (cw->pending_count == 0)
213      {
214         free(cw);
215      }
216 }
217
218 static inline Eina_Bool
219 _e_mod_comp_shaped_check(int                      w,
220                          int                      h,
221                          const Ecore_X_Rectangle *rects,
222                          int                      num)
223 {
224    if ((!rects) || (num < 1)) return EINA_FALSE;
225    if (num > 1) return EINA_TRUE;
226    if ((rects[0].x == 0) && (rects[0].y == 0) &&
227        ((int)rects[0].width == w) && ((int)rects[0].height == h))
228      return EINA_FALSE;
229    return EINA_TRUE;
230 }
231
232 static inline Eina_Bool
233 _e_mod_comp_win_shaped_check(const E_Comp_Win        *cw,
234                              const Ecore_X_Rectangle *rects,
235                              int                      num)
236 {
237    return _e_mod_comp_shaped_check(cw->w, cw->h, rects, num);
238 }
239
240 static void
241 _e_mod_comp_win_shape_rectangles_apply(E_Comp_Win              *cw,
242                                        const Ecore_X_Rectangle *rects,
243                                        int                      num)
244 {
245    Eina_List *l, *ll;
246    Evas_Object *o;
247    E_Comp_Object *co;
248    int i;
249
250    if (!_e_mod_comp_win_shaped_check(cw, rects, num))
251      {
252         rects = NULL;
253      }
254    EINA_LIST_FOREACH(cw->objs, l, co)
255      {
256         if (rects)
257           {
258              unsigned int *pix, *p;
259              unsigned char *spix, *sp;
260              int w, h, px, py;
261
262              evas_object_image_size_get(co->img, &w, &h);
263              if ((w > 0) && (h > 0))
264                {
265                   if (co->native) return;
266                   evas_object_image_native_surface_set(co->img, NULL);
267                   evas_object_image_alpha_set(co->img, 1);
268                   EINA_LIST_FOREACH(co->img_mirror, ll, o)
269                     {
270                        evas_object_image_native_surface_set(o, NULL);
271                        evas_object_image_alpha_set(o, 1);
272                     }
273
274                   pix = evas_object_image_data_get(co->img, 1);
275                   if (pix)
276                     {
277                        spix = calloc(w * h, sizeof(unsigned char));
278                        if (spix)
279                          {
280                             for (i = 0; i < num; i++)
281                               {
282                                  int rx, ry, rw, rh;
283
284                                  rx = rects[i].x; ry = rects[i].y;
285                                  rw = rects[i].width; rh = rects[i].height;
286                                  E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
287                                  sp = spix + (w * ry) + rx;
288                                  for (py = 0; py < rh; py++)
289                                    {
290                                       for (px = 0; px < rw; px++)
291                                         {
292                                            *sp = 0xff; sp++;
293                                         }
294                                       sp += w - rw;
295                                    }
296                               }
297                             sp = spix;
298                             p = pix;
299                             for (py = 0; py < h; py++)
300                               {
301                                  for (px = 0; px < w; px++)
302                                    {
303                                       unsigned int mask, imask;
304                                       mask = ((unsigned int)(*sp)) << 24;
305                                       imask = mask >> 8;
306                                       imask |= imask >> 8;
307                                       imask |= imask >> 8;
308                                       *p = mask | (*p & imask);
309                                       sp++;
310                                       p++;
311                                    }
312                               }
313                             free(spix);
314                          }
315                        evas_object_image_data_set(co->img, pix);
316                        evas_object_image_data_update_add(co->img, 0, 0, w, h);
317                        EINA_LIST_FOREACH(co->img_mirror, ll, o)
318                          {
319                             evas_object_image_data_set(o, pix);
320                             evas_object_image_data_update_add(o, 0, 0, w, h);
321                          }
322                     }
323                }
324           }
325         else
326           {
327              if (cw->shaped)
328                {
329                   unsigned int *pix, *p;
330                   int w, h, px, py;
331
332                   evas_object_image_size_get(co->img, &w, &h);
333                   if ((w > 0) && (h > 0))
334                     {
335                        if (co->native) return;
336                        evas_object_image_alpha_set(co->img, 0);
337                        EINA_LIST_FOREACH(co->img_mirror, l, o)
338                          {
339                             evas_object_image_alpha_set(o, 1);
340                          }
341                        pix = evas_object_image_data_get(co->img, 1);
342                        if (pix)
343                          {
344                             p = pix;
345                             for (py = 0; py < h; py++)
346                               {
347                                  for (px = 0; px < w; px++)
348                                     *p |= 0xff000000;
349                               }
350                          }
351                        evas_object_image_data_set(co->img, pix);
352                        evas_object_image_data_update_add(co->img, 0, 0, w, h);
353                        EINA_LIST_FOREACH(co->img_mirror, ll, o)
354                          {
355                             evas_object_image_data_set(o, pix);
356                             evas_object_image_data_update_add(o, 0, 0, w, h);
357                          }
358                     }
359                }
360              // dont need to fix alpha chanel as blending
361              // should be totally off here regardless of
362              // alpha channel content
363           }
364      }
365 }
366
367 static void
368 _e_mod_comp_win_update(E_Comp_Win *cw)
369 {
370    E_Update_Rect *r;
371    int i;
372
373    if (_comp_mod->conf->use_hw_ov &&
374        TYPE_INDICATOR_CHECK(cw))
375      {
376         Eina_List *l;
377         E_Comp_Canvas *canvas;
378         EINA_LIST_FOREACH(cw->c->canvases, l, canvas)
379           {
380              if (!canvas) continue;
381              if (!canvas->ov) continue;
382              e_mod_comp_hw_ov_win_update(canvas->ov, cw);
383              cw->update = 0;
384           }
385         return;
386      }
387
388    _e_mod_comp_x_grab_set(cw->c, EINA_TRUE);
389    cw->update = 0;
390
391    if (cw->argb)
392      {
393         if (cw->rects)
394           {
395              free(cw->rects);
396              cw->rects = NULL;
397              cw->rects_num = 0;
398           }
399      }
400    else
401      {
402         if (cw->shape_changed)
403           {
404              if (cw->rects)
405                {
406                   free(cw->rects);
407                   cw->rects = NULL;
408                   cw->rects_num = 0;
409                }
410              ecore_x_pixmap_geometry_get(cw->win, NULL, NULL, &(cw->w), &(cw->h));
411              cw->rects = ecore_x_window_shape_rectangles_get(cw->win, &(cw->rects_num));
412              if (cw->rects)
413                {
414                   for (i = 0; i < cw->rects_num; i++)
415                     {
416                        E_RECTS_CLIP_TO_RECT(cw->rects[i].x,
417                                             cw->rects[i].y,
418                                             cw->rects[i].width,
419                                             cw->rects[i].height,
420                                             0, 0, cw->w, cw->h);
421                     }
422                }
423              if (!_e_mod_comp_win_shaped_check(cw, cw->rects, cw->rects_num))
424                {
425                   free(cw->rects);
426                   cw->rects = NULL;
427                   cw->rects_num = 0;
428                }
429              if ((cw->rects) && (!cw->shaped))
430                {
431                   cw->shaped = 1;
432                }
433              else if ((!cw->rects) && (cw->shaped))
434                {
435                   cw->shaped = 0;
436                }
437           }
438      }
439
440    if ((cw->needpix) && (cw->dmg_updates <= 0))
441      {
442         _e_mod_comp_x_grab_set(cw->c, EINA_FALSE);
443         return;
444      }
445
446    if ((!cw->pixmap) || (cw->needpix))
447      {
448         Ecore_X_Pixmap pm = 0;
449         pm = ecore_x_composite_name_window_pixmap_get(cw->win);
450         if (pm)
451           {
452              Ecore_X_Pixmap oldpm;
453              cw->needpix = 0;
454              e_mod_comp_win_comp_objs_needxim_set(cw, 1);
455              oldpm = cw->pixmap;
456              cw->pixmap = pm;
457              if (cw->pixmap)
458                {
459                   ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
460                   // pixmap's size is not equal with window's size case
461                   if (!((cw->pw == cw->w) && (cw->ph == cw->h)))
462                     {
463                        cw->pw = cw->w;
464                        cw->ph = cw->h;
465                        cw->pixmap = oldpm;
466                        cw->needpix = 1;
467                        ecore_x_pixmap_free(pm);
468                        _e_mod_comp_x_grab_set(cw->c, EINA_FALSE);
469                        return;
470                     }
471                   if ((cw->pw > 0) && (cw->ph > 0))
472                     e_mod_comp_win_comp_objs_img_resize(cw, cw->pw, cw->ph);
473                }
474              else
475                {
476                   cw->pw = 0;
477                   cw->ph = 0;
478                }
479              if ((cw->pw <= 0) || (cw->ph <= 0))
480                {
481                   e_mod_comp_win_comp_objs_img_deinit(cw);
482                   if (cw->pixmap)
483                     {
484                        ecore_x_pixmap_free(cw->pixmap);
485                        cw->pixmap = 0;
486                     }
487                   cw->pw = 0;
488                   cw->ph = 0;
489                }
490              ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
491              e_mod_comp_win_comp_objs_native_set(cw, 0);
492              e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
493              e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
494              if (oldpm) ecore_x_pixmap_free(oldpm);
495           }
496      }
497
498    if (!((cw->pw > 0) && (cw->ph > 0)))
499      {
500         _e_mod_comp_x_grab_set(cw->c, EINA_FALSE);
501         return;
502      }
503
504    // update obj geometry when task switcher is not open
505    // or task switcher is open and new window is added
506    cw->defer_move_resize = EINA_FALSE;
507    if ((!cw->c->switcher) ||
508        ((cw->c->switcher) && (!cw->first_show_worked)) ||
509        ((cw->c->switcher) && TYPE_INDICATOR_CHECK(cw)))
510      {
511         if (!cw->move_lock)
512           e_mod_comp_win_comp_objs_move(cw, cw->x, cw->y);
513         e_mod_comp_win_comp_objs_resize(cw,
514                                   cw->pw + (cw->border * 2),
515                                   cw->ph + (cw->border * 2));
516      }
517    else
518      {
519         cw->defer_move_resize = EINA_TRUE;
520      }
521
522    if ((cw->c->gl)
523        && (_comp_mod->conf->texture_from_pixmap)
524        && (!cw->shaped)
525        && (!cw->rects))
526      {
527         e_mod_comp_win_comp_objs_img_size_set(cw, cw->pw, cw->ph);
528         e_mod_comp_win_comp_objs_img_init(cw);
529
530         r = e_mod_comp_update_rects_get(cw->up);
531         if (r)
532           {
533              for (i = 0; r[i].w > 0; i++)
534                {
535                   int x, y, w, h;
536                   x = r[i].x; y = r[i].y;
537                   w = r[i].w; h = r[i].h;
538                   e_mod_comp_win_comp_objs_img_data_update_add(cw, x, y, w, h);
539                }
540              e_mod_comp_update_clear(cw->up);
541              free(r);
542           }
543      }
544    else
545      {
546         Eina_List *l, *ll;
547         E_Comp_Object *co;
548         Evas_Object *o;
549         EINA_LIST_FOREACH(cw->objs, l, co)
550           {
551              if (co->native)
552                {
553                   evas_object_image_native_surface_set(co->img, NULL);
554                   EINA_LIST_FOREACH(co->img_mirror, ll, o)
555                     {
556                        evas_object_image_native_surface_set(o, NULL);
557                     }
558                   co->native = 0;
559                }
560              if (co->needxim)
561                {
562                   co->needxim = 0;
563                   if (co->xim)
564                     {
565                        evas_object_image_size_set(co->img, 1, 1);
566                        evas_object_image_data_set(co->img, NULL);
567                        EINA_LIST_FOREACH(co->img_mirror, ll, o)
568                          {
569                             evas_object_image_size_set(o, 1, 1);
570                             evas_object_image_data_set(o, NULL);
571                          }
572                        ecore_x_image_free(co->xim);
573                        co->xim = NULL;
574                     }
575                }
576              if (!co->xim)
577                {
578                   if ((co->xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth)))
579                     e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
580                }
581           }
582         r = e_mod_comp_update_rects_get(cw->up);
583         if (r)
584           {
585              EINA_LIST_FOREACH(cw->objs, l, co)
586                {
587                   if (co->xim)
588                     {
589                        unsigned int *pix;
590
591                        pix = ecore_x_image_data_get(co->xim, NULL, NULL, NULL);
592                        evas_object_image_data_set(co->img, pix);
593                        evas_object_image_size_set(co->img, cw->pw, cw->ph);
594                        EINA_LIST_FOREACH(co->img_mirror, ll, o)
595                          {
596                             evas_object_image_data_set(o, pix);
597                             evas_object_image_size_set(o, cw->pw, cw->ph);
598                          }
599
600                        e_mod_comp_update_clear(cw->up);
601                        for (i = 0; r[i].w > 0; i++)
602                          {
603                             int x, y, w, h;
604                             x = r[i].x; y = r[i].y;
605                             w = r[i].w; h = r[i].h;
606                             if (!ecore_x_image_get(co->xim, cw->pixmap, x, y, x, y, w, h))
607                               {
608                                  e_mod_comp_update_add(cw->up, x, y, w, h);
609                                  cw->update = 1;
610                               }
611                             else
612                               {
613                                  // why do we neeed these 2? this smells wrong
614                                  pix = ecore_x_image_data_get(co->xim, NULL, NULL, NULL);
615                                  evas_object_image_data_set(co->img, pix);
616                                  evas_object_image_data_update_add(co->img, x, y, w, h);
617                                  EINA_LIST_FOREACH(co->img_mirror, ll, o)
618                                    {
619                                       evas_object_image_data_set(o, pix);
620                                       evas_object_image_data_update_add(o, x, y, w, h);
621                                    }
622                               }
623                          }
624                     }
625                }
626              free(r);
627              if (cw->shaped)
628                {
629                   _e_mod_comp_win_shape_rectangles_apply(cw, cw->rects, cw->rects_num);
630                }
631              else
632                {
633                   if (cw->shape_changed)
634                     _e_mod_comp_win_shape_rectangles_apply(cw, cw->rects, cw->rects_num);
635                }
636              cw->shape_changed = 0;
637           }
638      }
639    e_mod_comp_win_comp_objs_show(cw);
640    e_mod_comp_effect_win_rotation_handler_update(cw);
641    _e_mod_comp_x_grab_set(cw->c, EINA_FALSE);
642 }
643
644 EINTERN void
645 e_mod_comp_pre_swap(void *data,
646                     Evas *e)
647 {
648    E_Comp *c = (E_Comp *)data;
649    Eina_List *l;
650    E_Comp_Canvas *canvas;
651    E_CHECK(c);
652
653    _e_mod_comp_x_grab_set(c, EINA_FALSE);
654
655    EINA_LIST_FOREACH(c->canvases, l, canvas)
656      {
657         if (!canvas) continue;
658         if (canvas->evas != e) continue;
659
660         L(LT_EVENT_X, "[COMP] %31s canvas:%d\n", "PRE_SWAP",
661           canvas->zone ? canvas->zone->num : -1);
662
663         e_mod_comp_hw_ov_win_msg_show
664           (E_COMP_LOG_TYPE_SWAP,
665           "%d %s SWAP a%d m%d",
666           canvas->num,
667           canvas->nocomp.run ? "NOCOMP" : "COMP",
668           canvas->animation.num,
669           ecore_evas_manual_render_get(canvas->ee));
670
671         if (_comp_mod->conf->fps_show)
672           {
673              if (!canvas->fps.bg)
674                {
675                   canvas->fps.bg = evas_object_rectangle_add(canvas->evas);
676                   evas_object_color_set(canvas->fps.bg, 0, 0, 0, 128);
677                   evas_object_layer_set(canvas->fps.bg, EVAS_LAYER_MAX);
678                   evas_object_show(canvas->fps.bg);
679                }
680              if (!canvas->fps.fg)
681                {
682                   canvas->fps.fg = evas_object_text_add(canvas->evas);
683                   evas_object_text_font_set(canvas->fps.fg, "Sans", 30);
684                   evas_object_text_text_set(canvas->fps.fg, "FPS: 0.0");
685                   evas_object_color_set(canvas->fps.fg, 255, 255, 255, 255);
686                   evas_object_layer_set(canvas->fps.fg, EVAS_LAYER_MAX);
687                   evas_object_show(canvas->fps.fg);
688                }
689              _e_mod_comp_fps_update(canvas);
690           }
691         else
692           {
693              if (canvas->fps.fg)
694                {
695                   evas_object_del(canvas->fps.fg);
696                   canvas->fps.fg = NULL;
697                }
698              if (canvas->fps.bg)
699                {
700                   evas_object_del(canvas->fps.bg);
701                   canvas->fps.bg = NULL;
702                }
703           }
704      }
705 }
706
707 static Eina_Bool
708 _e_mod_comp_cb_delayed_update_timer(void *data)
709 {
710    E_Comp *c = data;
711    _e_mod_comp_render_queue(c);
712    c->new_up_timer = NULL;
713    return ECORE_CALLBACK_CANCEL;
714 }
715
716 static E_Comp_Win *
717 _e_mod_comp_fullscreen_check(E_Comp        *c,
718                              E_Comp_Canvas *canvas)
719 {
720    E_Comp_Win *cw;
721    E_Zone *z = canvas->zone;
722    if (!c->wins) return NULL;
723    if (!_comp_mod->conf->nocomp_fs) return NULL;
724    EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
725      {
726         if (cw->move_lock)
727           return NULL;
728
729         if ((!cw->visible)   ||
730             (cw->input_only) ||
731             (cw->invalid))
732           {
733              continue;
734           }
735         if (!E_INTERSECTS(z->x, z->y, z->w, z->h,
736                           cw->x, cw->y, cw->w, cw->h))
737           {
738              continue;
739           }
740         if (TYPE_INDICATOR_CHECK(cw)) continue;
741         if (REGION_EQUAL_TO_ZONE(cw, z) &&
742             (!cw->argb) &&
743             (!cw->shaped) &&
744             (cw->dmg_updates >= 1) &&
745             (!cw->show_ready) &&
746             (cw->show_done) &&
747             (cw->use_dri2))
748           return cw;
749         else
750           return NULL;
751      }
752    return NULL;
753 }
754
755 static Eina_Bool
756 _e_mod_comp_nocomp_begin(E_Comp        *c,
757                          E_Comp_Canvas *canvas,
758                          E_Comp_Win    *cw)
759 {
760    L(LT_EVENT_X,
761      "[COMP] %31s w:0x%08x canvas:%d dmg:%d\n",
762      "NOCOMP_BEGIN", e_mod_comp_util_client_xid_get(cw),
763      canvas->num, cw->dmg_updates);
764
765    e_mod_comp_hw_ov_win_msg_show
766      (E_COMP_LOG_TYPE_NOCOMP,
767      ">> %d NOCOMP 0x%x dmg:%d",
768      canvas->num,
769      e_mod_comp_util_client_xid_get(cw),
770      cw->dmg_updates);
771
772    ecore_x_grab();
773    ecore_evas_manual_render_set(canvas->ee, 1);
774    c->nocomp = 1;
775    c->render_overflow = OVER_FLOW;
776    canvas->nocomp.run = 1;
777    canvas->nocomp.cw = cw;
778    cw->nocomp = 1;
779    if (cw->redirected)
780      {
781         ecore_x_composite_unredirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
782         cw->redirected = 0;
783      }
784    if (cw->damage)
785      {
786         Ecore_X_Region parts;
787         eina_hash_del(damages, e_util_winid_str_get(cw->damage), cw);
788         parts = ecore_x_region_new(NULL, 0);
789         ecore_x_damage_subtract(cw->damage, 0, parts);
790         ecore_x_region_free(parts);
791         ecore_x_damage_free(cw->damage);
792         cw->damage = 0;
793      }
794    if (cw->update_timeout)
795      {
796         ecore_timer_del(cw->update_timeout);
797         cw->update_timeout = NULL;
798      }
799
800    e_mod_comp_win_comp_objs_img_deinit(cw);
801    if (cw->pixmap)
802      {
803         ecore_x_pixmap_free(cw->pixmap);
804         cw->pixmap = 0;
805         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
806      }
807    cw->pw = 0;
808    cw->ph = 0;
809    cw->needpix = 1;
810
811    _e_mod_comp_render_queue(c);
812    e_mod_comp_win_shape_input_invalid_set(c, 1);
813    ecore_x_window_shape_rectangle_subtract(c->win,
814                                            canvas->zone->x,
815                                            canvas->zone->y,
816                                            canvas->zone->w,
817                                            canvas->zone->h);
818    ecore_x_sync();
819    ecore_x_ungrab();
820    return EINA_TRUE;
821 }
822
823 static Eina_Bool
824 _e_mod_comp_nocomp_end(E_Comp        *c,
825                        E_Comp_Canvas *canvas,
826                        E_Comp_Win    *cw)
827 {
828    Ecore_X_Pixmap pm = 0;
829    E_Update_Rect *r;
830    int i;
831
832    if (!_comp_mod->conf->nocomp_fs) return EINA_FALSE;
833
834    L(LT_EVENT_X,
835      "[COMP] %31s new_w:0x%08x nocomp.cw:0x%08x canvas:%d\n",
836      "NOCOMP_END", cw ? e_mod_comp_util_client_xid_get(cw) : 0,
837      e_mod_comp_util_client_xid_get(canvas->nocomp.cw),
838      canvas->num);
839
840    e_mod_comp_hw_ov_win_msg_show
841      (E_COMP_LOG_TYPE_NOCOMP,
842      ">> %d COMP 0x%x",
843      canvas->num,
844      cw ? e_mod_comp_util_client_xid_get(cw) : 0);
845
846    ecore_x_grab();
847    ecore_evas_manual_render_set(canvas->ee, 0);
848    ecore_x_window_shape_rectangle_add(c->win,
849                                       canvas->zone->x,
850                                       canvas->zone->y,
851                                       canvas->zone->w,
852                                       canvas->zone->h);
853    ecore_x_sync();
854
855    c->nocomp = 0;
856    c->render_overflow = OVER_FLOW;
857    canvas->nocomp.run = 0;
858    canvas->nocomp.cw = NULL;
859
860    if (!cw)
861      {
862         ecore_x_ungrab();
863         return EINA_FALSE;
864      }
865
866    if (!cw->nocomp)
867      {
868         ecore_x_ungrab();
869         return EINA_FALSE;
870      }
871    cw->nocomp = 0;
872
873    e_mod_comp_win_comp_objs_img_deinit(cw);
874    if (cw->pixmap)
875      {
876         ecore_x_pixmap_free(cw->pixmap);
877         cw->pixmap = 0;
878         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
879      }
880    cw->pw = 0;
881    cw->ph = 0;
882    cw->needpix = 1;
883
884    if (!cw->redirected)
885      {
886         ecore_x_composite_redirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
887         cw->redirected = 1;
888      }
889
890    pm = ecore_x_composite_name_window_pixmap_get(cw->win);
891    if (pm)
892      {
893         Ecore_X_Pixmap oldpm;
894         cw->needpix = 0;
895         e_mod_comp_win_comp_objs_needxim_set(cw, 1);
896         oldpm = cw->pixmap;
897         cw->pixmap = pm;
898         if (cw->pixmap)
899           {
900              ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
901              if (!((cw->pw == cw->w) && (cw->ph == cw->h)))
902                {
903                   cw->pw = cw->w;
904                   cw->ph = cw->h;
905                   cw->pixmap = oldpm;
906                   cw->needpix = 1;
907                   ecore_x_pixmap_free(pm);
908                }
909              if ((cw->pw > 0) && (cw->ph > 0))
910                e_mod_comp_win_comp_objs_img_resize(cw, cw->pw, cw->ph);
911           }
912         else
913           {
914              cw->pw = 0;
915              cw->ph = 0;
916           }
917         if ((cw->pw <= 0) || (cw->ph <= 0))
918           {
919              e_mod_comp_win_comp_objs_img_deinit(cw);
920              if (cw->pixmap)
921                {
922                   ecore_x_pixmap_free(cw->pixmap);
923                   cw->pixmap = 0;
924                }
925              cw->pw = 0;
926              cw->ph = 0;
927           }
928         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
929         e_mod_comp_win_comp_objs_native_set(cw, 0);
930         e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
931         e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
932         if (oldpm) ecore_x_pixmap_free(oldpm);
933      }
934    if ((cw->c->gl)
935        && (_comp_mod->conf->texture_from_pixmap)
936        && (!cw->shaped)
937        && (!cw->rects))
938      {
939         e_mod_comp_win_comp_objs_img_size_set(cw, cw->pw, cw->ph);
940         e_mod_comp_win_comp_objs_img_init(cw);
941         r = e_mod_comp_update_rects_get(cw->up);
942         if (r)
943           {
944              for (i = 0; r[i].w > 0; i++)
945                {
946                   int x, y, w, h;
947                   x = r[i].x; y = r[i].y;
948                   w = r[i].w; h = r[i].h;
949                   e_mod_comp_win_comp_objs_img_data_update_add(cw, x, y, w, h);
950                }
951              e_mod_comp_update_clear(cw->up);
952              free(r);
953           }
954      }
955
956    if (!cw->damage)
957      {
958         cw->damage = ecore_x_damage_new
959           (cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
960         eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
961      }
962    ecore_x_sync();
963    ecore_x_ungrab();
964    return EINA_TRUE;
965 }
966
967 EINTERN void
968 e_mod_comp_post_swap(void *data,
969                      Evas *e)
970 {
971    E_Comp *c = (E_Comp *)data;
972    Eina_List *l;
973    E_Comp_Canvas *canvas;
974    E_Comp_Win *cw;
975    E_CHECK(c);
976
977    if (!_comp_mod->conf->nocomp_fs) return;
978
979    EINA_LIST_FOREACH(c->canvases, l, canvas)
980      {
981         if (!canvas) continue;
982         if (canvas->nocomp.run) continue;
983         if (canvas->evas != e) continue;
984         if (canvas->nocomp.force_composite) continue;
985         if (canvas->animation.run) continue;
986         cw = _e_mod_comp_fullscreen_check(c, canvas);
987         if (!cw) continue;
988         _e_mod_comp_nocomp_begin(canvas->comp,
989                                  canvas, cw);
990      }
991 }
992
993 static Eina_Bool
994 _e_mod_comp_cb_update(E_Comp *c)
995 {
996    E_Comp_Win *cw;
997    Eina_List *l;
998    E_Comp_Canvas *canvas;
999    Eina_List *new_updates = NULL;
1000    Eina_List *update_done = NULL;
1001
1002    c->update_job = NULL;
1003
1004    if (_comp_mod->conf->nocomp_fs)
1005      {
1006         EINA_LIST_FOREACH(c->canvases, l, canvas)
1007           {
1008              if (!canvas) continue;
1009              if (!canvas->nocomp.run) continue;
1010              cw = _e_mod_comp_fullscreen_check(c, canvas);
1011              if ((!cw) || (cw != canvas->nocomp.cw) ||
1012                  (canvas->nocomp.force_composite))
1013                {
1014                   L(LT_EVENT_X,
1015                     "[COMP] %31s new_w:0x%08x nocomp.cw:0x%08x canvas:%d\n",
1016                     "NOCOMP_END", cw ? e_mod_comp_util_client_xid_get(cw) : 0,
1017                     e_mod_comp_util_client_xid_get(canvas->nocomp.cw),
1018                     canvas->num);
1019
1020                   _e_mod_comp_nocomp_end(canvas->comp,
1021                                          canvas,
1022                                          canvas->nocomp.cw);
1023                }
1024           }
1025      }
1026
1027    _e_mod_comp_x_grab_set(c, EINA_TRUE);
1028
1029    EINA_LIST_FREE(c->updates, cw)
1030      {
1031         if (!cw) continue;
1032         if (_comp_mod->conf->efl_sync)
1033           {
1034              if (((cw->counter) && (cw->drawme)) || (!cw->counter))
1035                {
1036                   _e_mod_comp_win_update(cw);
1037                   if (cw->drawme)
1038                     {
1039                        update_done = eina_list_append(update_done, cw);
1040                        cw->drawme = 0;
1041                     }
1042                }
1043              else
1044                cw->update = 0;
1045           }
1046         else
1047           _e_mod_comp_win_update(cw);
1048         if (cw->update)
1049           new_updates = eina_list_append(new_updates, cw);
1050      }
1051
1052    if (_comp_mod->conf->efl_sync)
1053      {
1054         EINA_LIST_FREE(update_done, cw)
1055           {
1056              if (!cw) continue;
1057              ecore_x_sync_counter_inc(cw->counter, 1);
1058              cw->sync_info.val++;
1059
1060              L(LT_EVENT_X,
1061                "[COMP] %31.31s w:0x%08x done:%d val:%d\n",
1062                "INC", e_mod_comp_util_client_xid_get(cw),
1063                cw->sync_info.done_count, cw->sync_info.val);
1064           }
1065      }
1066    e_mod_comp_win_shape_input_update(c);
1067    _e_mod_comp_x_grab_set(c, EINA_FALSE);
1068    if (new_updates)
1069      {
1070         if (c->new_up_timer) ecore_timer_del(c->new_up_timer);
1071         c->new_up_timer =
1072           ecore_timer_add(0.001, _e_mod_comp_cb_delayed_update_timer, c);
1073      }
1074    c->updates = new_updates;
1075    if (!c->animating) c->render_overflow--;
1076
1077    if (!c->nocomp)
1078      e_mod_comp_effect_signal_flush();
1079
1080    if (c->render_overflow <= 0)
1081      {
1082         c->render_overflow = 0;
1083         if (c->render_animator) c->render_animator = NULL;
1084         return ECORE_CALLBACK_CANCEL;
1085      }
1086    return ECORE_CALLBACK_RENEW;
1087 }
1088
1089 static void
1090 _e_mod_comp_cb_job(void *data)
1091 {
1092    _e_mod_comp_cb_update(data);
1093 }
1094
1095 static Eina_Bool
1096 _e_mod_comp_cb_animator(void *data)
1097 {
1098    return _e_mod_comp_cb_update(data);
1099 }
1100
1101 static void
1102 _e_mod_comp_render_queue(E_Comp *c)
1103 {
1104    if (_comp_mod->conf->lock_fps)
1105      {
1106         if (c->render_animator)
1107           {
1108              c->render_overflow = OVER_FLOW;
1109              return;
1110           }
1111         c->render_animator = ecore_animator_add(_e_mod_comp_cb_animator, c);
1112      }
1113    else
1114      {
1115         if (c->update_job)
1116           {
1117              ecore_job_del(c->update_job);
1118              c->update_job = NULL;
1119              c->render_overflow = 0;
1120           }
1121         c->update_job = ecore_job_add(_e_mod_comp_cb_job, c);
1122      }
1123 }
1124
1125 static void
1126 _e_mod_comp_win_render_queue(E_Comp_Win *cw)
1127 {
1128    _e_mod_comp_render_queue(cw->c);
1129 }
1130
1131 static E_Comp *
1132 _e_mod_comp_find(Ecore_X_Window root)
1133 {
1134    Eina_List *l;
1135    E_Comp *c;
1136    EINA_LIST_FOREACH(compositors, l, c)
1137      {
1138         if (!c) continue;
1139         if (c->man->root == root) return c;
1140      }
1141    return NULL;
1142 }
1143
1144 static E_Comp_Win *
1145 _e_mod_comp_win_find(Ecore_X_Window win)
1146 {
1147    return eina_hash_find(windows, e_util_winid_str_get(win));
1148 }
1149
1150 static E_Comp_Win *
1151 _e_mod_comp_border_client_find(Ecore_X_Window win)
1152 {
1153    return eina_hash_find(borders, e_util_winid_str_get(win));
1154 }
1155
1156 /* wrapper function for external file */
1157 EINTERN E_Comp_Win *
1158 e_mod_comp_win_find(Ecore_X_Window win)
1159 {
1160    return _e_mod_comp_win_find(win);
1161 }
1162
1163 EINTERN E_Comp_Win *
1164 e_mod_comp_border_client_find(Ecore_X_Window win)
1165 {
1166    return _e_mod_comp_border_client_find(win);
1167 }
1168
1169 EINTERN E_Comp *
1170 e_mod_comp_find(Ecore_X_Window win)
1171 {
1172    E_CHECK_RETURN(win, 0);
1173    return _e_mod_comp_find(win);
1174 }
1175
1176 EINTERN void
1177 e_mod_comp_win_render_queue(E_Comp_Win *cw)
1178 {
1179    E_CHECK(cw);
1180    _e_mod_comp_win_render_queue(cw);
1181 }
1182
1183 EINTERN Eina_Bool
1184 e_mod_comp_win_damage_timeout(void *data)
1185 {
1186    E_CHECK_RETURN(data, 0);
1187    return _e_mod_comp_win_damage_timeout(data);
1188 }
1189
1190 EINTERN Eina_Bool
1191 e_mod_comp_cb_update(E_Comp *c)
1192 {
1193    E_CHECK_RETURN(c, 0);
1194    return _e_mod_comp_cb_update(c);
1195 }
1196
1197 EINTERN Evas_Object *
1198 e_mod_comp_win_mirror_add(E_Comp_Win *cw)
1199 {
1200    E_CHECK_RETURN(cw, 0);
1201    return _e_mod_comp_win_mirror_add(cw);
1202 }
1203
1204 EINTERN void
1205 e_mod_comp_cb_win_mirror_del(void        *data,
1206                              Evas        *e,
1207                              Evas_Object *obj,
1208                              void        *event_info)
1209 {
1210    E_CHECK(data);
1211    _e_mod_comp_cb_win_mirror_del(data,
1212                                  e,
1213                                  obj,
1214                                  event_info);
1215 }
1216
1217 EINTERN void
1218 e_mod_comp_src_hidden_set_func(void                  *data,
1219                                E_Manager             *man,
1220                                E_Manager_Comp_Source *src,
1221                                Eina_Bool              hidden)
1222 {
1223    _e_mod_comp_src_hidden_set_func(data, man, src, hidden);
1224 }
1225
1226 static E_Comp_Win *
1227 _e_mod_comp_win_damage_find(Ecore_X_Damage damage)
1228 {
1229    return eina_hash_find(damages, e_util_winid_str_get(damage));
1230 }
1231
1232 static Eina_Bool
1233 _e_mod_comp_win_is_borderless(E_Comp_Win *cw)
1234 {
1235    if (!cw->bd) return 1;
1236    if ((cw->bd->client.border.name) &&
1237        (!strcmp(cw->bd->client.border.name, "borderless")))
1238      return 1;
1239    return 0;
1240 }
1241
1242 static Eina_Bool
1243 _e_mod_comp_win_damage_timeout(void *data)
1244 {
1245    E_Comp_Win *cw = data;
1246    E_CHECK_RETURN(cw, 0);
1247
1248    if (!cw->update)
1249      {
1250         if (cw->update_timeout)
1251           {
1252              ecore_timer_del(cw->update_timeout);
1253              cw->update_timeout = NULL;
1254           }
1255         cw->update = 1;
1256         cw->c->updates = eina_list_append(cw->c->updates, cw);
1257      }
1258    cw->drawme = 1;
1259    _e_mod_comp_win_render_queue(cw);
1260    if (cw->update_timeout)
1261      {
1262         ecore_timer_del(cw->update_timeout);
1263         cw->update_timeout = NULL;
1264      }
1265    return ECORE_CALLBACK_CANCEL;
1266 }
1267
1268 static void
1269 _e_mod_comp_object_del(void *data,
1270                        void *obj)
1271 {
1272    E_Comp_Win *cw = (E_Comp_Win *)data;
1273    E_CHECK(cw);
1274
1275    _e_mod_comp_win_render_queue(cw);
1276
1277    if (obj == cw->bd)
1278      {
1279         if (cw->counter)
1280           {
1281              Ecore_X_Window _w = e_mod_comp_util_client_xid_get(cw);
1282              ecore_x_e_comp_sync_cancel_send(_w);
1283              ecore_x_sync_counter_inc(cw->counter, 1);
1284              cw->sync_info.val++;
1285           }
1286         if (cw->bd) eina_hash_del(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1287         cw->bd = NULL;
1288         e_mod_comp_win_comp_objs_data_del(cw, "border");
1289      }
1290    else if (obj == cw->pop)
1291      {
1292         cw->pop = NULL;
1293         e_mod_comp_win_comp_objs_data_del(cw, "popup");
1294      }
1295    else if (obj == cw->menu)
1296      {
1297         cw->menu = NULL;
1298         e_mod_comp_win_comp_objs_data_del(cw, "menu");
1299      }
1300    if (cw->dfn)
1301      {
1302         e_object_delfn_del(obj, cw->dfn);
1303         cw->dfn = NULL;
1304      }
1305 }
1306
1307 EINTERN void
1308 e_mod_comp_done_defer(E_Comp_Win *cw)
1309 {
1310    E_CHECK(cw);
1311    e_mod_comp_effect_disable_stage(cw->c, cw);
1312    e_mod_comp_effect_animating_set(cw->c, cw, EINA_FALSE);
1313
1314    if (cw->defer_raise)
1315      {
1316         L(LT_EFFECT,
1317           "[COMP] w:0x%08x force win to raise. bd:%s\n",
1318           e_mod_comp_util_client_xid_get(cw),
1319           cw->bd ? "O" : "X");
1320
1321         E_Comp_Win *_cw;
1322         EINA_INLIST_FOREACH(cw->c->wins, _cw)
1323           {
1324              if (!_cw) continue;
1325              e_mod_comp_win_comp_objs_raise(_cw);
1326              Eina_Bool run = e_mod_comp_effect_win_roation_run_check(_cw->eff_winrot);
1327              if (!run) continue;
1328
1329              Eina_List *l, *ll;
1330              E_Comp_Canvas *canvas;
1331              E_Comp_Object *co;
1332              EINA_LIST_FOREACH(_cw->c->canvases, l, canvas)
1333                {
1334                   if (!canvas) continue;
1335                   if (!canvas->use_bg_img) continue;
1336                   EINA_LIST_FOREACH(_cw->objs, ll, co)
1337                     {
1338                        if (!co) continue;
1339                        if (co->canvas == canvas)
1340                          {
1341                             evas_object_stack_below(canvas->bg_img,
1342                                                     co->shadow);
1343                          }
1344                     }
1345                }
1346           }
1347         cw->defer_raise = EINA_FALSE;
1348         e_mod_comp_effect_signal_add
1349           (cw, NULL, "e,state,raise_above_post,on", "e");
1350      }
1351    cw->force = 1;
1352    if (cw->defer_hide)
1353      {
1354         L(LT_EVENT_X,
1355           "[COMP] %31s w:0x%08x force win to hide. bd:%s\n",
1356           "EDJ_DONE", e_mod_comp_util_client_xid_get(cw),
1357           cw->bd ? "O" : "X");
1358
1359         _e_mod_comp_win_hide(cw);
1360      }
1361    cw->force = 1;
1362    if (cw->delete_me)
1363      {
1364         L(LT_EVENT_X,
1365           "[COMP] %31s w:0x%08x force win to delete. bd:%s\n",
1366           "EDJ_DONE", e_mod_comp_util_client_xid_get(cw),
1367           cw->bd ? "O" : "X");
1368
1369         _e_mod_comp_win_del(cw);
1370      }
1371    else cw->force = 0;
1372 }
1373
1374 static void
1375 _e_mod_comp_show_done(void        *data,
1376                       Evas_Object *obj,
1377                       const char  *emission __UNUSED__,
1378                       const char  *source   __UNUSED__)
1379 {
1380    E_Comp_Win *cw = (E_Comp_Win *)data;
1381    E_CHECK(cw);
1382
1383    LOG(LOG_DEBUG, "LAUNCH",
1384        "[e17:Application:Launching:done] win:0x%07x name:%s",
1385        cw->bd ? cw->bd->client.win : cw->win,
1386        cw->bd ? cw->bd->client.netwm.name : NULL);
1387
1388    L(LT_EFFECT,
1389      "[COMP] %18.18s w:0x%08x %s\n", "SIGNAL",
1390      e_mod_comp_util_client_xid_get(cw),
1391      "SHOW_DONE");
1392
1393    e_mod_comp_effect_signal_del(cw, obj, "show,done");
1394
1395    cw->show_done = EINA_TRUE;
1396    e_mod_comp_done_defer(cw);
1397 }
1398
1399 static void
1400 _e_mod_comp_hide_done(void        *data,
1401                       Evas_Object *obj,
1402                       const char  *emission __UNUSED__,
1403                       const char  *source   __UNUSED__)
1404 {
1405    E_Comp_Win *cw = (E_Comp_Win *)data;
1406    E_CHECK(cw);
1407
1408    L(LT_EFFECT,
1409      "[COMP] %18.18s w:0x%08x %s\n", "SIGNAL",
1410      e_mod_comp_util_client_xid_get(cw),
1411      "HIDE_DONE");
1412
1413    e_mod_comp_effect_signal_del(cw, obj, "hide,done");
1414
1415    cw->show_done = EINA_FALSE;
1416    e_mod_comp_done_defer(cw);
1417 }
1418
1419 static void
1420 _e_mod_comp_raise_above_hide_done(void        *data,
1421                                   Evas_Object *obj,
1422                                   const char  *emission __UNUSED__,
1423                                   const char  *source   __UNUSED__)
1424 {
1425    E_Comp_Win *cw = data;
1426    E_CHECK(cw);
1427
1428    L(LT_EFFECT,
1429      "[COMP] %18.18s w:0x%08x %s\n", "SIGNAL",
1430      e_mod_comp_util_client_xid_get(cw),
1431      "RAISE_HIDE_DONE");
1432
1433    e_mod_comp_effect_signal_del(cw, obj, "raise,hide,done");
1434
1435    e_mod_comp_done_defer(cw);
1436 }
1437
1438 static void
1439 _e_mod_comp_background_show_done(void        *data,
1440                                  Evas_Object *obj,
1441                                  const char  *emission __UNUSED__,
1442                                  const char  *source   __UNUSED__)
1443 {
1444    E_Comp_Win *cw = data;
1445    E_CHECK(cw);
1446
1447    L(LT_EFFECT,
1448      "[COMP] %18.18s w:0x%08x %s\n", "SIGNAL",
1449      e_mod_comp_util_client_xid_get(cw),
1450      "BG_SHOW_DONE");
1451
1452    e_mod_comp_effect_signal_del(cw, obj, "bg,show,done");
1453
1454    e_mod_comp_done_defer(cw);
1455 }
1456
1457 static void
1458 _e_mod_comp_background_hide_done(void        *data,
1459                                  Evas_Object *obj,
1460                                  const char  *emission __UNUSED__,
1461                                  const char  *source   __UNUSED__)
1462 {
1463    E_Comp_Win *cw = data;
1464    E_CHECK(cw);
1465
1466    L(LT_EFFECT,
1467      "[COMP] %18.18s w:0x%08x %s\n", "SIGNAL",
1468      e_mod_comp_util_client_xid_get(cw),
1469      "BG_HIDE_DONE");
1470
1471    e_mod_comp_effect_signal_del(cw, obj, "bg,hide,done");
1472
1473    e_mod_comp_done_defer(cw);
1474 }
1475
1476 static void
1477 _e_mod_comp_win_sync_setup(E_Comp_Win *cw,
1478                            Ecore_X_Window win)
1479 {
1480    if (!_comp_mod->conf->efl_sync) return;
1481    if (cw->bd)
1482      {
1483         if (_e_mod_comp_win_is_borderless(cw) ||
1484             (_comp_mod->conf->loose_sync))
1485           {
1486              cw->counter = ecore_x_e_comp_sync_counter_get(win);
1487           }
1488         else
1489           {
1490              ecore_x_e_comp_sync_cancel_send(win);
1491              cw->counter = 0;
1492           }
1493      }
1494    else
1495      cw->counter = ecore_x_e_comp_sync_counter_get(win);
1496
1497    if (cw->counter)
1498      {
1499         if (cw->bd)
1500           {
1501              E_Comp_Win *client_cw = _e_mod_comp_win_find(win);
1502              if (client_cw &&
1503                  client_cw->counter == cw->counter)
1504                {
1505                   ecore_x_sync_counter_inc(cw->counter, 1);
1506                   cw->sync_info.val++;
1507                   return;
1508                }
1509           }
1510
1511         ecore_x_e_comp_sync_begin_send(win);
1512         ecore_x_sync_counter_inc(cw->counter, 1);
1513         cw->sync_info.val++;
1514      }
1515 }
1516
1517 EINTERN void
1518 e_mod_comp_win_shadow_setup(E_Comp_Win    *cw,
1519                             E_Comp_Object *co)
1520 {
1521    Evas_Object *o;
1522    int ok = 0;
1523    char buf[PATH_MAX];
1524    Eina_List *l;
1525
1526    evas_object_image_smooth_scale_set(co->img, _comp_mod->conf->smooth_windows);
1527    EINA_LIST_FOREACH(co->img_mirror, l, o)
1528      {
1529         evas_object_image_smooth_scale_set(o, _comp_mod->conf->smooth_windows);
1530      }
1531
1532    if (_comp_mod->conf->shadow_file)
1533      ok = edje_object_file_set
1534         (co->shadow, _comp_mod->conf->shadow_file,
1535         e_mod_comp_policy_win_shadow_group_get(cw));
1536
1537    if (!ok)
1538      {
1539         fprintf(stdout, "[E17-comp] EDC file ERROR win:0x%08x %s(%d) f:%s\n",
1540                 cw->win, __func__, __LINE__, _comp_mod->conf->shadow_file);
1541         e_mod_comp_debug_edje_error_get
1542            (co->shadow, e_mod_comp_util_client_xid_get(cw));
1543
1544         if (_comp_mod->conf->shadow_style)
1545           {
1546              snprintf(buf, sizeof(buf), "e/comp/%s",
1547                       _comp_mod->conf->shadow_style);
1548              ok = e_theme_edje_object_set(co->shadow,
1549                                           "base/theme/borders",
1550                                           buf);
1551           }
1552         if (!ok)
1553           {
1554              ok = e_theme_edje_object_set(co->shadow,
1555                                           "base/theme/borders",
1556                                           "e/comp/default");
1557           }
1558      }
1559    // fallback to local shadow.edj - will go when default theme supports this
1560    if (!ok)
1561      {
1562         fprintf(stdout, "[E17-comp] EDC file ERROR win:0x%08x %s(%d)\n",
1563                 cw->win, __func__, __LINE__);
1564         e_mod_comp_debug_edje_error_get
1565            (co->shadow, e_mod_comp_util_client_xid_get(cw));
1566         snprintf(buf, sizeof(buf), "%s/shadow.edj",
1567                  e_module_dir_get(_comp_mod->module));
1568         ok = edje_object_file_set(co->shadow, buf, "shadow");
1569      }
1570    if (!edje_object_part_swallow(co->shadow,
1571                                  "e.swallow.content",
1572                                  co->img))
1573      {
1574         fprintf(stdout, "[E17-comp] EDC swallow ERROR win:0x%08x %s(%d)\n",
1575                 cw->win, __func__, __LINE__);
1576      }
1577
1578    e_mod_comp_debug_edje_error_get
1579      (co->shadow, e_mod_comp_util_client_xid_get(cw));
1580
1581    e_mod_comp_effect_signal_add
1582      (cw, NULL, "e,state,shadow,off", "e");
1583
1584    if (cw->bd)
1585      {
1586         if (cw->bd->focused)
1587           e_mod_comp_effect_signal_add
1588             (cw, NULL, "e,state,focus,on", "e");
1589         if (cw->bd->client.icccm.urgent)
1590           e_mod_comp_effect_signal_add
1591             (cw, NULL, "e,state,urgent,on", "e");
1592      }
1593 }
1594
1595 static void
1596 _e_mod_comp_cb_win_mirror_del(void            *data,
1597                               Evas            *e,
1598                               Evas_Object     *obj,
1599                               void *event_info __UNUSED__)
1600 {
1601    E_Comp_Win *cw = (E_Comp_Win *)data;
1602    E_Comp_Object *co;
1603    Eina_List *l;
1604    E_CHECK(cw);
1605
1606    EINA_LIST_FOREACH(cw->objs, l, co)
1607      {
1608         if (co->canvas->evas == e)
1609           {
1610              co->img_mirror = eina_list_remove(co->img_mirror, obj);
1611              break;
1612           }
1613      }
1614 }
1615
1616 static Evas_Object *
1617 _e_mod_comp_win_mirror_add(E_Comp_Win *cw)
1618 {
1619    Evas_Object *o;
1620    Eina_List *l;
1621    E_Comp_Object *co;
1622    E_Zone *z;
1623
1624    E_CHECK_RETURN(cw->c, 0);
1625
1626    if (cw->bd) z = cw->bd->zone;
1627    else z = e_util_zone_current_get(cw->c->man);
1628    EINA_LIST_FOREACH(cw->objs, l, co)
1629      {
1630         if ((_comp_mod->conf->canvas_per_zone) &&
1631             ((co->zone) != (z)))
1632           continue;
1633
1634         o = evas_object_image_filled_add(co->canvas->evas);
1635         evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
1636         co->img_mirror = eina_list_append(co->img_mirror, o);
1637         evas_object_image_smooth_scale_set(o, _comp_mod->conf->smooth_windows);
1638
1639         evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
1640                                        _e_mod_comp_cb_win_mirror_del, cw);
1641
1642         if ((cw->pixmap) && (cw->pw > 0) && (cw->ph > 0))
1643           {
1644              unsigned int *pix;
1645              Eina_Bool alpha;
1646              int w, h;
1647
1648              alpha = evas_object_image_alpha_get(co->img);
1649              evas_object_image_size_get(co->img, &w, &h);
1650
1651              evas_object_image_alpha_set(o, alpha);
1652
1653              if (cw->shaped)
1654                {
1655                   pix = evas_object_image_data_get(co->img, 0);
1656                   evas_object_image_data_set(o, pix);
1657                   evas_object_image_size_set(o, w, h);
1658                   evas_object_image_data_set(o, pix);
1659                   evas_object_image_data_update_add(o, 0, 0, w, h);
1660                }
1661              else
1662                {
1663                   if (co->native)
1664                     {
1665                        Evas_Native_Surface ns;
1666
1667                        ns.version = EVAS_NATIVE_SURFACE_VERSION;
1668                        ns.type = EVAS_NATIVE_SURFACE_X11;
1669                        ns.data.x11.visual = cw->vis;
1670                        ns.data.x11.pixmap = cw->pixmap;
1671                        evas_object_image_size_set(o, w, h);
1672                        evas_object_image_native_surface_set(o, &ns);
1673                        evas_object_image_data_update_add(o, 0, 0, w, h);
1674                     }
1675                   else
1676                     {
1677                        if (!co->xim)
1678                          {
1679                             evas_object_del(o);
1680                             return NULL;
1681                          }
1682                        pix = ecore_x_image_data_get(co->xim, NULL, NULL, NULL);
1683                        evas_object_image_data_set(o, pix);
1684                        evas_object_image_size_set(o, w, h);
1685                        evas_object_image_data_set(o, pix);
1686                        evas_object_image_data_update_add(o, 0, 0, w, h);
1687                     }
1688                }
1689              evas_object_image_size_set(o, w, h);
1690              evas_object_image_data_update_add(o, 0, 0, w, h);
1691           }
1692         evas_object_stack_above(o, co->shadow);
1693         return o;
1694      }
1695    return NULL;
1696 }
1697
1698 static E_Comp_Win *
1699 _e_mod_comp_win_add(E_Comp        *c,
1700                     Ecore_X_Window win)
1701 {
1702    Ecore_X_Window_Attributes att;
1703    E_Comp_Win *cw;
1704    Eina_List *l;
1705    E_Comp_Object *co;
1706
1707    cw = E_NEW(E_Comp_Win, 1);
1708    E_CHECK_RETURN(cw, 0);
1709    cw->win = win;
1710    cw->c = c;
1711    cw->opacity = 255.0;
1712    cw->bd = e_border_find_by_window(cw->win);
1713    _e_mod_comp_x_grab_set(c, EINA_TRUE);
1714    if (cw->bd)
1715      {
1716         eina_hash_add(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1717         cw->dfn = e_object_delfn_add(E_OBJECT(cw->bd), _e_mod_comp_object_del, cw);
1718      }
1719    else if ((cw->pop = e_popup_find_by_window(cw->win)))
1720      {
1721         cw->dfn = e_object_delfn_add(E_OBJECT(cw->pop),
1722                                      _e_mod_comp_object_del, cw);
1723         cw->show_ready = 1;
1724      }
1725    else if ((cw->menu = e_menu_find_by_window(cw->win)))
1726      {
1727         cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu),
1728                                      _e_mod_comp_object_del, cw);
1729         cw->show_ready = 1;
1730      }
1731    else
1732      {
1733         char *netwm_title = NULL;
1734
1735         cw->title = ecore_x_icccm_title_get(cw->win);
1736         if (ecore_x_netwm_name_get(cw->win, &netwm_title))
1737           {
1738              if (cw->title) free(cw->title);
1739              cw->title = netwm_title;
1740           }
1741         ecore_x_icccm_name_class_get(cw->win, &cw->name, &cw->clas);
1742         cw->role = ecore_x_icccm_window_role_get(cw->win);
1743         if (!ecore_x_netwm_window_type_get(cw->win, &cw->primary_type))
1744           cw->primary_type = ECORE_X_WINDOW_TYPE_UNKNOWN;
1745      }
1746
1747    e_mod_comp_win_type_setup(cw);
1748    memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
1749    if (!ecore_x_window_attributes_get(cw->win, &att))
1750      {
1751         free(cw);
1752         _e_mod_comp_x_grab_set(c, EINA_FALSE);
1753         return NULL;
1754      }
1755
1756    if ((!att.input_only) &&
1757        ((att.depth != 24) && (att.depth != 32)))
1758      {
1759         printf("WARNING: window 0x%x not 24/32bpp -> %ibpp\n",
1760                cw->win, att.depth);
1761         cw->invalid = 1;
1762      }
1763    cw->input_only = att.input_only;
1764    cw->override = att.override;
1765    cw->vis = att.visual;
1766    cw->depth = att.depth;
1767    cw->argb = ecore_x_window_argb_get(cw->win);
1768
1769    eina_hash_add(windows, e_util_winid_str_get(cw->win), cw);
1770    cw->inhash = 1;
1771    if ((!cw->input_only) && (!cw->invalid))
1772      {
1773         Ecore_X_Rectangle *rects;
1774         int num;
1775
1776         cw->damage = ecore_x_damage_new
1777           (cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
1778         eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
1779         cw->objs = e_mod_comp_win_comp_objs_add(cw);
1780         if (!cw->objs)
1781           {
1782              free(cw);
1783              _e_mod_comp_x_grab_set(c, EINA_FALSE);
1784              return NULL;
1785           }
1786              
1787         E_Comp_Canvas *canvas;
1788         EINA_LIST_FOREACH(c->canvases, l, canvas)
1789           {
1790              if (!canvas) continue;
1791              if (canvas->use_bg_img) continue;
1792              evas_object_lower(canvas->bg_img);
1793           }
1794
1795         EINA_LIST_FOREACH(cw->objs, l, co)
1796           {
1797              if (!co) continue;
1798              e_mod_comp_win_shadow_setup(cw, co);
1799              e_mod_comp_win_cb_setup(cw, co);
1800              if (co->img) evas_object_show(co->img);
1801           }
1802
1803         ecore_x_window_shape_events_select(cw->win, 1);
1804         rects = ecore_x_window_shape_rectangles_get(cw->win, &num);
1805         if (rects)
1806           {
1807              int i;
1808              for (i = 0; i < num; i++)
1809                E_RECTS_CLIP_TO_RECT(rects[i].x, rects[i].y,
1810                                     rects[i].width, rects[i].height,
1811                                     0, 0, att.w, att.h);
1812              if (_e_mod_comp_shaped_check(att.w, att.h, rects, num))
1813                cw->shape_changed = 1;
1814
1815              free(rects);
1816           }
1817
1818         if (cw->bd) e_mod_comp_win_comp_objs_data_set(cw, "border", cw->bd);
1819         else if (cw->pop)
1820           e_mod_comp_win_comp_objs_data_set(cw, "popup", cw->pop);
1821         else if (cw->menu)
1822           e_mod_comp_win_comp_objs_data_set(cw, "menu", cw->menu);
1823
1824         e_mod_comp_win_comp_objs_img_pass_events_set(cw, 1);
1825
1826         cw->pending_count++;
1827         e_manager_comp_event_src_add_send
1828           (cw->c->man, (E_Manager_Comp_Source *)cw,
1829           _e_mod_comp_cb_pending_after, cw->c);
1830      }
1831    else
1832      {
1833         cw->objs = e_mod_comp_win_comp_objs_add(cw);
1834         if (!cw->objs)
1835           {
1836              free(cw);
1837              _e_mod_comp_x_grab_set(c, EINA_FALSE);
1838              return NULL;
1839           }
1840      }
1841    e_mod_comp_win_comp_objs_pass_events_set(cw, 1);
1842    e_mod_comp_win_comp_objs_data_set(cw, "win",
1843                                (void *)((unsigned long)cw->win));
1844    e_mod_comp_win_comp_objs_data_set(cw, "src", cw);
1845
1846    c->wins_invalid = 1;
1847    c->wins = eina_inlist_append(c->wins, EINA_INLIST_GET(cw));
1848    cw->up = e_mod_comp_update_new();
1849    e_mod_comp_update_tile_size_set(cw->up, 32, 32);
1850    // for software:
1851    e_mod_comp_update_policy_set
1852      (cw->up, E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH);
1853    if (((!cw->input_only) && (!cw->invalid)) && (cw->override))
1854      {
1855         cw->redirected = 1;
1856         cw->dmg_updates = 0;
1857      }
1858
1859    cw->eff_type = e_mod_comp_effect_type_new();
1860    if (cw->eff_type)
1861      {
1862         e_mod_comp_effect_type_setup
1863           (cw->eff_type,
1864           e_mod_comp_util_client_xid_get(cw));
1865      }
1866
1867    _e_mod_comp_x_grab_set(c, EINA_FALSE);
1868    return cw;
1869 }
1870
1871 static void
1872 _e_mod_comp_win_del(E_Comp_Win *cw)
1873 {
1874    int pending_count;
1875
1876    Eina_List *l;
1877    E_Comp_Object *co;
1878    EINA_LIST_FOREACH(cw->objs, l, co)
1879      {
1880         if (!co) continue;
1881         e_mod_comp_effect_signal_del(cw,
1882                                      co->shadow,
1883                                      "hide,done");
1884      }
1885
1886    // while win_hide animation is progressing, at that time win_del is called,
1887    // background window effect is may not work fully.
1888    // so, explicit call disable effect stage function.
1889    if (cw->effect_stage)
1890      e_mod_comp_effect_disable_stage(cw->c, cw);
1891
1892    if (cw->animating)
1893      e_mod_comp_effect_animating_set(cw->c, cw, EINA_FALSE);
1894
1895    if (cw->shape_input)
1896      {
1897         e_mod_comp_win_shape_input_free(cw->shape_input);
1898         cw->shape_input = NULL;
1899      }
1900
1901    if ((!cw->input_only) && (!cw->invalid))
1902      {
1903         cw->pending_count++;
1904         e_manager_comp_event_src_del_send
1905           (cw->c->man, (E_Manager_Comp_Source *)cw,
1906           _e_mod_comp_cb_pending_after, cw->c);
1907      }
1908
1909    e_mod_comp_update_free(cw->up);
1910    e_mod_comp_effect_win_rotation_handler_release(cw);
1911    e_mod_comp_bg_win_handler_release(cw);
1912
1913    if (cw->rects)
1914      {
1915         free(cw->rects);
1916         cw->rects = NULL;
1917      }
1918    if (cw->update_timeout)
1919      {
1920         ecore_timer_del(cw->update_timeout);
1921         cw->update_timeout = NULL;
1922      }
1923    if (cw->dfn)
1924      {
1925         if (cw->bd)
1926           {
1927              eina_hash_del(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1928              e_object_delfn_del(E_OBJECT(cw->bd), cw->dfn);
1929              cw->bd = NULL;
1930           }
1931         else if (cw->pop)
1932           {
1933              e_object_delfn_del(E_OBJECT(cw->pop), cw->dfn);
1934              cw->pop = NULL;
1935           }
1936         else if (cw->menu)
1937           {
1938              e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn);
1939              cw->menu = NULL;
1940           }
1941         cw->dfn = NULL;
1942      }
1943    if (cw->pixmap)
1944      {
1945         e_mod_comp_win_comp_objs_img_deinit(cw);
1946
1947         ecore_x_pixmap_free(cw->pixmap);
1948         cw->pixmap = 0;
1949         cw->pw = 0;
1950         cw->ph = 0;
1951         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
1952         e_mod_comp_win_comp_objs_xim_free(cw);
1953      }
1954    if (cw->redirected)
1955      {
1956         cw->redirected = 0;
1957         cw->pw = 0;
1958         cw->ph = 0;
1959      }
1960    if (cw->update)
1961      {
1962         cw->update = 0;
1963         cw->c->updates = eina_list_remove(cw->c->updates, cw);
1964      }
1965    e_mod_comp_win_comp_objs_del(cw, cw->objs);
1966    if (cw->inhash)
1967      eina_hash_del(windows, e_util_winid_str_get(cw->win), cw);
1968    if (cw->damage)
1969      {
1970         Ecore_X_Region parts;
1971         eina_hash_del(damages, e_util_winid_str_get(cw->damage), cw);
1972         parts = ecore_x_region_new(NULL, 0);
1973         ecore_x_damage_subtract(cw->damage, 0, parts);
1974         ecore_x_region_free(parts);
1975         ecore_x_damage_free(cw->damage);
1976         cw->damage = 0;
1977      }
1978    if (cw->title) free(cw->title);
1979    if (cw->name) free(cw->name);
1980    if (cw->clas) free(cw->clas);
1981    if (cw->role) free(cw->role);
1982    if (cw->eff_type)
1983      {
1984         e_mod_comp_effect_type_free(cw->eff_type);
1985         cw->eff_type = NULL;
1986      }
1987    cw->c->wins_invalid = 1;
1988    cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
1989    pending_count = cw->pending_count;
1990    memset(cw, 0, sizeof(E_Comp_Win));
1991    cw->pending_count = pending_count;
1992    cw->delete_pending = 1;
1993    if (cw->pending_count > 0) return;
1994    free(cw);
1995 }
1996
1997 static void
1998 _e_mod_comp_win_show(E_Comp_Win *cw)
1999 {
2000    Ecore_X_Window win;
2001
2002    // if win_hide was showed then immediatly win_show() function is called. case.
2003    if (cw->defer_hide == 1) cw->defer_hide = 0;
2004    if (cw->visible) return;
2005    cw->visible = 1;
2006    _e_mod_comp_win_configure(cw,
2007                              cw->hidden.x, cw->hidden.y,
2008                              cw->w, cw->h,
2009                              cw->border);
2010    if ((cw->input_only) || (cw->invalid)) return;
2011
2012    if (cw->bd)
2013      _e_mod_comp_win_sync_setup(cw, cw->bd->client.win);
2014    else
2015      _e_mod_comp_win_sync_setup(cw, cw->win);
2016
2017    if (cw->real_hid)
2018      {
2019         cw->real_hid = 0;
2020         e_mod_comp_win_comp_objs_img_deinit(cw);
2021         if (cw->pixmap)
2022           {
2023              ecore_x_pixmap_free(cw->pixmap);
2024              cw->pixmap = 0;
2025              cw->pw = 0;
2026              cw->ph = 0;
2027              ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2028           }
2029         e_mod_comp_win_comp_objs_xim_free(cw);
2030         if (cw->redirected)
2031           {
2032              cw->redirected = 0;
2033              cw->pw = 0;
2034              cw->ph = 0;
2035           }
2036      }
2037
2038    if ((!cw->redirected) || (!cw->pixmap))
2039      {
2040         if (!cw->pixmap)
2041           cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win);
2042         if (cw->pixmap)
2043           ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
2044         else
2045           {
2046              cw->pw = 0;
2047              cw->ph = 0;
2048           }
2049         if ((cw->pw <= 0) || (cw->ph <= 0))
2050           {
2051              if (cw->pixmap)
2052                {
2053                   ecore_x_pixmap_free(cw->pixmap);
2054                   cw->pixmap = 0;
2055                   cw->needpix = 1;
2056                }
2057           }
2058         cw->redirected = 1;
2059
2060         e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
2061         e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
2062
2063         e_mod_comp_win_comp_objs_img_size_set(cw, cw->pw, cw->ph);
2064         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2065      }
2066
2067    if (cw->dmg_updates >= 1)
2068      {
2069         if ((cw->c->gl) && (_comp_mod->conf->texture_from_pixmap))
2070           {
2071              if (!cw->pixmap)
2072                cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win);
2073
2074              if (cw->pixmap)
2075                {
2076                   ecore_x_pixmap_geometry_get(cw->pixmap,
2077                                               NULL, NULL,
2078                                               &(cw->pw), &(cw->ph));
2079                }
2080              else
2081                {
2082                   cw->pw = 0;
2083                   cw->ph = 0;
2084                }
2085
2086              if ((cw->pw <= 0) || (cw->ph <= 0))
2087                {
2088                   if (cw->pixmap)
2089                     ecore_x_pixmap_free(cw->pixmap);
2090                   cw->pixmap = 0;
2091                   cw->needpix = 1;
2092                }
2093              else
2094                {
2095                   ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2096                   e_mod_comp_win_comp_objs_img_size_set(cw, cw->pw, cw->ph);
2097                   e_mod_comp_win_comp_objs_img_init(cw);
2098                }
2099             }
2100
2101         if (cw->pixmap)
2102           {
2103              cw->defer_hide = 0;
2104              if (!cw->hidden_override)
2105                {
2106                   if (cw->defer_move_resize)
2107                     {
2108                        if (!cw->move_lock)
2109                          e_mod_comp_win_comp_objs_move(cw, cw->x, cw->y);
2110                        e_mod_comp_win_comp_objs_resize(cw,
2111                                                  cw->pw + (cw->border * 2),
2112                                                  cw->ph + (cw->border * 2));
2113                        cw->defer_move_resize = EINA_FALSE;
2114                     }
2115                   e_mod_comp_win_comp_objs_force_show(cw);
2116                }
2117           }
2118      }
2119    e_mod_comp_bg_win_handler_show(cw);
2120
2121    win = e_mod_comp_util_client_xid_get(cw);
2122    cw->use_dri2 = _e_mod_comp_prop_window_use_dri2_get(win);
2123
2124    e_mod_comp_win_shape_input_invalid_set(cw->c, 1);
2125    _e_mod_comp_win_render_queue(cw);
2126 }
2127
2128 static void
2129 _e_mod_comp_win_real_hide(E_Comp_Win *cw)
2130 {
2131    if (cw->bd)
2132      {
2133         _e_mod_comp_win_hide(cw);
2134         return;
2135      }
2136    cw->real_hid = 1;
2137    _e_mod_comp_win_hide(cw);
2138 }
2139
2140 static void
2141 _e_mod_comp_win_hide(E_Comp_Win *cw)
2142 {
2143    Ecore_X_Window _w;
2144
2145    if ((!cw->visible) && (!cw->defer_hide)) return;
2146
2147    e_mod_comp_win_shape_input_invalid_set(cw->c, 1);
2148
2149    cw->visible = 0;
2150    if ((cw->input_only) || (cw->invalid)) return;
2151
2152    e_mod_comp_effect_win_rotation_handler_release(cw);
2153
2154    if (!cw->force)
2155      {
2156         cw->defer_hide = 1;
2157         if (STATE_INSET_CHECK(cw))
2158           e_mod_comp_effect_signal_add
2159             (cw, NULL, "e,state,shadow,off", "e");
2160         e_mod_comp_effect_win_hide(cw);
2161         return;
2162      }
2163
2164    Eina_List *l;
2165    E_Comp_Object *co;
2166    EINA_LIST_FOREACH(cw->objs, l, co)
2167      {
2168         if (!co) continue;
2169         e_mod_comp_effect_signal_del(cw,
2170                                      co->shadow,
2171                                      "hide,done");
2172      }
2173
2174    cw->defer_hide = 0;
2175    cw->force = 0;
2176    e_mod_comp_win_comp_objs_hide(cw);
2177
2178    if (cw->update_timeout)
2179      {
2180         ecore_timer_del(cw->update_timeout);
2181         cw->update_timeout = NULL;
2182      }
2183    if (_comp_mod->conf->keep_unmapped)
2184      {
2185         goto finish;
2186      }
2187
2188    e_mod_comp_win_comp_objs_img_deinit(cw);
2189    if (cw->pixmap)
2190      {
2191         ecore_x_pixmap_free(cw->pixmap);
2192         cw->pixmap = 0;
2193         cw->pw = 0;
2194         cw->ph = 0;
2195         ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2196      }
2197
2198    e_mod_comp_win_comp_objs_xim_free(cw);
2199
2200    if (cw->redirected)
2201      {
2202         cw->redirected = 0;
2203         cw->pw = 0;
2204         cw->ph = 0;
2205      }
2206
2207 finish:
2208    _e_mod_comp_win_render_queue(cw);
2209    _w = e_mod_comp_util_client_xid_get(cw);
2210    if (_comp_mod->conf->send_flush) ecore_x_e_comp_flush_send(_w);
2211    if (_comp_mod->conf->send_dump) ecore_x_e_comp_dump_send(_w);
2212 }
2213
2214 static void
2215 _e_mod_comp_win_raise_above(E_Comp_Win *cw,
2216                             E_Comp_Win *cw2)
2217 {
2218    Eina_Bool v1, v2;
2219    Eina_Bool raise = EINA_FALSE;
2220    Eina_Bool lower = EINA_FALSE;
2221    E_Comp_Win *below;
2222
2223    v1 = e_mod_comp_util_win_visible_get(cw);
2224    below = e_mod_comp_util_win_below_get(cw, 0);
2225
2226    cw->c->wins_invalid = 1;
2227    cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2228    cw->c->wins = eina_inlist_append_relative(cw->c->wins,
2229                                              EINA_INLIST_GET(cw),
2230                                              EINA_INLIST_GET(cw2));
2231    v2 = e_mod_comp_util_win_visible_get(cw);
2232
2233    if ((v1) && (!v2))
2234      lower = e_mod_comp_policy_win_lower_check(cw, below);
2235    else if ((!v1) && (v2))
2236      raise = e_mod_comp_policy_win_restack_check(cw, cw2);
2237
2238    L(LT_EFFECT,
2239      "[COMP] %18.18s w:0x%08x w2:0x%08x wb:0x%08x [fs%d sd%d v%d v%d l%d r%d]\n", "EFF",
2240      e_mod_comp_util_client_xid_get(cw),
2241      e_mod_comp_util_client_xid_get(cw2),
2242      e_mod_comp_util_client_xid_get(below),
2243      cw->first_show_worked, cw->show_done,
2244      v1, v2, lower, raise);
2245
2246    if ((raise) && (cw->first_show_worked))
2247      {
2248         e_mod_comp_effect_win_restack(cw, cw2);
2249      }
2250    else if ((lower) && (cw->show_done))
2251      {
2252         e_mod_comp_effect_win_lower(cw, below);
2253      }
2254    else
2255      {
2256         e_mod_comp_win_comp_objs_stack_above(cw, cw2);
2257         if ((cw->visible) && (cw->first_show_worked))
2258           {
2259              e_mod_comp_effect_signal_add
2260                (cw, NULL, "e,state,visible,on,noeffect", "e");
2261           }
2262      }
2263
2264    _e_mod_comp_win_render_queue(cw);
2265    cw->pending_count++;
2266    e_manager_comp_event_src_config_send
2267      (cw->c->man, (E_Manager_Comp_Source *)cw,
2268      _e_mod_comp_cb_pending_after, cw->c);
2269 }
2270
2271 static void
2272 _e_mod_comp_win_raise(E_Comp_Win *cw)
2273 {
2274    cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2275    cw->c->wins = eina_inlist_append(cw->c->wins, EINA_INLIST_GET(cw));
2276
2277    e_mod_comp_win_comp_objs_raise(cw);
2278    _e_mod_comp_win_render_queue(cw);
2279 }
2280
2281 static void
2282 _e_mod_comp_win_lower(E_Comp_Win *cw)
2283 {
2284    cw->c->wins_invalid = 1;
2285    cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2286    cw->c->wins = eina_inlist_prepend(cw->c->wins, EINA_INLIST_GET(cw));
2287
2288    e_mod_comp_win_comp_objs_lower(cw);
2289    _e_mod_comp_win_render_queue(cw);
2290    cw->pending_count++;
2291    e_manager_comp_event_src_config_send
2292      (cw->c->man, (E_Manager_Comp_Source *)cw,
2293      _e_mod_comp_cb_pending_after, cw->c);
2294 }
2295
2296 static void
2297 _e_mod_comp_win_configure(E_Comp_Win *cw,
2298                           int x, int y,
2299                           int w, int h,
2300                           int border)
2301 {
2302    Eina_Bool geo_changed = EINA_FALSE;
2303    if (!((w == cw->w) && (h == cw->h)))
2304      {
2305         cw->w = w;
2306         cw->h = h;
2307         cw->needpix = 1;
2308         cw->dmg_updates = 0;
2309         geo_changed = EINA_TRUE;
2310      }
2311
2312    if (!cw->visible)
2313      {
2314         cw->hidden.x = x;
2315         cw->hidden.y = y;
2316         cw->border = border;
2317      }
2318    else
2319      {
2320         if (!((x == cw->x) && (y == cw->y)))
2321           {
2322              cw->x = x;
2323              cw->y = y;
2324              geo_changed = EINA_TRUE;
2325              if (!cw->needpix && !cw->move_lock)
2326                e_mod_comp_win_comp_objs_move(cw, cw->x, cw->y);
2327           }
2328         cw->hidden.x = x;
2329         cw->hidden.y = y;
2330      }
2331
2332    if (cw->border != border)
2333      {
2334         cw->border = border;
2335         geo_changed = EINA_TRUE;
2336         e_mod_comp_win_comp_objs_resize(cw,
2337                                   cw->pw + (cw->border * 2),
2338                                   cw->ph + (cw->border * 2));
2339      }
2340    cw->hidden.w = cw->w;
2341    cw->hidden.h = cw->h;
2342    if (geo_changed)
2343      e_mod_comp_win_shape_input_invalid_set(cw->c, 1);
2344    if ((cw->input_only) || (cw->invalid) || (cw->needpix)) return;
2345    _e_mod_comp_win_render_queue(cw);
2346    cw->pending_count++;
2347    e_manager_comp_event_src_config_send
2348      (cw->c->man, (E_Manager_Comp_Source *)cw,
2349      _e_mod_comp_cb_pending_after, cw->c);
2350 }
2351
2352 static void
2353 _e_mod_comp_win_damage(E_Comp_Win *cw,
2354                        int         x,
2355                        int         y,
2356                        int         w,
2357                        int         h,
2358                        Eina_Bool   dmg)
2359 {
2360    if ((cw->input_only) || (cw->invalid)) return;
2361    if ((dmg) && (cw->damage))
2362      {
2363         Ecore_X_Region parts;
2364         parts = ecore_x_region_new(NULL, 0);
2365         ecore_x_damage_subtract(cw->damage, 0, parts);
2366         ecore_x_region_free(parts);
2367         cw->dmg_updates++;
2368      }
2369    e_mod_comp_update_add(cw->up, x, y, w, h);
2370    if (dmg)
2371      {
2372         if (cw->counter)
2373           {
2374              if (!cw->update_timeout)
2375                cw->update_timeout = ecore_timer_add
2376                    (_comp_mod->conf->damage_timeout,
2377                    _e_mod_comp_win_damage_timeout, cw);
2378              return;
2379           }
2380      }
2381
2382    if ((dmg) &&
2383        (cw->dmg_updates <= 1))
2384      {
2385         if (!(cw->needpix))
2386           {
2387              L(LT_EVENT_X,
2388                "[COMP] %31s w:0x%08x bd:%s skip first damage.\n",
2389                "X_DAMAGE", e_mod_comp_util_client_xid_get(cw),
2390                cw->bd ? "O" : "X");
2391              return;
2392           }
2393      }
2394
2395    if (!cw->update)
2396      {
2397         cw->update = 1;
2398         cw->c->updates = eina_list_append(cw->c->updates, cw);
2399      }
2400    _e_mod_comp_win_render_queue(cw);
2401 }
2402
2403 static void
2404 _e_mod_comp_win_reshape(E_Comp_Win *cw)
2405 {
2406    if (cw->shape_changed) return;
2407    cw->shape_changed = 1;
2408    if (!cw->update)
2409      {
2410         cw->update = 1;
2411         cw->c->updates = eina_list_append(cw->c->updates, cw);
2412      }
2413    e_mod_comp_update_add(cw->up, 0, 0, cw->w, cw->h);
2414    _e_mod_comp_win_render_queue(cw);
2415 }
2416
2417 static Eina_Bool
2418 _e_mod_comp_create(void *data __UNUSED__,
2419                    int type   __UNUSED__,
2420                    void      *event)
2421 {
2422    Ecore_X_Event_Window_Create *ev = event;
2423    Eina_List *l;
2424    E_Comp_Win *cw;
2425    E_Comp_Canvas *canvas;
2426    E_Comp *c = _e_mod_comp_find(ev->parent);
2427    if (!c) return ECORE_CALLBACK_PASS_ON;
2428    if (_e_mod_comp_win_find(ev->win)) return ECORE_CALLBACK_PASS_ON;
2429    if (c->win == ev->win) return ECORE_CALLBACK_PASS_ON;
2430    EINA_LIST_FOREACH(c->canvases, l, canvas)
2431      {
2432         if (canvas->ee_win == ev->win) return ECORE_CALLBACK_PASS_ON;
2433      }
2434    L(LT_EVENT_X,
2435      "[COMP] ev:%15.15s w:0x%08x\n",
2436      "X_CREATE", ev->win);
2437    cw = _e_mod_comp_win_add(c, ev->win);
2438    if (cw)
2439      _e_mod_comp_win_configure(cw,
2440                                ev->x, ev->y,
2441                                ev->w, ev->h,
2442                                ev->border);
2443    return ECORE_CALLBACK_PASS_ON;
2444 }
2445
2446 static Eina_Bool
2447 _e_mod_comp_destroy(void *data __UNUSED__,
2448                     int type   __UNUSED__,
2449                     void      *event)
2450 {
2451    Ecore_X_Event_Window_Destroy *ev = event;
2452    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2453    if (!cw) return ECORE_CALLBACK_PASS_ON;
2454    L(LT_EVENT_X,
2455      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p\n",
2456      "X_DESTROY", ev->win, _e_mod_comp_win_is_border(cw),
2457      e_mod_comp_util_client_xid_get(cw), cw);
2458    if (!cw->c->nocomp && cw->animating) cw->delete_me = 1;
2459    else _e_mod_comp_win_del(cw);
2460    return ECORE_CALLBACK_PASS_ON;
2461 }
2462
2463 static Eina_Bool
2464 _e_mod_comp_show(void *data __UNUSED__,
2465                  int type   __UNUSED__,
2466                  void      *event)
2467 {
2468    Ecore_X_Event_Window_Show *ev = event;
2469    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2470    if (!cw) return ECORE_CALLBACK_PASS_ON;
2471    if (cw->visible) return ECORE_CALLBACK_PASS_ON;
2472    if (_e_mod_comp_win_is_border(cw)) return ECORE_CALLBACK_PASS_ON;
2473    L(LT_EVENT_X,
2474      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p\n",
2475      "X_SHOW", ev->win, _e_mod_comp_win_is_border(cw),
2476      e_mod_comp_util_client_xid_get(cw), cw);
2477    _e_mod_comp_win_show(cw);
2478    return ECORE_CALLBACK_PASS_ON;
2479 }
2480
2481 static Eina_Bool
2482 _e_mod_comp_hide(void *data __UNUSED__,
2483                  int type   __UNUSED__,
2484                  void      *event)
2485 {
2486    Ecore_X_Event_Window_Hide *ev = event;
2487    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2488    if (!cw) return ECORE_CALLBACK_PASS_ON;
2489    if (!cw->visible) return ECORE_CALLBACK_PASS_ON;
2490    if (_e_mod_comp_win_is_border(cw)) return ECORE_CALLBACK_PASS_ON;
2491    L(LT_EVENT_X,
2492      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p\n",
2493      "X_HIDE", ev->win, _e_mod_comp_win_is_border(cw),
2494      e_mod_comp_util_client_xid_get(cw), cw);
2495    _e_mod_comp_win_real_hide(cw);
2496    return ECORE_CALLBACK_PASS_ON;
2497 }
2498
2499 static Eina_Bool
2500 _e_mod_comp_reparent(void *data __UNUSED__,
2501                      int   type __UNUSED__,
2502                      void *event)
2503 {
2504    Ecore_X_Event_Window_Reparent *ev = event;
2505    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2506    if (!cw) return ECORE_CALLBACK_PASS_ON;
2507    L(LT_EVENT_X,
2508      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p TO rw:0x%08x\n",
2509      "X_REPARENT", ev->win, _e_mod_comp_win_is_border(cw),
2510      e_mod_comp_util_client_xid_get(cw), cw, ev->parent);
2511    if (ev->parent != cw->c->man->root)
2512      {
2513         L(LT_EVENT_X, "[COMP] %31s w:0x%08x\n", "DEL", ev->win);
2514         _e_mod_comp_win_del(cw);
2515      }
2516    return ECORE_CALLBACK_PASS_ON;
2517 }
2518
2519 static Eina_Bool
2520 _e_mod_comp_configure(void *data __UNUSED__,
2521                       int   type __UNUSED__,
2522                       void *event)
2523 {
2524    Ecore_X_Event_Window_Configure *ev = event;
2525    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2526    Eina_Bool need_shape_merge = EINA_FALSE;
2527    if (!cw) return ECORE_CALLBACK_PASS_ON;
2528    L(LT_EVENT_X,
2529      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p %4d %4d %3dx%3d\n",
2530      "X_CONFIGURE", ev->win, _e_mod_comp_win_is_border(cw),
2531      e_mod_comp_util_client_xid_get(cw), cw, ev->x, ev->y, ev->w, ev->h);
2532    if (ev->abovewin == 0)
2533      {
2534         if (EINA_INLIST_GET(cw)->prev)
2535           {
2536              L(LT_EVENT_X,
2537                "[COMP] %31s w:0x%08x\n",
2538                "LOWER", ev->win);
2539
2540              _e_mod_comp_win_lower(cw);
2541              need_shape_merge = EINA_TRUE;
2542           }
2543      }
2544    else
2545      {
2546         E_Comp_Win *cw2 = _e_mod_comp_win_find(ev->abovewin);
2547         if (cw2)
2548           {
2549              E_Comp_Win *cw3 = (E_Comp_Win *)(EINA_INLIST_GET(cw)->prev);
2550              if (cw3 != cw2)
2551                {
2552                   L(LT_EVENT_X,
2553                     "[COMP] %31s bd:%d above_w:0x%08x\n",
2554                     "RAISE_ABOVE", _e_mod_comp_win_is_border(cw2),
2555                     e_mod_comp_util_client_xid_get(cw2));
2556
2557                   _e_mod_comp_win_raise_above(cw, cw2);
2558                   need_shape_merge = EINA_TRUE;
2559                }
2560           }
2561      }
2562
2563    if (need_shape_merge)
2564      {
2565         e_mod_comp_win_shape_input_invalid_set(cw->c, 1);
2566         _e_mod_comp_win_render_queue(cw);
2567      }
2568
2569   if (!((cw->x == ev->x) && (cw->y == ev->y)) &&
2570       ((cw->w == ev->w) && (cw->h == ev->h)) &&
2571       _e_mod_comp_win_is_border(cw))
2572     {
2573        return ECORE_CALLBACK_PASS_ON;
2574     }
2575
2576    if (!((cw->x == ev->x) && (cw->y == ev->y) &&
2577          (cw->w == ev->w) && (cw->h == ev->h) &&
2578          (cw->border == ev->border)))
2579      {
2580         _e_mod_comp_win_configure(cw,
2581                                   ev->x, ev->y,
2582                                   ev->w, ev->h,
2583                                   ev->border);
2584      }
2585    return ECORE_CALLBACK_PASS_ON;
2586 }
2587
2588 static Eina_Bool
2589 _e_mod_comp_stack(void *data __UNUSED__,
2590                   int type __UNUSED__,
2591                   void *event)
2592 {
2593    Ecore_X_Event_Window_Stack *ev = event;
2594    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2595    L(LT_EVENT_X,
2596      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p\n",
2597      "X_STACK", ev->win, _e_mod_comp_win_is_border(cw), e_mod_comp_util_client_xid_get(cw), cw);
2598    if (!cw) return ECORE_CALLBACK_PASS_ON;
2599    if (ev->detail == ECORE_X_WINDOW_STACK_ABOVE) _e_mod_comp_win_raise(cw);
2600    else _e_mod_comp_win_lower(cw);
2601    return ECORE_CALLBACK_PASS_ON;
2602 }
2603
2604 static Eina_Bool
2605 _e_mod_comp_prop_effect_state(Ecore_X_Event_Window_Property *ev __UNUSED__)
2606 {
2607    E_Comp *c;
2608    unsigned int val;
2609    int ret;
2610
2611    c = e_mod_comp_util_get();
2612    E_CHECK_RETURN(c, 0);
2613
2614    ret = ecore_x_window_prop_card32_get
2615            (c->man->root, ATOM_EFFECT_ENABLE, &val, 1);
2616    E_CHECK_RETURN((ret >= 0), 0);
2617
2618    if (val != 0)
2619      {
2620         c->animatable = EINA_TRUE;
2621         if (_comp_mod->conf->default_window_effect != 1)
2622           {
2623              _comp_mod->conf->default_window_effect = 1;
2624              e_config_domain_save("module.comp-slp",
2625                                   _comp_mod->conf_edd,
2626                                   _comp_mod->conf);
2627
2628           }
2629      }
2630    else
2631      {
2632         c->animatable = EINA_FALSE;
2633         if (_comp_mod->conf->default_window_effect != 0)
2634           {
2635              _comp_mod->conf->default_window_effect = 0;
2636              e_config_domain_save("module.comp-slp",
2637                                   _comp_mod->conf_edd,
2638                                   _comp_mod->conf);
2639           }
2640      }
2641
2642    L(LT_EVENT_X,
2643      "[COMP] %31s c->animatable:%d\n",
2644      "ATOM_EFFECT_ENABLE",
2645      c->animatable);
2646
2647    return EINA_TRUE;
2648 }
2649
2650 static Eina_Bool
2651 _e_mod_comp_prop_window_effect_state(Ecore_X_Event_Window_Property *ev)
2652 {
2653    E_Comp_Win *cw = NULL;
2654    Ecore_X_Window w = 0;
2655    E_CHECK_RETURN(ev, 0);
2656
2657    cw = _e_mod_comp_win_find(ev->win);
2658    if (!cw)
2659      {
2660         cw = _e_mod_comp_border_client_find(ev->win);
2661         E_CHECK_RETURN(cw, 0);
2662      }
2663
2664    E_CHECK_RETURN(cw->eff_type, 0);
2665
2666    w = e_mod_comp_util_client_xid_get(cw);
2667    e_mod_comp_effect_state_setup(cw->eff_type, w);
2668
2669    return EINA_TRUE;
2670 }
2671
2672 static Eina_Bool
2673 _e_mod_comp_prop_effect_style(Ecore_X_Event_Window_Property *ev)
2674 {
2675    E_Comp_Win *cw = NULL;
2676    Ecore_X_Window w = 0;
2677    E_CHECK_RETURN(ev, 0);
2678
2679    cw = _e_mod_comp_win_find(ev->win);
2680    if (!cw)
2681      {
2682         cw = _e_mod_comp_border_client_find(ev->win);
2683         E_CHECK_RETURN(cw, 0);
2684      }
2685
2686    E_CHECK_RETURN(cw->eff_type, 0);
2687
2688    w = e_mod_comp_util_client_xid_get(cw);
2689    e_mod_comp_effect_style_setup(cw->eff_type, w);
2690
2691    return EINA_TRUE;
2692 }
2693
2694 static Eina_Bool
2695 _e_mod_comp_prop_opacity(Ecore_X_Event_Window_Property *ev)
2696 {
2697    E_Comp_Win *cw = NULL;
2698    unsigned int val = 0;
2699    int ret = -1;
2700
2701    cw = _e_mod_comp_win_find(ev->win);
2702    if (!cw)
2703      {
2704         cw = _e_mod_comp_border_client_find(ev->win);
2705         E_CHECK_RETURN(cw, 0);
2706      }
2707
2708    ret = ecore_x_window_prop_card32_get
2709            (cw->win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, &val, 1);
2710    E_CHECK_RETURN((ret > 0), 0);
2711
2712    cw->opacity = (val >> 24);
2713
2714    Eina_List *l;
2715    E_Comp_Object *co;
2716    EINA_LIST_FOREACH(cw->objs, l, co)
2717      {
2718         evas_object_color_set(co->shadow,
2719                               cw->opacity,
2720                               cw->opacity,
2721                               cw->opacity,
2722                               cw->opacity);
2723      }
2724    return EINA_TRUE;
2725 }
2726
2727 static Eina_Bool
2728 _e_mod_comp_prop_illume_window_state(Ecore_X_Event_Window_Property *ev)
2729 {
2730    E_Comp_Win *cw = NULL;
2731    unsigned int state;
2732
2733    cw = _e_mod_comp_border_client_find(ev->win);
2734    E_CHECK_RETURN(cw, 0);
2735    E_CHECK_RETURN((cw->bd), 0);
2736
2737    state = cw->bd->client.illume.win_state.state;
2738    switch (state)
2739      {
2740       case ECORE_X_ILLUME_WINDOW_STATE_FLOATING:
2741          e_mod_comp_effect_signal_add
2742             (cw, NULL, "e,state,shadow,on", "e");
2743          break;
2744       case ECORE_X_ILLUME_WINDOW_STATE_NORMAL:
2745       default:
2746          e_mod_comp_effect_signal_add
2747             (cw, NULL, "e,state,shadow,off", "e");
2748          break;
2749      }
2750    return EINA_TRUE;
2751 }
2752
2753 static Eina_Bool
2754 _e_mod_comp_prop_sync_counter(Ecore_X_Event_Window_Property *ev)
2755 {
2756    E_Comp_Win *cw = NULL;
2757    cw = _e_mod_comp_win_find(ev->win);
2758    if (!cw) cw = _e_mod_comp_border_client_find(ev->win);
2759
2760    Ecore_X_Sync_Counter counter = ecore_x_e_comp_sync_counter_get(ev->win);
2761    if (cw)
2762      {
2763         if (cw->counter != counter)
2764           {
2765              Ecore_X_Window _w = e_mod_comp_util_client_xid_get(cw);
2766              if (cw->counter)
2767                {
2768                   ecore_x_e_comp_sync_cancel_send(_w);
2769                   ecore_x_sync_counter_inc(cw->counter, 1);
2770                   cw->sync_info.val++;
2771                }
2772              cw->counter = counter;
2773              if (cw->counter)
2774                {
2775                   ecore_x_sync_counter_inc(cw->counter, 1);
2776                   ecore_x_e_comp_sync_begin_send(_w);
2777                   cw->sync_info.val = 1;
2778                }
2779           }
2780      }
2781    else
2782      {
2783         if (counter) ecore_x_sync_counter_inc(counter, 1);
2784      }
2785    return EINA_TRUE;
2786 }
2787
2788 static Eina_Bool
2789 _e_mod_comp_prop_window_use_dri2_get(Ecore_X_Window win)
2790 {
2791    unsigned int val = 0;
2792    int ret = ecore_x_window_prop_card32_get(win,
2793                                             ATOM_X_WIN_USE_DRI2,
2794                                             &val,
2795                                             1);
2796    if (ret == -1) return EINA_FALSE;
2797
2798    return val ? EINA_TRUE : EINA_FALSE;
2799 }
2800
2801 static Eina_Bool
2802 _e_mod_comp_prop_use_dri2(Ecore_X_Event_Window_Property *ev)
2803 {
2804    E_Comp_Win *cw = NULL;
2805    Ecore_X_Window win;
2806    cw = _e_mod_comp_win_find(ev->win);
2807    if (!cw)
2808      {
2809         cw = _e_mod_comp_border_client_find(ev->win);
2810         E_CHECK_RETURN(cw, 0);
2811      }
2812
2813    win = e_mod_comp_util_client_xid_get(cw);
2814    cw->use_dri2 = _e_mod_comp_prop_window_use_dri2_get(win);
2815
2816    return EINA_TRUE;
2817 }
2818
2819 static Eina_Bool
2820 _e_mod_comp_property(void *data __UNUSED__,
2821                      int type __UNUSED__,
2822                      void *event __UNUSED__)
2823 {
2824    Ecore_X_Event_Window_Property *ev = event;
2825    Ecore_X_Atom a = 0;
2826    if (!ev) return ECORE_CALLBACK_PASS_ON;
2827    if (!ev->atom) return ECORE_CALLBACK_PASS_ON;
2828    if (!e_mod_comp_atoms_name_get(ev->atom)) return ECORE_CALLBACK_PASS_ON;
2829    a = ev->atom;
2830
2831    L(LT_EVENT_X,
2832      "[COMP] ev:%15.15s w:0x%08x atom:%s\n",
2833      "X_PROPERTY", ev->win,
2834      e_mod_comp_atoms_name_get(a));
2835
2836    if      (a == ECORE_X_ATOM_E_COMP_SYNC_COUNTER         ) _e_mod_comp_prop_sync_counter(ev);
2837    else if (a == ATOM_X_WIN_USE_DRI2                      ) _e_mod_comp_prop_use_dri2(ev);
2838    else if (a == ATOM_EFFECT_ENABLE                       ) _e_mod_comp_prop_effect_state(ev);
2839    else if (a == ATOM_WINDOW_EFFECT_ENABLE                ) _e_mod_comp_prop_window_effect_state(ev);
2840    else if (a == ATOM_WINDOW_EFFECT_TYPE                  ) _e_mod_comp_prop_effect_style(ev);
2841    else if (a == ECORE_X_ATOM_NET_WM_WINDOW_OPACITY       ) _e_mod_comp_prop_opacity(ev);
2842    else if (a == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE       ) _e_mod_comp_prop_illume_window_state(ev);
2843    else if (a == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE) e_mod_comp_effect_win_rotation_handler_prop(ev);
2844    else if (a == ECORE_X_ATOM_WM_CLASS                    ) e_mod_comp_win_type_handler_prop(ev);
2845    else if (a == ATOM_NET_CM_WINDOW_BACKGROUND            ) e_mod_comp_bg_win_handler_prop(ev);
2846    else if (a == ATOM_CM_LOG                              ) e_mod_comp_debug_prop_handle(ev);
2847
2848    return ECORE_CALLBACK_PASS_ON;
2849 }
2850
2851 static Eina_Bool
2852 _e_mod_comp_msg_sync_draw_done(Ecore_X_Event_Client_Message *ev)
2853 {
2854    E_Comp_Win *cw = NULL;
2855    int v = 0, w = 0, h = 0;
2856    cw = _e_mod_comp_border_client_find(ev->data.l[0]);
2857    v = ev->data.l[1];
2858    w = ev->data.l[2];
2859    h = ev->data.l[3];
2860    if (cw)
2861      {
2862         cw->sync_info.version = v;
2863         if (!cw->bd) return EINA_FALSE;
2864         if ((Ecore_X_Window)(ev->data.l[0]) != cw->bd->client.win) return EINA_FALSE;
2865      }
2866    else
2867      {
2868         cw = _e_mod_comp_win_find(ev->data.l[0]);
2869         if (!cw || (ev->data.l[0] != (int)cw->win))
2870           {
2871              Ecore_X_Sync_Counter counter = ecore_x_e_comp_sync_counter_get(ev->win);
2872              ecore_x_e_comp_sync_cancel_send(ev->win);
2873              if (counter) ecore_x_sync_counter_inc(counter, 1);
2874              L(LT_EVENT_X,
2875                "[COMP] ev:%15.15s w:0x%08x type:%s !cw v%d %03dx%03d\n",
2876                "X_CLIENT_MSG", ev->win, "SYNC_DRAW_DONE", v, w, h);
2877              return EINA_FALSE;
2878           }
2879      }
2880    if (!cw->counter)
2881      {
2882         cw->counter = ecore_x_e_comp_sync_counter_get(e_mod_comp_util_client_xid_get(cw));
2883         if (cw->counter)
2884           {
2885              ecore_x_sync_counter_inc(cw->counter, 1);
2886              ecore_x_e_comp_sync_begin_send(e_mod_comp_util_client_xid_get(cw));
2887              cw->sync_info.val = 1;
2888              cw->sync_info.done_count = 1;
2889           }
2890         L(LT_EVENT_X,
2891           "[COMP] ev:%15.15s w:0x%08x type:%s !cw->counter v%d %03dx%03d\n",
2892           "X_CLIENT_MSG", e_mod_comp_util_client_xid_get(cw),
2893           "SYNC_DRAW_DONE", v, w, h);
2894         return EINA_FALSE;
2895      }
2896
2897    if ((_comp_mod->conf->efl_sync) &&
2898        (_comp_mod->conf->nocomp_fs) &&
2899        (cw->nocomp))
2900      {
2901         ecore_x_sync_counter_inc(cw->counter, 1);
2902         cw->update = 0;
2903         cw->drawme = 0;
2904         cw->sync_info.done_count++;
2905         cw->sync_info.val++;
2906
2907         L(LT_EVENT_X,
2908           "[COMP] ev:%15.15s w:0x%08x type:%s v%d %03dx%03d NOCOMP INC done:%d val:%d\n",
2909           "X_CLIENT_MSG", e_mod_comp_util_client_xid_get(cw),
2910           "SYNC_DRAW_DONE", v, w, h, cw->sync_info.done_count,
2911           cw->sync_info.val);
2912
2913         return EINA_TRUE;
2914      }
2915
2916    if (!cw->update)
2917      {
2918         if (cw->update_timeout)
2919           {
2920              ecore_timer_del(cw->update_timeout);
2921              cw->update_timeout = NULL;
2922           }
2923         cw->update = 1;
2924         cw->c->updates = eina_list_append(cw->c->updates, cw);
2925      }
2926
2927    cw->drawme = 1;
2928    cw->sync_info.done_count++;
2929
2930    L(LT_EVENT_X,
2931      "[COMP] ev:%15.15s w:0x%08x type:%s v%d %03dx%03d\n",
2932      "X_CLIENT_MSG", e_mod_comp_util_client_xid_get(cw),
2933      "SYNC_DRAW_DONE", v, w, h);
2934
2935    _e_mod_comp_win_render_queue(cw);
2936    return EINA_TRUE;
2937 }
2938
2939 static Eina_Bool
2940 _e_mod_comp_hib_leave(Ecore_X_Event_Client_Message *ev)
2941 {
2942    E_Comp *c;
2943    Config *cfg;
2944
2945    E_CHECK_RETURN(ev, 0);
2946    E_CHECK_RETURN((ev->data.l[0] == 0), 0);
2947    E_CHECK_RETURN(_comp_mod, 0);
2948
2949    c = _e_mod_comp_find(ev->win);
2950    E_CHECK_RETURN(c, 0);
2951
2952    cfg = e_config_domain_load("module.comp-slp",
2953                               _comp_mod->conf_edd);
2954    E_CHECK_RETURN(cfg, 0);
2955
2956    if (cfg->default_window_effect != c->animatable)
2957      {
2958         if (cfg->default_window_effect)
2959           {
2960              c->animatable = EINA_TRUE;
2961              _comp_mod->conf->default_window_effect = 1;
2962           }
2963         else
2964           {
2965              c->animatable = EINA_FALSE;
2966              _comp_mod->conf->default_window_effect = 0;
2967           }
2968         ecore_x_window_prop_card32_set
2969            (c->man->root, ATOM_EFFECT_ENABLE,
2970            (unsigned int *)(&(_comp_mod->conf->default_window_effect)), 1);
2971      }
2972
2973    if (cfg->shadow_file) eina_stringshare_del(cfg->shadow_file);
2974    if (cfg->shadow_style) eina_stringshare_del(cfg->shadow_style);
2975
2976    free(cfg);
2977    return EINA_TRUE;
2978 }
2979
2980 static Eina_Bool
2981 _e_mod_comp_message(void *data __UNUSED__,
2982                     int   type __UNUSED__,
2983                     void *event)
2984 {
2985    Ecore_X_Event_Client_Message *ev;
2986    Ecore_X_Atom t;
2987    ev = (Ecore_X_Event_Client_Message *)event;
2988
2989    E_CHECK_RETURN(ev, 0);
2990    E_CHECK_RETURN((ev->format == 32), 0);
2991
2992    t = ev->message_type;
2993
2994    if      (t == ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE) _e_mod_comp_msg_sync_draw_done(ev);
2995    else if (t == ATOM_CM_LOCK_SCREEN               ) e_mod_comp_screen_lock_handler_message(ev);
2996    else if (t == ATOM_X_HIBERNATION_STATE          ) _e_mod_comp_hib_leave(ev);
2997
2998    return ECORE_CALLBACK_PASS_ON;
2999 }
3000
3001 static Eina_Bool
3002 _e_mod_comp_shape(void *data __UNUSED__,
3003                   int type __UNUSED__,
3004                   void *event)
3005 {
3006    Ecore_X_Event_Window_Shape *ev = event;
3007    E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
3008    if (!cw) return ECORE_CALLBACK_PASS_ON;
3009    if (ev->type != ECORE_X_SHAPE_BOUNDING) return ECORE_CALLBACK_PASS_ON;
3010    L(LT_EVENT_X,
3011      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p\n",
3012      "X_SHAPE", ev->win, _e_mod_comp_win_is_border(cw),
3013      e_mod_comp_util_client_xid_get(cw), cw);
3014    _e_mod_comp_win_reshape(cw);
3015    return ECORE_CALLBACK_PASS_ON;
3016 }
3017
3018 static Eina_Bool
3019 _e_mod_comp_damage(void *data __UNUSED__,
3020                    int type __UNUSED__,
3021                    void *event)
3022 {
3023    Ecore_X_Event_Damage *ev = event;
3024    E_Comp_Win *cw = _e_mod_comp_win_damage_find(ev->damage);
3025
3026    L(LT_EVENT_X,
3027      "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p %4d %4d %3dx%3d\n",
3028      "X_DAMAGE", ev->drawable, _e_mod_comp_win_is_border(cw),
3029      e_mod_comp_util_client_xid_get(cw), cw,
3030      ev->area.x, ev->area.y, ev->area.width, ev->area.height);
3031
3032    if (!cw)
3033      {
3034         L(LT_EVENT_X,
3035           "[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p %4d %4d %3dx%3d ERR1\n",
3036           "X_DAMAGE", ev->drawable, _e_mod_comp_win_is_border(cw),
3037           e_mod_comp_util_client_xid_get(cw), cw,
3038           ev->area.x, ev->area.y, ev->area.width, ev->area.height);
3039
3040         cw = _e_mod_comp_border_client_find(ev->drawable);
3041
3042         if (!cw)
3043           {
3044              L(LT_EVENT_X,"[COMP] ev:%15.15s w:0x%08x bd:%d c:0x%08x cw:%p %4d %4d %3dx%3d ERR2\n",
3045                "X_DAMAGE", ev->drawable, _e_mod_comp_win_is_border(cw),
3046                e_mod_comp_util_client_xid_get(cw), cw,
3047                ev->area.x, ev->area.y, ev->area.width, ev->area.height);
3048              return ECORE_CALLBACK_PASS_ON;
3049           }
3050      }
3051
3052    _e_mod_comp_win_damage(cw,
3053                           ev->area.x, ev->area.y,
3054                           ev->area.width, ev->area.height, 1);
3055    return ECORE_CALLBACK_PASS_ON;
3056 }
3057
3058 static Eina_Bool
3059 _e_mod_comp_damage_win(void *data __UNUSED__,
3060                        int   type __UNUSED__,
3061                        void *event)
3062 {
3063    Ecore_X_Event_Window_Damage *ev = event;
3064    Eina_List *l, *ll;
3065    E_Comp *c;
3066    E_Comp_Canvas *canvas;
3067
3068    L(LT_EVENT_X, "[COMP] ev:%15.15s w:0x%08x\n", "WINDOW_DAMAGE", ev->win);
3069
3070    // fixme: use hash if compositors list > 4
3071    EINA_LIST_FOREACH(compositors, l, c)
3072      {
3073         if (!c) continue;
3074         EINA_LIST_FOREACH(c->canvases, ll, canvas)
3075           {
3076              if (!canvas) continue;
3077              if (ev->win == canvas->ee_win)
3078                {
3079                   // expose on comp win - init win or some other bypass win did it
3080                   _e_mod_comp_render_queue(c);
3081                   break;
3082                }
3083           }
3084      }
3085    return ECORE_CALLBACK_PASS_ON;
3086 }
3087
3088 static Eina_Bool
3089 _e_mod_comp_randr(void *data  __UNUSED__,
3090                   int type    __UNUSED__,
3091                   void *event __UNUSED__)
3092 {
3093    Eina_List *l;
3094    E_Comp *c;
3095    E_Comp_Canvas *canvas;
3096
3097    L(LT_EVENT_X,
3098      "[COMP] ev:%15.15s\n",
3099      "E_CONTNR_RESIZE");
3100
3101    if (_comp_mod->conf->canvas_per_zone)
3102      return ECORE_CALLBACK_PASS_ON;
3103
3104    EINA_LIST_FOREACH(compositors, l, c)
3105      {
3106         if (!c) continue;
3107         canvas = eina_list_data_get(c->canvases);
3108         if (!canvas) continue;
3109         ecore_evas_resize(canvas->ee,
3110                           c->man->w,
3111                           c->man->h);
3112      }
3113    return ECORE_CALLBACK_PASS_ON;
3114 }
3115
3116 static Eina_Bool
3117 _e_mod_comp_bd_add(void *data __UNUSED__,
3118                    int type   __UNUSED__,
3119                    void      *event)
3120 {
3121    E_Event_Border_Add *ev = event;
3122    Eina_List *l;
3123    E_Comp_Win *cw;
3124    E_Comp_Canvas *canvas;
3125    E_Comp* c = _e_mod_comp_find(ev->border->zone->container->manager->root);
3126
3127    L(LT_EVENT_X,
3128      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_ADD",
3129      ev->border->win, ev->border->client.win);
3130
3131    if (!c) return ECORE_CALLBACK_PASS_ON;
3132    if (_e_mod_comp_win_find(ev->border->win)) return ECORE_CALLBACK_PASS_ON;
3133    if (c->win == ev->border->win) return ECORE_CALLBACK_PASS_ON;
3134    EINA_LIST_FOREACH(c->canvases, l, canvas)
3135      {
3136         if (canvas->ee_win == ev->border->win) return ECORE_CALLBACK_PASS_ON;
3137      }
3138    cw = _e_mod_comp_win_add(c, ev->border->win);
3139    if (cw)
3140      _e_mod_comp_win_configure
3141        (cw, ev->border->x, ev->border->y,
3142        ev->border->w, ev->border->h,
3143        ev->border->client.initial_attributes.border);
3144
3145    if (ev->border->internal && ev->border->visible)
3146      _e_mod_comp_win_show(cw);
3147
3148    if (!ev->border->borderless)
3149      e_mod_comp_effect_signal_add(cw, NULL, "e,state,shadow,on", "e");
3150
3151    return ECORE_CALLBACK_PASS_ON;
3152 }
3153
3154 static Eina_Bool
3155 _e_mod_comp_bd_del(void *data __UNUSED__,
3156                    int type   __UNUSED__,
3157                    void      *event)
3158 {
3159    E_Event_Border_Remove *ev = event;
3160    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3161
3162    L(LT_EVENT_X,
3163      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_DEL",
3164      ev->border->win, ev->border->client.win);
3165
3166    if (!cw) return ECORE_CALLBACK_PASS_ON;
3167    if (cw->bd == ev->border)
3168      {
3169         if (!ev->border->borderless)
3170           e_mod_comp_effect_signal_add(cw, NULL, "e,state,shadow,off", "e");
3171
3172         _e_mod_comp_object_del(cw, ev->border);
3173      }
3174    return ECORE_CALLBACK_PASS_ON;
3175 }
3176
3177 static Eina_Bool
3178 _e_mod_comp_bd_show(void *data __UNUSED__,
3179                     int type   __UNUSED__,
3180                     void      *event)
3181 {
3182    E_Event_Border_Show *ev = event;
3183    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3184
3185    L(LT_EVENT_X,
3186      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_SHOW",
3187      ev->border->win, ev->border->client.win);
3188
3189    if (!cw) return ECORE_CALLBACK_PASS_ON;
3190    if (cw->visible) return ECORE_CALLBACK_PASS_ON;
3191    _e_mod_comp_win_show(cw);
3192
3193    if (_comp_mod->conf->use_hw_ov &&
3194        TYPE_INDICATOR_CHECK(cw))
3195      {
3196         Eina_List *l;
3197         E_Comp_Canvas *canvas;
3198         EINA_LIST_FOREACH(cw->c->canvases, l, canvas)
3199           {
3200              if (!canvas) continue;
3201              if (!canvas->ov) continue;
3202              e_mod_comp_hw_ov_win_update(canvas->ov, cw);
3203              break;
3204           }
3205      }
3206
3207    return ECORE_CALLBACK_PASS_ON;
3208 }
3209
3210 static Eina_Bool
3211 _e_mod_comp_bd_hide(void *data __UNUSED__,
3212                     int type   __UNUSED__,
3213                     void      *event)
3214 {
3215    E_Event_Border_Hide *ev = event;
3216    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3217
3218    L(LT_EVENT_X,
3219      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_HIDE",
3220      ev->border->win, ev->border->client.win);
3221
3222    if (!cw) return ECORE_CALLBACK_PASS_ON;
3223    if (!cw->visible) return ECORE_CALLBACK_PASS_ON;
3224    _e_mod_comp_win_hide(cw);
3225
3226    if (_comp_mod->conf->use_hw_ov &&
3227        TYPE_INDICATOR_CHECK(cw))
3228      {
3229         Eina_List *l;
3230         E_Comp_Canvas *canvas;
3231         EINA_LIST_FOREACH(cw->c->canvases, l, canvas)
3232           {
3233              if (!canvas) continue;
3234              if (!canvas->ov) continue;
3235              e_mod_comp_hw_ov_win_hide(canvas->ov, cw);
3236           }
3237      }
3238    return ECORE_CALLBACK_PASS_ON;
3239 }
3240
3241 static Eina_Bool
3242 _e_mod_comp_bd_move(void *data __UNUSED__,
3243                     int type   __UNUSED__,
3244                     void      *event)
3245 {
3246    E_Event_Border_Move *ev = event;
3247    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3248    if (!cw) return ECORE_CALLBACK_PASS_ON;
3249
3250    L(LT_EVENT_X,
3251      "[COMP] ev:%15.15s w:0x%08x c:0x%08x v:%d \
3252       cw[%d,%d] hidden[%d,%d] ev[%d,%d]\n", "BD_MOVE",
3253      ev->border->win, ev->border->client.win, cw->visible,
3254      cw->x, cw->y, cw->hidden.x, cw->hidden.y,
3255      ev->border->x, ev->border->y);
3256
3257    if (!((cw->x == ev->border->x) &&
3258          (cw->y == ev->border->y)) &&
3259        (cw->visible))
3260      {
3261         _e_mod_comp_win_configure
3262           (cw, ev->border->x, ev->border->y,
3263           ev->border->w, ev->border->h, 0);
3264      }
3265    else if (!((cw->hidden.x == ev->border->x) &&
3266               (cw->hidden.y == ev->border->y)) &&
3267             (!cw->visible))
3268      {
3269         _e_mod_comp_win_configure
3270           (cw, ev->border->x, ev->border->y,
3271           ev->border->w, ev->border->h, 0);
3272      }
3273    return ECORE_CALLBACK_PASS_ON;
3274 }
3275
3276 static Eina_Bool
3277 _e_mod_comp_bd_resize(void *data __UNUSED__,
3278                       int type   __UNUSED__,
3279                       void      *event)
3280 {
3281    E_Event_Border_Resize *ev = event;
3282    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3283
3284    L(LT_EVENT_X,
3285      "[COMP] ev:%15.15s w:0x%08x c:0x%08x ev:%4dx%4d\n",
3286      "BD_RESIZE", ev->border->win, ev->border->client.win,
3287      ev->border->w, ev->border->h);
3288
3289    if (!cw) return ECORE_CALLBACK_PASS_ON;
3290    if ((cw->w == ev->border->w) && (cw->h == ev->border->h))
3291      return ECORE_CALLBACK_PASS_ON;
3292    _e_mod_comp_win_configure
3293      (cw, cw->x, cw->y,
3294      ev->border->w, ev->border->h, cw->border);
3295    return ECORE_CALLBACK_PASS_ON;
3296 }
3297
3298 static Eina_Bool
3299 _e_mod_comp_bd_iconify(void *data __UNUSED__,
3300                        int type   __UNUSED__,
3301                        void      *event)
3302 {
3303    E_Event_Border_Iconify *ev = event;
3304    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3305
3306    L(LT_EVENT_X,
3307      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_ICONIFY",
3308      ev->border->win, ev->border->client.win);
3309
3310    if (!cw) return ECORE_CALLBACK_PASS_ON;
3311    // fimxe: special iconfiy anim
3312    return ECORE_CALLBACK_PASS_ON;
3313 }
3314
3315 static Eina_Bool
3316 _e_mod_comp_bd_uniconify(void *data __UNUSED__,
3317                          int type   __UNUSED__,
3318                          void      *event)
3319 {
3320    E_Event_Border_Uniconify *ev = event;
3321    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3322
3323    L(LT_EVENT_X,
3324      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_UNICONIFY",
3325      ev->border->win, ev->border->client.win);
3326
3327    if (!cw) return ECORE_CALLBACK_PASS_ON;
3328    // fimxe: special uniconfiy anim
3329    return ECORE_CALLBACK_PASS_ON;
3330 }
3331
3332 static Eina_Bool
3333 _e_mod_comp_bd_urgent_change(void *data __UNUSED__,
3334                              int type   __UNUSED__,
3335                              void      *event)
3336 {
3337    E_Event_Border_Urgent_Change *ev = event;
3338    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3339
3340    L(LT_EVENT_X, "[COMP] ev:%15.15s w:0x%08x\n",
3341      "URGENT_CHANGE", ev->border ? ev->border->win : 0);
3342
3343    if (!cw) return ECORE_CALLBACK_PASS_ON;
3344    if (cw->bd->client.icccm.urgent)
3345      e_mod_comp_effect_signal_add(cw, NULL, "e,state,urgent,on", "e");
3346    else
3347      e_mod_comp_effect_signal_add(cw, NULL, "e,state,urgent,off", "e");
3348    return ECORE_CALLBACK_PASS_ON;
3349 }
3350
3351 static Eina_Bool
3352 _e_mod_comp_bd_focus_in(void *data __UNUSED__,
3353                         int type   __UNUSED__,
3354                         void      *event)
3355 {
3356    E_Event_Border_Focus_In *ev = event;
3357    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3358
3359    L(LT_EVENT_X,
3360      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_FOCUS_IN",
3361      ev->border->win, ev->border->client.win);
3362
3363    if (!cw) return ECORE_CALLBACK_PASS_ON;
3364    e_mod_comp_effect_signal_add(cw, NULL, "e,state,focus,on", "e");
3365    return ECORE_CALLBACK_PASS_ON;
3366 }
3367
3368 static Eina_Bool
3369 _e_mod_comp_bd_focus_out(void *data __UNUSED__,
3370                          int type   __UNUSED__,
3371                          void      *event)
3372 {
3373    E_Event_Border_Focus_Out *ev = event;
3374    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3375
3376    L(LT_EVENT_X,
3377      "[COMP] ev:%15.15s w:0x%08x c:0x%08x\n", "BD_FOCUS_OUT",
3378      ev->border->win, ev->border->client.win);
3379
3380    if (!cw) return ECORE_CALLBACK_PASS_ON;
3381    e_mod_comp_effect_signal_add(cw, NULL, "e,state,focus,off", "e");
3382    return ECORE_CALLBACK_PASS_ON;
3383 }
3384
3385 static Eina_Bool
3386 _e_mod_comp_bd_property(void *data __UNUSED__,
3387                         int type   __UNUSED__,
3388                         void      *event)
3389 {
3390    E_Event_Border_Property *ev = event;
3391    E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
3392    if (!cw) return ECORE_CALLBACK_PASS_ON;
3393    // fimxe: other properties?
3394    return ECORE_CALLBACK_PASS_ON;
3395 }
3396
3397 static Eina_Bool
3398 _e_mod_comp_key_down(void *data __UNUSED__,
3399                      int type   __UNUSED__,
3400                      void      *event)
3401 {
3402    Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
3403    E_CHECK_RETURN(ev, 0);
3404
3405    if ((!strcmp(ev->keyname, "Home")) &&
3406        (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) &&
3407        (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
3408        (ev->modifiers & ECORE_EVENT_MODIFIER_ALT))
3409      {
3410         if (_comp_mod)
3411           {
3412              _e_mod_config_free(_comp_mod->module);
3413              _e_mod_config_new(_comp_mod->module);
3414              e_config_save();
3415              e_module_disable(_comp_mod->module);
3416              e_config_save();
3417              e_sys_action_do(E_SYS_RESTART, NULL);
3418           }
3419      }
3420    return ECORE_CALLBACK_PASS_ON;
3421 }
3422
3423 //////////////////////////////////////////////////////////////////////////
3424 static Evas *
3425 _e_mod_comp_evas_get_func(void          *data,
3426                           E_Manager *man __UNUSED__)
3427 {
3428    E_Comp *c = (E_Comp *)data;
3429    Eina_List *l;
3430    E_Comp_Canvas *canvas;
3431    E_Zone *z;
3432    E_CHECK_RETURN(c, 0);
3433
3434    z = e_util_zone_current_get(c->man);
3435    EINA_LIST_FOREACH(c->canvases, l, canvas)
3436      {
3437         if (!_comp_mod->conf->canvas_per_zone)
3438           return canvas->evas;
3439         else if ((canvas->zone) && (canvas->zone == z))
3440           return canvas->evas;
3441      }
3442    return NULL;
3443 }
3444
3445 static void
3446 _e_mod_comp_update_func(void          *data,
3447                         E_Manager *man __UNUSED__)
3448 {
3449    E_Comp *c = (E_Comp *)data;
3450    E_CHECK(c);
3451    _e_mod_comp_render_queue(c);
3452 }
3453
3454 static E_Manager_Comp_Source *
3455 _e_mod_comp_src_get_func(void           *data __UNUSED__,
3456                          E_Manager      *man __UNUSED__,
3457                          Ecore_X_Window  win)
3458 {
3459    return (E_Manager_Comp_Source *)_e_mod_comp_win_find(win);
3460 }
3461
3462 static const Eina_List *
3463 _e_mod_comp_src_list_get_func(void          *data,
3464                               E_Manager *man __UNUSED__)
3465 {
3466    E_Comp *c = (E_Comp *)data;
3467    E_Comp_Win *cw;
3468    Eina_List *l;
3469    E_Comp_Object *co;
3470    E_CHECK_RETURN(c, 0);
3471    E_CHECK_RETURN(c->wins, 0);
3472
3473    // source list should always be updated if multi-canvas is enabled.
3474    if (_comp_mod->conf->canvas_per_zone)
3475      {
3476         if (c->wins_invalid) c->wins_invalid = 0;
3477         if (c->wins_list)
3478           {
3479              eina_list_free(c->wins_list);
3480              c->wins_list = NULL;
3481           }
3482         E_Zone *z = e_util_zone_current_get(c->man);
3483         EINA_INLIST_FOREACH(c->wins, cw)
3484           {
3485              EINA_LIST_FOREACH(cw->objs, l, co)
3486                {
3487                   if ((co->shadow) && (co->img) && (z == co->zone))
3488                     c->wins_list = eina_list_append(c->wins_list, cw);
3489                }
3490           }
3491      }
3492    else
3493      {
3494         if (c->wins_invalid)
3495           {
3496              c->wins_invalid = 0;
3497              if (c->wins_list)
3498                {
3499                   eina_list_free(c->wins_list);
3500                   c->wins_list = NULL;
3501                }
3502              EINA_INLIST_FOREACH(c->wins, cw)
3503                {
3504                   EINA_LIST_FOREACH(cw->objs, l, co)
3505                     {
3506                        if ((co->shadow) && (co->img))
3507                          c->wins_list = eina_list_append(c->wins_list, cw);
3508                     }
3509                }
3510           }
3511      }
3512    return c->wins_list;
3513 }
3514
3515 static Evas_Object *
3516 _e_mod_comp_src_image_get_func(void                  *data,
3517                                E_Manager *man         __UNUSED__,
3518                                E_Manager_Comp_Source *src)
3519 {
3520    E_Comp *c = (E_Comp *)data;
3521    E_Comp_Win *cw = (E_Comp_Win *)src;
3522    Eina_List *l;
3523    E_Comp_Object *co;
3524    E_Zone *z;
3525    E_CHECK_RETURN(cw, 0);
3526    E_CHECK_RETURN(cw->c, 0);
3527
3528    if (cw->bd) z = cw->bd->zone;
3529    else z = e_util_zone_current_get(c->man);
3530    EINA_LIST_FOREACH(cw->objs, l, co)
3531      {
3532         if (!_comp_mod->conf->canvas_per_zone)
3533           return co->img;
3534         else if ((co->zone) && (co->zone == z))
3535           return co->img;
3536      }
3537    return NULL;
3538 }
3539
3540 static Evas_Object *
3541 _e_mod_comp_src_shadow_get_func(void                  *data,
3542                                 E_Manager *man         __UNUSED__,
3543                                 E_Manager_Comp_Source *src)
3544 {
3545    E_Comp *c = (E_Comp *)data;
3546    E_Comp_Win *cw = (E_Comp_Win *)src;
3547    Eina_List *l;
3548    E_Comp_Object *co;
3549    E_Zone *z;
3550    E_CHECK_RETURN(cw, 0);
3551    E_CHECK_RETURN(cw->c, 0);
3552
3553    if (cw->bd) z = cw->bd->zone;
3554    else z = e_util_zone_current_get(c->man);
3555    EINA_LIST_FOREACH(cw->objs, l, co)
3556      {
3557         if (!_comp_mod->conf->canvas_per_zone)
3558           return co->shadow;
3559         else if ((co->zone) && (co->zone == z))
3560           return co->shadow;
3561      }
3562    return NULL;
3563 }
3564
3565 static Evas_Object *
3566 _e_mod_comp_src_image_mirror_add_func(void *data             __UNUSED__,
3567                                       E_Manager *man         __UNUSED__,
3568                                       E_Manager_Comp_Source *src)
3569 {
3570    E_Comp_Win *cw = (E_Comp_Win *)src;
3571    Eina_List *l;
3572    E_Comp_Canvas *canvas;
3573    E_CHECK_RETURN(cw, 0);
3574    E_CHECK_RETURN(cw->c, 0);
3575
3576    if (_comp_mod->conf->nocomp_fs)
3577      {
3578         EINA_LIST_FOREACH(cw->c->canvases, l, canvas)
3579           {
3580              if (!canvas) continue;
3581              if (!canvas->nocomp.run) continue;
3582              if (cw == canvas->nocomp.cw)
3583                {
3584                   L(LT_EVENT_X,
3585                     "[COMP] %31s new_w:0x%08x nocomp.cw:0x%08x canvas:%d\n",
3586                     "NOCOMP_END MIRROR_ADD", cw ? e_mod_comp_util_client_xid_get(cw) : 0,
3587                     e_mod_comp_util_client_xid_get(canvas->nocomp.cw),
3588                     canvas->num);
3589
3590                   _e_mod_comp_nocomp_end(canvas->comp,
3591                                          canvas,
3592                                          canvas->nocomp.cw);
3593                }
3594           }
3595      }
3596    return _e_mod_comp_win_mirror_add(cw);
3597 }
3598
3599 static Eina_Bool
3600 _e_mod_comp_src_visible_get_func(void *data             __UNUSED__,
3601                                  E_Manager *man         __UNUSED__,
3602                                  E_Manager_Comp_Source *src)
3603 {
3604    E_Comp_Win *cw = (E_Comp_Win *)src;
3605    E_CHECK_RETURN(cw, 0);
3606    E_CHECK_RETURN(cw->c, 0);
3607    return cw->visible;
3608 }
3609
3610 static void
3611 _e_mod_comp_src_hidden_set_func(void *data             __UNUSED__,
3612                                 E_Manager *man         __UNUSED__,
3613                                 E_Manager_Comp_Source *src,
3614                                 Eina_Bool              hidden)
3615 {
3616    E_Comp_Win *cw = (E_Comp_Win *)src;
3617    Eina_List *l;
3618    E_Comp_Object *co;
3619    E_CHECK(cw);
3620    E_CHECK(cw->c);
3621    if (cw->hidden_override == hidden) return;
3622    cw->hidden_override = hidden;
3623    if (cw->bd)
3624      e_border_comp_hidden_set(cw->bd,
3625                               cw->hidden_override);
3626    EINA_LIST_FOREACH(cw->objs, l, co)
3627      {
3628         if (cw->visible)
3629           {
3630              if (cw->hidden_override)
3631                evas_object_hide(co->shadow);
3632              else if (!cw->bd || cw->bd->visible)
3633                evas_object_show(co->shadow);
3634           }
3635         else
3636           {
3637              if (cw->hidden_override)
3638                evas_object_hide(co->shadow);
3639           }
3640      }
3641 }
3642
3643 static Eina_Bool
3644 _e_mod_comp_src_hidden_get_func(void *data             __UNUSED__,
3645                                 E_Manager *man         __UNUSED__,
3646                                 E_Manager_Comp_Source *src)
3647 {
3648    E_Comp_Win *cw = (E_Comp_Win *)src;
3649    E_CHECK_RETURN(cw, 0);
3650    E_CHECK_RETURN(cw->c, 0);
3651    return cw->hidden_override;
3652 }
3653
3654 static E_Popup *
3655 _e_mod_comp_src_popup_get_func(void *data             __UNUSED__,
3656                                E_Manager *man         __UNUSED__,
3657                                E_Manager_Comp_Source *src)
3658 {
3659    E_Comp_Win *cw = (E_Comp_Win *)src;
3660    E_CHECK_RETURN(cw, 0);
3661    E_CHECK_RETURN(cw->c, 0);
3662    return cw->pop;
3663 }
3664
3665 static E_Border *
3666 _e_mod_comp_src_border_get_func(void *data             __UNUSED__,
3667                                 E_Manager *man         __UNUSED__,
3668                                 E_Manager_Comp_Source *src)
3669 {
3670    E_Comp_Win *cw = (E_Comp_Win *)src;
3671    E_CHECK_RETURN(cw, 0);
3672    E_CHECK_RETURN(cw->c, 0);
3673    return cw->bd;
3674 }
3675
3676 static Ecore_X_Window
3677 _e_mod_comp_src_window_get_func(void *data             __UNUSED__,
3678                                 E_Manager *man         __UNUSED__,
3679                                 E_Manager_Comp_Source *src)
3680 {
3681    E_Comp_Win *cw = (E_Comp_Win *)src;
3682    E_CHECK_RETURN(cw, 0);
3683    E_CHECK_RETURN(cw->c, 0);
3684    return cw->win;
3685 }
3686
3687 static Eina_Bool
3688 _e_mod_comp_src_input_region_set_func(void *data             __UNUSED__,
3689                                       E_Manager *man         __UNUSED__,
3690                                       E_Manager_Comp_Source *src,
3691                                       int x,
3692                                       int y,
3693                                       int w,
3694                                       int h)
3695 {
3696    E_Comp_Win *cw = (E_Comp_Win *)src;
3697    Eina_Bool res = EINA_FALSE;
3698    E_CHECK_RETURN(cw, 0);
3699    E_CHECK_RETURN(cw->c, 0);
3700
3701    if (!cw->shape_input)
3702      cw->shape_input = e_mod_comp_win_shape_input_new(cw);
3703    E_CHECK_RETURN(cw->shape_input, 0);
3704
3705    res = e_mod_comp_win_shape_input_rect_set(cw->shape_input, x, y, w, h);
3706    E_CHECK_RETURN(res, 0);
3707
3708    e_mod_comp_win_shape_input_invalid_set(cw->c, 1);
3709    _e_mod_comp_win_render_queue(cw);
3710    return EINA_TRUE;
3711 }
3712
3713 static Eina_Bool
3714 _e_mod_comp_src_move_lock_func(void *data             __UNUSED__,
3715                                E_Manager *man         __UNUSED__,
3716                                E_Manager_Comp_Source *src)
3717 {
3718    E_Comp_Win *cw = (E_Comp_Win *)src;
3719    E_CHECK_RETURN(cw, 0);
3720    E_CHECK_RETURN(cw->c, 0);
3721
3722    cw->move_lock = EINA_TRUE;
3723
3724    return EINA_TRUE;
3725 }
3726
3727 static Eina_Bool
3728 _e_mod_comp_src_move_unlock_func(void *data             __UNUSED__,
3729                                  E_Manager *man         __UNUSED__,
3730                                  E_Manager_Comp_Source *src)
3731 {
3732    E_Comp_Win *cw = (E_Comp_Win *)src;
3733    E_CHECK_RETURN(cw, 0);
3734    E_CHECK_RETURN(cw->c, 0);
3735
3736    cw->move_lock = EINA_FALSE;
3737    e_mod_comp_win_comp_objs_move(cw, cw->x, cw->y);
3738    return EINA_TRUE;
3739 }
3740
3741 static void
3742 _e_mod_comp_composite_mode_set(void           *data,
3743                                E_Manager *man __UNUSED__,
3744                                E_Zone        *zone,
3745                                Eina_Bool      set)
3746 {
3747    E_Comp *c = (E_Comp *)data;
3748    E_Comp_Canvas *canvas;
3749    Eina_List *l;
3750
3751    E_CHECK(_comp_mod->conf->nocomp_fs);
3752    E_CHECK(c);
3753
3754    EINA_LIST_FOREACH(c->canvases, l, canvas)
3755      {
3756         if (!canvas) continue;
3757         if (canvas->zone == zone)
3758           {
3759              if (set)
3760                {
3761                   if (!canvas->nocomp.force_composite)
3762                     {
3763                        canvas->nocomp.force_composite = set;
3764                        e_mod_comp_hw_ov_win_msg_show
3765                          (E_COMP_LOG_TYPE_NOCOMP,
3766                          ">> %d COMP REQUEST", canvas->num);
3767
3768                        if (canvas->nocomp.cw)
3769                          {
3770                             canvas->nocomp.cw->update = 1;
3771                             c->updates = eina_list_append(c->updates, canvas->nocomp.cw);
3772                             _e_mod_comp_win_render_queue(canvas->nocomp.cw);
3773                          }
3774                        else
3775                          {
3776                             _e_mod_comp_render_queue(c);
3777                          }
3778                     }
3779                }
3780              else
3781                {
3782                   if (canvas->nocomp.force_composite)
3783                     {
3784                        canvas->nocomp.force_composite = EINA_FALSE;
3785                        e_mod_comp_hw_ov_win_msg_show
3786                          (E_COMP_LOG_TYPE_NOCOMP,
3787                          ">> %d NOCOMP REQUEST", canvas->num);
3788                     }
3789                }
3790              break;
3791           }
3792      }
3793 }
3794
3795 static Eina_Bool
3796 _e_mod_comp_composite_mode_get(void          *data,
3797                                E_Manager *man __UNUSED__,
3798                                E_Zone        *zone)
3799 {
3800    E_Comp *c = (E_Comp *)data;
3801    E_Comp_Canvas *canvas;
3802    Eina_List *l;
3803
3804    E_CHECK_RETURN(_comp_mod->conf->nocomp_fs, 1);
3805    E_CHECK_RETURN(c, 1);
3806
3807    EINA_LIST_FOREACH(c->canvases, l, canvas)
3808      {
3809         if (!canvas) continue;
3810         if (canvas->zone == zone)
3811           return !(canvas->nocomp.run);
3812      }
3813    return EINA_TRUE;
3814 }
3815
3816 static E_Comp *
3817 _e_mod_comp_add(E_Manager *man)
3818 {
3819    E_Comp *c;
3820    Ecore_X_Window *wins;
3821    Ecore_X_Window_Attributes att;
3822    Eina_Bool res;
3823    int i, num;
3824
3825    E_Container *con;
3826    E_Zone *zone;
3827    E_Comp_Canvas *canvas;
3828    Eina_List *l, *ll;
3829
3830    c = E_NEW(E_Comp, 1);
3831    E_CHECK_RETURN(c, NULL);
3832
3833    res = ecore_x_screen_is_composited(man->num);
3834    if (res)
3835      {
3836         e_util_dialog_internal
3837            (_("Compositor Error"),
3838            _("Another compositor is already running<br>"
3839              "on your screen."));
3840         free(c);
3841         return NULL;
3842      }
3843
3844    c->cm_selection = ecore_x_window_input_new(man->root, 0, 0, 1, 1);
3845    if (!c->cm_selection)
3846      {
3847         free(c);
3848         return NULL;
3849      }
3850    ecore_x_screen_is_composited_set(man->num, c->cm_selection);
3851    
3852    ecore_x_e_comp_sync_supported_set(man->root, _comp_mod->conf->efl_sync);
3853
3854    c->man = man;
3855    c->win = ecore_x_composite_render_window_enable(man->root);
3856    if (!c->win)
3857      {
3858         e_util_dialog_internal
3859           (_("Compositor Error"),
3860           _("Your screen does not support the compositor<br>"
3861             "overlay window. This is needed for it to<br>"
3862             "function."));
3863         E_FREE(c);
3864         return NULL;
3865      }
3866
3867    memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
3868    ecore_x_window_attributes_get(c->win, &att);
3869
3870    if ((att.depth != 24) && (att.depth != 32))
3871      {
3872         e_util_dialog_internal
3873           (_("Compositor Error"),
3874           _("Your screen is not in 24/32bit display mode.<br>"
3875             "This is required to be your default depth<br>"
3876             "setting for the compositor to work properly."));
3877         ecore_x_composite_render_window_disable(c->win);
3878         E_FREE(c);
3879         return NULL;
3880      }
3881
3882    if (c->man->num == 0) e_alert_composite_win = c->win;
3883
3884    e_mod_comp_screen_lock_init(&(c->lock));
3885
3886    if (_comp_mod->conf->canvas_per_zone)
3887      {
3888         EINA_LIST_FOREACH(man->containers, l, con)
3889           {
3890              EINA_LIST_FOREACH(con->zones, ll, zone)
3891                {
3892                   if (!zone) continue;
3893                   canvas = e_mod_comp_canvas_add(c, zone);
3894                   if (!canvas)
3895                     {
3896                        ecore_x_composite_render_window_disable(c->win);
3897                        E_FREE(c);
3898                        return NULL;
3899                     }
3900
3901                }
3902           }
3903      }
3904    else
3905      {
3906         canvas = e_mod_comp_canvas_add(c, NULL);
3907         if (!canvas)
3908           {
3909              ecore_x_composite_render_window_disable(c->win);
3910              E_FREE(c);
3911              return NULL;
3912           }
3913      }
3914
3915    ecore_x_composite_redirect_subwindows
3916      (c->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
3917
3918    wins = ecore_x_window_children_get(c->man->root, &num);
3919    if (wins)
3920      {
3921         for (i = 0; i < num; i++)
3922           {
3923              E_Comp_Win *cw;
3924              int x, y, w, h, border;
3925              char *wname = NULL, *wclass = NULL;
3926
3927              ecore_x_icccm_name_class_get(wins[i], &wname, &wclass);
3928              if ((man->initwin == wins[i]) ||
3929                  ((wname) && (wclass) && (!strcmp(wname, "E")) &&
3930                   (!strcmp(wclass, "Init_Window"))))
3931                {
3932                   free(wname);
3933                   free(wclass);
3934                   ecore_x_window_reparent(wins[i], c->win, 0, 0);
3935                   ecore_x_sync();
3936                   continue;
3937                }
3938              if (wname) free(wname);
3939              if (wclass) free(wclass);
3940              wname = wclass = NULL;
3941              cw = _e_mod_comp_win_add(c, wins[i]);
3942              if (!cw) continue;
3943              ecore_x_window_geometry_get(cw->win, &x, &y, &w, &h);
3944              border = ecore_x_window_border_width_get(cw->win);
3945              if (wins[i] == c->win) continue;
3946              _e_mod_comp_win_configure(cw, x, y, w, h, border);
3947              if (ecore_x_window_visible_get(wins[i]))
3948                _e_mod_comp_win_show(cw);
3949           }
3950         free(wins);
3951      }
3952
3953    ecore_x_window_key_grab
3954      (c->man->root, "Home",
3955      ECORE_EVENT_MODIFIER_SHIFT |
3956      ECORE_EVENT_MODIFIER_CTRL |
3957      ECORE_EVENT_MODIFIER_ALT, 0);
3958    ecore_x_window_key_grab
3959      (c->man->root, "F",
3960      ECORE_EVENT_MODIFIER_SHIFT |
3961      ECORE_EVENT_MODIFIER_CTRL |
3962      ECORE_EVENT_MODIFIER_ALT, 0);
3963
3964    c->comp.data                      = c;
3965    c->comp.func.evas_get             = _e_mod_comp_evas_get_func;
3966    c->comp.func.update               = _e_mod_comp_update_func;
3967    c->comp.func.src_get              = _e_mod_comp_src_get_func;
3968    c->comp.func.src_list_get         = _e_mod_comp_src_list_get_func;
3969    c->comp.func.src_image_get        = _e_mod_comp_src_image_get_func;
3970    c->comp.func.src_shadow_get       = _e_mod_comp_src_shadow_get_func;
3971    c->comp.func.src_image_mirror_add = _e_mod_comp_src_image_mirror_add_func;
3972    c->comp.func.src_visible_get      = _e_mod_comp_src_visible_get_func;
3973    c->comp.func.src_hidden_set       = _e_mod_comp_src_hidden_set_func;
3974    c->comp.func.src_hidden_get       = _e_mod_comp_src_hidden_get_func;
3975    c->comp.func.src_window_get       = _e_mod_comp_src_window_get_func;
3976    c->comp.func.src_border_get       = _e_mod_comp_src_border_get_func;
3977    c->comp.func.src_popup_get        = _e_mod_comp_src_popup_get_func;
3978    c->comp.func.screen_lock          = e_mod_comp_screen_lock_func;
3979    c->comp.func.screen_unlock        = e_mod_comp_screen_unlock_func;
3980    c->comp.func.src_input_region_set = _e_mod_comp_src_input_region_set_func;
3981    c->comp.func.src_move_lock        = _e_mod_comp_src_move_lock_func;
3982    c->comp.func.src_move_unlock      = _e_mod_comp_src_move_unlock_func;
3983    c->comp.func.composite_mode_set   = _e_mod_comp_composite_mode_set;
3984    c->comp.func.composite_mode_get   = _e_mod_comp_composite_mode_get;
3985
3986    e_manager_comp_set(c->man, &(c->comp));
3987    return c;
3988 }
3989
3990 static void
3991 _e_mod_comp_del(E_Comp *c)
3992 {
3993    E_Comp_Win *cw;
3994    E_Comp_Canvas *canvas;
3995
3996    e_manager_comp_set(c->man, NULL);
3997
3998    ecore_x_window_key_ungrab
3999      (c->man->root, "F",
4000      ECORE_EVENT_MODIFIER_SHIFT |
4001      ECORE_EVENT_MODIFIER_CTRL |
4002      ECORE_EVENT_MODIFIER_ALT, 0);
4003    ecore_x_window_key_ungrab
4004      (c->man->root, "Home",
4005      ECORE_EVENT_MODIFIER_SHIFT |
4006      ECORE_EVENT_MODIFIER_CTRL |
4007      ECORE_EVENT_MODIFIER_ALT, 0);
4008
4009    _e_mod_comp_x_grab_set(c, EINA_FALSE);
4010    while (c->wins)
4011      {
4012         cw = (E_Comp_Win *)(c->wins);
4013         if (cw->counter)
4014           {
4015              ecore_x_sync_counter_free(cw->counter);
4016              cw->counter = 0;
4017              cw->sync_info.val = 0;
4018           }
4019         cw->force = 1;
4020         _e_mod_comp_win_hide(cw);
4021         cw->force = 1;
4022         _e_mod_comp_win_del(cw);
4023      }
4024
4025    EINA_LIST_FREE(c->canvases, canvas) e_mod_comp_canvas_del(canvas);
4026    c->canvases = NULL;
4027
4028    ecore_x_composite_unredirect_subwindows
4029      (c->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
4030    ecore_x_composite_render_window_disable(c->win);
4031    if (c->man->num == 0) e_alert_composite_win = 0;
4032    if (c->render_animator) ecore_animator_del(c->render_animator);
4033    if (c->new_up_timer) ecore_timer_del(c->new_up_timer);
4034    if (c->update_job) ecore_job_del(c->update_job);
4035    if (c->wins_list) eina_list_free(c->wins_list);
4036
4037    ecore_x_window_free(c->cm_selection);
4038    ecore_x_e_comp_sync_supported_set(c->man->root, 0);
4039    ecore_x_screen_is_composited_set(c->man->num, 0);
4040
4041    free(c);
4042 }
4043
4044 ///////////////////////////////////////////////////////////////////////////////////////////
4045 static Eina_Bool
4046 _e_mod_comp_zone_move_resize(void *data __UNUSED__,
4047                              int type   __UNUSED__,
4048                              void      *event)
4049 {
4050    E_Event_Zone_Move_Resize *ev = (E_Event_Zone_Move_Resize *)event;
4051    Eina_List *l, *ll;
4052    E_Comp *c;
4053    E_Comp_Canvas *canvas;
4054    if (!(ev && ev->zone))
4055      return ECORE_CALLBACK_PASS_ON;
4056
4057    if (!_comp_mod->conf->canvas_per_zone)
4058      return ECORE_CALLBACK_PASS_ON;
4059
4060    L(LT_EVENT_X,
4061      "[COMP] ev:%15.15s\n",
4062      "E_ZONE_MOVE_RESIZE");
4063
4064    EINA_LIST_FOREACH(compositors, l, c)
4065      {
4066         if (!c) continue;
4067         EINA_LIST_FOREACH(c->canvases, ll, canvas)
4068           {
4069              if (!canvas) continue;
4070              if (canvas->zone != ev->zone) continue;
4071              if (!((ev->zone->x == canvas->x) &&
4072                    (ev->zone->y == canvas->y)))
4073                {
4074                   canvas->x = ev->zone->x;
4075                   canvas->y = ev->zone->y;
4076                   ecore_evas_move(canvas->ee,
4077                                   canvas->x,
4078                                   canvas->y);
4079                }
4080              if (!((ev->zone->w == canvas->w) &&
4081                    (ev->zone->h == canvas->h)))
4082                {
4083                   canvas->w = ev->zone->w;
4084                   canvas->h = ev->zone->h;
4085                   ecore_evas_resize(canvas->ee,
4086                                     canvas->w,
4087                                     canvas->h);
4088                }
4089              break;
4090           }
4091      }
4092    return ECORE_CALLBACK_PASS_ON;
4093 }
4094
4095 static Eina_Bool
4096 _e_mod_comp_zone_add(void *data __UNUSED__,
4097                      int type   __UNUSED__,
4098                      void      *event)
4099 {
4100    E_Event_Zone_Add *ev = (E_Event_Zone_Add *)event;
4101    Eina_List *l, *ll;
4102    E_Comp *c;
4103    E_Comp_Canvas *canvas;
4104    E_Comp_Win *cw;
4105    E_Comp_Object *co;
4106    Eina_Bool found = EINA_FALSE;
4107    if ((!ev) || (!ev->zone) ||
4108        (!ev->zone->container))
4109      {
4110         return ECORE_CALLBACK_PASS_ON;
4111      }
4112    if (!_comp_mod->conf->canvas_per_zone)
4113      {
4114         return ECORE_CALLBACK_PASS_ON;
4115      }
4116
4117    EINA_LIST_FOREACH(compositors, l, c)
4118      {
4119         EINA_LIST_FOREACH(c->canvases, ll, canvas)
4120           {
4121              if (canvas->zone == ev->zone)
4122                {
4123                   found = EINA_TRUE;
4124                   break;
4125                }
4126           }
4127      }
4128
4129    if (found) return ECORE_CALLBACK_PASS_ON;
4130
4131    L(LT_EVENT_X,
4132      "[COMP] ev:%15.15s\n",
4133      "E_ZONE_ADD");
4134
4135    EINA_LIST_FOREACH(compositors, l, c)
4136      {
4137         if ((!c) || (c->man != ev->zone->container->manager))
4138           {
4139              continue;
4140           }
4141
4142         canvas = e_mod_comp_canvas_add(c, ev->zone);
4143         if (!canvas) return ECORE_CALLBACK_PASS_ON;
4144
4145         ecore_x_window_shape_rectangle_add(c->win,
4146                                            canvas->zone->x,
4147                                            canvas->zone->y,
4148                                            canvas->zone->w,
4149                                            canvas->zone->h);
4150         ecore_x_sync();
4151
4152         EINA_INLIST_FOREACH(c->wins, cw)
4153           {
4154              Eina_Bool found = EINA_FALSE;
4155              Eina_List *lll;
4156              E_Comp_Canvas *_canvas;
4157              EINA_LIST_FOREACH(c->canvases, lll, _canvas)
4158                {
4159                   if (_canvas->ee_win == cw->win)
4160                     {
4161                        found = 1;
4162                        break;
4163                     }
4164                }
4165
4166              co = e_mod_comp_obj_add(cw, canvas);
4167              if (!co) continue;
4168
4169              cw->objs = eina_list_append(cw->objs, co);
4170
4171              if ((!cw->input_only) && (!cw->invalid))
4172                {
4173                   e_mod_comp_win_shadow_setup(cw, co);
4174                   e_mod_comp_win_cb_setup(cw, co);
4175                   evas_object_show(co->img);
4176
4177                   if (cw->bd) evas_object_data_set(co->shadow, "border", cw->bd);
4178                   else if (cw->pop)
4179                     evas_object_data_set(co->shadow, "popup", cw->pop);
4180                   else if (cw->menu)
4181                     evas_object_data_set(co->shadow, "menu", cw->menu);
4182
4183                   evas_object_pass_events_set(co->img, 1);
4184                }
4185
4186              evas_object_pass_events_set(co->shadow, 1);
4187              evas_object_data_set(co->shadow, "win",
4188                                   (void *)((unsigned long)cw->win));
4189              evas_object_data_set(co->shadow, "src", cw);
4190
4191              int zx = 0, zy = 0;
4192              zx = co->zone->x;
4193              zy = co->zone->y;
4194              evas_object_move(co->shadow, cw->x - zx, cw->y - zy);
4195              evas_object_resize(co->shadow, cw->pw, cw->ph);
4196
4197              if (cw->visible)
4198                {
4199                   evas_object_image_size_set(co->img, cw->pw, cw->ph);
4200                   Evas_Object *o;
4201                   EINA_LIST_FOREACH(co->img_mirror, ll, o)
4202                     {
4203                        evas_object_image_size_set(o, cw->pw, cw->ph);
4204                     }
4205                   if ((cw->dmg_updates >= 1))
4206                     {
4207                        cw->defer_hide = 0;
4208                        if (!cw->hidden_override)
4209                          evas_object_show(co->shadow);
4210                        edje_object_signal_emit(co->shadow, "e,state,visible,on", "e");
4211                        if (!cw->animating)
4212                          {
4213                             cw->c->animating++;
4214                          }
4215                        cw->animating = 1;
4216                        _e_mod_comp_win_render_queue(cw);
4217
4218                        cw->pending_count++;
4219                        e_manager_comp_event_src_visibility_send
4220                          (cw->c->man, (E_Manager_Comp_Source *)cw,
4221                          _e_mod_comp_cb_pending_after, cw->c);
4222                     }
4223                }
4224           } // end of eina_inlist
4225      }
4226    return ECORE_CALLBACK_PASS_ON;
4227 }
4228
4229 static Eina_Bool
4230 _e_mod_comp_zone_del(void *data __UNUSED__,
4231                      int type   __UNUSED__,
4232                      void      *event)
4233 {
4234    E_Event_Zone_Del *ev = (E_Event_Zone_Del *)event;
4235    Eina_List *l, *ll, *lll;
4236    E_Comp *c;
4237    E_Comp_Canvas *canvas;
4238    E_Comp_Win *cw;
4239    E_Comp_Object *co;
4240    if (!ev || !ev->zone)
4241      {
4242         return ECORE_CALLBACK_PASS_ON;
4243      }
4244    if (!_comp_mod->conf->canvas_per_zone)
4245      {
4246         return ECORE_CALLBACK_PASS_ON;
4247      }
4248
4249    L(LT_EVENT_X,
4250      "[COMP] ev:%15.15s\n",
4251      "E_ZONE_DEL");
4252
4253    EINA_LIST_FOREACH(compositors, l, c)
4254      {
4255         EINA_LIST_FOREACH(c->canvases, ll, canvas)
4256           {
4257              if (canvas->zone != ev->zone) continue;
4258              EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
4259                {
4260                   EINA_LIST_FOREACH(cw->objs, lll, co)
4261                     {
4262                        if (co->zone != ev->zone) continue;
4263                        cw->objs = eina_list_remove(cw->objs, co);
4264                        e_mod_comp_obj_del(co);
4265                     }
4266                }
4267
4268              ecore_x_window_shape_rectangle_subtract(c->win,
4269                                                      canvas->zone->x,
4270                                                      canvas->zone->y,
4271                                                      canvas->zone->w,
4272                                                      canvas->zone->h);
4273              ecore_x_sync();
4274
4275              c->canvases = eina_list_remove(c->canvases, canvas);
4276              e_mod_comp_canvas_del(canvas);
4277              break;
4278           }
4279      }
4280    return ECORE_CALLBACK_PASS_ON;
4281 }
4282
4283 //////////////////////////////////////////////////////////////////////////
4284
4285 Eina_Bool
4286 e_mod_comp_init(void)
4287 {
4288    Eina_List *l;
4289    E_Manager *man;
4290    unsigned int effect = 0;
4291    int res = 0;
4292
4293    windows = eina_hash_string_superfast_new(NULL);
4294    borders = eina_hash_string_superfast_new(NULL);
4295    damages = eina_hash_string_superfast_new(NULL);
4296
4297    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE,    _e_mod_comp_create,           NULL));
4298    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY,   _e_mod_comp_destroy,          NULL));
4299    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW,      _e_mod_comp_show,             NULL));
4300    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE,      _e_mod_comp_hide,             NULL));
4301    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT,  _e_mod_comp_reparent,         NULL));
4302    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_mod_comp_configure,        NULL));
4303    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK,     _e_mod_comp_stack,            NULL));
4304    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,  _e_mod_comp_property,         NULL));
4305    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,   _e_mod_comp_message,          NULL));
4306    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE,     _e_mod_comp_shape,            NULL));
4307    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY,    _e_mod_comp_damage,           NULL));
4308    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE,    _e_mod_comp_damage_win,       NULL));
4309    handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,           _e_mod_comp_key_down,         NULL));
4310    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONTAINER_RESIZE,       _e_mod_comp_randr,            NULL));
4311    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ADD,             _e_mod_comp_bd_add,           NULL));
4312    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_REMOVE,          _e_mod_comp_bd_del,           NULL));
4313    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_SHOW,            _e_mod_comp_bd_show,          NULL));
4314    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_HIDE,            _e_mod_comp_bd_hide,          NULL));
4315    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_MOVE,            _e_mod_comp_bd_move,          NULL));
4316    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_RESIZE,          _e_mod_comp_bd_resize,        NULL));
4317    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ICONIFY,         _e_mod_comp_bd_iconify,       NULL));
4318    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_UNICONIFY,       _e_mod_comp_bd_uniconify,     NULL));
4319    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_URGENT_CHANGE,   _e_mod_comp_bd_urgent_change, NULL));
4320    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN,        _e_mod_comp_bd_focus_in,      NULL));
4321    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT,       _e_mod_comp_bd_focus_out,     NULL));
4322    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_PROPERTY,        _e_mod_comp_bd_property,      NULL));
4323    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,       _e_mod_comp_zone_move_resize, NULL));
4324    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ADD,               _e_mod_comp_zone_add,         NULL));
4325    handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_DEL,               _e_mod_comp_zone_del,         NULL));
4326
4327    res = e_mod_comp_atoms_init();
4328    E_CHECK_RETURN(res, 0);
4329
4330    res = e_mod_comp_win_type_init();
4331    E_CHECK_RETURN(res, 0);
4332
4333    res = e_mod_comp_policy_init();
4334    E_CHECK_RETURN(res, 0);
4335
4336    if (!ecore_x_composite_query())
4337      {
4338         e_util_dialog_internal
4339           (_("Compositor Error"),
4340           _("Your X Display does not support the XComposite extension<br>"
4341             "or Ecore was built without XComposite support.<br>"
4342             "Note that for composite support you will also need<br>"
4343             "XRender and XFixes support in X11 and Ecore."));
4344         return 0;
4345      }
4346    if (!ecore_x_damage_query())
4347      {
4348         e_util_dialog_internal
4349           (_("Compositor Error"),
4350           _("Your screen does not support the XDamage extension<br>"
4351             "or Ecore was built without XDamage support."));
4352         return 0;
4353      }
4354
4355    /* enable nocomp_fs for the authorized device */
4356    FILE *_fp = fopen("/sys/devices/platform/exynos-busfreq/modalias", "r");
4357    if (!_fp)
4358      {
4359         if (_comp_mod->conf->nocomp_fs)
4360           {
4361              _comp_mod->conf->nocomp_fs = 0;
4362              printf("[COMP] change nocomp_fs 1 -> 0\n");
4363           }
4364         if (_comp_mod->conf->use_hw_ov)
4365           {
4366              _comp_mod->conf->use_hw_ov = 0;
4367              printf("[COMP] change use_hw_ov 1 -> 0\n");
4368           }
4369      }
4370    else
4371      fclose(_fp);
4372
4373    printf("[COMP] nocomp_fs:%d use_hw_ov:%d\n",
4374           _comp_mod->conf->nocomp_fs,
4375           _comp_mod->conf->use_hw_ov);
4376
4377    EINA_LIST_FOREACH(e_manager_list(), l, man)
4378      {
4379         E_Comp *c;
4380         if (!man) continue;
4381         c = _e_mod_comp_add(man);
4382         if (c)
4383           {
4384              compositors = eina_list_append(compositors, c);
4385              e_mod_comp_util_set(c, man);
4386              ecore_animator_frametime_set(1.0f/60.0f);
4387
4388              if (_comp_mod->conf->default_window_effect) effect = 1;
4389              ecore_x_window_prop_card32_set
4390                (c->man->root, ATOM_EFFECT_ENABLE,
4391                &effect, 1);
4392              ecore_x_window_prop_property_set
4393                (c->man->root, ATOM_OVERAY_WINDOW,
4394                ECORE_X_ATOM_WINDOW, 32, &c->win, 1);
4395           }
4396      }
4397    ecore_x_sync();
4398    return 1;
4399 }
4400
4401 void
4402 e_mod_comp_shutdown(void)
4403 {
4404    E_Comp *c;
4405
4406    EINA_LIST_FREE(compositors, c) _e_mod_comp_del(c);
4407
4408    E_FREE_LIST(handlers, ecore_event_handler_del);
4409
4410    if (damages) eina_hash_free(damages);
4411    if (windows) eina_hash_free(windows);
4412    if (borders) eina_hash_free(borders);
4413    damages = NULL;
4414    windows = NULL;
4415    borders = NULL;
4416
4417    e_mod_comp_policy_shutdown();
4418    e_mod_comp_win_type_shutdown();
4419    e_mod_comp_atoms_shutdown();
4420
4421    e_mod_comp_util_set(NULL, NULL);
4422 }
4423
4424 void
4425 e_mod_comp_shadow_set(void)
4426 {
4427    Eina_List *l, *ll;
4428    E_Comp *c;
4429    E_Comp_Object *co;
4430
4431    EINA_LIST_FOREACH(compositors, l, c)
4432      {
4433         if (!c) continue;
4434         E_Comp_Win *cw;
4435         EINA_INLIST_FOREACH(c->wins, cw)
4436           {
4437              if (!cw) continue;
4438              Eina_Bool animatable = EINA_FALSE;
4439              Eina_Bool pending = EINA_TRUE;
4440              e_mod_comp_win_type_setup(cw);
4441              EINA_LIST_FOREACH(cw->objs, ll, co)
4442                {
4443                   if (!co) continue;
4444                   if ((co->shadow) && (co->img))
4445                     {
4446                        e_mod_comp_win_shadow_setup(cw, co);
4447
4448                        if (cw->visible)
4449                          edje_object_signal_emit(co->shadow, "e,state,visible,on", "e");
4450                        else
4451                          {
4452                             pending = EINA_FALSE;
4453                          }
4454                     }
4455                   else
4456                     pending = EINA_FALSE;
4457                }
4458              animatable = e_mod_comp_effect_state_get(cw->eff_type);
4459              if (animatable)
4460                e_mod_comp_effect_signal_add
4461                  (cw, NULL, "e,state,visible,on", "e");
4462              else
4463                e_mod_comp_effect_signal_add
4464                  (cw, NULL, "e,state,visible,on,noeffect", "e");
4465
4466              if (_comp_mod->conf->use_shadow)
4467                {
4468                   if (cw->bd)
4469                     {
4470                        if (!cw->bd->borderless)
4471                          e_mod_comp_effect_signal_add(cw, NULL, "e,state,shadow,on", "e");
4472                     }
4473                }
4474
4475              e_mod_comp_comp_event_src_visibility_send(cw);
4476           }
4477      }
4478 }
4479
4480 EINTERN void
4481 e_mod_comp_win_cb_setup(E_Comp_Win    *cw,
4482                         E_Comp_Object *co)
4483 {
4484    edje_object_signal_callback_add(co->shadow, "e,action,show,done",            "e", _e_mod_comp_show_done,            cw);
4485    edje_object_signal_callback_add(co->shadow, "e,action,hide,done",            "e", _e_mod_comp_hide_done,            cw);
4486    edje_object_signal_callback_add(co->shadow, "e,action,background,show,done", "e", _e_mod_comp_background_show_done, cw);
4487    edje_object_signal_callback_add(co->shadow, "e,action,background,hide,done", "e", _e_mod_comp_background_hide_done, cw);
4488    edje_object_signal_callback_add(co->shadow, "e,action,raise_above_hide,done","e", _e_mod_comp_raise_above_hide_done,cw);
4489 }