Alexandre Julliard : gdi.exe: Implement the DIB.DRV driver using a window surface.
Alexandre Julliard
julliard at winehq.org
Fri Feb 23 15:10:23 CST 2018
Module: wine
Branch: master
Commit: 16943efa70d721875d0cc24a848f17159c3f8beb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=16943efa70d721875d0cc24a848f17159c3f8beb
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Feb 23 15:55:24 2018 +0100
gdi.exe: Implement the DIB.DRV driver using a window surface.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi.exe16/gdi.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c
index 8ee37d7..f0c354b 100644
--- a/dlls/gdi.exe16/gdi.c
+++ b/dlls/gdi.exe16/gdi.c
@@ -19,6 +19,7 @@
*/
#include <stdarg.h>
+#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
@@ -26,6 +27,7 @@
#include "wownt32.h"
#include "wine/wingdi16.h"
#include "wine/list.h"
+#include "wine/gdi_driver.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdi);
@@ -428,6 +430,129 @@ static void free_segptr_bits( HBITMAP16 bmp )
}
}
+/* window surface used to implement the DIB.DRV driver */
+
+struct dib_window_surface
+{
+ struct window_surface header;
+ RECT bounds;
+ void *bits;
+ UINT info_size;
+ BITMAPINFO info; /* variable size, must be last */
+};
+
+static struct dib_window_surface *get_dib_surface( struct window_surface *surface )
+{
+ return (struct dib_window_surface *)surface;
+}
+
+/***********************************************************************
+ * dib_surface_lock
+ */
+static void dib_surface_lock( struct window_surface *window_surface )
+{
+ /* nothing to do */
+}
+
+/***********************************************************************
+ * dib_surface_unlock
+ */
+static void dib_surface_unlock( struct window_surface *window_surface )
+{
+ /* nothing to do */
+}
+
+/***********************************************************************
+ * dib_surface_get_bitmap_info
+ */
+static void *dib_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info )
+{
+ struct dib_window_surface *surface = get_dib_surface( window_surface );
+
+ memcpy( info, &surface->info, surface->info_size );
+ return surface->bits;
+}
+
+/***********************************************************************
+ * dib_surface_get_bounds
+ */
+static RECT *dib_surface_get_bounds( struct window_surface *window_surface )
+{
+ struct dib_window_surface *surface = get_dib_surface( window_surface );
+
+ return &surface->bounds;
+}
+
+/***********************************************************************
+ * dib_surface_set_region
+ */
+static void dib_surface_set_region( struct window_surface *window_surface, HRGN region )
+{
+ /* nothing to do */
+}
+
+/***********************************************************************
+ * dib_surface_flush
+ */
+static void dib_surface_flush( struct window_surface *window_surface )
+{
+ /* nothing to do */
+}
+
+/***********************************************************************
+ * dib_surface_destroy
+ */
+static void dib_surface_destroy( struct window_surface *window_surface )
+{
+ struct dib_window_surface *surface = get_dib_surface( window_surface );
+
+ TRACE( "freeing %p\n", surface );
+ HeapFree( GetProcessHeap(), 0, surface );
+}
+
+static const struct window_surface_funcs dib_surface_funcs =
+{
+ dib_surface_lock,
+ dib_surface_unlock,
+ dib_surface_get_bitmap_info,
+ dib_surface_get_bounds,
+ dib_surface_set_region,
+ dib_surface_flush,
+ dib_surface_destroy
+};
+
+/***********************************************************************
+ * create_surface
+ */
+static struct window_surface *create_surface( const BITMAPINFO *info )
+{
+ struct dib_window_surface *surface;
+ int color = 0;
+
+ if (info->bmiHeader.biBitCount <= 8)
+ color = info->bmiHeader.biClrUsed ? info->bmiHeader.biClrUsed : (1 << info->bmiHeader.biBitCount);
+ else if (info->bmiHeader.biCompression == BI_BITFIELDS)
+ color = 3;
+
+ surface = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ offsetof( struct dib_window_surface, info.bmiColors[color] ));
+ if (!surface) return NULL;
+
+ surface->header.funcs = &dib_surface_funcs;
+ surface->header.rect.left = 0;
+ surface->header.rect.top = 0;
+ surface->header.rect.right = info->bmiHeader.biWidth;
+ surface->header.rect.bottom = abs(info->bmiHeader.biHeight);
+ surface->header.ref = 1;
+ surface->info_size = offsetof( BITMAPINFO, bmiColors[color] );
+ surface->bits = (char *)info + surface->info_size;
+ memcpy( &surface->info, info, surface->info_size );
+
+ TRACE( "created %p %ux%u for info %p bits %p\n",
+ surface, surface->header.rect.right, surface->header.rect.bottom, info, surface->bits );
+ return &surface->header;
+}
+
/***********************************************************************
* SetBkColor (GDI.1)
@@ -1172,6 +1297,22 @@ HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
const DEVMODEA *initData )
{
+ if (!lstrcmpiA( driver, "dib" ) || !lstrcmpiA( driver, "dirdib" ))
+ {
+ struct window_surface *surface;
+ HDC hdc;
+
+ if (!(surface = create_surface( (const BITMAPINFO *)initData ))) return 0;
+
+ if ((hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL )))
+ {
+ __wine_set_visible_region( hdc, CreateRectRgnIndirect( &surface->rect ),
+ &surface->rect, &surface->rect, surface );
+ TRACE( "returning hdc %p surface %p\n", hdc, surface );
+ }
+ window_surface_release( surface );
+ return HDC_16( hdc );
+ }
return HDC_16( CreateDCA( driver, device, output, initData ) );
}
More information about the wine-cvs
mailing list