handle shaped windows on compositing. not pretty - but needed.
SVN revision: 45028
This commit is contained in:
parent
dc87e6da83
commit
6c55b5eb39
|
@ -59,8 +59,10 @@ struct _Comp_Win
|
||||||
Eina_Bool visible : 1; // is visible
|
Eina_Bool visible : 1; // is visible
|
||||||
Eina_Bool input_only : 1; // is input_only
|
Eina_Bool input_only : 1; // is input_only
|
||||||
Eina_Bool argb : 1; // is argb
|
Eina_Bool argb : 1; // is argb
|
||||||
|
Eina_Bool shaped : 1; // is shaped
|
||||||
Eina_Bool update : 1; // has updates to fetch
|
Eina_Bool update : 1; // has updates to fetch
|
||||||
Eina_Bool redirected : 1; // has updates to fetch
|
Eina_Bool redirected : 1; // has updates to fetch
|
||||||
|
Eina_Bool shape_changed : 1; // shape changed
|
||||||
};
|
};
|
||||||
|
|
||||||
static Eina_List *handlers = NULL;
|
static Eina_List *handlers = NULL;
|
||||||
|
@ -309,10 +311,102 @@ _e_mod_comp_cb_animator(void *data)
|
||||||
w = r[i].w;
|
w = r[i].w;
|
||||||
h = r[i].h;
|
h = r[i].h;
|
||||||
ecore_x_image_get(cw->xim, cw->pixmap, x, y, x, y, w, 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);
|
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_size_set(cw->obj, cw->pw, cw->ph);
|
||||||
evas_object_image_data_set(cw->obj, pix);
|
evas_object_image_data_set(cw->obj, pix);
|
||||||
evas_object_image_data_update_add(cw->obj, x, y, w, h);
|
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);
|
free(r);
|
||||||
|
@ -397,6 +491,9 @@ _e_mod_comp_win_add(Comp *c, Ecore_X_Window win)
|
||||||
eina_hash_add(windows, e_util_winid_str_get(cw->win), cw);
|
eina_hash_add(windows, e_util_winid_str_get(cw->win), cw);
|
||||||
if (!cw->input_only)
|
if (!cw->input_only)
|
||||||
{
|
{
|
||||||
|
Ecore_X_Rectangle *rects;
|
||||||
|
int num;
|
||||||
|
|
||||||
cw->damage = ecore_x_damage_new(cw->win, ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES);
|
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);
|
eina_hash_add(damages, e_util_winid_str_get(cw->damage), cw);
|
||||||
cw->obj = evas_object_image_filled_add(c->evas);
|
cw->obj = evas_object_image_filled_add(c->evas);
|
||||||
|
@ -405,6 +502,28 @@ _e_mod_comp_win_add(Comp *c, Ecore_X_Window win)
|
||||||
evas_object_image_alpha_set(cw->obj, 1);
|
evas_object_image_alpha_set(cw->obj, 1);
|
||||||
else
|
else
|
||||||
evas_object_image_alpha_set(cw->obj, 0);
|
evas_object_image_alpha_set(cw->obj, 0);
|
||||||
|
ecore_x_window_shape_events_select(cw->win, 1);
|
||||||
|
rects = ecore_x_window_shape_rectangles_get(cw->win, &num);
|
||||||
|
if (rects)
|
||||||
|
{
|
||||||
|
if ((rects) && (num == 1))
|
||||||
|
{
|
||||||
|
if ((rects[0].x == 0) &&
|
||||||
|
(rects[0].y == 0) &&
|
||||||
|
(rects[0].width == att.w) &&
|
||||||
|
(rects[0].height == att.h))
|
||||||
|
{
|
||||||
|
free(rects);
|
||||||
|
rects = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rects)
|
||||||
|
{
|
||||||
|
cw->shaped = 1;
|
||||||
|
cw->shape_changed = 1;
|
||||||
|
free(rects);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -609,6 +728,20 @@ _e_mod_comp_win_damage(Comp_Win *cw, int x, int y, int w, int h, Eina_Bool dmg)
|
||||||
_e_mod_comp_win_render_queue(cw);
|
_e_mod_comp_win_render_queue(cw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_mod_comp_win_reshape(Comp_Win *cw)
|
||||||
|
{
|
||||||
|
if (cw->shape_changed) return;
|
||||||
|
cw->shape_changed = 1;
|
||||||
|
if (!cw->update)
|
||||||
|
{
|
||||||
|
cw->update = 1;
|
||||||
|
cw->c->updates = eina_list_append(cw->c->updates, cw);
|
||||||
|
}
|
||||||
|
_e_mod_comp_update_add(cw->up, 0, 0, cw->w, cw->h);
|
||||||
|
_e_mod_comp_win_render_queue(cw);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -737,6 +870,10 @@ static int
|
||||||
_e_mod_comp_shape(void *data, int type, void *event)
|
_e_mod_comp_shape(void *data, int type, void *event)
|
||||||
{ // later
|
{ // later
|
||||||
Ecore_X_Event_Window_Shape *ev = event;
|
Ecore_X_Event_Window_Shape *ev = event;
|
||||||
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue