gdi.exe: Implement the DIB.DRV driver using a window surface.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d3f32bd0c7
commit
16943efa70
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue