Alexandre Julliard : winex11: Take the alpha channel into account to compute the region of layered windows .

Alexandre Julliard julliard at winehq.org
Tue Oct 2 14:09:39 CDT 2012


Module: wine
Branch: master
Commit: d8247efd5ecb8c4604624eb2bbf47e194ce59e7e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d8247efd5ecb8c4604624eb2bbf47e194ce59e7e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 27 20:47:08 2012 +0200

winex11: Take the alpha channel into account to compute the region of layered windows.

---

 dlls/winex11.drv/bitblt.c |   45 ++++++++++++++++++++++++++++++++++-----------
 dlls/winex11.drv/window.c |    5 +++--
 dlls/winex11.drv/x11drv.h |    3 ++-
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 8701d73..ceecb0c 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1545,6 +1545,7 @@ struct x11drv_window_surface
     XImage               *image;
     RECT                  bounds;
     BOOL                  is_r8g8b8;
+    BOOL                  is_argb;
     COLORREF              color_key;
     struct gdi_image_bits bits;
     CRITICAL_SECTION      crit;
@@ -1598,7 +1599,7 @@ static void update_surface_region( struct x11drv_window_surface *surface )
     int x, y, start, width;
     HRGN rgn;
 
-    if (surface->color_key == CLR_INVALID)
+    if (!surface->is_argb && surface->color_key == CLR_INVALID)
     {
         XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet );
         return;
@@ -1662,17 +1663,38 @@ static void update_surface_region( struct x11drv_window_surface *surface )
     case 32:
     {
         DWORD *bits = surface->bits.ptr;
-        UINT mask = info->bmiHeader.biCompression == BI_RGB ? 0xffffff : (masks[0] | masks[1] | masks[2]);
 
-        for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
+        if (info->bmiHeader.biCompression == BI_RGB)
         {
-            x = 0;
-            while (x < width)
+            for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
             {
-                while (x < width && (bits[x] & mask) == surface->color_key) x++;
-                start = x;
-                while (x < width && (bits[x] & mask) != surface->color_key) x++;
-                add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+                x = 0;
+                while (x < width)
+                {
+                    while (x < width &&
+                           ((bits[x] & 0xffffff) == surface->color_key ||
+                            (surface->is_argb && !(bits[x] & 0xff000000)))) x++;
+                    start = x;
+                    while (x < width &&
+                           ((bits[x] & 0xffffff) != surface->color_key ||
+                            !(surface->is_argb && !(bits[x] & 0xff000000)))) x++;
+                    add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+                }
+            }
+        }
+        else
+        {
+            UINT mask = masks[0] | masks[1] | masks[2];
+            for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
+            {
+                x = 0;
+                while (x < width)
+                {
+                    while (x < width && (bits[x] & mask) == surface->color_key) x++;
+                    start = x;
+                    while (x < width && (bits[x] & mask) != surface->color_key) x++;
+                    add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+                }
             }
         }
         break;
@@ -1782,7 +1804,7 @@ static void x11drv_surface_flush( struct window_surface *window_surface )
                surface, coords.width, coords.height,
                wine_dbgstr_rect( &surface->bounds ), surface->bits.ptr );
 
-        if (surface->color_key != CLR_INVALID) update_surface_region( surface );
+        if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface );
 
         if (surface->image->bits_per_pixel == 4 || surface->image->bits_per_pixel == 8)
             mapping = X11DRV_PALETTE_PaletteToXPixel;
@@ -1836,7 +1858,7 @@ static const struct window_surface_funcs x11drv_surface_funcs =
  *           create_surface
  */
 struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect,
-                                       COLORREF color_key )
+                                       COLORREF color_key, BOOL use_alpha )
 {
     const XPixmapFormatValues *format = pixmap_formats[vis->depth];
     struct x11drv_window_surface *surface;
@@ -1862,6 +1884,7 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co
     surface->header.ref   = 1;
     surface->window = window;
     surface->is_r8g8b8 = is_r8g8b8( vis );
+    surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB);
     set_color_key( surface, color_key );
     reset_bounds( &surface->bounds );
     if (!(surface->bits.ptr  = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index f090b2d..5b68968 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2084,7 +2084,7 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
     if (!layered || !GetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY))
         key = CLR_INVALID;
 
-    *surface = create_surface( data->whole_window, &data->vis, &surface_rect, key );
+    *surface = create_surface( data->whole_window, &data->vis, &surface_rect, key, FALSE );
 
 done:
     release_win_data( data );
@@ -2384,7 +2384,8 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO
     surface = data->surface;
     if (!surface || memcmp( &surface->rect, &rect, sizeof(RECT) ))
     {
-        data->surface = create_surface( data->whole_window, &data->vis, &rect, color_key );
+        data->surface = create_surface( data->whole_window, &data->vis, &rect,
+                                        color_key, !data->embedded );
         if (surface) window_surface_release( surface );
         surface = data->surface;
     }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index f496158..05c8ca9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -190,7 +190,8 @@ extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const B
                                         const struct gdi_image_bits *bits, UINT coloruse ) DECLSPEC_HIDDEN;
 extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
                                BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
-extern struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect, COLORREF color_key ) DECLSPEC_HIDDEN;
+extern struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect,
+                                              COLORREF color_key, BOOL use_alpha ) DECLSPEC_HIDDEN;
 extern void set_surface_color_key( struct window_surface *window_surface, COLORREF color_key ) DECLSPEC_HIDDEN;
 
 extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list