From: Enlightenment S. <no-...@en...> - 2010-09-18 17:19:18
|
Log: 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. Author: caro Date: 2010-09-18 10:19:11 -0700 (Sat, 18 Sep 2010) New Revision: 52416 Modified: trunk/evas/src/modules/engines/software_gdi/Evas_Engine_Software_Gdi.h trunk/evas/src/modules/engines/software_gdi/evas_engine.c trunk/evas/src/modules/engines/software_gdi/evas_engine.h trunk/evas/src/modules/engines/software_gdi/evas_gdi_main.c trunk/evas/src/modules/engines/software_gdi/evas_outbuf.c Modified: trunk/evas/src/modules/engines/software_gdi/Evas_Engine_Software_Gdi.h =================================================================== --- trunk/evas/src/modules/engines/software_gdi/Evas_Engine_Software_Gdi.h 2010-09-18 14:23:20 UTC (rev 52415) +++ trunk/evas/src/modules/engines/software_gdi/Evas_Engine_Software_Gdi.h 2010-09-18 17:19:11 UTC (rev 52416) @@ -17,11 +17,11 @@ 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 */ Modified: trunk/evas/src/modules/engines/software_gdi/evas_engine.c =================================================================== --- trunk/evas/src/modules/engines/software_gdi/evas_engine.c 2010-09-18 14:23:20 UTC (rev 52415) +++ trunk/evas/src/modules/engines/software_gdi/evas_engine.c 2010-09-18 17:19:11 UTC (rev 52416) @@ -25,10 +25,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ { Render_Engine *re; + printf ("%s\n", __FUNCTION__); re = (Render_Engine *)data; evas_software_gdi_outbuf_reconfigure(re->ob, width, @@ -202,6 +203,7 @@ { 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 @@ { 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 @@ int uw; int uh; + printf ("%s\n", __FUNCTION__); re = (Render_Engine *)data; if (re->end) { @@ -291,6 +295,7 @@ { 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 @@ { Render_Engine *re; + printf ("%s\n", __FUNCTION__); re = (Render_Engine *)data; evas_software_gdi_outbuf_flush(re->ob); } @@ -314,6 +320,7 @@ { Render_Engine *re; + printf ("%s\n", __FUNCTION__); re = (Render_Engine *)data; evas_software_gdi_outbuf_idle_flush(re->ob); } Modified: trunk/evas/src/modules/engines/software_gdi/evas_engine.h =================================================================== --- trunk/evas/src/modules/engines/software_gdi/evas_engine.h 2010-09-18 14:23:20 UTC (rev 52415) +++ trunk/evas/src/modules/engines/software_gdi/evas_engine.h 2010-09-18 17:19:11 UTC (rev 52416) @@ -68,11 +68,11 @@ 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 @@ unsigned char destination_alpha : 1; unsigned char debug : 1; unsigned char synced : 1; + + unsigned char region_built : 1; } priv; }; @@ -116,10 +118,10 @@ /* 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 @@ 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); Modified: trunk/evas/src/modules/engines/software_gdi/evas_gdi_main.c =================================================================== --- trunk/evas/src/modules/engines/software_gdi/evas_gdi_main.c 2010-09-18 14:23:20 UTC (rev 52415) +++ trunk/evas/src/modules/engines/software_gdi/evas_gdi_main.c 2010-09-18 17:19:11 UTC (rev 52416) @@ -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 @@ } 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 @@ } 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)); Modified: trunk/evas/src/modules/engines/software_gdi/evas_outbuf.c =================================================================== --- trunk/evas/src/modules/engines/software_gdi/evas_outbuf.c 2010-09-18 14:23:20 UTC (rev 52415) +++ trunk/evas/src/modules/engines/software_gdi/evas_outbuf.c 2010-09-18 17:19:11 UTC (rev 52416) @@ -10,8 +10,8 @@ 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 @@ 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 @@ 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 @@ buf->priv.gdi.bitmap_info->masks[2]); } } - if (buf->priv.gdi.mask != mask) - buf->priv.gdi.mask = mask; } return buf; @@ -226,6 +224,7 @@ buf->height = height; buf->rot = rotation; evas_software_gdi_bitmap_resize(buf); + buf->priv.region_built = 0; } RGBA_Image * @@ -254,7 +253,7 @@ *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 @@ /* 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 @@ int w, int h) { + HRGN regions = NULL; Gfx_Func_Convert conv_func; Outbuf_Region *obr; DATA32 *src_data; @@ -404,13 +404,159 @@ 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 |