From 79dcd015f8cde802305573b3840cf73709d16cfe Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 15 Jan 2010 04:41:20 +0000 Subject: [PATCH] lots of work on compositor stuff. looking slick and nice internally too. SVN revision: 45159 --- src/bin/e_menu.c | 28 +- src/bin/e_menu.h | 2 + src/bin/e_object.c | 40 +- src/bin/e_object.h | 39 +- src/bin/e_popup.c | 126 +---- src/bin/e_popup.h | 1 + src/modules/comp/Makefile.am | 3 +- src/modules/comp/e_mod_comp.c | 750 ++++++++++++++++++--------- src/modules/comp/e_mod_comp.h | 18 +- src/modules/comp/e_mod_comp_update.c | 38 +- src/modules/comp/e_mod_comp_update.h | 30 +- src/modules/comp/e_mod_config.c | 107 +--- src/modules/comp/e_mod_main.c | 9 +- src/modules/comp/e_mod_main.h | 3 +- src/modules/comp/shadow.edj | Bin 0 -> 9407 bytes x-ui.sh | 3 + 16 files changed, 705 insertions(+), 492 deletions(-) create mode 100644 src/modules/comp/shadow.edj diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index 5cd1fdf5d..f01fd115b 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -90,6 +90,7 @@ static Eina_Bool _e_menu_categories_free_cb(const Eina_Hash *hash, const void *k /* local subsystem globals */ static Ecore_X_Window _e_menu_win = 0; static Eina_List *_e_active_menus = NULL; +static Eina_Hash *_e_menu_hash = NULL; static E_Menu_Item *_e_active_menu_item = NULL; /*static Eina_Hash *_e_menu_category_items = NULL;*/ static Eina_Hash *_e_menu_categories = NULL; @@ -160,6 +161,8 @@ e_menu_init(void) ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_menu_cb_window_shape, NULL); _e_menu_categories = eina_hash_string_superfast_new(NULL); + + if (!_e_menu_hash) _e_menu_hash = eina_hash_string_superfast_new(NULL); return 1; } @@ -168,6 +171,12 @@ e_menu_shutdown(void) { E_Menu *m; + if (_e_menu_hash) + { + eina_hash_free(_e_menu_hash); + _e_menu_hash = NULL; + } + E_FN_DEL(ecore_event_handler_del, _e_menu_key_down_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_key_up_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_down_handler); @@ -1044,6 +1053,18 @@ e_menu_grab_window_get(void) return _e_menu_win; } +EAPI E_Menu * +e_menu_find_by_window(Ecore_X_Window win) +{ + E_Menu *m; + + m = eina_hash_find(_e_menu_hash, e_util_winid_str_get(win)); + if ((m) && (m->evas_win != win)) + return NULL; + return m; +} + + /* local subsystem functions */ static void _e_menu_free(E_Menu *m) @@ -1418,6 +1439,7 @@ _e_menu_realize(E_Menu *m) m->cur.x, m->cur.y, m->cur.w, m->cur.h, 1, 1, &(m->evas_win)); e_canvas_add(m->ecore_evas); + eina_hash_add(_e_menu_hash, e_util_winid_str_get(m->evas_win), m); m->shape = e_container_shape_add(m->zone->container); e_container_shape_move(m->shape, m->cur.x, m->cur.y); e_container_shape_resize(m->shape, m->cur.w, m->cur.h); @@ -1464,7 +1486,10 @@ _e_menu_realize(E_Menu *m) if (e_config->use_composite) { ecore_evas_alpha_set(m->ecore_evas, m->shaped); - m->evas_win = ecore_evas_software_x11_window_get(m->ecore_evas); + + eina_hash_del(_e_menu_hash, e_util_winid_str_get(m->evas_win), m); + m->evas_win = ecore_evas_software_x11_window_get(m->ecore_evas); + eina_hash_add(_e_menu_hash, e_util_winid_str_get(m->evas_win), m); } else ecore_evas_shaped_set(m->ecore_evas, m->shaped); @@ -1737,6 +1762,7 @@ _e_menu_unrealize(E_Menu *m) ecore_evas_free(m->ecore_evas); m->ecore_evas = NULL; m->evas = NULL; + eina_hash_del(_e_menu_hash, e_util_winid_str_get(m->evas_win), m); m->evas_win = 0; } diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index e173154b1..ec4466211 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -208,5 +208,7 @@ EAPI void e_menu_idler_before(void); EAPI Ecore_X_Window e_menu_grab_window_get(void); +EAPI E_Menu *e_menu_find_by_window(Ecore_X_Window win); + #endif #endif diff --git a/src/bin/e_object.c b/src/bin/e_object.c index 6457ea6fd..1ff2216ae 100644 --- a/src/bin/e_object.c +++ b/src/bin/e_object.c @@ -66,6 +66,16 @@ e_object_free(E_Object *obj) { E_OBJECT_CHECK(obj); if (obj->free_att_func) obj->free_att_func(obj); + obj->walking_list++; + while (obj->del_fn_list) + { + E_Object_Delfn *dfn = (E_Object_Delfn *)obj->del_fn_list; + if (!dfn->delete_me) dfn->func(dfn->data, obj); + obj->del_fn_list = eina_inlist_remove(obj->del_fn_list, + EINA_INLIST_GET(dfn)); + free(dfn); + } + obj->walking_list--; /* * FIXME: * although this is good - if during cleanup the cleanup func calls @@ -262,19 +272,45 @@ e_object_data_get(E_Object *obj) } EAPI void -e_object_free_attach_func_set(E_Object *obj, void (*func) (void *obj)) +e_object_free_attach_func_set(E_Object *obj, E_Object_Cleanup_Func func) { E_OBJECT_CHECK(obj); obj->free_att_func = func; } EAPI void -e_object_del_attach_func_set(E_Object *obj, void (*func) (void *obj)) +e_object_del_attach_func_set(E_Object *obj, E_Object_Cleanup_Func func) { E_OBJECT_CHECK(obj); obj->del_att_func = func; } +EAPI E_Object_Delfn * +e_object_delfn_add(E_Object *obj, void (*func) (void *data, void *obj), void *data) +{ + E_Object_Delfn *dfn; + E_OBJECT_CHECK_RETURN(obj, NULL); + dfn = calloc(1, sizeof(E_Object_Delfn)); + if (!dfn) return NULL; + dfn->func = func; + dfn->data = data; + obj->del_fn_list = eina_inlist_append(obj->del_fn_list, EINA_INLIST_GET(dfn)); + return dfn; +} + +EAPI void +e_object_delfn_del(E_Object *obj, E_Object_Delfn *dfn) +{ + E_OBJECT_CHECK(obj); + if (obj->walking_list) + { + dfn->delete_me = 1; + return; + } + obj->del_fn_list = eina_inlist_remove(obj->del_fn_list, EINA_INLIST_GET(dfn)); + free(dfn); +} + /* void e_object_breadcrumb_add(E_Object *obj, char *crumb) diff --git a/src/bin/e_object.h b/src/bin/e_object.h index 577e3c00c..f3ebe75cb 100644 --- a/src/bin/e_object.h +++ b/src/bin/e_object.h @@ -50,7 +50,8 @@ typedef void (*E_Object_Cleanup_Func) (void *obj); -typedef struct _E_Object E_Object; +typedef struct _E_Object E_Object; +typedef struct _E_Object_Delfn E_Object_Delfn; #else #ifndef E_OBJECT_H @@ -58,15 +59,26 @@ typedef struct _E_Object E_Object; struct _E_Object { - int magic; - int type; - int references; - E_Object_Cleanup_Func del_func; - E_Object_Cleanup_Func cleanup_func; - void (*free_att_func) (void *obj); - void (*del_att_func) (void *obj); - void *data; - unsigned char deleted : 1; + int magic; + int type; + int references; + E_Object_Cleanup_Func del_func; + E_Object_Cleanup_Func cleanup_func; + E_Object_Cleanup_Func free_att_func; + E_Object_Cleanup_Func del_att_func; + Eina_Inlist *del_fn_list; + void *data; + int walking_list; + Eina_Bool deleted : 1; +}; + +struct _E_Object_Delfn +{ + EINA_INLIST; + + void (*func) (void *data, void *obj); + void *data; + Eina_Bool delete_me : 1; }; EAPI void *e_object_alloc (int size, int type, E_Object_Cleanup_Func cleanup_func); @@ -81,8 +93,11 @@ EAPI int e_object_ref_get (E_Object *obj); EAPI int e_object_error (E_Object *obj); EAPI void e_object_data_set (E_Object *obj, void *data); EAPI void *e_object_data_get (E_Object *obj); -EAPI void e_object_free_attach_func_set(E_Object *obj, void (*func) (void *obj)); -EAPI void e_object_del_attach_func_set (E_Object *obj, void (*func) (void *obj)); +EAPI void e_object_free_attach_func_set(E_Object *obj, E_Object_Cleanup_Func func); +EAPI void e_object_del_attach_func_set (E_Object *obj, E_Object_Cleanup_Func func); + +EAPI E_Object_Delfn *e_object_delfn_add (E_Object *obj, void (*func) (void *data, void *obj), void *data); +EAPI void e_object_delfn_del (E_Object *obj, E_Object_Delfn *dfn); /* EAPI void e_object_breadcrumb_add (E_Object *obj, char *crumb); diff --git a/src/bin/e_popup.c b/src/bin/e_popup.c index ebb677489..cbf392221 100644 --- a/src/bin/e_popup.c +++ b/src/bin/e_popup.c @@ -7,20 +7,11 @@ static void _e_popup_free(E_Popup *pop); static int _e_popup_idle_enterer(void *data); static int _e_popup_cb_window_shape(void *data, int ev_type, void *ev); -/*static E_Popup *_e_popup_find_by_window(Ecore_X_Window win); -static int _e_popup_cb_mouse_down(void *data, int type, void *event); -static int _e_popup_cb_mouse_up(void *data, int type, void *event); -static int _e_popup_cb_mouse_wheel(void *data, int type, void *event); -*/ /* local subsystem globals */ static Ecore_Event_Handler *_e_popup_window_shape_handler = NULL; -/* -static Ecore_Event_Handler *_e_popup_mouse_down_handler = NULL; -static Ecore_Event_Handler *_e_popup_mouse_up_handler = NULL; -static Ecore_Event_Handler *_e_popup_mouse_wheel_handler = NULL; - */ static Eina_List *_e_popup_list = NULL; +static Eina_Hash *_e_popup_hash = NULL; /* externally accessible functions */ @@ -29,26 +20,19 @@ e_popup_init(void) { _e_popup_window_shape_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_popup_cb_window_shape, NULL); -/* - _e_popup_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, - _e_popup_cb_mouse_down, NULL); - _e_popup_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, - _e_popup_cb_mouse_up, NULL); - _e_popup_mouse_wheel_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, - _e_popup_cb_mouse_wheel, NULL); - */ + if (!_e_popup_hash) _e_popup_hash = eina_hash_string_superfast_new(NULL); return 1; } EAPI int e_popup_shutdown(void) { + if (_e_popup_hash) + { + eina_hash_free(_e_popup_hash); + _e_popup_hash = NULL; + } E_FN_DEL(ecore_event_handler_del, _e_popup_window_shape_handler); -/* - E_FN_DEL(ecore_event_handler_del, _e_popup_mouse_down_handler); - E_FN_DEL(ecore_event_handler_del, _e_popup_mouse_up_handler); - E_FN_DEL(ecore_event_handler_del, _e_popup_mouse_wheel_handler); - */ return 1; } @@ -83,6 +67,7 @@ e_popup_new(E_Zone *zone, int x, int y, int w, int h) e_object_ref(E_OBJECT(pop->zone)); pop->zone->popups = eina_list_append(pop->zone->popups, pop); _e_popup_list = eina_list_append(_e_popup_list, pop); + eina_hash_add(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop); return pop; } @@ -194,7 +179,9 @@ e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *o) if (e_config->use_composite) { ecore_evas_alpha_set(pop->ecore_evas, pop->shaped); + eina_hash_del(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop); pop->evas_win = ecore_evas_software_x11_window_get(pop->ecore_evas); + eina_hash_add(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop); e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer); } else @@ -288,6 +275,17 @@ e_popup_idler_before(void) } } +EAPI E_Popup * +e_popup_find_by_window(Ecore_X_Window win) +{ + E_Popup *pop; + + pop = eina_hash_find(_e_popup_hash, e_util_winid_str_get(win)); + if ((pop) && (pop->evas_win != win)) + return NULL; + return pop; +} + /* local subsystem functions */ static void @@ -304,6 +302,7 @@ _e_popup_free(E_Popup *pop) e_object_unref(E_OBJECT(pop->zone)); pop->zone->popups = eina_list_remove(pop->zone->popups, pop); _e_popup_list = eina_list_remove(_e_popup_list, pop); + eina_hash_del(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop); free(pop); } @@ -327,88 +326,11 @@ _e_popup_idle_enterer(void *data) static int _e_popup_cb_window_shape(void *data, int ev_type, void *ev) { - Eina_List *l; E_Popup *pop; Ecore_X_Event_Window_Shape *e; e = ev; - EINA_LIST_FOREACH(_e_popup_list, l, pop) - { - if (pop->evas_win == e->win) - pop->need_shape_export = 1; - } + pop = e_popup_find_by_window(e->win); + if (pop) pop->need_shape_export = 1; return 1; } - -/*static E_Popup * -_e_popup_find_by_window(Ecore_X_Window win) -{ - E_Popup *pop; - Eina_List *l; - - EINA_LIST_FOREACH(_e_popup_list, l, pop) - { - if (pop->evas_win == win) return pop; - } - return NULL; -} -*/ -/* -static int -_e_popup_cb_mouse_down(void *data, int type, void *event) -{ - Ecore_Event_Mouse_Button *ev; - E_Popup *pop; - - ev = event; - pop = _e_popup_find_by_window(ev->event_window); - if (pop) - { - Evas_Button_Flags flags = EVAS_BUTTON_NONE; - - e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_POPUP, - E_OBJECT(pop), ev); - if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; - if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; - evas_event_feed_mouse_down(pop->evas, ev->buttons, flags, ev->timestamp, NULL); - return 0; - } - return 1; -} - -static int -_e_popup_cb_mouse_up(void *data, int type, void *event) -{ - Ecore_Event_Mouse_Button *ev; - E_Popup *pop; - - ev = event; - pop = _e_popup_find_by_window(ev->event_window); - if (pop) - { - evas_event_feed_mouse_up(pop->evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL); - e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_POPUP, - E_OBJECT(pop), ev); - return 0; - } - return 1; -} - -static int -_e_popup_cb_mouse_wheel(void *data, int type, void *event) -{ - Ecore_Event_Mouse_Wheel *ev; - E_Popup *pop; - - ev = event; - pop = _e_popup_find_by_window(ev->event_window); - if (pop) - { - e_bindings_wheel_event_handle(E_BINDING_CONTEXT_POPUP, - E_OBJECT(pop), ev); - evas_event_feed_mouse_wheel(pop->evas, ev->direction, ev->z, ev->timestamp, NULL); - return 0; - } - return 1; -} -*/ diff --git a/src/bin/e_popup.h b/src/bin/e_popup.h index ad10ade22..6cb08df4d 100644 --- a/src/bin/e_popup.h +++ b/src/bin/e_popup.h @@ -44,6 +44,7 @@ EAPI void e_popup_ignore_events_set(E_Popup *pop, int ignore); EAPI void e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *o); EAPI void e_popup_layer_set(E_Popup *pop, int layer); EAPI void e_popup_idler_before(void); +EAPI E_Popup *e_popup_find_by_window(Ecore_X_Window win); #endif #endif diff --git a/src/modules/comp/Makefile.am b/src/modules/comp/Makefile.am index b78210b05..3473c9dad 100644 --- a/src/modules/comp/Makefile.am +++ b/src/modules/comp/Makefile.am @@ -4,7 +4,8 @@ MODULE = comp # data files for the module filesdir = $(libdir)/enlightenment/modules/$(MODULE) files_DATA = \ -e-module-$(MODULE).edj module.desktop +e-module-$(MODULE).edj module.desktop \ +shadow.edj EXTRA_DIST = $(files_DATA) diff --git a/src/modules/comp/e_mod_comp.c b/src/modules/comp/e_mod_comp.c index 9ac5cd3dc..bbc0bbceb 100644 --- a/src/modules/comp/e_mod_comp.c +++ b/src/modules/comp/e_mod_comp.c @@ -4,6 +4,8 @@ #include "e_mod_comp_update.h" #include "config.h" +////////////////////////////////////////////////////////////////////////// +// // TODO (no specific order): // 1. abstract evas object and compwin so we can duplicate the object N times // in N canvases - for winlist, everything, pager etc. too @@ -12,19 +14,16 @@ // 3. for unmapped windows - when window goes out of unmapped comp cache // make a miniature copy (1/4 width+height?) and set property on window // with pixmap id -// 4. add shadow to rect non argb windows -// 5. abstract composite canvas to add extras in and "expose" it // 6. other engine fast-paths (gl specifically)! // 8. transparenty property // 9. shortcut lots of stuff to draw inside the compositor - shelf, // wallpaper, efm - hell even menus and anything else in e (this is what // e18 was mostly about) // 10. fullscreen windows need to be able to bypass compositing +// +////////////////////////////////////////////////////////////////////////// -typedef struct _Comp Comp; -typedef struct _Comp_Win Comp_Win; - -struct _Comp +struct _E_Comp { Ecore_X_Window win; Ecore_Evas *ee; @@ -36,14 +35,15 @@ struct _Comp Ecore_Animator *render_animator; }; -struct _Comp_Win +struct _E_Comp_Win { EINA_INLIST; - Comp *c; // parent compositor + E_Comp *c; // parent compositor Ecore_X_Window win; // raw window - for menus etc. E_Border *bd; // if its a border - later E_Popup *pop; // if its a popup - later + E_Menu *menu; // if it is a menu - later int x, y, w, h; // geometry int pw, ph; // pixmap w/h int border; // border width @@ -51,9 +51,12 @@ struct _Comp_Win Ecore_X_Damage damage; // damage region Ecore_X_Visual vis; int depth; - Evas_Object *obj; // shadow object + Evas_Object *obj; // composite object + Evas_Object *shobj; // shadow object Ecore_X_Image *xim; // x image - software fallback - Update *up; // update handler + E_Update *up; // update handler + E_Object_Delfn *dfn; // delete function handle for objects being tracked + Eina_Bool visible : 1; // is visible Eina_Bool input_only : 1; // is input_only Eina_Bool argb : 1; // is argb @@ -76,197 +79,201 @@ static Eina_Hash *damages = NULL; #define DBG(f, x...) #endif -static void _e_mod_comp_render_queue(Comp *c); -static void _e_mod_comp_win_damage(Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg); +static void _e_mod_comp_render_queue(E_Comp *c); +static void _e_mod_comp_win_damage(E_Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg); + +static void +_e_mod_comp_win_shape_rectangles_apply(E_Comp_Win *cw) +{ + Ecore_X_Rectangle *rects; + int num, i; + + DBG("SHAPE [0x%x] change\n", cw->win); + rects = ecore_x_window_shape_rectangles_get(cw->win, &num); + if ((rects) && (num == 1)) + { + DBG("SHAPE [0x%x] rect 1\n", cw->win); + if ((rects[0].x == 0) && + (rects[0].y == 0) && + (rects[0].width == cw->w) && + (rects[0].height == cw->h)) + { + DBG("SHAPE [0x%x] rect solid\n", cw->win); + free(rects); + rects = NULL; + } + } + if (rects) + { + unsigned int *pix, *p; + unsigned char *spix, *sp; + int w, h, px, py; + + cw->shaped = 1; + evas_object_image_size_get(cw->obj, &w, &h); + if ((w > 0) && (h > 0)) + { + pix = evas_object_image_data_get(cw->obj, 1); + spix = calloc(w * h, sizeof(unsigned char)); + if (spix) + { + DBG("SHAPE [0x%x] rects %i\n", num); + for (i = 0; i < num; i++) + { + int rx, ry, rw, rh; + + rx = rects[i].x; ry = rects[i].y; + rw = rects[i].width; rh = rects[i].height; + E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h); + sp = spix + (w * ry) + rx; + for (py = 0; py < rh; py++) + { + for (px = 0; px < rw; px++) + { + *sp = 1; sp++; + } + sp += w - rw; + } + } + sp = spix; + p = pix; + for (py = 0; py < h; py++) + { + for (px = 0; px < w; px++) + { + if (*sp) *p |= 0xff000000; + else *p = 0x00000000; + sp++; + p++; + } + } + free(spix); + } + evas_object_image_data_set(cw->obj, pix); + evas_object_image_alpha_set(cw->obj, 1); + evas_object_image_data_update_add(cw->obj, 0, 0, w, h); + } + free(rects); + } + else + { + cw->shaped = 0; + evas_object_image_alpha_set(cw->obj, 0); + // dont need to fix alpha chanel as blending + // should be totally off here regardless of + // alpha channe; content + } +} + +static void +_e_mod_comp_win_update(E_Comp_Win *cw) +{ + E_Update_Rect *r; + int i; + + cw->update = 0; + if (!cw->pixmap) + { + cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win); + if (cw->pixmap) + ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph)); + else + { + cw->pw = 0; + cw->ph = 0; + } + DBG("REND [0x%x] pixma = [0x%x], %ix%i\n", cw->win, cw->pixmap, cw->pw, cw->ph); + if ((cw->pw <= 0) || (cw->ph <= 0)) + { + ecore_x_pixmap_free(cw->pixmap); + cw->pixmap = 0; + cw->pw = 0; + cw->ph = 0; + } + } + if (!((cw->pw > 0) && (cw->ph > 0))) return; + + e_mod_comp_update_resize(cw->up, cw->pw, cw->ph); + if (!cw->xim) + { + if (cw->xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth)) + e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph); + } + r = e_mod_comp_update_rects_get(cw->up); + if (r) + { + if (cw->xim) + { + e_mod_comp_update_clear(cw->up); + for (i = 0; r[i].w > 0; i++) + { + unsigned int *pix; + int x, y, w, h; + + x = r[i].x; y = r[i].y; + w = r[i].w; h = r[i].h; + ecore_x_image_get(cw->xim, cw->pixmap, x, y, x, y, w, h); + DBG("UPDATE [0x%x] %i %i %ix%i\n", cw->win, x, y, w, h); + pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL); + evas_object_image_size_set(cw->obj, cw->pw, cw->ph); + evas_object_image_data_set(cw->obj, pix); + evas_object_image_data_update_add(cw->obj, x, y, w, h); + if (cw->shaped) cw->shape_changed = 1; + } + if ((cw->shape_changed) && (!cw->argb)) + { + _e_mod_comp_win_shape_rectangles_apply(cw); + cw->shape_changed = 0; + } + } + free(r); + } + else + cw->update = 1; + if (cw->shobj) + { + if (cw->shaped) evas_object_hide(cw->shobj); + } +} static int _e_mod_comp_cb_animator(void *data) { - Comp *c = data; - Comp_Win *cw; + E_Comp *c = data; + E_Comp_Win *cw; Eina_List *new_updates = NULL; // for failed pixmap fetches - get them next frame c->render_animator = NULL; EINA_LIST_FREE(c->updates, cw) { - Update_Rect *r; - int i; - - cw->update = 0; - if (!cw->pixmap) - { - cw->pixmap = ecore_x_composite_name_window_pixmap_get(cw->win); - if (cw->pixmap) - ecore_x_pixmap_geometry_get(cw->pixmap, NULL, NULL, &(cw->pw), &(cw->ph)); - else - { - cw->pw = 0; - cw->ph = 0; - } - DBG("REND [0x%x] pixma = [0x%x], %ix%i\n", cw->win, cw->pixmap, cw->pw, cw->ph); - if ((cw->pw <= 0) || (cw->ph <= 0)) - { - ecore_x_pixmap_free(cw->pixmap); - cw->pixmap = 0; - cw->pw = 0; - cw->ph = 0; - } - } - if ((cw->pw > 0) && (cw->ph > 0)) - { - e_mod_comp_update_resize(cw->up, cw->pw, cw->ph); - if (!cw->xim) - { - if (cw->xim = ecore_x_image_new(cw->pw, cw->ph, cw->vis, cw->depth)) - e_mod_comp_update_add(cw->up, 0, 0, cw->pw, cw->ph); - } - r = e_mod_comp_update_rects_get(cw->up); - if (r) - { - if (cw->xim) - { - e_mod_comp_update_clear(cw->up); - for (i = 0; r[i].w > 0; i++) - { - unsigned int *pix; - int x, y, w, h; - - x = r[i].x; - y = r[i].y; - w = r[i].w; - h = r[i].h; - ecore_x_image_get(cw->xim, cw->pixmap, x, y, x, y, w, h); - DBG("UPDATE [0x%x] %i %i %ix%i\n", cw->win, x, y, w, h); - pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL); - evas_object_image_size_set(cw->obj, cw->pw, cw->ph); - evas_object_image_data_set(cw->obj, pix); - evas_object_image_data_update_add(cw->obj, x, y, w, h); - if (cw->shaped) cw->shape_changed = 1; - } - if ((cw->shape_changed) && (!cw->argb)) -// if (0) - { - Ecore_X_Rectangle *rects; - int num, i; - - DBG("SHAPE [0x%x] change\n", cw->win); - rects = ecore_x_window_shape_rectangles_get - (cw->win, &num); - if ((rects) && (num == 1)) - { - DBG("SHAPE [0x%x] rect 1\n", cw->win); - if ((rects[0].x == 0) && - (rects[0].y == 0) && - (rects[0].width == cw->w) && - (rects[0].height == cw->h)) - { - DBG("SHAPE [0x%x] rect solid\n", cw->win); - free(rects); - rects = NULL; - } - } - if (rects) - { - unsigned int *pix, *p; - unsigned char *spix, *sp; - int w, h, px, py; - - cw->shaped = 1; - evas_object_image_size_get(cw->obj, &w, &h); - if ((w > 0) && (h > 0)) - { - pix = evas_object_image_data_get(cw->obj, 1); - spix = calloc(w * h, sizeof(unsigned char)); - if (spix) - { - DBG("SHAPE [0x%x] rects %i\n", num); - for (i = 0; i < num; i++) - { - int rx, ry, rw, rh; - - rx = rects[i].x; - ry = rects[i].y; - rw = rects[i].width; - rh = rects[i].height; - E_RECTS_CLIP_TO_RECT - (rx, ry, rw, rh, 0, 0, w, h); - sp = spix + (w * ry) + rx; - for (py = 0; py < rh; py++) - { - for (px = 0; px < rw; px++) - { - *sp = 1; - sp++; - } - sp += w - rw; - } - } - sp = spix; - p = pix; - for (py = 0; py < h; py++) - { - for (px = 0; px < w; px++) - { - if (*sp) - *p |= 0xff000000; - else - *p = 0x00000000; - sp++; - p++; - } - } - free(spix); - } - evas_object_image_data_set(cw->obj, pix); - evas_object_image_alpha_set(cw->obj, 1); - evas_object_image_data_update_add(cw->obj, 0, 0, w, h); - } - free(rects); - } - else - { - cw->shaped = 0; - evas_object_image_alpha_set(cw->obj, 0); - // dont need to fix alpha chanel as blending - // should be totally off here regardless of - // alpha channe; content - } - cw->shape_changed = 0; - } - } - free(r); - } - else - { - cw->update = 1; - new_updates = eina_list_append(new_updates, cw); - _e_mod_comp_render_queue(c); - } - } + _e_mod_comp_win_update(cw); + if (cw->update) + new_updates = eina_list_append(new_updates, cw); } ecore_evas_manual_render(c->ee); + if (new_updates) _e_mod_comp_render_queue(c); c->updates = new_updates; return 0; } static void -_e_mod_comp_render_queue(Comp *c) +_e_mod_comp_render_queue(E_Comp *c) { if (c->render_animator) return; c->render_animator = ecore_animator_add(_e_mod_comp_cb_animator, c); } static void -_e_mod_comp_win_render_queue(Comp_Win *cw) +_e_mod_comp_win_render_queue(E_Comp_Win *cw) { _e_mod_comp_render_queue(cw->c); } -static Comp * +static E_Comp * _e_mod_comp_find(Ecore_X_Window root) { Eina_List *l; - Comp *c; + E_Comp *c; // fixme: use hash if compositors list > 4 EINA_LIST_FOREACH(compositors, l, c) @@ -276,39 +283,44 @@ _e_mod_comp_find(Ecore_X_Window root) return NULL; } -static Comp_Win * +static E_Comp_Win * _e_mod_comp_win_find(Ecore_X_Window win) { Eina_List *l; - Comp_Win *cw; + E_Comp_Win *cw; cw = eina_hash_find(windows, e_util_winid_str_get(win)); return cw; } -static Comp_Win * +static E_Comp_Win * _e_mod_comp_win_damage_find(Ecore_X_Damage damage) { - Comp_Win *cw; + E_Comp_Win *cw; cw = eina_hash_find(damages, e_util_winid_str_get(damage)); return cw; } -static Comp_Win * -_e_mod_comp_win_add(Comp *c, Ecore_X_Window win) +static E_Comp_Win * +_e_mod_comp_win_add(E_Comp *c, Ecore_X_Window win) { Ecore_X_Window_Attributes att; - Comp_Win *cw; + E_Comp_Win *cw; - cw = calloc(1, sizeof(Comp_Win)); + cw = calloc(1, sizeof(E_Comp_Win)); if (!cw) return NULL; cw->win = win; // FIXME: check if bd or pop - track cw->c = c; memset((&att), 0, sizeof(Ecore_X_Window_Attributes)); - ecore_x_window_attributes_get(cw->win, &att); - if ((!att.input_only) && (att.depth != 24)) + if (!ecore_x_window_attributes_get(cw->win, &att)) + { + free(cw); + return NULL; + } + if ((!att.input_only) && + ((att.depth != 24) && (att.depth != 32))) { printf("WARNING: window 0x%x not 24/32bpp -> %ibpp\n", cw->win, att.depth); free(cw); @@ -326,6 +338,7 @@ _e_mod_comp_win_add(Comp *c, Ecore_X_Window win) cw->damage = ecore_x_damage_new(cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES); eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw); + cw->shobj = edje_object_add(c->evas); cw->obj = evas_object_image_filled_add(c->evas); evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888); if (cw->argb) @@ -364,16 +377,24 @@ _e_mod_comp_win_add(Comp *c, Ecore_X_Window win) cw->up = e_mod_comp_update_new(); e_mod_comp_update_tile_size_set(cw->up, 32, 32); // for software: - e_mod_comp_update_policy_set(cw->up, UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH); + e_mod_comp_update_policy_set + (cw->up, E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH); DBG(" [0x%x] add\n", cw->win); return cw; } static void -_e_mod_comp_win_del(Comp_Win *cw) +_e_mod_comp_win_del(E_Comp_Win *cw) { e_mod_comp_update_free(cw->up); DBG(" [0x%x] del\n", cw->win); + if (cw->dfn) + { + if (cw->bd) e_object_delfn_del(E_OBJECT(cw->bd), cw->dfn); + else if (cw->pop) e_object_delfn_del(E_OBJECT(cw->pop), cw->dfn); + else if (cw->menu) e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn); + cw->dfn = NULL; + } if (cw->pixmap) { ecore_x_pixmap_free(cw->pixmap); @@ -392,6 +413,10 @@ _e_mod_comp_win_del(Comp_Win *cw) { evas_object_del(cw->obj); } + if (cw->shobj) + { + evas_object_del(cw->shobj); + } eina_hash_del(windows, e_util_winid_str_get(cw->win), cw); if (cw->damage) { @@ -409,7 +434,22 @@ _e_mod_comp_win_del(Comp_Win *cw) } static void -_e_mod_comp_win_show(Comp_Win *cw) +_e_mod_comp_object_del(void *data, void *obj) +{ + E_Comp_Win *cw = data; + + if (obj == cw->bd) cw->bd = NULL; + else if (obj == cw->pop) cw->pop = NULL; + else if (obj == cw->menu) cw->menu = NULL; + if (cw->dfn) + { + e_object_delfn_del(obj, cw->dfn); + cw->dfn = NULL; + } +} + +static void +_e_mod_comp_win_show(E_Comp_Win *cw) { if (cw->visible) return; cw->visible = 1; @@ -421,12 +461,89 @@ _e_mod_comp_win_show(Comp_Win *cw) ecore_x_composite_redirect_window(cw->win, ECORE_X_COMPOSITE_UPDATE_MANUAL); _e_mod_comp_win_damage(cw, 0, 0, cw->w, cw->h, 0); } + + if (cw->dfn) + { + if (cw->bd) e_object_delfn_del(E_OBJECT(cw->bd), cw->dfn); + else if (cw->pop) e_object_delfn_del(E_OBJECT(cw->pop), cw->dfn); + else if (cw->menu) e_object_delfn_del(E_OBJECT(cw->menu), cw->dfn); + cw->dfn = NULL; + } + + cw->bd = NULL; + cw->pop = NULL; + cw->menu = NULL; + + cw->bd = e_border_find_by_window(cw->win); + if (cw->bd) + { + cw->dfn = e_object_delfn_add(E_OBJECT(cw->bd), + _e_mod_comp_object_del, cw); + // ref bd + } + else + { + cw->pop = e_popup_find_by_window(cw->win); + if (cw->pop) + { + cw->dfn = e_object_delfn_add(E_OBJECT(cw->pop), + _e_mod_comp_object_del, cw); + // ref pop + } + else + { + cw->menu = e_menu_find_by_window(cw->win); + if (cw->menu) + { + cw->dfn = e_object_delfn_add(E_OBJECT(cw->menu), + _e_mod_comp_object_del, cw); + // ref menu + } + } + } evas_object_show(cw->obj); + if (cw->shobj) + { + if (_comp_mod->conf->use_shadow) + { + if ((!cw->argb) && (!cw->shaped)) + { + int ok = 0; + char buf[PATH_MAX]; + + // fimxe: maker shadow object configurable - use theme first + if (_comp_mod->conf->shadow_file) + { + ok = 1; + if (!edje_object_file_set(cw->shobj, + _comp_mod->conf->shadow_file, + "shadow")) + ok = 0; + } + if (!ok) + { + ok = 1; + if (!e_theme_edje_object_set(cw->shobj, + "base/theme/borders", + "e/shadow/box")) + ok = 0; + } + if (!ok) + { + snprintf(buf, sizeof(buf), "%s/shadow.edj", + e_module_dir_get(_comp_mod->module) + ); + edje_object_file_set(cw->shobj, buf, "shadow"); + } + evas_object_show(cw->shobj); + } + } + } _e_mod_comp_win_render_queue(cw); } static void -_e_mod_comp_win_hide(Comp_Win *cw) +_e_mod_comp_win_hide(E_Comp_Win *cw) { if (!cw->visible) return; cw->visible = 0; @@ -445,11 +562,15 @@ _e_mod_comp_win_hide(Comp_Win *cw) cw->pixmap = 0; } evas_object_hide(cw->obj); + if (cw->shobj) + { + evas_object_hide(cw->shobj); + } _e_mod_comp_win_render_queue(cw); } static void -_e_mod_comp_win_raise_above(Comp_Win *cw, Comp_Win *cw2) +_e_mod_comp_win_raise_above(E_Comp_Win *cw, E_Comp_Win *cw2) { DBG(" [0x%x] abv [0x%x]\n", cw->win, cw2->win); cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw)); @@ -457,34 +578,46 @@ _e_mod_comp_win_raise_above(Comp_Win *cw, Comp_Win *cw2) EINA_INLIST_GET(cw), EINA_INLIST_GET(cw2)); evas_object_stack_above(cw->obj, cw2->obj); + if (cw->shobj) + { + evas_object_stack_below(cw->shobj, cw->obj); + } _e_mod_comp_win_render_queue(cw); if (cw->input_only) return; } static void -_e_mod_comp_win_raise(Comp_Win *cw) +_e_mod_comp_win_raise(E_Comp_Win *cw) { DBG(" [0x%x] rai\n", cw->win); cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw)); cw->c->wins = eina_inlist_append(cw->c->wins, EINA_INLIST_GET(cw)); evas_object_raise(cw->obj); + if (cw->shobj) + { + evas_object_stack_below(cw->shobj, cw->obj); + } _e_mod_comp_win_render_queue(cw); if (cw->input_only) return; } static void -_e_mod_comp_win_lower(Comp_Win *cw) +_e_mod_comp_win_lower(E_Comp_Win *cw) { DBG(" [0x%x] low\n", cw->win); cw->c->wins = eina_inlist_remove(cw->c->wins, EINA_INLIST_GET(cw)); cw->c->wins = eina_inlist_prepend(cw->c->wins, EINA_INLIST_GET(cw)); evas_object_lower(cw->obj); + if (cw->shobj) + { + evas_object_stack_below(cw->shobj, cw->obj); + } _e_mod_comp_win_render_queue(cw); if (cw->input_only) return; } static void -_e_mod_comp_win_configure(Comp_Win *cw, int x, int y, int w, int h, int border) +_e_mod_comp_win_configure(E_Comp_Win *cw, int x, int y, int w, int h, int border) { if (!((x == cw->x) && (y == cw->y))) { @@ -492,6 +625,10 @@ _e_mod_comp_win_configure(Comp_Win *cw, int x, int y, int w, int h, int border) cw->x = x; cw->y = y; evas_object_move(cw->obj, cw->x, cw->y); + if (cw->shobj) + { + evas_object_move(cw->shobj, cw->x, cw->y); + } } if (!((w == cw->w) && (h == cw->h))) { @@ -510,6 +647,12 @@ _e_mod_comp_win_configure(Comp_Win *cw, int x, int y, int w, int h, int border) evas_object_resize(cw->obj, cw->w + (cw->border * 2), cw->h + (cw->border * 2)); + if (cw->shobj) + { + evas_object_resize(cw->shobj, + cw->w + (cw->border * 2), + cw->h + (cw->border * 2)); + } if (cw->xim) { evas_object_image_data_set(cw->obj, NULL); @@ -523,13 +666,19 @@ _e_mod_comp_win_configure(Comp_Win *cw, int x, int y, int w, int h, int border) evas_object_resize(cw->obj, cw->w + (cw->border * 2), cw->h + (cw->border * 2)); + if (cw->shobj) + { + evas_object_resize(cw->shobj, + cw->w + (cw->border * 2), + cw->h + (cw->border * 2)); + } } if (cw->input_only) return; _e_mod_comp_win_render_queue(cw); } static void -_e_mod_comp_win_damage(Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg) +_e_mod_comp_win_damage(E_Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg) { if (cw->input_only) return; DBG(" [0x%x] dmg %4i %4i %4ix%4i\n", cw->win, x, y, w, h); @@ -541,18 +690,6 @@ _e_mod_comp_win_damage(Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg) ecore_x_damage_subtract(cw->damage, 0, parts); ecore_x_region_free(parts); } - /* - if (cw->xim) - { - unsigned int *pix; - - ecore_x_image_get(cw->xim, cw->pixmap, x, y, x, y, w, h); - pix = ecore_x_image_data_get(cw->xim, NULL, NULL, NULL); - evas_object_image_data_set(cw->obj, pix); - evas_object_image_size_set(cw->obj, cw->w, cw->h); - evas_object_image_data_update_add(cw->obj, x, y, w, h); - } - */ if (!cw->update) { cw->update = 1; @@ -563,7 +700,7 @@ _e_mod_comp_win_damage(Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg) } static void -_e_mod_comp_win_reshape(Comp_Win *cw) +_e_mod_comp_win_reshape(E_Comp_Win *cw) { if (cw->shape_changed) return; cw->shape_changed = 1; @@ -580,10 +717,10 @@ _e_mod_comp_win_reshape(Comp_Win *cw) static int _e_mod_comp_create(void *data, int type, void *event) -{ // do nothing. only worry about maps +{ Ecore_X_Event_Window_Create *ev = event; - Comp_Win *cw; - Comp *c = _e_mod_comp_find(ev->parent); + E_Comp_Win *cw; + E_Comp *c = _e_mod_comp_find(ev->parent); if (!c) return 1; if (_e_mod_comp_win_find(ev->win)) return 1; if (c->win == ev->win) return 1; @@ -595,11 +732,10 @@ _e_mod_comp_create(void *data, int type, void *event) static int _e_mod_comp_destroy(void *data, int type, void *event) -{ // do nothing. only worry about unmaps +{ Ecore_X_Event_Window_Destroy *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; _e_mod_comp_win_del(cw); return 1; } @@ -608,9 +744,8 @@ static int _e_mod_comp_show(void *data, int type, void *event) { Ecore_X_Event_Window_Show *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; if (cw->visible) return 1; _e_mod_comp_win_show(cw); return 1; @@ -620,9 +755,8 @@ static int _e_mod_comp_hide(void *data, int type, void *event) { Ecore_X_Event_Window_Hide *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; if (!cw->visible) return 1; _e_mod_comp_win_hide(cw); return 1; @@ -632,7 +766,7 @@ static int _e_mod_comp_reparent(void *data, int type, void *event) { Ecore_X_Event_Window_Reparent *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; DBG("== repar [0x%x] to [0x%x]\n", ev->win, ev->parent); if (ev->parent != cw->c->man->root) @@ -644,9 +778,8 @@ static int _e_mod_comp_configure(void *data, int type, void *event) { Ecore_X_Event_Window_Configure *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; if (ev->abovewin == 0) { @@ -654,11 +787,11 @@ _e_mod_comp_configure(void *data, int type, void *event) } else { - Comp_Win *cw2 = _e_mod_comp_win_find(ev->abovewin); + E_Comp_Win *cw2 = _e_mod_comp_win_find(ev->abovewin); if (cw2) { - Comp_Win *cw3 = (Comp_Win *)(EINA_INLIST_GET(cw)->prev); + E_Comp_Win *cw3 = (E_Comp_Win *)(EINA_INLIST_GET(cw)->prev); if (cw3 != cw2) _e_mod_comp_win_raise_above(cw, cw2); @@ -678,9 +811,8 @@ static int _e_mod_comp_stack(void *data, int type, void *event) { Ecore_X_Event_Window_Stack *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; if (ev->detail == ECORE_X_WINDOW_STACK_ABOVE) _e_mod_comp_win_raise(cw); else _e_mod_comp_win_lower(cw); return 1; @@ -688,36 +820,33 @@ _e_mod_comp_stack(void *data, int type, void *event) static int _e_mod_comp_property(void *data, int type, void *event) -{ // later +{ Ecore_X_Event_Window_Property *ev = event; return 1; } static int _e_mod_comp_message(void *data, int type, void *event) -{ // later +{ Ecore_X_Event_Client_Message *ev = event; return 1; } static int _e_mod_comp_shape(void *data, int type, void *event) -{ // later +{ Ecore_X_Event_Window_Shape *ev = event; - Comp_Win *cw = _e_mod_comp_win_find(ev->win); + E_Comp_Win *cw = _e_mod_comp_win_find(ev->win); if (!cw) return 1; -// if (ev->event_win != cw->c->man->root) return 1; _e_mod_comp_win_reshape(cw); return 1; } -////////////////////////////////////////////////////////////////////////// - static int _e_mod_comp_damage(void *data, int type, void *event) { Ecore_X_Event_Damage *ev = event; - Comp_Win *cw = _e_mod_comp_win_damage_find(ev->damage); + E_Comp_Win *cw = _e_mod_comp_win_damage_find(ev->damage); if (!cw) return 1; _e_mod_comp_win_damage(cw, ev->area.x, ev->area.y, @@ -725,15 +854,17 @@ _e_mod_comp_damage(void *data, int type, void *event) return 1; } -static Comp * +////////////////////////////////////////////////////////////////////////// + +static E_Comp * _e_mod_comp_add(E_Manager *man) { - Comp *c; + E_Comp *c; Ecore_X_Window *wins; Ecore_X_Window_Attributes att; int i, num; - c = calloc(1, sizeof(Comp)); + c = calloc(1, sizeof(E_Comp)); if (!c) return NULL; c->man = man; c->win = ecore_x_composite_render_window_enable(man->root); @@ -751,7 +882,7 @@ _e_mod_comp_add(E_Manager *man) memset((&att), 0, sizeof(Ecore_X_Window_Attributes)); ecore_x_window_attributes_get(c->win, &att); - if (att.depth != 24) + if ((att.depth != 24) && (att.depth != 32)) { e_util_dialog_internal (_("Compositor Error"), @@ -779,7 +910,7 @@ _e_mod_comp_add(E_Manager *man) { for (i = 0; i < num; i++) { - Comp_Win *cw; + E_Comp_Win *cw; int x, y, w, h, border; cw = _e_mod_comp_win_add(c, wins[i]); @@ -800,14 +931,14 @@ _e_mod_comp_add(E_Manager *man) } static void -_e_mod_comp_del(Comp *c) +_e_mod_comp_del(E_Comp *c) { - Comp_Win *cw; + E_Comp_Win *cw; ecore_x_screen_is_composited_set(c->man->num, 0); while (c->wins) { - cw = (Comp_Win *)(c->wins); + cw = (E_Comp_Win *)(c->wins); _e_mod_comp_win_hide(cw); _e_mod_comp_win_del(cw); } @@ -845,7 +976,7 @@ e_mod_comp_init(void) EINA_LIST_FOREACH(e_manager_list(), l, man) { - Comp *c; + E_Comp *c; c = _e_mod_comp_add(man); if (c) compositors = eina_list_append(compositors, c); @@ -857,7 +988,7 @@ e_mod_comp_init(void) void e_mod_comp_shutdown(void) { - Comp *c; + E_Comp *c; EINA_LIST_FREE(compositors, c) _e_mod_comp_del(c); @@ -866,3 +997,144 @@ e_mod_comp_shutdown(void) eina_hash_free(damages); eina_hash_free(windows); } + +void +e_mod_comp_shadow_set(void) +{ + Eina_List *l; + E_Comp *c; + + EINA_LIST_FOREACH(compositors, l, c) + { + E_Comp_Win *cw; + + EINA_INLIST_FOREACH(c->wins, cw) + { + if (cw->shobj) + { + if (_comp_mod->conf->use_shadow) + { + if ((!cw->argb) && (!cw->shaped)) + { + int ok = 0; + char buf[PATH_MAX]; + + if (_comp_mod->conf->shadow_file) + { + ok = 1; + if (!edje_object_file_set(cw->shobj, + _comp_mod->conf->shadow_file, + "shadow")) + ok = 0; + } + if (!ok) + { + ok = 1; + if (!e_theme_edje_object_set(cw->shobj, + "base/theme/borders", + "e/shadow/box")) + ok = 0; + } + if (!ok) + { + snprintf(buf, sizeof(buf), "%s/shadow.edj", + e_module_dir_get(_comp_mod->module) + ); + edje_object_file_set(cw->shobj, buf, "shadow"); + } + evas_object_show(cw->shobj); + } + } + else + evas_object_hide(cw->shobj); + } + } + } +} + +E_Comp * +e_mod_comp_manager_get(E_Manager *man) +{ + return _e_mod_comp_find(man->root); +} + +/* +void +e_mod_comp_callback_win_add_add(E_Comp *c, void (*func) (void *data, Comp *c, Comp_Win *cw), void *data) +{ +} + +void +e_mod_comp_callback_win_add_del(E_Comp *c, void (*func) (void *data, Comp *c, Comp_Win *cw), void *data) +{ +} + +void +e_mod_comp_callback_del_add(E_Comp *c, void (*func) (void *data, Comp *c), void *data) +{ +} + +void +e_mod_comp_callback_del_delE_Comp *c, void (*func) (void *data, Comp *c), void *data) +{ +} +*/ + +E_Comp_Win * +e_mod_comp_win_find_by_window(E_Comp *c, Ecore_X_Window win) +{ + E_Comp_Win *cw; + + EINA_INLIST_FOREACH(c->wins, cw) + { + if (cw->win == win) return cw; + } + return NULL; +} + +E_Comp_Win * +e_mod_comp_win_find_by_border(E_Comp *c, E_Border *bd) +{ + E_Comp_Win *cw; + + EINA_INLIST_FOREACH(c->wins, cw) + { + if (cw->bd == bd) return cw; + } + return NULL; +} + +E_Comp_Win * +e_mod_comp_win_find_by_popup(E_Comp *c, E_Popup *pop) +{ + E_Comp_Win *cw; + + EINA_INLIST_FOREACH(c->wins, cw) + { + if (cw->pop == pop) return cw; + } + return NULL; +} + +E_Comp_Win * +e_mod_comp_win_find_by_menu(E_Comp *c, E_Menu *menu) +{ + E_Comp_Win *cw; + + EINA_INLIST_FOREACH(c->wins, cw) + { + if (cw->menu == menu) return cw; + } + return NULL; +} + +Evas_Object * +e_mod_comp_win_evas_object_get(E_Comp_Win *cw) +{ + return cw->obj; +} + +Evas_Object * +e_mod_comp_win_mirror_object_add(Evas *e, E_Comp_Win *cw) +{ +} diff --git a/src/modules/comp/e_mod_comp.h b/src/modules/comp/e_mod_comp.h index 704ecba00..3046454c7 100644 --- a/src/modules/comp/e_mod_comp.h +++ b/src/modules/comp/e_mod_comp.h @@ -2,7 +2,21 @@ #else #ifndef E_MOD_COMP_H #define E_MOD_COMP_H -Eina_Bool e_mod_comp_init(void); -void e_mod_comp_shutdown(void); + +typedef struct _E_Comp E_Comp; +typedef struct _E_Comp_Win E_Comp_Win; + +Eina_Bool e_mod_comp_init (void); +void e_mod_comp_shutdown (void); + +void e_mod_comp_shadow_set (void); + +E_Comp *e_mod_comp_manager_get (E_Manager *man); +E_Comp_Win *e_mod_comp_win_find_by_window (E_Comp *c, Ecore_X_Window win); +E_Comp_Win *e_mod_comp_win_find_by_border (E_Comp *c, E_Border *bd); +E_Comp_Win *e_mod_comp_win_find_by_popup (E_Comp *c, E_Popup *pop); +E_Comp_Win *e_mod_comp_win_find_by_menu (E_Comp *c, E_Menu *menu); +Evas_Object *e_mod_comp_win_evas_object_get (E_Comp_Win *cw); + #endif #endif diff --git a/src/modules/comp/e_mod_comp_update.c b/src/modules/comp/e_mod_comp_update.c index 8fefde05e..6b9a25f2f 100644 --- a/src/modules/comp/e_mod_comp_update.c +++ b/src/modules/comp/e_mod_comp_update.c @@ -5,17 +5,17 @@ ////////////////////////////////////////////////////////////////////////// -struct _Update +struct _E_Update { int w, h; int tw, th; int tsw, tsh; unsigned char *tiles; - Update_Policy pol; + E_Update_Policy pol; }; static void -_e_mod_comp_tiles_alloc(Update *up) +_e_mod_comp_tiles_alloc(E_Update *up) { if (up->tiles) return; up->tiles = calloc(up->tw * up->th, sizeof(unsigned char)); @@ -23,33 +23,33 @@ _e_mod_comp_tiles_alloc(Update *up) ////////////////////////////////////////////////////////////////////////// -Update * +E_Update * e_mod_comp_update_new(void) { - Update *up; + E_Update *up; - up = calloc(1, sizeof(Update)); + up = calloc(1, sizeof(E_Update)); up->tsw = 32; up->tsh = 32; - up->pol = UPDATE_POLICY_RAW; + up->pol = E_UPDATE_POLICY_RAW; return up; } void -e_mod_comp_update_free(Update *up) +e_mod_comp_update_free(E_Update *up) { if (up->tiles) free(up->tiles); free(up); } void -e_mod_comp_update_policy_set(Update *up, Update_Policy pol) +e_mod_comp_update_policy_set(E_Update *up, E_Update_Policy pol) { up->pol = pol; } void -e_mod_comp_update_tile_size_set(Update *up, int tsw, int tsh) +e_mod_comp_update_tile_size_set(E_Update *up, int tsw, int tsh) { if ((up->tsw == tsw) && (up->tsh == tsh)) return; up->tsw = tsw; @@ -58,7 +58,7 @@ e_mod_comp_update_tile_size_set(Update *up, int tsw, int tsh) } void -e_mod_comp_update_resize(Update *up, int w, int h) +e_mod_comp_update_resize(E_Update *up, int w, int h) { if ((up->w == w) && (up->h == h)) return; up->w = w; @@ -73,7 +73,7 @@ e_mod_comp_update_resize(Update *up, int w, int h) } void -e_mod_comp_update_add(Update *up, int x, int y, int w, int h) +e_mod_comp_update_add(E_Update *up, int x, int y, int w, int h) { int tx, ty, txx, tyy, xx, yy; unsigned char *t, *t2; @@ -88,9 +88,9 @@ e_mod_comp_update_add(Update *up, int x, int y, int w, int h) switch (up->pol) { - case UPDATE_POLICY_RAW: + case E_UPDATE_POLICY_RAW: break; - case UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH: + case E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH: if (w > (up->w / 2)) { x = 0; @@ -118,16 +118,16 @@ e_mod_comp_update_add(Update *up, int x, int y, int w, int h) } } -Update_Rect * -e_mod_comp_update_rects_get(Update *up) +E_Update_Rect * +e_mod_comp_update_rects_get(E_Update *up) { - Update_Rect *r; + E_Update_Rect *r; int ri = 0; int x, y; unsigned char *t, *t2, *t3; if (!up->tiles) return NULL; - r = calloc((up->tw * up->th) + 1, sizeof(Update_Rect)); + r = calloc((up->tw * up->th) + 1, sizeof(E_Update_Rect)); if (!r) return NULL; t = up->tiles; for (y = 0; y < up->th; y++) @@ -198,7 +198,7 @@ e_mod_comp_update_rects_get(Update *up) } void -e_mod_comp_update_clear(Update *up) +e_mod_comp_update_clear(E_Update *up) { if (up->tiles) { diff --git a/src/modules/comp/e_mod_comp_update.h b/src/modules/comp/e_mod_comp_update.h index 17124ad48..5e81416ee 100644 --- a/src/modules/comp/e_mod_comp_update.h +++ b/src/modules/comp/e_mod_comp_update.h @@ -3,27 +3,27 @@ #ifndef E_MOD_COMP_UPDATE_H #define E_MOD_COMP_UPDATE_H -typedef struct _Update Update; -typedef struct _Update_Rect Update_Rect; -typedef enum _Update_Policy +typedef struct _E_Update E_Update; +typedef struct _E_Update_Rect E_Update_Rect; +typedef enum _E_Update_Policy { - UPDATE_POLICY_RAW, - UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH, -} Update_Policy; + E_UPDATE_POLICY_RAW, + E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH, +} E_Update_Policy; -struct _Update_Rect +struct _E_Update_Rect { int x, y, w, h; }; -Update *e_mod_comp_update_new (void); -void e_mod_comp_update_free (Update *up); -void e_mod_comp_update_policy_set (Update *up, Update_Policy pol); -void e_mod_comp_update_tile_size_set (Update *up, int tsw, int tsh); -void e_mod_comp_update_resize (Update *up, int w, int h); -void e_mod_comp_update_add (Update *up, int x, int y, int w, int h); -Update_Rect *e_mod_comp_update_rects_get (Update *up); -void e_mod_comp_update_clear (Update *up); +E_Update *e_mod_comp_update_new (void); +void e_mod_comp_update_free (E_Update *up); +void e_mod_comp_update_policy_set (E_Update *up, E_Update_Policy pol); +void e_mod_comp_update_tile_size_set (E_Update *up, int tsw, int tsh); +void e_mod_comp_update_resize (E_Update *up, int w, int h); +void e_mod_comp_update_add (E_Update *up, int x, int y, int w, int h); +E_Update_Rect *e_mod_comp_update_rects_get (E_Update *up); +void e_mod_comp_update_clear (E_Update *up); #endif #endif diff --git a/src/modules/comp/e_mod_config.c b/src/modules/comp/e_mod_config.c index 872695ff1..86d9f8ce9 100644 --- a/src/modules/comp/e_mod_config.c +++ b/src/modules/comp/e_mod_config.c @@ -1,11 +1,12 @@ #include "e.h" #include "e_mod_main.h" #include "e_mod_config.h" +#include "e_mod_comp.h" #include "config.h" struct _E_Config_Dialog_Data { - int x; + int use_shadow; }; /* Protos */ @@ -43,28 +44,20 @@ e_int_config_comp_module(E_Container *con, const char *params __UNUSED__) static void * _create_data(E_Config_Dialog *cfd) { - /* E_Config_Dialog_Data *cfdata; - Dropshadow *ds; - ds = cfd->data; cfdata = E_NEW(E_Config_Dialog_Data, 1); - _fill_data(ds, cfdata); + + cfdata->use_shadow = _comp_mod->conf->use_shadow; + return cfdata; - */ - return NULL; } static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) { - /* - Dropshadow *ds; - - ds = cfd->data; - ds->config_dialog = NULL; + _comp_mod->config_dialog = NULL; free(cfdata); - */ } static Evas_Object * @@ -76,100 +69,26 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf o = e_widget_list_add(evas, 0, 0); ot = e_widget_table_add(evas, 1); - of = e_widget_framelist_add(evas, _("Quality"), 0); + of = e_widget_framelist_add(evas, _("Shadow"), 0); e_widget_framelist_content_align_set(of, 0.5, 0.0); - rg = e_widget_radio_group_new(&(cfdata->x)); - ob = e_widget_radio_add(evas, _("X"), 1, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Y"), 2, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Z"), 4, rg); + ob = e_widget_check_add(evas, _("Enabled"), &(cfdata->use_shadow)); e_widget_framelist_object_append(of, ob); e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); -/* - of = e_widget_framelist_add(evas, _("Blur Type"), 0); - e_widget_framelist_content_align_set(of, 0.5, 0.0); - rg = e_widget_radio_group_new(&(cfdata->blur_size)); - ob = e_widget_radio_add(evas, _("Very Fuzzy"), 80, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Fuzzy"), 40, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Medium"), 20, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Sharp"), 10, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Very Sharp"), 5, rg); - e_widget_framelist_object_append(of, ob); - e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 1, 1, 1); - - of = e_widget_framelist_add(evas, _("Shadow Distance"), 0); - e_widget_framelist_content_align_set(of, 0.5, 0.0); - rg = e_widget_radio_group_new(&(cfdata->shadow_x)); - ob = e_widget_radio_add(evas, _("Very Far"), 32, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Far"), 16, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Near"), 8, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Very Near"), 4, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Extremely Near"), 2, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Underneath"), 0, rg); - e_widget_framelist_object_append(of, ob); - e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1); - - of = e_widget_framelist_add(evas, _("Shadow Darkness"), 0); - e_widget_framelist_content_align_set(of, 0.5, 0.0); - rg = e_widget_radio_group_new(&(cfdata->darkness)); - ob = e_widget_radio_add(evas, _("Very Dark"), 0, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Dark"), 1, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Light"), 2, rg); - e_widget_framelist_object_append(of, ob); - ob = e_widget_radio_add(evas, _("Very Light"), 3, rg); - e_widget_framelist_object_append(of, ob); - e_widget_table_object_append(ot, of, 1, 1, 1, 1, 1, 1, 1, 1); - + e_widget_list_object_append(o, ot, 1, 1, 0.5); -*/ + return o; } static int _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) { - /* - Dropshadow *ds; - - ds = cfd->data; - e_border_button_bindings_ungrab_all(); - - ds->conf->quality = cfdata->quality; - ds->conf->blur_size = cfdata->blur_size; - ds->conf->shadow_x = cfdata->shadow_x; - ds->conf->shadow_y = cfdata->shadow_x; - switch (cfdata->darkness) + if (_comp_mod->conf->use_shadow != cfdata->use_shadow) { - case 0: - ds->conf->shadow_darkness = 1.0; - break; - case 1: - ds->conf->shadow_darkness = 0.75; - break; - case 2: - ds->conf->shadow_darkness = 0.5; - break; - case 3: - ds->conf->shadow_darkness = 0.25; - break; + _comp_mod->conf->use_shadow = cfdata->use_shadow; + e_mod_comp_shadow_set(); } e_config_save_queue(); - e_border_button_bindings_grab_all(); - - _dropshadow_cb_config_updated(ds); - */ return 1; } diff --git a/src/modules/comp/e_mod_main.c b/src/modules/comp/e_mod_main.c index 85424e019..b322104fa 100644 --- a/src/modules/comp/e_mod_main.c +++ b/src/modules/comp/e_mod_main.c @@ -30,15 +30,16 @@ e_modapi_init(E_Module *m) #undef D #define T Config #define D mod->conf_edd - E_CONFIG_VAL(D, T, x, INT); + E_CONFIG_VAL(D, T, use_shadow, UCHAR); + E_CONFIG_VAL(D, T, shadow_file, STR); mod->conf = e_config_domain_load("module.comp", mod->conf_edd); if (!mod->conf) { mod->conf = E_NEW(Config, 1); - mod->conf->x = 1; + mod->conf->use_shadow = 1; + mod->conf->shadow_file = NULL; } - E_CONFIG_LIMIT(mod->conf->x, -2, 2); _comp_mod = mod; @@ -65,7 +66,7 @@ e_modapi_shutdown(E_Module *m) e_object_del(E_OBJECT(mod->config_dialog)); mod->config_dialog = NULL; } - + if (mod->conf->shadow_file) eina_stringshare_del(mod->conf->shadow_file); free(mod->conf); E_CONFIG_DD_FREE(mod->conf_edd); free(mod); diff --git a/src/modules/comp/e_mod_main.h b/src/modules/comp/e_mod_main.h index 3e01c52c9..8ac0b17c5 100644 --- a/src/modules/comp/e_mod_main.h +++ b/src/modules/comp/e_mod_main.h @@ -7,7 +7,8 @@ typedef struct _Mod Mod; struct _Config { - int x; + unsigned char use_shadow; + const char *shadow_file; }; struct _Mod diff --git a/src/modules/comp/shadow.edj b/src/modules/comp/shadow.edj new file mode 100644 index 0000000000000000000000000000000000000000..967d9327752d210dd18bdca634aca6e41e9aec21 GIT binary patch literal 9407 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 j?%k|E=48;+wCm(@8?b+@7i!l