Alexandre Julliard : gdi32: Add a separate set of GDI object functions for DIBs.
Alexandre Julliard
julliard at winehq.org
Tue Jan 10 13:11:20 CST 2012
Module: wine
Branch: master
Commit: a51b2c8bd594199bf1a3de36a20845f5b604d366
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a51b2c8bd594199bf1a3de36a20845f5b604d366
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jan 10 14:37:48 2012 +0100
gdi32: Add a separate set of GDI object functions for DIBs.
---
dlls/gdi32/bitmap.c | 45 ++--------------
dlls/gdi32/dib.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 150 insertions(+), 41 deletions(-)
diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 0d637ec..dcccd3d 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -566,7 +566,7 @@ static BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev )
if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE;
- if (!bitmap->dib && bitmap->funcs != physdev->funcs)
+ if (bitmap->funcs != physdev->funcs)
{
/* we can only change from the null driver to some other driver */
if (bitmap->funcs == &null_driver)
@@ -634,7 +634,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
old_physdev = pop_dc_driver( &dc->physDev );
physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
- if (bitmap->dib || physdev->funcs == &null_driver)
+ if (physdev->funcs == &null_driver)
{
physdev = dc->dibdrv;
if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
@@ -701,26 +701,6 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
if (!(bmp = free_gdi_handle( handle ))) return FALSE;
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
-
- if (bmp->dib)
- {
- DIBSECTION *dib = bmp->dib;
-
- if (dib->dsBm.bmBits)
- {
- if (dib->dshSection)
- {
- SYSTEM_INFO SystemInfo;
- GetSystemInfo( &SystemInfo );
- UnmapViewOfFile( (char *)dib->dsBm.bmBits -
- (dib->dsOffset % SystemInfo.dwAllocationGranularity) );
- }
- else if (!dib->dsOffset)
- VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
- }
- HeapFree(GetProcessHeap(), 0, dib);
- HeapFree(GetProcessHeap(), 0, bmp->color_table);
- }
return HeapFree( GetProcessHeap(), 0, bmp );
}
@@ -730,30 +710,13 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
*/
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
- INT ret;
+ INT ret = 0;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
if (!bmp) return 0;
if (!buffer) ret = sizeof(BITMAP);
- else if (count < sizeof(BITMAP)) ret = 0;
- else if (bmp->dib)
- {
- if (count >= sizeof(DIBSECTION))
- {
- DIBSECTION *dib = buffer;
- *dib = *bmp->dib;
- dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
- ret = sizeof(DIBSECTION);
- }
- else /* if (count >= sizeof(BITMAP)) */
- {
- DIBSECTION *dib = bmp->dib;
- memcpy( buffer, &dib->dsBm, sizeof(BITMAP) );
- ret = sizeof(BITMAP);
- }
- }
- else
+ else if (count >= sizeof(BITMAP))
{
memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) );
((BITMAP *) buffer)->bmBits = NULL;
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 5aab956..0f17972 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -72,6 +72,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
+static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc );
+static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
+static BOOL DIB_DeleteObject( HGDIOBJ handle );
+
+static const struct gdi_obj_funcs dib_funcs =
+{
+ DIB_SelectObject, /* pSelectObject */
+ DIB_GetObject, /* pGetObjectA */
+ DIB_GetObject, /* pGetObjectW */
+ NULL, /* pUnrealizeObject */
+ DIB_DeleteObject /* pDeleteObject */
+};
+
/***********************************************************************
* bitmap_info_size
*
@@ -1576,6 +1589,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
bmp->dib = dib;
+ bmp->header.funcs = &dib_funcs;
bmp->funcs = physdev->funcs;
bmp->color_table = color_table;
GDI_ReleaseObj( ret );
@@ -1600,3 +1614,135 @@ error:
HeapFree( GetProcessHeap(), 0, dib );
return 0;
}
+
+
+/***********************************************************************
+ * DIB_SelectObject
+ */
+static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc )
+{
+ HGDIOBJ ret;
+ BITMAPOBJ *bitmap;
+ DC *dc;
+ PHYSDEV physdev = NULL, old_physdev = NULL, pathdev = NULL;
+
+ if (!(dc = get_dc_ptr( hdc ))) return 0;
+
+ if (GetObjectType( hdc ) != OBJ_MEMDC)
+ {
+ ret = 0;
+ goto done;
+ }
+ ret = dc->hBitmap;
+ if (handle == dc->hBitmap) goto done; /* nothing to do */
+
+ if (!(bitmap = GDI_GetObjPtr( handle, OBJ_BITMAP )))
+ {
+ ret = 0;
+ goto done;
+ }
+
+ if (bitmap->header.selcount)
+ {
+ WARN( "Bitmap already selected in another DC\n" );
+ GDI_ReleaseObj( handle );
+ ret = 0;
+ goto done;
+ }
+
+ if (dc->physDev->funcs == &path_driver) pathdev = pop_dc_driver( &dc->physDev );
+
+ old_physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
+ physdev = dc->dibdrv;
+ if (old_physdev != dc->dibdrv)
+ {
+ if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
+ else
+ {
+ if (!dib_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) goto done;
+ dc->dibdrv = physdev = dc->physDev;
+ }
+ }
+
+ if (!physdev->funcs->pSelectBitmap( physdev, handle ))
+ {
+ GDI_ReleaseObj( handle );
+ ret = 0;
+ }
+ else
+ {
+ dc->hBitmap = handle;
+ GDI_inc_ref_count( handle );
+ dc->dirty = 0;
+ dc->vis_rect.left = 0;
+ dc->vis_rect.top = 0;
+ dc->vis_rect.right = bitmap->bitmap.bmWidth;
+ dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
+ GDI_ReleaseObj( handle );
+ DC_InitDC( dc );
+ GDI_dec_ref_count( ret );
+ }
+
+ done:
+ if(!ret)
+ {
+ if (old_physdev && old_physdev != dc->dibdrv) pop_dc_driver( &dc->physDev );
+ }
+ if (pathdev) push_dc_driver( &dc->physDev, pathdev, pathdev->funcs );
+ release_dc_ptr( dc );
+ return ret;
+}
+
+
+/***********************************************************************
+ * DIB_GetObject
+ */
+static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
+{
+ INT ret = 0;
+ BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
+
+ if (!bmp) return 0;
+
+ if (!buffer) ret = sizeof(BITMAP);
+ else if (count >= sizeof(DIBSECTION))
+ {
+ DIBSECTION *dib = buffer;
+ *dib = *bmp->dib;
+ dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
+ ret = sizeof(DIBSECTION);
+ }
+ else if (count >= sizeof(BITMAP))
+ {
+ BITMAP *bitmap = buffer;
+ *bitmap = bmp->dib->dsBm;
+ ret = sizeof(BITMAP);
+ }
+
+ GDI_ReleaseObj( handle );
+ return ret;
+}
+
+
+/***********************************************************************
+ * DIB_DeleteObject
+ */
+static BOOL DIB_DeleteObject( HGDIOBJ handle )
+{
+ BITMAPOBJ *bmp;
+
+ if (!(bmp = free_gdi_handle( handle ))) return FALSE;
+
+ if (bmp->dib->dshSection)
+ {
+ SYSTEM_INFO SystemInfo;
+ GetSystemInfo( &SystemInfo );
+ UnmapViewOfFile( (char *)bmp->dib->dsBm.bmBits -
+ (bmp->dib->dsOffset % SystemInfo.dwAllocationGranularity) );
+ }
+ else VirtualFree( bmp->dib->dsBm.bmBits, 0, MEM_RELEASE );
+
+ HeapFree(GetProcessHeap(), 0, bmp->dib);
+ HeapFree(GetProcessHeap(), 0, bmp->color_table);
+ return HeapFree( GetProcessHeap(), 0, bmp );
+}
More information about the wine-cvs
mailing list