forked from enlightenment/efl
Fix shaped windows on Windows. It uses regions.
Advantages: * it is the simplest method to implement Disadvantages: * it's slow * it does not take into account transparency * it does not work with the composite manager (Windows >= Vista) Layered windows should be used (all the disadvantaged above are fixed), but i've never succeeded in making them work. SVN revision: 52416
This commit is contained in:
parent
6f4d152810
commit
9acfb01811
|
@ -17,11 +17,11 @@ struct _Evas_Engine_Info_Software_Gdi
|
|||
|
||||
struct {
|
||||
HWND window;
|
||||
HBITMAP mask;
|
||||
int depth;
|
||||
int rotation;
|
||||
unsigned int layered : 1;
|
||||
unsigned int borderless : 1;
|
||||
unsigned int fullscreen : 1;
|
||||
unsigned int region : 1;
|
||||
} info;
|
||||
|
||||
/* non-blocking or blocking mode */
|
||||
|
|
|
@ -25,10 +25,10 @@ _output_setup(int width,
|
|||
int height,
|
||||
int rot,
|
||||
HWND window,
|
||||
HBITMAP mask,
|
||||
int depth,
|
||||
unsigned int layered,
|
||||
unsigned int fullscreen)
|
||||
unsigned int borderless,
|
||||
unsigned int fullscreen,
|
||||
unsigned int region)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
|
@ -59,7 +59,7 @@ _output_setup(int width,
|
|||
|
||||
re->ob = evas_software_gdi_outbuf_setup(width, height, rot,
|
||||
OUTBUF_DEPTH_INHERIT,
|
||||
window, mask, depth, layered, fullscreen,
|
||||
window, depth, borderless, fullscreen, region,
|
||||
0, 0);
|
||||
if (!re->ob)
|
||||
{
|
||||
|
@ -122,10 +122,10 @@ eng_setup(Evas *e, void *in)
|
|||
e->output.h,
|
||||
info->info.rotation,
|
||||
info->info.window,
|
||||
info->info.mask,
|
||||
info->info.depth,
|
||||
info->info.layered,
|
||||
info->info.fullscreen);
|
||||
info->info.borderless,
|
||||
info->info.fullscreen,
|
||||
info->info.region);
|
||||
else
|
||||
{
|
||||
int ponebuf = 0;
|
||||
|
@ -138,10 +138,10 @@ eng_setup(Evas *e, void *in)
|
|||
info->info.rotation,
|
||||
OUTBUF_DEPTH_INHERIT,
|
||||
info->info.window,
|
||||
info->info.mask,
|
||||
info->info.depth,
|
||||
info->info.layered,
|
||||
info->info.borderless,
|
||||
info->info.fullscreen,
|
||||
info->info.region,
|
||||
0, 0);
|
||||
re->ob->onebuf = ponebuf;
|
||||
}
|
||||
|
@ -176,6 +176,7 @@ eng_output_resize(void *data, int width, int height)
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
evas_software_gdi_outbuf_reconfigure(re->ob,
|
||||
width,
|
||||
|
@ -202,6 +203,7 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
|
||||
}
|
||||
|
@ -211,6 +213,7 @@ eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
|
||||
}
|
||||
|
@ -243,6 +246,7 @@ eng_output_redraws_next_update_get(void *data,
|
|||
int uw;
|
||||
int uh;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
if (re->end)
|
||||
{
|
||||
|
@ -291,6 +295,7 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
#ifdef BUILD_PIPE_RENDER
|
||||
evas_common_pipe_map4_begin(surface);
|
||||
|
@ -305,6 +310,7 @@ eng_output_flush(void *data)
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
evas_software_gdi_outbuf_flush(re->ob);
|
||||
}
|
||||
|
@ -314,6 +320,7 @@ eng_output_idle_flush(void *data)
|
|||
{
|
||||
Render_Engine *re;
|
||||
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
re = (Render_Engine *)data;
|
||||
evas_software_gdi_outbuf_idle_flush(re->ob);
|
||||
}
|
||||
|
|
|
@ -68,11 +68,11 @@ struct _Outbuf
|
|||
struct {
|
||||
BITMAPINFO_GDI *bitmap_info;
|
||||
HWND window;
|
||||
HBITMAP mask;
|
||||
HDC dc;
|
||||
int depth;
|
||||
unsigned char layered : 1;
|
||||
unsigned char borderless : 1;
|
||||
unsigned char fullscreen : 1;
|
||||
unsigned char region : 1;
|
||||
} gdi;
|
||||
|
||||
/* 1 big buffer for updates - flush on idle_flush */
|
||||
|
@ -88,6 +88,8 @@ struct _Outbuf
|
|||
unsigned char destination_alpha : 1;
|
||||
unsigned char debug : 1;
|
||||
unsigned char synced : 1;
|
||||
|
||||
unsigned char region_built : 1;
|
||||
} priv;
|
||||
};
|
||||
|
||||
|
@ -116,10 +118,10 @@ struct _Gdi_Output_Buffer
|
|||
/* evas_gdi_main.c */
|
||||
|
||||
int evas_software_gdi_init (HWND window,
|
||||
HBITMAP mask,
|
||||
int depth,
|
||||
unsigned int layered,
|
||||
unsigned int borderless,
|
||||
unsigned int fullscreen,
|
||||
unsigned int region,
|
||||
Outbuf *buf);
|
||||
|
||||
void evas_software_gdi_shutdown(Outbuf *buf);
|
||||
|
@ -157,10 +159,10 @@ Outbuf *evas_software_gdi_outbuf_setup(int width,
|
|||
int rotation,
|
||||
Outbuf_Depth depth,
|
||||
HWND window,
|
||||
HBITMAP mask,
|
||||
int w_depth,
|
||||
unsigned int layered,
|
||||
unsigned int borderless,
|
||||
unsigned int fullscreen,
|
||||
unsigned int region,
|
||||
int mask_dither,
|
||||
int destination_alpha);
|
||||
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
|
||||
int
|
||||
evas_software_gdi_init (HWND window,
|
||||
HBITMAP mask,
|
||||
int depth,
|
||||
unsigned int layered,
|
||||
unsigned int borderless,
|
||||
unsigned int fullscreen __UNUSED__,
|
||||
unsigned int region,
|
||||
Outbuf *buf)
|
||||
{
|
||||
RECT window_rect;
|
||||
SIZE mask_size;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
ERR("[Engine] [GDI] Window is NULL");
|
||||
|
@ -20,8 +17,9 @@ evas_software_gdi_init (HWND window,
|
|||
}
|
||||
|
||||
buf->priv.gdi.window = window;
|
||||
buf->priv.gdi.mask = mask;
|
||||
buf->priv.gdi.dc = GetDC(window);
|
||||
buf->priv.gdi.borderless = borderless;
|
||||
buf->priv.gdi.region = region;
|
||||
if (!buf->priv.gdi.dc)
|
||||
{
|
||||
ERR("[Engine] [GDI] Can not get DC");
|
||||
|
@ -37,22 +35,6 @@ evas_software_gdi_init (HWND window,
|
|||
}
|
||||
buf->priv.gdi.depth = depth;
|
||||
|
||||
/* mask */
|
||||
if (layered && mask)
|
||||
{
|
||||
if (GetBitmapDimensionEx(mask, &mask_size) &&
|
||||
GetClientRect(window, &window_rect))
|
||||
{
|
||||
if ((mask_size.cx == window_rect.right) &&
|
||||
(mask_size.cy == window_rect.bottom))
|
||||
{
|
||||
/* if (SetLayeredWindowAttributes(window, RGB(0, 0, 0), 255, LWA_COLORKEY)) */
|
||||
/* { */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: support fullscreen */
|
||||
|
||||
buf->priv.gdi.bitmap_info = (BITMAPINFO_GDI *)malloc(sizeof(BITMAPINFO_GDI));
|
||||
|
|
|
@ -10,8 +10,8 @@ static int gdicountlimit = 32;
|
|||
static Gdi_Output_Buffer *
|
||||
_find_gdiob(HDC dc, BITMAPINFO_GDI *bitmap_info, int depth, int w, int h, void *data)
|
||||
{
|
||||
Eina_List *l;
|
||||
Eina_List *gdil;
|
||||
Eina_List *l = NULL;
|
||||
Eina_List *gdil = NULL;
|
||||
Gdi_Output_Buffer *gdiob = NULL;
|
||||
Gdi_Output_Buffer *gdiob2;
|
||||
int sz;
|
||||
|
@ -132,10 +132,10 @@ evas_software_gdi_outbuf_setup(int width,
|
|||
int rotation,
|
||||
Outbuf_Depth depth,
|
||||
HWND window,
|
||||
HBITMAP mask,
|
||||
int w_depth,
|
||||
unsigned int layered,
|
||||
unsigned int borderless,
|
||||
unsigned int fullscreen,
|
||||
unsigned int region,
|
||||
int mask_dither,
|
||||
int destination_alpha)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ evas_software_gdi_outbuf_setup(int width,
|
|||
buf->priv.mask_dither = mask_dither;
|
||||
buf->priv.destination_alpha = destination_alpha;
|
||||
|
||||
if (!evas_software_gdi_init(window, mask, w_depth, layered, fullscreen, buf))
|
||||
if (!evas_software_gdi_init(window, w_depth, borderless, fullscreen, region, buf))
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
|
@ -205,8 +205,6 @@ evas_software_gdi_outbuf_setup(int width,
|
|||
buf->priv.gdi.bitmap_info->masks[2]);
|
||||
}
|
||||
}
|
||||
if (buf->priv.gdi.mask != mask)
|
||||
buf->priv.gdi.mask = mask;
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
@ -226,6 +224,7 @@ evas_software_gdi_outbuf_reconfigure(Outbuf *buf,
|
|||
buf->height = height;
|
||||
buf->rot = rotation;
|
||||
evas_software_gdi_bitmap_resize(buf);
|
||||
buf->priv.region_built = 0;
|
||||
}
|
||||
|
||||
RGBA_Image *
|
||||
|
@ -254,7 +253,7 @@ evas_software_gdi_outbuf_new_region_for_update(Outbuf *buf,
|
|||
*cw = w;
|
||||
*ch = h;
|
||||
|
||||
alpha = ((buf->priv.gdi.mask) || (buf->priv.destination_alpha));
|
||||
alpha = ((buf->priv.gdi.region) || (buf->priv.destination_alpha));
|
||||
|
||||
if ((buf->rot == 0) &&
|
||||
(buf->priv.gdi.bitmap_info->masks[0] == 0xff0000) &&
|
||||
|
@ -319,7 +318,7 @@ evas_software_gdi_outbuf_new_region_for_update(Outbuf *buf,
|
|||
/* 1, */
|
||||
/* w, h, NULL); */
|
||||
}
|
||||
if ((buf->priv.gdi.mask) || (buf->priv.destination_alpha))
|
||||
if ((buf->priv.gdi.region) || (buf->priv.destination_alpha))
|
||||
/* FIXME: faster memset! */
|
||||
memset(im->image.data, 0, w * h * sizeof(DATA32));
|
||||
|
||||
|
@ -335,6 +334,7 @@ evas_software_gdi_outbuf_push_updated_region(Outbuf *buf,
|
|||
int w,
|
||||
int h)
|
||||
{
|
||||
HRGN regions = NULL;
|
||||
Gfx_Func_Convert conv_func;
|
||||
Outbuf_Region *obr;
|
||||
DATA32 *src_data;
|
||||
|
@ -404,13 +404,159 @@ evas_software_gdi_outbuf_push_updated_region(Outbuf *buf,
|
|||
x,
|
||||
y,
|
||||
NULL);
|
||||
/* if (obr->mxob) */
|
||||
/* { */
|
||||
/* int yy; */
|
||||
/* for (yy = 0; yy < obr->h; yy++) */
|
||||
/* evas_software_xlib_x_write_mask_line(buf, obr->mxob, */
|
||||
/* src_data + */
|
||||
/* (yy * obr->w), obr->w, yy); */
|
||||
|
||||
/* Region code */
|
||||
if (!buf->priv.gdi.region)
|
||||
{
|
||||
if (regions)
|
||||
DeleteObject(regions);
|
||||
SetWindowRgn(buf->priv.gdi.window, NULL, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buf->priv.region_built)
|
||||
{
|
||||
RECT rect;
|
||||
POINT pt = { 0, 0 };
|
||||
HRGN region;
|
||||
int *tmp;
|
||||
int i;
|
||||
int j;
|
||||
int ww;
|
||||
int wh;
|
||||
int dx;
|
||||
int dy;
|
||||
int xmin;
|
||||
int xmax;
|
||||
|
||||
if (!GetClientRect(buf->priv.gdi.window, &rect))
|
||||
return;
|
||||
|
||||
ww = rect.right - rect.left;
|
||||
wh = rect.bottom - rect.top;
|
||||
printf ("(%d,%d) (%d,%d)\n", w, h, ww, wh);
|
||||
|
||||
if (!GetWindowRect(buf->priv.gdi.window, &rect))
|
||||
return;
|
||||
if (!ClientToScreen(buf->priv.gdi.window, &pt))
|
||||
return;
|
||||
dx = x + pt.x - rect.left;
|
||||
dy = y + pt.y - rect.top;
|
||||
|
||||
tmp = src_data;
|
||||
|
||||
for (j = 0; j < h; j++)
|
||||
{
|
||||
i = 0;
|
||||
while (i < w)
|
||||
{
|
||||
if ((*tmp & 0xff000000) == 0xff000000)
|
||||
{
|
||||
xmin = dx + i;
|
||||
if ((i + 1) == w)
|
||||
{
|
||||
xmax = dx + i;
|
||||
region = CreateRectRgn(xmin, dy + j, xmax + 1, dy + j + 1);
|
||||
if (regions == NULL)
|
||||
regions = region;
|
||||
else
|
||||
{
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
tmp++;
|
||||
|
||||
while (i < w)
|
||||
{
|
||||
if ((*tmp & 0xff000000) == 0xff000000)
|
||||
{
|
||||
if ((i + 1) == w)
|
||||
{
|
||||
xmax = dx + i;
|
||||
region = CreateRectRgn(xmin, dy + j, xmax + 1, dy + j + 1);
|
||||
if (regions == NULL)
|
||||
regions = region;
|
||||
else
|
||||
{
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmax = dx + i - 1;
|
||||
region = CreateRectRgn(xmin, dy + j, xmax + 1, dy + j + 1);
|
||||
if (regions == NULL)
|
||||
regions = region;
|
||||
else
|
||||
{
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!buf->priv.gdi.borderless)
|
||||
{
|
||||
RECT rnc;
|
||||
RECT rc;
|
||||
POINT pt = { 0, 0 };
|
||||
LONG ncw;
|
||||
LONG nch;
|
||||
LONG cw;
|
||||
LONG ch;
|
||||
|
||||
if (!GetWindowRect(buf->priv.gdi.window, &rnc))
|
||||
return;
|
||||
if (!GetClientRect(buf->priv.gdi.window, &rc))
|
||||
return;
|
||||
if (!ClientToScreen(buf->priv.gdi.window, &pt))
|
||||
return;
|
||||
|
||||
ncw = rnc.right - rnc.left;
|
||||
nch = rnc.bottom - rnc.top;
|
||||
cw = rc.right - rc.left;
|
||||
ch = rc.bottom - rc.top;
|
||||
|
||||
region = CreateRectRgn(0, 0, ncw, pt.y - rnc.top);
|
||||
if (!regions)
|
||||
regions = region;
|
||||
else
|
||||
{
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
}
|
||||
region = CreateRectRgn(0, pt.y - rnc.top, pt.x - rnc.left, nch);
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
region = CreateRectRgn(pt.x - rnc.left, pt.y - rnc.top + ch, pt.x - rnc.left + cw, nch);
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
region = CreateRectRgn(pt.x - rnc.left + cw, pt.y - rnc.top, ncw, nch);
|
||||
CombineRgn(regions, regions, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
}
|
||||
|
||||
if (regions)
|
||||
SetWindowRgn(buf->priv.gdi.window, regions, 1);
|
||||
|
||||
buf->priv.region_built = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue