2 #include "e_mod_main.h"
3 #include "e_mod_comp.h"
4 #include "e_mod_comp_update.h"
8 //////////////////////////////////////////////////////////////////////////
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
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*
24 //////////////////////////////////////////////////////////////////////////
30 Ecore_X_Window ee_win;
36 Ecore_Animator *render_animator;
37 Ecore_Job *update_job;
38 Ecore_Timer *new_up_timer;
43 double frametimes[122];
47 Ecore_X_Window cm_selection;
50 Eina_Bool grabbed : 1;
52 Eina_Bool wins_invalid : 1;
59 E_Comp *c; // parent compositor
60 Ecore_X_Window win; // raw window - for menus etc.
61 E_Border *bd; // if its a border - later
62 E_Popup *pop; // if its a popup - later
63 E_Menu *menu; // if it is a menu - later
64 int x, y, w, h; // geometry
67 int x, y, w, h; // hidden geometry (used when its unmapped and re-instated on map)
69 int pw, ph; // pixmap w/h
70 int border; // border width
71 Ecore_X_Pixmap pixmap; // the compositing pixmap
72 Ecore_X_Damage damage; // damage region
73 Ecore_X_Visual vis; // window visual
74 int depth; // window depth
75 Evas_Object *obj; // composite object
76 Evas_Object *shobj; // shadow object
77 Eina_List *obj_mirror; // extra mirror objects
78 Ecore_X_Image *xim; // x image - software fallback
79 E_Update *up; // update handler
80 E_Object_Delfn *dfn; // delete function handle for objects being tracked
81 Ecore_X_Sync_Counter counter; // sync counter for syncronised drawing
82 Ecore_Timer *update_timeout; // max time between damage and "done" event
83 Ecore_Timer *ready_timeout; // max time on show (new window draw) to wait for window contents to be ready if sync protocol not handled. this is fallback.
84 int dmg_updates; // num of damage event updates since a redirect
85 Ecore_X_Rectangle *rects; // shape rects... if shaped :(
86 int rects_num; // num rects above
88 Ecore_X_Pixmap cache_pixmap; // the cached pixmap (1/nth the dimensions)
89 int cache_w, cache_h; // cached pixmap size
90 int update_count; // how many updates have happened to this win
91 double last_visible_time; // last time window was visible
92 double last_draw_time; // last time window was damaged
94 int pending_count; // pending event count
96 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
98 char *title, *name, *clas, *role; // fetched for override-redirect windowa
99 Ecore_X_Window_Type primary_type; // fetched for override-redirect windowa
101 unsigned char misses; // number of sync misses
103 Eina_Bool delete_pending : 1; // delete pendig
104 Eina_Bool hidden_override : 1; // hidden override
105 Eina_Bool animating : 1; // it's busy animating - defer hides/dels
106 Eina_Bool force : 1; // force del/hide even if animating
107 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
108 Eina_Bool delete_me : 1; // delete me!
109 Eina_Bool visible : 1; // is visible
110 Eina_Bool input_only : 1; // is input_only
112 Eina_Bool override : 1; // is override-redirect
113 Eina_Bool argb : 1; // is argb
114 Eina_Bool shaped : 1; // is shaped
115 Eina_Bool update : 1; // has updates to fetch
116 Eina_Bool redirected : 1; // has updates to fetch
117 Eina_Bool shape_changed : 1; // shape changed
118 Eina_Bool native : 1; // native
119 Eina_Bool drawme : 1; // drawme flag fo syncing rendering
121 Eina_Bool invalid : 1; // invalid depth used - just use as marker
122 Eina_Bool nocomp : 1; // nocomp applied
123 Eina_Bool needpix : 1; // need new pixmap
124 Eina_Bool needxim : 1; // need new xim
125 Eina_Bool real_hid : 1; // last hide was a real window unmap
126 Eina_Bool inhash : 1; // is in the windows hash
127 Eina_Bool show_ready : 1; // is this window ready for its first show
128 Eina_Bool show_anim : 1; // ran show animation
131 static Eina_List *handlers = NULL;
132 static Eina_List *compositors = NULL;
133 static Eina_Hash *windows = NULL;
134 static Eina_Hash *borders = NULL;
135 static Eina_Hash *damages = NULL;
137 //////////////////////////////////////////////////////////////////////////
140 #define DBG(f, x ...) printf(f, ##x)
142 #define DBG(f, x ...)
145 static void _e_mod_comp_win_ready_timeout_setup(E_Comp_Win *cw);
146 static void _e_mod_comp_render_queue(E_Comp *c);
147 static void _e_mod_comp_win_damage(E_Comp_Win *cw,
153 static void _e_mod_comp_win_render_queue(E_Comp_Win *cw);
154 static void _e_mod_comp_win_del(E_Comp_Win *cw);
155 static void _e_mod_comp_win_real_hide(E_Comp_Win *cw);
156 static void _e_mod_comp_win_hide(E_Comp_Win *cw);
157 static void _e_mod_comp_win_configure(E_Comp_Win *cw,
165 _e_mod_comp_cb_pending_after(void *data __UNUSED__,
166 E_Manager *man __UNUSED__,
167 E_Manager_Comp_Source *src)
169 E_Comp_Win *cw = (E_Comp_Win *)src;
171 if (!cw->delete_pending) return;
172 if (cw->pending_count == 0)
179 _e_mod_comp_fullscreen_check(E_Comp *c)
183 if (!c->wins) return NULL;
184 EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
186 if ((!cw->visible) || (cw->input_only) || (cw->invalid))
188 if ((cw->x == 0) && (cw->y == 0) &&
189 ((cw->x + cw->w) >= c->man->w) &&
190 ((cw->y + cw->h) >= c->man->h) &&
191 (!cw->argb) && (!cw->shaped)
201 static inline Eina_Bool
202 _e_mod_comp_shaped_check(int w,
204 const Ecore_X_Rectangle *rects,
207 if ((!rects) || (num < 1)) return EINA_FALSE;
208 if (num > 1) return EINA_TRUE;
209 if ((rects[0].x == 0) && (rects[0].y == 0) &&
210 (rects[0].width == w) && (rects[0].height == h))
215 static inline Eina_Bool
216 _e_mod_comp_win_shaped_check(const E_Comp_Win *cw,
217 const Ecore_X_Rectangle *rects,
220 return _e_mod_comp_shaped_check(cw->w, cw->h, rects, num);
224 _e_mod_comp_win_shape_rectangles_apply(E_Comp_Win *cw,
225 const Ecore_X_Rectangle *rects,
232 DBG("SHAPE [0x%x] change, rects=%p (%d)\n", cw->win, rects, num);
233 if (!_e_mod_comp_win_shaped_check(cw, rects, num))
239 unsigned int *pix, *p;
240 unsigned char *spix, *sp;
243 evas_object_image_size_get(cw->obj, &w, &h);
244 if ((w > 0) && (h > 0))
248 printf("BUGGER: shape with native surface? cw=%p\n", cw);
252 evas_object_image_native_surface_set(cw->obj, NULL);
253 evas_object_image_alpha_set(cw->obj, 1);
254 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
256 evas_object_image_native_surface_set(o, NULL);
257 evas_object_image_alpha_set(o, 1);
259 pix = evas_object_image_data_get(cw->obj, 1);
262 spix = calloc(w * h, sizeof(unsigned char));
265 DBG("SHAPE [0x%x] rects %i\n", cw->win, num);
266 for (i = 0; i < num; i++)
270 rx = rects[i].x; ry = rects[i].y;
271 rw = rects[i].width; rh = rects[i].height;
272 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
273 sp = spix + (w * ry) + rx;
274 for (py = 0; py < rh; py++)
276 for (px = 0; px < rw; px++)
285 for (py = 0; py < h; py++)
287 for (px = 0; px < w; px++)
289 unsigned int mask, imask;
291 mask = ((unsigned int)(*sp)) << 24;
295 *p = mask | (*p & imask);
296 // if (*sp) *p = 0xff000000 | *p;
297 // else *p = 0x00000000;
304 evas_object_image_data_set(cw->obj, pix);
305 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
306 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
308 evas_object_image_data_set(o, pix);
309 evas_object_image_data_update_add(o, 0, 0, w, h);
318 unsigned int *pix, *p;
321 evas_object_image_size_get(cw->obj, &w, &h);
322 if ((w > 0) && (h > 0))
326 fprintf(stderr, "BUGGER: shape with native surface? cw=%p\n", cw);
330 evas_object_image_alpha_set(cw->obj, 0);
331 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
333 evas_object_image_alpha_set(o, 1);
335 pix = evas_object_image_data_get(cw->obj, 1);
339 for (py = 0; py < h; py++)
341 for (px = 0; px < w; px++)
345 evas_object_image_data_set(cw->obj, pix);
346 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
347 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
349 evas_object_image_data_set(o, pix);
350 evas_object_image_data_update_add(o, 0, 0, w, h);
354 // dont need to fix alpha chanel as blending
355 // should be totally off here regardless of
356 // alpha channel content
361 _e_mod_comp_cb_win_show_ready_timeout(void *data)
363 E_Comp_Win *cw = data;
369 if (cw->update_timeout)
371 ecore_timer_del(cw->update_timeout);
372 cw->update_timeout = NULL;
375 cw->c->updates = eina_list_append(cw->c->updates, cw);
377 _e_mod_comp_win_render_queue(cw);
379 cw->ready_timeout = NULL;
380 return ECORE_CALLBACK_CANCEL;
384 _e_mod_comp_win_ready_timeout_setup(E_Comp_Win *cw)
386 if (cw->ready_timeout)
388 ecore_timer_del(cw->ready_timeout);
389 cw->ready_timeout = NULL;
391 if (cw->show_ready) return;
392 if (cw->counter) return;
393 // FIXME: make show_ready option
400 cw->ready_timeout = ecore_timer_add
401 (_comp_mod->conf->first_draw_delay, _e_mod_comp_cb_win_show_ready_timeout, cw);
406 _e_mod_comp_win_update(E_Comp_Win *cw)
412 int pshaped = cw->shaped;
414 DBG("UPDATE [0x%x] pm = %x\n", cw->win, cw->pixmap);
415 if (_comp_mod->conf->grab) ecore_x_grab();
429 if (cw->shape_changed)
437 ecore_x_pixmap_geometry_get(cw->win, NULL, NULL, &(cw->w), &(cw->h));
438 cw->rects = ecore_x_window_shape_rectangles_get(cw->win, &(cw->rects_num));
441 for (i = 0; i < cw->rects_num; i++)
443 E_RECTS_CLIP_TO_RECT(cw->rects[i].x,
450 if (!_e_mod_comp_win_shaped_check(cw, cw->rects, cw->rects_num))
456 if ((cw->rects) && (!cw->shaped))
460 else if ((!cw->rects) && (cw->shaped))
467 if ((!cw->pixmap) || (cw->needpix))
471 pm = ecore_x_composite_name_window_pixmap_get(cw->win);
474 Ecore_X_Pixmap oldpm;
477 if (cw->xim) cw->needxim = 1;
482 ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
483 _e_mod_comp_win_ready_timeout_setup(cw);
484 if ((cw->pw > 0) && (cw->ph > 0))
485 evas_object_resize(cw->obj, cw->pw, cw->ph);
492 DBG("REND [0x%x] pixmap = [0x%x], %ix%i\n", cw->win, cw->pixmap, cw->pw, cw->ph);
493 if ((cw->pw <= 0) || (cw->ph <= 0))
497 DBG(" [0x%x] free native\n", cw->win);
498 evas_object_image_native_surface_set(cw->obj, NULL);
500 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
502 evas_object_image_native_surface_set(o, NULL);
507 DBG(" [0x%x] free pixmap\n", cw->win);
508 ecore_x_pixmap_free(cw->pixmap);
510 // cw->show_ready = 0; // hmm maybe not needed?
515 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
517 DBG(" [0x%x] up resize %ix%i\n", cw->win, cw->pw, cw->ph);
518 e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
519 e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
522 DBG(" [0x%x] free pm %x\n", cw->win, oldpm);
526 if (!((cw->pw > 0) && (cw->ph > 0)))
528 evas_object_image_native_surface_set(cw->obj, NULL);
529 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
531 evas_object_image_native_surface_set(o, NULL);
535 ecore_x_pixmap_free(oldpm);
539 if (!((cw->pw > 0) && (cw->ph > 0)))
541 if (_comp_mod->conf->grab) ecore_x_ungrab();
545 evas_object_move(cw->shobj, cw->x, cw->y);
547 evas_object_resize(cw->shobj, cw->pw, cw->ph);
549 if ((cw->c->gl) && (_comp_mod->conf->texture_from_pixmap) &&
550 (!cw->shaped) && (!cw->rects))
552 DBG("DEBUG - pm now %x\n", ecore_x_composite_name_window_pixmap_get(cw->win));
553 evas_object_image_size_set(cw->obj, cw->pw, cw->ph);
554 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
556 evas_object_image_size_set(o, cw->pw, cw->ph);
560 Evas_Native_Surface ns;
562 ns.version = EVAS_NATIVE_SURFACE_VERSION;
563 ns.type = EVAS_NATIVE_SURFACE_X11;
564 ns.data.x11.visual = cw->vis;
565 ns.data.x11.pixmap = cw->pixmap;
566 evas_object_image_native_surface_set(cw->obj, &ns);
567 DBG("NATIVE [0x%x] %x %ix%i\n", cw->win, cw->pixmap, cw->pw, cw->ph);
569 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
571 evas_object_image_native_surface_set(o, &ns);
574 r = e_mod_comp_update_rects_get(cw->up);
577 e_mod_comp_update_clear(cw->up);
578 for (i = 0; r[i].w > 0; i++)
582 x = r[i].x; y = r[i].y;
583 w = r[i].w; h = r[i].h;
584 DBG("UPDATE [0x%x] pm [0x%x] %i %i %ix%i\n", cw->win, cw->pixmap, x, y, w, h);
585 evas_object_image_data_update_add(cw->obj, x, y, w, h);
586 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
588 evas_object_image_data_update_add(o, x, y, w, h);
602 evas_object_image_native_surface_set(cw->obj, NULL);
603 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
605 evas_object_image_native_surface_set(o, NULL);
614 evas_object_image_size_set(cw->obj, 1, 1);
615 evas_object_image_data_set(cw->obj, NULL);
616 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
618 evas_object_image_size_set(o, 1, 1);
619 evas_object_image_data_set(o, NULL);
621 ecore_x_image_free(cw->xim);
627 if ((cw->xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth)))
628 e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
630 r = e_mod_comp_update_rects_get(cw->up);
637 pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL);
638 evas_object_image_data_set(cw->obj, pix);
639 evas_object_image_size_set(cw->obj, cw->pw, cw->ph);
640 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
642 evas_object_image_data_set(o, pix);
643 evas_object_image_size_set(o, cw->pw, cw->ph);
646 e_mod_comp_update_clear(cw->up);
647 for (i = 0; r[i].w > 0; i++)
651 x = r[i].x; y = r[i].y;
652 w = r[i].w; h = r[i].h;
653 if (!ecore_x_image_get(cw->xim, cw->pixmap, x, y, x, y, w, h))
655 DBG("UPDATE [0x%x] %i %i %ix%i FAIL!!!!!!!!!!!!!!!!!\n", cw->win, x, y, w, h);
656 e_mod_comp_update_add(cw->up, x, y, w, h);
661 // why do we neeed these 2? this smells wrong
662 pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL);
663 DBG("UPDATE [0x%x] %i %i %ix%i -- pix = %p\n", cw->win, x, y, w, h, pix);
664 evas_object_image_data_set(cw->obj, pix);
665 evas_object_image_data_update_add(cw->obj, x, y, w, h);
666 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
668 evas_object_image_data_set(o, pix);
669 evas_object_image_data_update_add(o, x, y, w, h);
677 _e_mod_comp_win_shape_rectangles_apply(cw, cw->rects, cw->rects_num);
681 if (cw->shape_changed)
682 _e_mod_comp_win_shape_rectangles_apply(cw, cw->rects, cw->rects_num);
684 cw->shape_changed = 0;
688 DBG("UPDATE [0x%x] NO RECTS!!! %i %i - %i %i\n", cw->win, cw->up->w, cw->up->h, cw->up->tw, cw->up->th);
689 // causes updates to be flagged when not needed - disabled
693 // FIXME: below cw update check screws with show
694 if (/*(!cw->update) &&*/ (cw->visible) && (cw->dmg_updates >= 1) &&
697 if (!evas_object_visible_get(cw->shobj))
699 if (!cw->hidden_override)
701 evas_object_show(cw->shobj);
702 _e_mod_comp_win_render_queue(cw);
707 edje_object_signal_emit(cw->shobj, "e,state,visible,on", "e");
716 e_manager_comp_event_src_visibility_send
717 (cw->c->man, (E_Manager_Comp_Source *)cw,
718 _e_mod_comp_cb_pending_after, cw->c);
720 cw->show_anim = EINA_TRUE;
724 if ((cw->shobj) && (cw->obj))
726 if (pshaped != cw->shaped)
729 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
731 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
735 if (_comp_mod->conf->grab) ecore_x_ungrab();
739 _e_mod_comp_pre_swap(void *data,
744 if (_comp_mod->conf->grab)
755 _e_mod_comp_cb_delayed_update_timer(void *data)
758 _e_mod_comp_render_queue(c);
759 c->new_up_timer = NULL;
760 return ECORE_CALLBACK_CANCEL;
764 _e_mod_comp_fps_update(E_Comp *c)
766 if (_comp_mod->conf->fps_show)
770 c->fps_bg = evas_object_rectangle_add(c->evas);
771 evas_object_color_set(c->fps_bg, 0, 0, 0, 128);
772 evas_object_layer_set(c->fps_bg, EVAS_LAYER_MAX);
773 evas_object_show(c->fps_bg);
775 c->fps_fg = evas_object_text_add(c->evas);
776 evas_object_text_font_set(c->fps_fg, "Sans", 10);
777 evas_object_text_text_set(c->fps_fg, "???");
778 evas_object_color_set(c->fps_fg, 255, 255, 255, 255);
779 evas_object_layer_set(c->fps_fg, EVAS_LAYER_MAX);
780 evas_object_show(c->fps_fg);
787 evas_object_del(c->fps_fg);
792 evas_object_del(c->fps_bg);
799 _e_mod_comp_cb_update(E_Comp *c)
804 Eina_List *new_updates = NULL; // for failed pixmap fetches - get them next frame
805 Eina_List *update_done = NULL;
806 // static int doframeinfo = -1;
808 c->update_job = NULL;
810 if (c->nocomp) goto nocomp;
811 if (_comp_mod->conf->grab)
817 EINA_LIST_FREE(c->updates, cw)
819 if (_comp_mod->conf->efl_sync)
821 if (((cw->counter) && (cw->drawme)) || (!cw->counter))
823 _e_mod_comp_win_update(cw);
826 update_done = eina_list_append(update_done, cw);
834 _e_mod_comp_win_update(cw);
837 new_updates = eina_list_append(new_updates, cw);
840 _e_mod_comp_fps_update(c);
841 if (_comp_mod->conf->fps_show)
844 double fps = 0.0, t, dt;
846 Evas_Coord x = 0, y = 0, w = 0, h = 0;
849 t = ecore_time_get();
850 if (_comp_mod->conf->fps_average_range < 1)
851 _comp_mod->conf->fps_average_range = 30;
852 else if (_comp_mod->conf->fps_average_range > 120)
853 _comp_mod->conf->fps_average_range = 120;
854 dt = t - c->frametimes[_comp_mod->conf->fps_average_range - 1];
855 if (dt > 0.0) fps = (double)_comp_mod->conf->fps_average_range / dt;
857 if (fps > 0.0) snprintf(buf, sizeof(buf), "FPS: %1.1f", fps);
858 else snprintf(buf, sizeof(buf), "N/A");
859 for (i = 121; i >= 1; i--) c->frametimes[i] = c->frametimes[i - 1];
860 c->frametimes[0] = t;
862 if (c->frameskip >= _comp_mod->conf->fps_average_range)
865 evas_object_text_text_set(c->fps_fg, buf);
867 evas_object_geometry_get(c->fps_fg, NULL, NULL, &w, &h);
870 z = e_util_zone_current_get(c->man);
873 switch (_comp_mod->conf->fps_corner)
875 case 3: // bottom-right
880 case 2: // bottom-left
890 default: // 0 // top-left
896 evas_object_move(c->fps_bg, x, y);
897 evas_object_resize(c->fps_bg, w, h);
898 evas_object_move(c->fps_fg, x + 4, y + 4);
900 if (_comp_mod->conf->lock_fps)
902 DBG("MANUAL RENDER...\n");
903 ecore_evas_manual_render(c->ee);
905 if (_comp_mod->conf->efl_sync)
907 EINA_LIST_FREE(update_done, cw)
909 ecore_x_sync_counter_inc(cw->counter, 1);
912 if (_comp_mod->conf->grab)
923 if (c->new_up_timer) ecore_timer_del(c->new_up_timer);
925 ecore_timer_add(0.001, _e_mod_comp_cb_delayed_update_timer, c);
926 // _e_mod_comp_render_queue(c);
928 c->updates = new_updates;
929 if (!c->animating) c->render_overflow--;
931 if (doframeinfo == -1)
934 if (getenv("DFI")) doframeinfo = 1;
938 static double t0 = 0.0;
941 t = ecore_time_get();
948 for (i = 0; i < fps; i+= 2) putchar('=');
949 printf(" : %3.3f\n", 1.0 / td);
955 cw = _e_mod_comp_fullscreen_check(c);
958 if (_comp_mod->conf->nocomp_fs)
963 printf("kill comp %x\n", cw->win);
965 c->render_overflow = OVER_FLOW;
966 ecore_x_window_hide(c->win);
970 printf("^^^^ undirect1 %x\n", cw->win);
971 ecore_x_composite_unredirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
978 ecore_x_pixmap_free(cw->pixmap);
982 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
983 cw->show_ready = 0; // hmm maybe not needed?
987 evas_object_image_size_set(cw->obj, 1, 1);
988 evas_object_image_data_set(cw->obj, NULL);
989 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
991 evas_object_image_size_set(o, 1, 1);
992 evas_object_image_data_set(o, NULL);
994 ecore_x_image_free(cw->xim);
999 Ecore_X_Region parts;
1001 eina_hash_del(damages, e_util_winid_str_get(cw->damage), cw);
1002 parts = ecore_x_region_new(NULL, 0);
1003 ecore_x_damage_subtract(cw->damage, 0, parts);
1004 ecore_x_region_free(parts);
1005 ecore_x_damage_free(cw->damage);
1008 if (cw->update_timeout)
1010 ecore_timer_del(cw->update_timeout);
1011 cw->update_timeout = NULL;
1016 cw->c->updates = eina_list_remove(cw->c->updates, cw);
1022 ecore_x_e_comp_sync_cancel_send(cw->bd->client.win);
1026 ecore_x_e_comp_sync_cancel_send(cw->win);
1028 ecore_x_sync_counter_inc(cw->counter, 1);
1030 // ecore_x_window_hide(cw->win);
1031 // ecore_x_window_show(cw->win);
1033 _e_mod_comp_render_queue(c);
1043 c->render_overflow = OVER_FLOW;
1044 ecore_x_window_show(c->win);
1045 EINA_INLIST_FOREACH(c->wins, cw)
1047 if (!cw->nocomp) continue;
1049 printf("restore comp %x --- %x\n", cw->win, cw->pixmap);
1050 if (cw->pixmap) ecore_x_pixmap_free(cw->pixmap);
1055 cw->show_ready = 0; // hmm maybe not needed?
1058 cw->damage = ecore_x_damage_new
1059 (cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
1060 eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
1062 if (!cw->redirected)
1064 printf("^^^^ redirect2 %x\n", cw->win);
1066 ecore_x_composite_redirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
1067 cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win);
1070 ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
1071 _e_mod_comp_win_ready_timeout_setup(cw);
1078 printf(" %x %ix%i\n", cw->pixmap, cw->pw, cw->ph);
1079 if ((cw->pw <= 0) || (cw->ph <= 0))
1081 ecore_x_pixmap_free(cw->pixmap);
1083 // cw->show_ready = 0; // hmm maybe not needed?
1085 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
1087 cw->dmg_updates = 0;
1088 DBG(" [0x%x] up resize2 %ix%i\n", cw->win, cw->pw, cw->ph);
1089 e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
1090 e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
1092 // _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
1095 if (!cw->hidden_override) evas_object_show(cw->shobj);
1096 cw->pending_count++;
1097 e_manager_comp_event_src_visibility_send
1098 (cw->c->man, (E_Manager_Comp_Source *)cw,
1099 _e_mod_comp_cb_pending_after, cw->c);
1100 // no need for effect
1102 _e_mod_comp_win_render_queue(cw);
1107 ecore_x_e_comp_sync_begin_send(cw->bd->client.win);
1111 ecore_x_e_comp_sync_begin_send(cw->win);
1118 DBG("UPDATE ALL DONE: overflow = %i\n", c->render_overflow);
1119 if (c->render_overflow <= 0)
1121 c->render_overflow = 0;
1122 if (c->render_animator) c->render_animator = NULL;
1123 return ECORE_CALLBACK_CANCEL;
1125 return ECORE_CALLBACK_RENEW;
1129 _e_mod_comp_cb_job(void *data)
1131 DBG("UPDATE ALL JOB...\n");
1132 _e_mod_comp_cb_update(data);
1136 _e_mod_comp_cb_animator(void *data)
1138 return _e_mod_comp_cb_update(data);
1142 _e_mod_comp_render_queue(E_Comp *c)
1144 if (_comp_mod->conf->lock_fps)
1146 if (c->render_animator)
1148 c->render_overflow = OVER_FLOW;
1151 c->render_animator = ecore_animator_add(_e_mod_comp_cb_animator, c);
1157 DBG("UPDATE JOB DEL...\n");
1158 ecore_job_del(c->update_job);
1159 c->update_job = NULL;
1160 c->render_overflow = 0;
1162 DBG("UPDATE JOB ADD...\n");
1163 c->update_job = ecore_job_add(_e_mod_comp_cb_job, c);
1168 _e_mod_comp_win_render_queue(E_Comp_Win *cw)
1171 _e_mod_comp_render_queue(cw->c);
1175 _e_mod_comp_find(Ecore_X_Window root)
1180 // fixme: use hash if compositors list > 4
1181 EINA_LIST_FOREACH(compositors, l, c)
1183 if (c->man->root == root) return c;
1189 _e_mod_comp_win_find(Ecore_X_Window win)
1191 return eina_hash_find(windows, e_util_winid_str_get(win));
1195 _e_mod_comp_border_client_find(Ecore_X_Window win)
1197 return eina_hash_find(borders, e_util_winid_str_get(win));
1201 _e_mod_comp_win_damage_find(Ecore_X_Damage damage)
1203 return eina_hash_find(damages, e_util_winid_str_get(damage));
1207 _e_mod_comp_win_is_borderless(E_Comp_Win *cw)
1209 if (!cw->bd) return 1;
1210 if ((cw->bd->client.border.name) &&
1211 (!strcmp(cw->bd->client.border.name, "borderless")))
1217 _e_mod_comp_win_do_shadow(E_Comp_Win *cw)
1219 if (cw->shaped) return 0;
1222 if (_e_mod_comp_win_is_borderless(cw)) return 0;
1228 _e_mod_comp_win_damage_timeout(void *data)
1230 E_Comp_Win *cw = data;
1234 if (cw->update_timeout)
1236 ecore_timer_del(cw->update_timeout);
1237 cw->update_timeout = NULL;
1240 cw->c->updates = eina_list_append(cw->c->updates, cw);
1243 _e_mod_comp_win_render_queue(cw);
1244 cw->update_timeout = NULL;
1245 return ECORE_CALLBACK_CANCEL;
1249 _e_mod_comp_object_del(void *data,
1252 E_Comp_Win *cw = data;
1256 _e_mod_comp_win_render_queue(cw);
1263 ecore_x_e_comp_sync_cancel_send(cw->bd->client.win);
1267 ecore_x_e_comp_sync_cancel_send(cw->win);
1269 ecore_x_sync_counter_inc(cw->counter, 1);
1271 if (cw->bd) eina_hash_del(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1273 evas_object_data_del(cw->shobj, "border");
1277 else if (obj == cw->pop)
1280 evas_object_data_del(cw->shobj, "popup");
1282 else if (obj == cw->menu)
1285 evas_object_data_del(cw->shobj, "menu");
1289 e_object_delfn_del(obj, cw->dfn);
1295 _e_mod_comp_done_defer(E_Comp_Win *cw)
1302 _e_mod_comp_win_render_queue(cw);
1304 if (cw->defer_hide) _e_mod_comp_win_hide(cw);
1306 if (cw->delete_me) _e_mod_comp_win_del(cw);
1311 _e_mod_comp_show_done(void *data,
1312 Evas_Object *obj __UNUSED__,
1313 const char *emission __UNUSED__,
1314 const char *source __UNUSED__)
1316 E_Comp_Win *cw = data;
1317 _e_mod_comp_done_defer(cw);
1321 _e_mod_comp_hide_done(void *data,
1322 Evas_Object *obj __UNUSED__,
1323 const char *emission __UNUSED__,
1324 const char *source __UNUSED__)
1326 E_Comp_Win *cw = data;
1327 _e_mod_comp_done_defer(cw);
1331 _e_mod_comp_win_sync_setup(E_Comp_Win *cw,
1334 if (!_comp_mod->conf->efl_sync) return;
1338 if (_e_mod_comp_win_is_borderless(cw) ||
1339 (_comp_mod->conf->loose_sync))
1340 cw->counter = ecore_x_e_comp_sync_counter_get(win);
1343 ecore_x_e_comp_sync_cancel_send(win);
1347 cw->counter = ecore_x_e_comp_sync_counter_get(win);
1350 ecore_x_e_comp_sync_begin_send(win);
1351 ecore_x_sync_counter_inc(cw->counter, 1);
1356 _e_mod_comp_win_shadow_setup(E_Comp_Win *cw)
1361 Eina_List *list = NULL, *l;
1363 const char *title = NULL, *name = NULL, *clas = NULL, *role = NULL;
1364 Ecore_X_Window_Type primary_type = ECORE_X_WINDOW_TYPE_UNKNOWN;
1366 evas_object_image_smooth_scale_set(cw->obj, _comp_mod->conf->smooth_windows);
1367 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
1369 evas_object_image_smooth_scale_set(o, _comp_mod->conf->smooth_windows);
1373 list = _comp_mod->conf->match.borders;
1374 title = cw->bd->client.icccm.title;
1375 if (cw->bd->client.netwm.name) title = cw->bd->client.netwm.name;
1376 name = cw->bd->client.icccm.name;
1377 clas = cw->bd->client.icccm.class;
1378 role = cw->bd->client.icccm.window_role;
1379 primary_type = cw->bd->client.netwm.type;
1383 // FIXME: i only added "shelf" as a name for popups that are shelves
1384 // ... need more nmes like for pager popup, evertything, exebuf
1386 list = _comp_mod->conf->match.popups;
1387 name = cw->pop->name;
1391 // FIXME: e has no way to tell e menus apart... need naming
1392 list = _comp_mod->conf->match.menus;
1396 list = _comp_mod->conf->match.overrides;
1401 primary_type = cw->primary_type;
1404 EINA_LIST_FOREACH(list, l, m)
1406 if (((m->title) && (!title)) ||
1407 ((title) && (m->title) && (!e_util_glob_match(title, m->title))))
1409 if (((m->name) && (!name)) ||
1410 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1412 if (((m->clas) && (!clas)) ||
1413 ((clas) && (m->clas) && (!e_util_glob_match(clas, m->clas))))
1415 if (((m->role) && (!role)) ||
1416 ((role) && (m->role) && (!e_util_glob_match(role, m->role))))
1418 if ((primary_type != ECORE_X_WINDOW_TYPE_UNKNOWN) &&
1419 (m->primary_type != ECORE_X_WINDOW_TYPE_UNKNOWN) &&
1420 (primary_type != m->primary_type))
1424 if (m->borderless != 0)
1428 if ((cw->bd->client.mwm.borderless) || (cw->bd->borderless))
1430 if (!(((m->borderless == -1) && (!borderless)) ||
1431 ((m->borderless == 1) && (borderless))))
1438 if (((cw->bd->client.icccm.transient_for != 0) ||
1439 (cw->bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)))
1441 if (!(((m->dialog == -1) && (!dialog)) ||
1442 ((m->dialog == 1) && (dialog))))
1445 if (m->accepts_focus != 0)
1447 int accepts_focus = 0;
1449 if (cw->bd->client.icccm.accepts_focus)
1451 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
1452 ((m->accepts_focus == 1) && (accepts_focus))))
1459 if (cw->bd->client.vkbd.vkbd)
1461 if (!(((m->vkbd == -1) && (!vkbd)) ||
1462 ((m->vkbd == 1) && (vkbd))))
1465 if (m->quickpanel != 0)
1469 if (cw->bd->client.illume.quickpanel.quickpanel)
1471 if (!(((m->quickpanel == -1) && (!quickpanel)) ||
1472 ((m->quickpanel == 1) && (quickpanel))))
1477 if (!(((m->argb == -1) && (!cw->argb)) ||
1478 ((m->argb == 1) && (cw->argb))))
1481 if (m->fullscreen != 0)
1485 if (cw->bd->client.netwm.state.fullscreen)
1487 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1488 ((m->fullscreen == 1) && (fullscreen))))
1495 if (cw->bd->client.netwm.state.modal)
1497 if (!(((m->modal == -1) && (!modal)) ||
1498 ((m->modal == 1) && (modal))))
1502 if (m->shadow_style)
1504 snprintf(buf, sizeof(buf), "e/comp/%s",
1506 ok = e_theme_edje_object_set(cw->shobj, "base/theme/borders",
1511 // use different shadow objects/group per window type?
1514 if (_comp_mod->conf->shadow_file)
1515 ok = edje_object_file_set(cw->shobj, _comp_mod->conf->shadow_file,
1520 if (_comp_mod->conf->shadow_style)
1522 snprintf(buf, sizeof(buf), "e/comp/%s",
1523 _comp_mod->conf->shadow_style);
1524 ok = e_theme_edje_object_set(cw->shobj, "base/theme/borders",
1528 ok = e_theme_edje_object_set(cw->shobj, "base/theme/borders",
1531 if (!ok) // fallback to local shadow.edj - will go when default theme supports this
1533 snprintf(buf, sizeof(buf), "%s/shadow.edj",
1534 e_module_dir_get(_comp_mod->module));
1535 ok = edje_object_file_set(cw->shobj, buf, "shadow");
1537 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1538 if (_comp_mod->conf->use_shadow)
1540 if (_e_mod_comp_win_do_shadow(cw))
1541 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1543 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1547 if (cw->bd->focused)
1548 edje_object_signal_emit(cw->shobj, "e,state,focus,on", "e");
1549 if (cw->bd->client.icccm.urgent)
1550 edje_object_signal_emit(cw->shobj, "e,state,urgent,on", "e");
1555 _e_mod_comp_cb_win_mirror_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
1559 if (!(cw = data)) return;
1560 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
1563 static Evas_Object *
1564 _e_mod_comp_win_mirror_add(E_Comp_Win *cw)
1568 if (!cw->c) return NULL;
1570 o = evas_object_image_filled_add(cw->c->evas);
1571 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
1572 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
1573 evas_object_image_smooth_scale_set(o, _comp_mod->conf->smooth_windows);
1575 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
1576 _e_mod_comp_cb_win_mirror_del, cw);
1578 if ((cw->pixmap) && (cw->pw > 0) && (cw->ph > 0))
1584 alpha = evas_object_image_alpha_get(cw->obj);
1585 evas_object_image_size_get(cw->obj, &w, &h);
1587 evas_object_image_alpha_set(o, alpha);
1591 pix = evas_object_image_data_get(cw->obj, 0);
1592 evas_object_image_data_set(o, pix);
1593 evas_object_image_size_set(o, w, h);
1594 evas_object_image_data_set(o, pix);
1595 evas_object_image_data_update_add(o, 0, 0, w, h);
1601 Evas_Native_Surface ns;
1603 ns.version = EVAS_NATIVE_SURFACE_VERSION;
1604 ns.type = EVAS_NATIVE_SURFACE_X11;
1605 ns.data.x11.visual = cw->vis;
1606 ns.data.x11.pixmap = cw->pixmap;
1607 evas_object_image_size_set(o, w, h);
1608 evas_object_image_native_surface_set(o, &ns);
1609 evas_object_image_data_update_add(o, 0, 0, w, h);
1613 pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL);
1614 evas_object_image_data_set(o, pix);
1615 evas_object_image_size_set(o, w, h);
1616 evas_object_image_data_set(o, pix);
1617 evas_object_image_data_update_add(o, 0, 0, w, h);
1620 evas_object_image_size_set(o, w, h);
1621 evas_object_image_data_update_add(o, 0, 0, w, h);
1623 evas_object_stack_above(o, cw->shobj);
1628 _e_mod_comp_win_add(E_Comp *c,
1631 Ecore_X_Window_Attributes att;
1634 cw = calloc(1, sizeof(E_Comp_Win));
1635 if (!cw) return NULL;
1638 cw->opacity = 255.0;
1639 cw->bd = e_border_find_by_window(cw->win);
1640 if (_comp_mod->conf->grab) ecore_x_grab();
1646 EINA_INLIST_FOREACH(c->wins, cw2)
1647 if (cw->bd == cw2->bd) break;
1656 eina_hash_del(windows, e_util_winid_str_get(cw->win), cw);
1660 Ecore_X_Region parts;
1662 eina_hash_del(damages, e_util_winid_str_get(cw->damage), cw);
1663 parts = ecore_x_region_new(NULL, 0);
1664 ecore_x_damage_subtract(cw->damage, 0, parts);
1665 ecore_x_region_free(parts);
1666 ecore_x_damage_free(cw->damage);
1670 if (cw->update_timeout)
1672 ecore_timer_del(cw->update_timeout);
1673 cw->update_timeout = NULL;
1676 if (cw->ready_timeout)
1678 ecore_timer_del(cw->ready_timeout);
1679 cw->ready_timeout = NULL;
1683 memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
1684 if (!ecore_x_window_attributes_get(cw->win, &att))
1686 if (_comp_mod->conf->grab) ecore_x_ungrab();
1690 cw->vis = att.visual;
1691 cw->depth = att.depth;
1692 cw->argb = (cw->bd->argb || cw->bd->client.argb);
1694 eina_hash_add(windows, e_util_winid_str_get(cw->win), cw);
1697 cw->damage = ecore_x_damage_new
1698 (cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
1699 eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
1702 cw->dmg_updates = 0;
1705 evas_object_image_alpha_set(cw->obj, cw->argb);
1707 if (_comp_mod->conf->grab) ecore_x_ungrab();
1713 eina_hash_add(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1714 cw->dfn = e_object_delfn_add(E_OBJECT(cw->bd), _e_mod_comp_object_del, cw);
1717 // _e_mod_comp_win_sync_setup(cw, cw->bd->client.win);
1719 else if ((cw->pop = e_popup_find_by_window(cw->win)))
1721 cw->dfn = e_object_delfn_add(E_OBJECT(cw->pop),
1722 _e_mod_comp_object_del, cw);
1725 else if ((cw->menu = e_menu_find_by_window(cw->win)))
1727 cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu),
1728 _e_mod_comp_object_del, cw);
1733 char *netwm_title = NULL;
1735 cw->title = ecore_x_icccm_title_get(cw->win);
1736 if (ecore_x_netwm_name_get(cw->win, &netwm_title))
1738 if (cw->title) free(cw->title);
1739 cw->title = netwm_title;
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;
1746 // _e_mod_comp_win_sync_setup(cw, cw->win);
1751 // FIXME: config - disable ready timeout for non-counter wins
1752 // cw->show_ready = 1;
1754 // fixme: could use bd/pop/menu for this too
1755 memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
1756 if (!ecore_x_window_attributes_get(cw->win, &att))
1759 if (_comp_mod->conf->grab) ecore_x_ungrab();
1762 if ((!att.input_only) &&
1763 ((att.depth != 24) && (att.depth != 32)))
1765 printf("WARNING: window 0x%x not 24/32bpp -> %ibpp\n", cw->win, att.depth);
1768 cw->input_only = att.input_only;
1769 cw->override = att.override;
1770 cw->vis = att.visual;
1771 cw->depth = att.depth;
1772 cw->argb = ecore_x_window_argb_get(cw->win);
1773 eina_hash_add(windows, e_util_winid_str_get(cw->win), cw);
1775 if ((!cw->input_only) && (!cw->invalid))
1777 Ecore_X_Rectangle *rects;
1780 cw->damage = ecore_x_damage_new
1781 (cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
1782 eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
1783 cw->shobj = edje_object_add(c->evas);
1784 cw->obj = evas_object_image_filled_add(c->evas);
1785 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
1786 if (cw->argb) evas_object_image_alpha_set(cw->obj, 1);
1787 else evas_object_image_alpha_set(cw->obj, 0);
1789 if (att.override && !(att.event_mask.mine & ECORE_X_EVENT_MASK_WINDOW_PROPERTY))
1790 ecore_x_event_mask_set(cw->win, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1792 _e_mod_comp_win_shadow_setup(cw);
1794 edje_object_signal_callback_add(cw->shobj, "e,action,show,done", "e",
1795 _e_mod_comp_show_done, cw);
1796 edje_object_signal_callback_add(cw->shobj, "e,action,hide,done", "e",
1797 _e_mod_comp_hide_done, cw);
1798 evas_object_show(cw->obj);
1799 ecore_x_window_shape_events_select(cw->win, 1);
1800 rects = ecore_x_window_shape_rectangles_get(cw->win, &num);
1807 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);
1814 if (!_e_mod_comp_shaped_check(att.w, att.h, rects, num))
1821 cw->shape_changed = 1;
1826 if (cw->bd) evas_object_data_set(cw->shobj, "border", cw->bd);
1828 evas_object_data_set(cw->shobj, "popup", cw->pop);
1830 evas_object_data_set(cw->shobj, "menu", cw->menu);
1832 evas_object_pass_events_set(cw->obj, 1);
1834 cw->pending_count++;
1835 e_manager_comp_event_src_add_send
1836 (cw->c->man, (E_Manager_Comp_Source *)cw,
1837 _e_mod_comp_cb_pending_after, cw->c);
1841 cw->shobj = evas_object_rectangle_add(c->evas);
1842 evas_object_color_set(cw->shobj, 0, 0, 0, 0);
1844 evas_object_pass_events_set(cw->shobj, 1);
1845 evas_object_data_set(cw->shobj, "win",
1846 (void *)((unsigned long)cw->win));
1847 evas_object_data_set(cw->shobj, "src", cw);
1849 c->wins_invalid = 1;
1850 c->wins = eina_inlist_append(c->wins, EINA_INLIST_GET(cw));
1851 cw->up = e_mod_comp_update_new();
1852 e_mod_comp_update_tile_size_set(cw->up, 32, 32);
1854 e_mod_comp_update_policy_set
1855 (cw->up, E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH);
1856 if (((!cw->input_only) && (!cw->invalid)) && (cw->override))
1859 // we redirect all subwindows anyway
1860 // ecore_x_composite_redirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
1861 cw->dmg_updates = 0;
1863 DBG(" [0x%x] add\n", cw->win);
1864 if (_comp_mod->conf->grab) ecore_x_ungrab();
1869 _e_mod_comp_win_del(E_Comp_Win *cw)
1878 if ((!cw->input_only) && (!cw->invalid))
1880 cw->pending_count++;
1881 e_manager_comp_event_src_del_send
1882 (cw->c->man, (E_Manager_Comp_Source *)cw,
1883 _e_mod_comp_cb_pending_after, cw->c);
1886 e_mod_comp_update_free(cw->up);
1887 DBG(" [0x%x] del\n", cw->win);
1893 if (cw->update_timeout)
1895 ecore_timer_del(cw->update_timeout);
1896 cw->update_timeout = NULL;
1898 if (cw->ready_timeout)
1900 ecore_timer_del(cw->ready_timeout);
1901 cw->ready_timeout = NULL;
1907 eina_hash_del(borders, e_util_winid_str_get(cw->bd->client.win), cw);
1908 e_object_delfn_del(E_OBJECT(cw->bd), cw->dfn);
1913 e_object_delfn_del(E_OBJECT(cw->pop), cw->dfn);
1918 e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn);
1925 ecore_x_pixmap_free(cw->pixmap);
1929 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
1930 cw->show_ready = 0; // hmm maybe not needed?
1934 // we redirect all subwindows anyway
1935 // ecore_x_composite_unredirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
1943 cw->c->updates = eina_list_remove(cw->c->updates, cw);
1948 EINA_LIST_FREE(cw->obj_mirror, o)
1950 if (cw->xim) evas_object_image_data_set(o, NULL);
1951 evas_object_event_callback_del(o, EVAS_CALLBACK_DEL,
1952 _e_mod_comp_cb_win_mirror_del);
1959 evas_object_image_data_set(cw->obj, NULL);
1960 ecore_x_image_free(cw->xim);
1965 evas_object_del(cw->obj);
1970 evas_object_del(cw->shobj);
1974 eina_hash_del(windows, e_util_winid_str_get(cw->win), cw);
1977 Ecore_X_Region parts;
1979 eina_hash_del(damages, e_util_winid_str_get(cw->damage), cw);
1980 parts = ecore_x_region_new(NULL, 0);
1981 ecore_x_damage_subtract(cw->damage, 0, parts);
1982 ecore_x_region_free(parts);
1983 ecore_x_damage_free(cw->damage);
1986 if (cw->title) free(cw->title);
1987 if (cw->name) free(cw->name);
1988 if (cw->clas) free(cw->clas);
1989 if (cw->role) free(cw->role);
1990 cw->c->wins_invalid = 1;
1991 cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
1992 pending_count = cw->pending_count;
1993 memset(cw, 0, sizeof(E_Comp_Win));
1994 cw->pending_count = pending_count;
1995 cw->delete_pending = 1;
1996 if (cw->pending_count > 0) return;
2001 _e_mod_comp_win_show(E_Comp_Win *cw)
2006 if (cw->visible) return;
2008 DBG(" [0x%x] sho ++ [redir=%i, pm=%x, dmg_up=%i]\n",
2009 cw->win, cw->redirected, cw->pixmap, cw->dmg_updates);
2010 _e_mod_comp_win_configure(cw, cw->hidden.x, cw->hidden.y, cw->w, cw->h, cw->border);
2011 if ((cw->input_only) || (cw->invalid)) return;
2013 cw->show_anim = EINA_FALSE;
2017 _e_mod_comp_win_sync_setup(cw, cw->bd->client.win);
2019 _e_mod_comp_win_sync_setup(cw, cw->win);
2023 DBG(" [0x%x] real hid - fix\n", cw->win);
2027 evas_object_image_native_surface_set(cw->obj, NULL);
2029 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
2031 evas_object_image_native_surface_set(o, NULL);
2036 ecore_x_pixmap_free(cw->pixmap);
2040 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2044 evas_object_image_size_set(cw->obj, 1, 1);
2045 evas_object_image_data_set(cw->obj, NULL);
2046 ecore_x_image_free(cw->xim);
2048 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
2050 evas_object_image_size_set(o, 1, 1);
2051 evas_object_image_data_set(o, NULL);
2061 cw->dmg_updates = 1;
2063 cw->dmg_updates = 0;
2066 cw->dmg_updates = 1;
2067 if ((!cw->redirected) || (!cw->pixmap))
2069 // we redirect all subwindows anyway
2070 // ecore_x_composite_redirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
2071 cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win);
2074 ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph));
2075 _e_mod_comp_win_ready_timeout_setup(cw);
2082 if ((cw->pw <= 0) || (cw->ph <= 0))
2086 ecore_x_pixmap_free(cw->pixmap);
2089 // cw->show_ready = 0; // hmm maybe not needed?
2092 DBG(" [0x%x] up resize %ix%i\n", cw->win, cw->pw, cw->ph);
2093 e_mod_comp_update_resize(cw->up, cw->pw, cw->ph);
2094 e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph);
2095 evas_object_image_size_set(cw->obj, cw->pw, cw->ph);
2096 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
2098 evas_object_image_size_set(o, cw->pw, cw->ph);
2100 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2102 if ((cw->dmg_updates >= 1) && (cw->show_ready))
2105 if (!cw->hidden_override) evas_object_show(cw->shobj);
2106 edje_object_signal_emit(cw->shobj, "e,state,visible,on", "e");
2112 _e_mod_comp_win_render_queue(cw);
2114 cw->pending_count++;
2115 e_manager_comp_event_src_visibility_send
2116 (cw->c->man, (E_Manager_Comp_Source *)cw,
2117 _e_mod_comp_cb_pending_after, cw->c);
2119 _e_mod_comp_win_render_queue(cw);
2123 _e_mod_comp_win_real_hide(E_Comp_Win *cw)
2127 _e_mod_comp_win_hide(cw);
2131 _e_mod_comp_win_hide(cw);
2135 _e_mod_comp_win_hide(E_Comp_Win *cw)
2140 if ((!cw->visible) && (!cw->defer_hide)) return;
2142 if ((cw->input_only) || (cw->invalid)) return;
2143 DBG(" [0x%x] hid --\n", cw->win);
2147 edje_object_signal_emit(cw->shobj, "e,state,visible,off", "e");
2153 _e_mod_comp_win_render_queue(cw);
2155 cw->pending_count++;
2156 e_manager_comp_event_src_visibility_send
2157 (cw->c->man, (E_Manager_Comp_Source *)cw,
2158 _e_mod_comp_cb_pending_after, cw->c);
2163 evas_object_hide(cw->shobj);
2165 if (cw->update_timeout)
2167 ecore_timer_del(cw->update_timeout);
2168 cw->update_timeout = NULL;
2170 if (_comp_mod->conf->keep_unmapped)
2172 if (_comp_mod->conf->send_flush)
2174 if (cw->bd) ecore_x_e_comp_flush_send(cw->bd->client.win);
2175 else ecore_x_e_comp_flush_send(cw->win);
2177 if (_comp_mod->conf->send_dump)
2179 if (cw->bd) ecore_x_e_comp_dump_send(cw->bd->client.win);
2180 else ecore_x_e_comp_dump_send(cw->win);
2184 if (cw->ready_timeout)
2186 ecore_timer_del(cw->ready_timeout);
2187 cw->ready_timeout = NULL;
2192 evas_object_image_native_surface_set(cw->obj, NULL);
2194 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
2196 evas_object_image_native_surface_set(o, NULL);
2201 ecore_x_pixmap_free(cw->pixmap);
2205 ecore_x_e_comp_pixmap_set(cw->win, cw->pixmap);
2206 // cw->show_ready = 0; // hmm maybe not needed?
2210 evas_object_image_size_set(cw->obj, 1, 1);
2211 evas_object_image_data_set(cw->obj, NULL);
2212 ecore_x_image_free(cw->xim);
2214 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
2216 evas_object_image_size_set(o, 1, 1);
2217 evas_object_image_data_set(o, NULL);
2222 // we redirect all subwindows anyway
2223 // ecore_x_composite_unredirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL);
2228 _e_mod_comp_win_render_queue(cw);
2229 if (_comp_mod->conf->send_flush)
2231 if (cw->bd) ecore_x_e_comp_flush_send(cw->bd->client.win);
2232 else ecore_x_e_comp_flush_send(cw->win);
2234 if (_comp_mod->conf->send_dump)
2236 if (cw->bd) ecore_x_e_comp_dump_send(cw->bd->client.win);
2237 else ecore_x_e_comp_dump_send(cw->win);
2242 _e_mod_comp_win_raise_above(E_Comp_Win *cw,
2245 DBG(" [0x%x] abv [0x%x]\n", cw->win, cw2->win);
2246 cw->c->wins_invalid = 1;
2247 cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2248 cw->c->wins = eina_inlist_append_relative(cw->c->wins,
2249 EINA_INLIST_GET(cw),
2250 EINA_INLIST_GET(cw2));
2251 evas_object_stack_above(cw->shobj, cw2->shobj);
2252 _e_mod_comp_win_render_queue(cw);
2253 cw->pending_count++;
2254 e_manager_comp_event_src_config_send
2255 (cw->c->man, (E_Manager_Comp_Source *)cw,
2256 _e_mod_comp_cb_pending_after, cw->c);
2260 _e_mod_comp_win_raise(E_Comp_Win *cw)
2262 DBG(" [0x%x] rai\n", cw->win);
2263 cw->c->wins_invalid = 1;
2264 cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2265 cw->c->wins = eina_inlist_append(cw->c->wins, EINA_INLIST_GET(cw));
2266 evas_object_raise(cw->shobj);
2267 _e_mod_comp_win_render_queue(cw);
2268 cw->pending_count++;
2269 e_manager_comp_event_src_config_send
2270 (cw->c->man, (E_Manager_Comp_Source *)cw,
2271 _e_mod_comp_cb_pending_after, cw->c);
2275 _e_mod_comp_win_lower(E_Comp_Win *cw)
2277 DBG(" [0x%x] low\n", cw->win);
2278 cw->c->wins_invalid = 1;
2279 cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw));
2280 cw->c->wins = eina_inlist_prepend(cw->c->wins, EINA_INLIST_GET(cw));
2281 evas_object_lower(cw->shobj);
2282 _e_mod_comp_win_render_queue(cw);
2283 cw->pending_count++;
2284 e_manager_comp_event_src_config_send
2285 (cw->c->man, (E_Manager_Comp_Source *)cw,
2286 _e_mod_comp_cb_pending_after, cw->c);
2290 _e_mod_comp_win_configure(E_Comp_Win *cw,
2301 cw->border = border;
2305 if (!((x == cw->x) && (y == cw->y)))
2307 DBG(" [0x%x] mov %4i %4i\n", cw->win, x, y);
2310 evas_object_move(cw->shobj, cw->x, cw->y);
2319 if (!((w == cw->w) && (h == cw->h)))
2325 // was cw->w / cw->h
2326 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2327 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2331 if ((cw->bd->shading) || (cw->bd->shaded))
2334 // was cw->w / cw->h
2335 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2336 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2344 // if (cw->ready_timeout) ecore_timer_del(cw->ready_timeout);
2345 // cw->ready_timeout = ecore_timer_add
2346 // (_comp_mod->conf->first_draw_delay,
2347 // _e_mod_comp_cb_win_show_ready_timeout, cw);
2351 if (cw->border != border)
2353 cw->border = border;
2355 // was cw->w / cw->h
2356 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2357 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2359 if ((cw->input_only) || (cw->invalid)) return;
2363 if (!((w == cw->w) && (h == cw->h)))
2365 DBG(" [0x%x] rsz %4ix%4i\n", cw->win, w, h);
2369 // was cw->w / cw->h
2370 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2371 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2373 if (cw->border != border)
2375 cw->border = border;
2377 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2378 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2380 if ((cw->input_only) || (cw->invalid)) return;
2381 _e_mod_comp_win_render_queue(cw);
2383 // add pending manager comp event count to match below config send
2384 cw->pending_count++;
2385 e_manager_comp_event_src_config_send(cw->c->man,
2386 (E_Manager_Comp_Source *)cw,
2387 _e_mod_comp_cb_pending_after, cw->c);
2391 _e_mod_comp_win_damage(E_Comp_Win *cw,
2398 if ((cw->input_only) || (cw->invalid)) return;
2399 DBG(" [0x%x] dmg [%x] %4i %4i %4ix%4i\n", cw->win, cw->damage, x, y, w, h);
2400 if ((dmg) && (cw->damage))
2402 Ecore_X_Region parts;
2404 parts = ecore_x_region_new(NULL, 0);
2405 ecore_x_damage_subtract(cw->damage, 0, parts);
2406 ecore_x_region_free(parts);
2409 e_mod_comp_update_add(cw->up, x, y, w, h);
2414 if (!cw->update_timeout)
2415 cw->update_timeout = ecore_timer_add
2416 (ecore_animator_frametime_get() * 2,
2417 _e_mod_comp_win_damage_timeout, cw);
2424 cw->c->updates = eina_list_append(cw->c->updates, cw);
2426 _e_mod_comp_win_render_queue(cw);
2430 _e_mod_comp_win_reshape(E_Comp_Win *cw)
2432 if (cw->shape_changed) return;
2433 cw->shape_changed = 1;
2437 cw->c->updates = eina_list_append(cw->c->updates, cw);
2439 e_mod_comp_update_add(cw->up, 0, 0, cw->w, cw->h);
2440 _e_mod_comp_win_render_queue(cw);
2443 //////////////////////////////////////////////////////////////////////////
2446 _e_mod_comp_create(void *data __UNUSED__,
2447 int type __UNUSED__,
2450 Ecore_X_Event_Window_Create *ev = event;
2452 E_Comp *c = _e_mod_comp_find(ev->parent);
2453 if (!c) return ECORE_CALLBACK_PASS_ON;
2454 if (_e_mod_comp_win_find(ev->win)) return ECORE_CALLBACK_PASS_ON;
2455 if (c->win == ev->win) return ECORE_CALLBACK_PASS_ON;
2456 if (c->ee_win == ev->win) return ECORE_CALLBACK_PASS_ON;
2457 cw = _e_mod_comp_win_add(c, ev->win);
2458 if (cw) _e_mod_comp_win_configure(cw, ev->x, ev->y, ev->w, ev->h, ev->border);
2459 return ECORE_CALLBACK_PASS_ON;
2463 _e_mod_comp_destroy(void *data __UNUSED__,
2464 int type __UNUSED__,
2467 Ecore_X_Event_Window_Destroy *ev = event;
2468 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2469 if (!cw) return ECORE_CALLBACK_PASS_ON;
2470 if (cw->animating) cw->delete_me = 1;
2471 else _e_mod_comp_win_del(cw);
2472 return ECORE_CALLBACK_PASS_ON;
2476 _e_mod_comp_show(void *data __UNUSED__,
2477 int type __UNUSED__,
2480 Ecore_X_Event_Window_Show *ev = event;
2481 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2482 if (!cw) return ECORE_CALLBACK_PASS_ON;
2483 if (cw->visible) return ECORE_CALLBACK_PASS_ON;
2484 _e_mod_comp_win_show(cw);
2485 return ECORE_CALLBACK_PASS_ON;
2489 _e_mod_comp_hide(void *data __UNUSED__,
2490 int type __UNUSED__,
2493 Ecore_X_Event_Window_Hide *ev = event;
2494 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2495 if (!cw) return ECORE_CALLBACK_PASS_ON;
2496 if (!cw->visible) return ECORE_CALLBACK_PASS_ON;
2497 _e_mod_comp_win_real_hide(cw);
2498 return ECORE_CALLBACK_PASS_ON;
2502 _e_mod_comp_reparent(void *data __UNUSED__,
2503 int type __UNUSED__,
2506 Ecore_X_Event_Window_Reparent *ev = event;
2507 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2508 if (!cw) return ECORE_CALLBACK_PASS_ON;
2509 DBG("== repar [0x%x] to [0x%x]\n", ev->win, ev->parent);
2510 if (ev->parent != cw->c->man->root)
2511 _e_mod_comp_win_del(cw);
2512 return ECORE_CALLBACK_PASS_ON;
2516 _e_mod_comp_configure(void *data __UNUSED__,
2517 int type __UNUSED__,
2520 Ecore_X_Event_Window_Configure *ev = event;
2521 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2522 if (!cw) return ECORE_CALLBACK_PASS_ON;
2524 if (ev->abovewin == 0)
2526 if (EINA_INLIST_GET(cw)->prev) _e_mod_comp_win_lower(cw);
2530 E_Comp_Win *cw2 = _e_mod_comp_win_find(ev->abovewin);
2534 E_Comp_Win *cw3 = (E_Comp_Win *)(EINA_INLIST_GET(cw)->prev);
2536 if (cw3 != cw2) _e_mod_comp_win_raise_above(cw, cw2);
2540 if (!((cw->x == ev->x) && (cw->y == ev->y) &&
2541 (cw->w == ev->w) && (cw->h == ev->h) &&
2542 (cw->border == ev->border)))
2544 _e_mod_comp_win_configure(cw, ev->x, ev->y, ev->w, ev->h, ev->border);
2546 return ECORE_CALLBACK_PASS_ON;
2550 _e_mod_comp_stack(void *data __UNUSED__,
2551 int type __UNUSED__,
2554 Ecore_X_Event_Window_Stack *ev = event;
2555 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2556 if (!cw) return ECORE_CALLBACK_PASS_ON;
2557 if (ev->detail == ECORE_X_WINDOW_STACK_ABOVE) _e_mod_comp_win_raise(cw);
2558 else _e_mod_comp_win_lower(cw);
2559 return ECORE_CALLBACK_PASS_ON;
2563 _e_mod_comp_win_opacity_set(E_Comp_Win *cw)
2567 if (ecore_x_window_prop_card32_get(cw->win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, &val, 1) > 0)
2569 cw->opacity = (val >> 24);
2570 evas_object_color_set(cw->shobj, cw->opacity, cw->opacity, cw->opacity, cw->opacity);
2575 _e_mod_comp_property(void *data __UNUSED__,
2576 int type __UNUSED__,
2577 void *event __UNUSED__)
2579 Ecore_X_Event_Window_Property *ev = event;
2581 if (ev->atom == ECORE_X_ATOM_NET_WM_WINDOW_OPACITY)
2583 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2584 if (!cw) return ECORE_CALLBACK_PASS_ON;
2585 _e_mod_comp_win_opacity_set(cw);
2587 return ECORE_CALLBACK_PASS_ON;
2591 _e_mod_comp_message(void *data __UNUSED__,
2592 int type __UNUSED__,
2595 Ecore_X_Event_Client_Message *ev = event;
2596 E_Comp_Win *cw = NULL;
2597 int version, w = 0, h = 0;
2598 Eina_Bool force = 0;
2600 if (ev->message_type == ECORE_X_ATOM_NET_WM_WINDOW_OPACITY)
2602 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2603 if (!cw) return ECORE_CALLBACK_PASS_ON;
2604 _e_mod_comp_win_opacity_set(cw);
2605 return ECORE_CALLBACK_PASS_ON;
2608 if ((ev->message_type != ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE) ||
2609 (ev->format != 32)) return ECORE_CALLBACK_PASS_ON;
2610 version = ev->data.l[1];
2611 cw = _e_mod_comp_border_client_find(ev->data.l[0]);
2614 if (!cw->bd) return ECORE_CALLBACK_PASS_ON;
2615 if (ev->data.l[0] != cw->bd->client.win) return ECORE_CALLBACK_PASS_ON;
2619 cw = _e_mod_comp_win_find(ev->data.l[0]);
2620 if (!cw) return ECORE_CALLBACK_PASS_ON;
2621 if (ev->data.l[0] != cw->win) return ECORE_CALLBACK_PASS_ON;
2623 if (version == 1) // v 0 was first, v1 added size params
2631 if ((cw->bd->shading) || (cw->bd->shaded)) force = 1;
2632 clw = cw->hidden.w -
2633 cw->bd->client_inset.l -
2634 cw->bd->client_inset.r;
2635 clh = cw->hidden.h -
2636 cw->bd->client_inset.t -
2637 cw->bd->client_inset.b;
2638 DBG(" [0x%x] sync draw done @%4ix%4i, bd %4ix%4i\n", cw->win,
2639 w, h, cw->bd->client.w, cw->bd->client.h);
2640 if ((w != clw) || (h != clh))
2648 else return ECORE_CALLBACK_PASS_ON;
2654 DBG(" [0x%x] sync draw done @%4ix%4i, cw %4ix%4i\n", cw->win, w, h, cw->hidden.w, cw->hidden.h);
2655 if ((w != cw->hidden.w) || (h != cw->hidden.h))
2662 else return ECORE_CALLBACK_PASS_ON;
2667 DBG(" [0x%x] sync draw done %4ix%4i\n", cw->win, cw->w, cw->h);
2672 DBG(" [0x%x] have counter\n", cw->win);
2676 DBG(" [0x%x] set update\n", cw->win);
2677 if (cw->update_timeout)
2679 DBG(" [0x%x] del timeout\n", cw->win);
2680 ecore_timer_del(cw->update_timeout);
2681 cw->update_timeout = NULL;
2684 cw->c->updates = eina_list_append(cw->c->updates, cw);
2686 if ((cw->w != cw->hidden.w) ||
2687 (cw->h != cw->hidden.h) ||
2690 DBG(" [0x%x] rsz done msg %4ix%4i\n", cw->win, cw->hidden.w, cw->hidden.h);
2691 cw->w = cw->hidden.w;
2692 cw->h = cw->hidden.h;
2694 // was cw->w / cw->h
2695 evas_object_resize(cw->shobj, cw->pw, cw->ph);
2696 _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0);
2699 _e_mod_comp_win_render_queue(cw);
2702 return ECORE_CALLBACK_PASS_ON;
2706 _e_mod_comp_shape(void *data __UNUSED__,
2707 int type __UNUSED__,
2710 Ecore_X_Event_Window_Shape *ev = event;
2711 E_Comp_Win *cw = _e_mod_comp_win_find(ev->win);
2712 if (!cw) return ECORE_CALLBACK_PASS_ON;
2713 if (ev->type != ECORE_X_SHAPE_BOUNDING) return ECORE_CALLBACK_PASS_ON;
2714 _e_mod_comp_win_reshape(cw);
2715 return ECORE_CALLBACK_PASS_ON;
2719 _e_mod_comp_damage(void *data __UNUSED__,
2720 int type __UNUSED__,
2723 Ecore_X_Event_Damage *ev = event;
2724 E_Comp_Win *cw = _e_mod_comp_win_damage_find(ev->damage);
2725 if (!cw) return ECORE_CALLBACK_PASS_ON;
2726 _e_mod_comp_win_damage(cw,
2727 ev->area.x, ev->area.y,
2728 ev->area.width, ev->area.height, 1);
2729 return ECORE_CALLBACK_PASS_ON;
2733 _e_mod_comp_damage_win(void *data __UNUSED__,
2734 int type __UNUSED__,
2737 Ecore_X_Event_Window_Damage *ev = event;
2741 // fixme: use hash if compositors list > 4
2742 EINA_LIST_FOREACH(compositors, l, c)
2744 if (ev->win == c->ee_win)
2746 // expose on comp win - init win or some other bypass win did it
2748 _e_mod_comp_render_queue(c);
2752 return ECORE_CALLBACK_PASS_ON;
2756 _e_mod_comp_randr(void *data __UNUSED__,
2757 int type __UNUSED__,
2758 __UNUSED__ void *event)
2763 EINA_LIST_FOREACH(compositors, l, c)
2765 ecore_evas_resize(c->ee, c->man->w, c->man->h);
2767 return ECORE_CALLBACK_PASS_ON;
2771 _e_mod_comp_bd_add(void *data __UNUSED__,
2772 int type __UNUSED__,
2775 E_Event_Border_Add *ev = event;
2776 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2777 if (!cw) return ECORE_CALLBACK_PASS_ON;
2778 // fimxe: add/enable compositing here not in show event for borders
2779 return ECORE_CALLBACK_PASS_ON;
2783 _e_mod_comp_bd_del(void *data __UNUSED__,
2784 int type __UNUSED__,
2787 E_Event_Border_Remove *ev = event;
2788 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2789 if (!cw) return ECORE_CALLBACK_PASS_ON;
2790 if (cw->bd == ev->border) _e_mod_comp_object_del(cw, ev->border);
2791 return ECORE_CALLBACK_PASS_ON;
2795 _e_mod_comp_bd_show(void *data __UNUSED__,
2796 int type __UNUSED__,
2799 E_Event_Border_Show *ev = event;
2800 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2801 if (!cw) return ECORE_CALLBACK_PASS_ON;
2802 if (cw->visible) return ECORE_CALLBACK_PASS_ON;
2803 _e_mod_comp_win_show(cw);
2804 return ECORE_CALLBACK_PASS_ON;
2808 _e_mod_comp_bd_hide(void *data __UNUSED__,
2809 int type __UNUSED__,
2812 E_Event_Border_Hide *ev = event;
2813 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2814 if (!cw) return ECORE_CALLBACK_PASS_ON;
2815 if (!cw->visible) return ECORE_CALLBACK_PASS_ON;
2816 _e_mod_comp_win_hide(cw);
2817 return ECORE_CALLBACK_PASS_ON;
2821 _e_mod_comp_bd_move(void *data __UNUSED__,
2822 int type __UNUSED__,
2825 E_Event_Border_Move *ev = event;
2826 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2827 if (!cw) return ECORE_CALLBACK_PASS_ON;
2828 // fimxe: do move here for composited bd
2829 return ECORE_CALLBACK_PASS_ON;
2833 _e_mod_comp_bd_resize(void *data __UNUSED__,
2834 int type __UNUSED__,
2837 E_Event_Border_Resize *ev = event;
2838 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2839 if (!cw) return ECORE_CALLBACK_PASS_ON;
2840 // fimxe: do resize here instead of conf notify
2841 return ECORE_CALLBACK_PASS_ON;
2845 _e_mod_comp_bd_iconify(void *data __UNUSED__,
2846 int type __UNUSED__,
2849 E_Event_Border_Iconify *ev = event;
2850 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2851 if (!cw) return ECORE_CALLBACK_PASS_ON;
2852 // fimxe: special iconfiy anim
2853 return ECORE_CALLBACK_PASS_ON;
2857 _e_mod_comp_bd_uniconify(void *data __UNUSED__,
2858 int type __UNUSED__,
2861 E_Event_Border_Uniconify *ev = event;
2862 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2863 if (!cw) return ECORE_CALLBACK_PASS_ON;
2864 // fimxe: special uniconfiy anim
2865 return ECORE_CALLBACK_PASS_ON;
2869 _e_mod_comp_bd_urgent_change(void *data __UNUSED__,
2870 int type __UNUSED__,
2873 E_Event_Border_Urgent_Change *ev = event;
2874 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2875 if (!cw) return ECORE_CALLBACK_PASS_ON;
2876 if (cw->bd->client.icccm.urgent)
2877 edje_object_signal_emit(cw->shobj, "e,state,urgent,on", "e");
2879 edje_object_signal_emit(cw->shobj, "e,state,urgent,off", "e");
2880 return ECORE_CALLBACK_PASS_ON;
2884 _e_mod_comp_bd_focus_in(void *data __UNUSED__,
2885 int type __UNUSED__,
2888 E_Event_Border_Focus_In *ev = event;
2889 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2890 if (!cw) return ECORE_CALLBACK_PASS_ON;
2891 edje_object_signal_emit(cw->shobj, "e,state,focus,on", "e");
2892 return ECORE_CALLBACK_PASS_ON;
2896 _e_mod_comp_bd_focus_out(void *data __UNUSED__,
2897 int type __UNUSED__,
2900 E_Event_Border_Focus_Out *ev = event;
2901 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2902 if (!cw) return ECORE_CALLBACK_PASS_ON;
2903 edje_object_signal_emit(cw->shobj, "e,state,focus,off", "e");
2904 return ECORE_CALLBACK_PASS_ON;
2908 _e_mod_comp_bd_property(void *data __UNUSED__,
2909 int type __UNUSED__,
2912 E_Event_Border_Property *ev = event;
2913 E_Comp_Win *cw = _e_mod_comp_win_find(ev->border->win);
2914 if (!cw) return ECORE_CALLBACK_PASS_ON;
2915 // fimxe: other properties?
2916 return ECORE_CALLBACK_PASS_ON;
2919 //////////////////////////////////////////////////////////////////////////
2921 _e_mod_comp_fps_toggle(void)
2928 if (_comp_mod->conf->fps_show)
2930 _comp_mod->conf->fps_show = 0;
2931 e_config_save_queue();
2935 _comp_mod->conf->fps_show = 1;
2936 e_config_save_queue();
2938 EINA_LIST_FOREACH(compositors, l, c) _e_mod_comp_cb_update(c);
2943 _e_mod_comp_key_down(void *data __UNUSED__,
2944 int type __UNUSED__,
2947 Ecore_Event_Key *ev = event;
2949 if ((!strcmp(ev->keyname, "Home")) &&
2950 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) &&
2951 (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
2952 (ev->modifiers & ECORE_EVENT_MODIFIER_ALT))
2956 _e_mod_config_free(_comp_mod->module);
2957 _e_mod_config_new(_comp_mod->module);
2959 e_module_disable(_comp_mod->module);
2961 e_sys_action_do(E_SYS_RESTART, NULL);
2964 else if ((!strcasecmp(ev->keyname, "f")) &&
2965 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) &&
2966 (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
2967 (ev->modifiers & ECORE_EVENT_MODIFIER_ALT))
2969 _e_mod_comp_fps_toggle();
2971 return ECORE_CALLBACK_PASS_ON;
2974 //////////////////////////////////////////////////////////////////////////
2976 _e_mod_comp_evas_get_func(void *data,
2977 E_Manager *man __UNUSED__)
2984 _e_mod_comp_update_func(void *data,
2985 E_Manager *man __UNUSED__)
2988 _e_mod_comp_render_queue(c);
2991 static const Eina_List *
2992 _e_mod_comp_src_list_get_func(void *data,
2993 E_Manager *man __UNUSED__)
2998 if (!c->wins) return NULL;
2999 if (c->wins_invalid)
3001 c->wins_invalid = 0;
3002 if (c->wins_list) eina_list_free(c->wins_list);
3003 c->wins_list = NULL;
3004 EINA_INLIST_FOREACH(c->wins, cw)
3006 if ((cw->shobj) && (cw->obj))
3007 c->wins_list = eina_list_append(c->wins_list, cw);
3010 return c->wins_list;
3013 static Evas_Object *
3014 _e_mod_comp_src_image_get_func(void *data __UNUSED__,
3015 E_Manager *man __UNUSED__,
3016 E_Manager_Comp_Source *src)
3018 // E_Comp *c = data;
3019 E_Comp_Win *cw = (E_Comp_Win *)src;
3020 if (!cw->c) return NULL;
3024 static Evas_Object *
3025 _e_mod_comp_src_shadow_get_func(void *data __UNUSED__,
3026 E_Manager *man __UNUSED__,
3027 E_Manager_Comp_Source *src)
3029 // E_Comp *c = data;
3030 E_Comp_Win *cw = (E_Comp_Win *)src;
3031 if (!cw->c) return NULL;
3035 static Evas_Object *
3036 _e_mod_comp_src_image_mirror_add_func(void *data __UNUSED__,
3037 E_Manager *man __UNUSED__,
3038 E_Manager_Comp_Source *src)
3040 // E_Comp *c = data;
3041 E_Comp_Win *cw = (E_Comp_Win *)src;
3042 if (!cw->c) return NULL;
3043 return _e_mod_comp_win_mirror_add(cw);
3047 _e_mod_comp_src_visible_get_func(void *data __UNUSED__,
3048 E_Manager *man __UNUSED__,
3049 E_Manager_Comp_Source *src)
3051 // E_Comp *c = data;
3052 E_Comp_Win *cw = (E_Comp_Win *)src;
3053 if (!cw->c) return 0;
3058 _e_mod_comp_src_hidden_set_func(void *data __UNUSED__,
3059 E_Manager *man __UNUSED__,
3060 E_Manager_Comp_Source *src,
3063 // E_Comp *c = data;
3064 E_Comp_Win *cw = (E_Comp_Win *)src;
3066 if (cw->hidden_override == hidden) return;
3067 cw->hidden_override = hidden;
3068 if (cw->bd) e_border_comp_hidden_set(cw->bd, cw->hidden_override);
3071 if (cw->hidden_override) evas_object_hide(cw->shobj);
3072 else evas_object_show(cw->shobj);
3076 if (cw->hidden_override) evas_object_hide(cw->shobj);
3081 _e_mod_comp_src_hidden_get_func(void *data __UNUSED__,
3082 E_Manager *man __UNUSED__,
3083 E_Manager_Comp_Source *src)
3085 // E_Comp *c = data;
3086 E_Comp_Win *cw = (E_Comp_Win *)src;
3087 if (!cw->c) return 0;
3088 return cw->hidden_override;
3092 _e_mod_comp_add(E_Manager *man)
3095 Ecore_X_Window *wins;
3096 Ecore_X_Window_Attributes att;
3099 c = calloc(1, sizeof(E_Comp));
3100 if (!c) return NULL;
3102 if (_comp_mod->conf->vsync)
3104 e_util_env_set("__GL_SYNC_TO_VBLANK", "1");
3108 e_util_env_set("__GL_SYNC_TO_VBLANK", NULL);
3111 ecore_x_e_comp_sync_supported_set(man->root, _comp_mod->conf->efl_sync);
3114 c->win = ecore_x_composite_render_window_enable(man->root);
3117 e_util_dialog_internal
3118 (_("Compositor Error"),
3119 _("Your screen does not support the compositor<br>"
3120 "overlay window. This is needed for it to<br>"
3126 memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
3127 ecore_x_window_attributes_get(c->win, &att);
3129 if ((att.depth != 24) && (att.depth != 32))
3131 e_util_dialog_internal
3132 (_("Compositor Error"),
3133 _("Your screen is not in 24/32bit display mode.<br>"
3134 "This is required to be your default depth<br>"
3135 "setting for the compositor to work properly."));
3136 ecore_x_composite_render_window_disable(c->win);
3141 /* FIXME check if already composited? */
3142 c->cm_selection = ecore_x_window_input_new(man->root, 0, 0, 1, 1);
3143 if (!c->cm_selection)
3145 ecore_x_composite_render_window_disable(c->win);
3149 ecore_x_screen_is_composited_set(c->man->num, c->cm_selection);
3151 if (c->man->num == 0) e_alert_composite_win = c->win;
3153 if (_comp_mod->conf->engine == E_EVAS_ENGINE_GL_X11)
3158 if (_comp_mod->conf->indirect)
3160 opt[opt_i] = ECORE_EVAS_GL_X11_OPT_INDIRECT;
3165 if (_comp_mod->conf->vsync)
3167 opt[opt_i] = ECORE_EVAS_GL_X11_OPT_VSYNC;
3174 opt[opt_i] = ECORE_EVAS_GL_X11_OPT_NONE;
3175 c->ee = ecore_evas_gl_x11_options_new
3176 (NULL, c->win, 0, 0, man->w, man->h, opt);
3179 c->ee = ecore_evas_gl_x11_new(NULL, c->win, 0, 0, man->w, man->h);
3183 ecore_evas_gl_x11_pre_post_swap_callback_set
3184 (c->ee, c, _e_mod_comp_pre_swap, NULL);
3189 if (_comp_mod->conf->engine == E_EVAS_ENGINE_GL_X11)
3191 e_util_dialog_internal
3192 (_("Compositor Warning"),
3193 _("Your screen does not support OpenGL.<br>"
3194 "Falling back to software engine."));
3197 c->ee = ecore_evas_software_x11_new(NULL, c->win, 0, 0, man->w, man->h);
3200 ecore_evas_comp_sync_set(c->ee, 0);
3201 ecore_evas_manual_render_set(c->ee, _comp_mod->conf->lock_fps);
3202 c->evas = ecore_evas_get(c->ee);
3203 ecore_evas_show(c->ee);
3205 c->ee_win = ecore_evas_window_get(c->ee);
3206 ecore_x_screen_is_composited_set(c->man->num, c->ee_win);
3207 ecore_x_composite_redirect_subwindows
3208 (c->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
3210 wins = ecore_x_window_children_get(c->man->root, &num);
3213 for (i = 0; i < num; i++)
3216 int x, y, w, h, border;
3217 char *wname = NULL, *wclass = NULL;
3219 ecore_x_icccm_name_class_get(wins[i], &wname, &wclass);
3220 if ((man->initwin == wins[i]) ||
3221 ((wname) && (wclass) && (!strcmp(wname, "E")) &&
3222 (!strcmp(wclass, "Init_Window"))))
3226 ecore_x_window_reparent(wins[i], c->win, 0, 0);
3230 if (wname) free(wname);
3231 if (wclass) free(wclass);
3232 wname = wclass = NULL;
3233 cw = _e_mod_comp_win_add(c, wins[i]);
3235 ecore_x_window_geometry_get(cw->win, &x, &y, &w, &h);
3236 border = ecore_x_window_border_width_get(cw->win);
3237 if (wins[i] == c->win) continue;
3238 _e_mod_comp_win_configure(cw, x, y, w, h, border);
3239 if (ecore_x_window_visible_get(wins[i]))
3240 _e_mod_comp_win_show(cw);
3245 ecore_x_window_key_grab(c->man->root,
3247 ECORE_EVENT_MODIFIER_SHIFT |
3248 ECORE_EVENT_MODIFIER_CTRL |
3249 ECORE_EVENT_MODIFIER_ALT, 0);
3250 ecore_x_window_key_grab(c->man->root,
3252 ECORE_EVENT_MODIFIER_SHIFT |
3253 ECORE_EVENT_MODIFIER_CTRL |
3254 ECORE_EVENT_MODIFIER_ALT, 0);
3257 c->comp.func.evas_get = _e_mod_comp_evas_get_func;
3258 c->comp.func.update = _e_mod_comp_update_func;
3259 c->comp.func.src_list_get = _e_mod_comp_src_list_get_func;
3260 c->comp.func.src_image_get = _e_mod_comp_src_image_get_func;
3261 c->comp.func.src_shadow_get = _e_mod_comp_src_shadow_get_func;
3262 c->comp.func.src_image_mirror_add = _e_mod_comp_src_image_mirror_add_func;
3263 c->comp.func.src_visible_get = _e_mod_comp_src_visible_get_func;
3264 c->comp.func.src_hidden_set = _e_mod_comp_src_hidden_set_func;
3265 c->comp.func.src_hidden_get = _e_mod_comp_src_hidden_get_func;
3267 e_manager_comp_set(c->man, &(c->comp));
3272 _e_mod_comp_del(E_Comp *c)
3278 evas_object_del(c->fps_fg);
3283 evas_object_del(c->fps_bg);
3286 e_manager_comp_set(c->man, NULL);
3288 ecore_x_window_key_ungrab(c->man->root,
3290 ECORE_EVENT_MODIFIER_SHIFT |
3291 ECORE_EVENT_MODIFIER_CTRL |
3292 ECORE_EVENT_MODIFIER_ALT, 0);
3293 ecore_x_window_key_ungrab(c->man->root,
3295 ECORE_EVENT_MODIFIER_SHIFT |
3296 ECORE_EVENT_MODIFIER_CTRL |
3297 ECORE_EVENT_MODIFIER_ALT, 0);
3303 ecore_x_screen_is_composited_set(c->man->num, 0);
3306 cw = (E_Comp_Win *)(c->wins);
3309 ecore_x_sync_counter_free(cw->counter);
3313 _e_mod_comp_win_hide(cw);
3315 _e_mod_comp_win_del(cw);
3317 ecore_evas_free(c->ee);
3318 ecore_x_composite_unredirect_subwindows
3319 (c->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
3320 ecore_x_composite_render_window_disable(c->win);
3321 if (c->man->num == 0) e_alert_composite_win = 0;
3322 if (c->render_animator) ecore_animator_del(c->render_animator);
3323 if (c->new_up_timer) ecore_timer_del(c->new_up_timer);
3324 if (c->update_job) ecore_job_del(c->update_job);
3325 if (c->wins_list) eina_list_free(c->wins_list);
3327 ecore_x_window_free(c->cm_selection);
3328 ecore_x_screen_is_composited_set(c->man->num, 0);
3329 ecore_x_e_comp_sync_supported_set(c->man->root, 0);
3334 //////////////////////////////////////////////////////////////////////////
3337 e_mod_comp_init(void)
3342 windows = eina_hash_string_superfast_new(NULL);
3343 borders = eina_hash_string_superfast_new(NULL);
3344 damages = eina_hash_string_superfast_new(NULL);
3346 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, _e_mod_comp_create, NULL));
3347 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_mod_comp_destroy, NULL));
3348 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, _e_mod_comp_show, NULL));
3349 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_mod_comp_hide, NULL));
3350 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_mod_comp_reparent, NULL));
3351 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_mod_comp_configure, NULL));
3352 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK, _e_mod_comp_stack, NULL));
3353 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_mod_comp_property, NULL));
3354 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_mod_comp_message, NULL));
3355 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_mod_comp_shape, NULL));
3356 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY, _e_mod_comp_damage, NULL));
3357 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, _e_mod_comp_damage_win, NULL));
3359 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_mod_comp_key_down, NULL));
3361 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONTAINER_RESIZE, _e_mod_comp_randr, NULL));
3363 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_mod_comp_bd_add, NULL));
3364 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_REMOVE, _e_mod_comp_bd_del, NULL));
3365 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_SHOW, _e_mod_comp_bd_show, NULL));
3366 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_HIDE, _e_mod_comp_bd_hide, NULL));
3367 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_MOVE, _e_mod_comp_bd_move, NULL));
3368 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_RESIZE, _e_mod_comp_bd_resize, NULL));
3369 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_ICONIFY, _e_mod_comp_bd_iconify, NULL));
3370 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_UNICONIFY, _e_mod_comp_bd_uniconify, NULL));
3371 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_URGENT_CHANGE, _e_mod_comp_bd_urgent_change, NULL));
3372 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN, _e_mod_comp_bd_focus_in, NULL));
3373 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, _e_mod_comp_bd_focus_out, NULL));
3374 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_BORDER_PROPERTY, _e_mod_comp_bd_property, NULL));
3376 if (!ecore_x_composite_query())
3378 e_util_dialog_internal
3379 (_("Compositor Error"),
3380 _("Your X Display does not support the XComposite extension<br>"
3381 "or Ecore was built without XComposite support.<br>"
3382 "Note that for composite support you will also need<br>"
3383 "XRender and XFixes support in X11 and Ecore."));
3386 if (!ecore_x_damage_query())
3388 e_util_dialog_internal
3389 (_("Compositor Error"),
3390 _("Your screen does not support the XDamage extension<br>"
3391 "or Ecore was built without XDamage support."));
3394 EINA_LIST_FOREACH(e_manager_list(), l, man)
3398 c = _e_mod_comp_add(man);
3399 if (c) compositors = eina_list_append(compositors, c);
3408 e_mod_comp_shutdown(void)
3412 EINA_LIST_FREE(compositors, c) _e_mod_comp_del(c);
3414 E_FREE_LIST(handlers, ecore_event_handler_del);
3416 if (damages) eina_hash_free(damages);
3417 if (windows) eina_hash_free(windows);
3418 if (borders) eina_hash_free(borders);
3425 e_mod_comp_shadow_set(void)
3430 EINA_LIST_FOREACH(compositors, l, c)
3434 ecore_evas_manual_render_set(c->ee, _comp_mod->conf->lock_fps);
3435 _e_mod_comp_fps_update(c);
3436 EINA_INLIST_FOREACH(c->wins, cw)
3438 if ((cw->shobj) && (cw->obj))
3440 _e_mod_comp_win_shadow_setup(cw);
3444 edje_object_signal_emit(cw->shobj, "e,state,visible,on", "e");
3449 _e_mod_comp_win_render_queue(cw);
3452 cw->pending_count++;
3453 e_manager_comp_event_src_visibility_send
3454 (cw->c->man, (E_Manager_Comp_Source *)cw,
3455 _e_mod_comp_cb_pending_after, cw->c);