diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 33e55429c7f..9f4f7377497 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -45,6 +45,54 @@ static const struct gdi_obj_funcs bitmap_funcs = BITMAP_DeleteObject /* pDeleteObject */ }; + +/*********************************************************************** + * null driver fallback implementations + */ + +LONG CDECL nulldrv_GetBitmapBits( HBITMAP bitmap, void *bits, LONG size ) +{ + BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); + + if (bmp->bitmap.bmBits) memcpy( bits, bmp->bitmap.bmBits, size ); + else memset( bits, 0, size ); + GDI_ReleaseObj( bitmap ); + return size; +} + +LONG CDECL nulldrv_SetBitmapBits( HBITMAP bitmap, const void *bits, LONG size ) +{ + BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); + + if (!bmp->bitmap.bmBits) + { + LONG total = bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes; /* alloc enough for entire bitmap */ + if (!(bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, total ))) + { + GDI_ReleaseObj( bitmap ); + return 0; + } + if (size < total) memset( (char *)bmp->bitmap.bmBits + size, 0, total - size ); + } + memcpy( bmp->bitmap.bmBits, bits, size ); + GDI_ReleaseObj( bitmap ); + return size; +} + +INT CDECL nulldrv_GetDIBits( PHYSDEV dev, HBITMAP bitmap, UINT start, UINT lines, LPVOID bits, + BITMAPINFO *info, UINT coloruse ) +{ + /* FIXME: transfer bits from bmp->bitmap.bmBits */ + return 0; +} + +INT CDECL nulldrv_SetDIBits( PHYSDEV dev, HBITMAP bitmap, UINT start, UINT lines, + const void *bits, const BITMAPINFO *info, UINT coloruse ) +{ + /* FIXME: transfer bits to bmp->bitmap.bmBits */ + return 0; +} + /*********************************************************************** * BITMAP_GetWidthBytes * @@ -290,7 +338,7 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) bmpobj->size.cy = 0; bmpobj->bitmap = bm; bmpobj->bitmap.bmBits = NULL; - bmpobj->funcs = NULL; + bmpobj->funcs = &null_driver; bmpobj->dib = NULL; bmpobj->color_table = NULL; bmpobj->nb_colors = 0; @@ -400,22 +448,7 @@ LONG WINAPI GetBitmapBits( hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 1 << bmp->bitmap.bmBitsPixel, height ); - if(bmp->funcs && bmp->funcs->pGetBitmapBits) - { - TRACE("Calling device specific BitmapBits\n"); - ret = bmp->funcs->pGetBitmapBits(hbitmap, bits, count); - } else { - - if(!bmp->bitmap.bmBits) { - TRACE("Bitmap is empty\n"); - memset(bits, 0, count); - ret = count; - } else { - memcpy(bits, bmp->bitmap.bmBits, count); - ret = count; - } - - } + ret = bmp->funcs->pGetBitmapBits( hbitmap, bits, count ); done: GDI_ReleaseObj( hbitmap ); return ret; @@ -483,23 +516,7 @@ LONG WINAPI SetBitmapBits( hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 1 << bmp->bitmap.bmBitsPixel, height ); - if(bmp->funcs && bmp->funcs->pSetBitmapBits) { - - TRACE("Calling device specific BitmapBits\n"); - ret = bmp->funcs->pSetBitmapBits(hbitmap, bits, count); - } else { - - if(!bmp->bitmap.bmBits) /* Alloc enough for entire bitmap */ - bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, count ); - if(!bmp->bitmap.bmBits) { - WARN("Unable to allocate bit buffer\n"); - ret = 0; - } else { - memcpy(bmp->bitmap.bmBits, bits, count); - ret = count; - } - } - + ret = bmp->funcs->pSetBitmapBits( hbitmap, bits, count ); GDI_ReleaseObj( hbitmap ); return ret; } @@ -565,27 +582,37 @@ HBITMAP BITMAP_CopyBitmap(HBITMAP hbitmap) * bitmap is selected into a device to initialize the bitmap function * table. */ -BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc ) +BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) { BITMAPOBJ *bitmap; - BOOL ret; + BOOL ret = TRUE; /* never set the owner of the stock bitmap since it can be selected in multiple DCs */ if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE; if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE; - ret = TRUE; - if (!bitmap->funcs) /* not owned by a DC yet */ + if (bitmap->funcs != physdev->funcs) { - if (dc->funcs->pCreateBitmap) ret = dc->funcs->pCreateBitmap( dc->physDev, hbitmap, - bitmap->bitmap.bmBits ); - if (ret) bitmap->funcs = dc->funcs; - } - else if (bitmap->funcs != dc->funcs) - { - FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); - ret = FALSE; + /* we can only change from the null driver to some other driver */ + if (bitmap->funcs == &null_driver) + { + if (physdev->funcs->pCreateBitmap) + { + ret = physdev->funcs->pCreateBitmap( physdev, hbitmap, bitmap->bitmap.bmBits ); + if (ret) bitmap->funcs = physdev->funcs; + } + else + { + WARN( "Trying to select bitmap %p in DC that doesn't support it\n", hbitmap ); + ret = FALSE; + } + } + else + { + FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); + ret = FALSE; + } } GDI_ReleaseObj( hbitmap ); return ret; @@ -626,14 +653,14 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) goto done; } - if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc )) + physdev = GET_DC_PHYSDEV( dc, pSelectBitmap ); + + if (!BITMAP_SetOwnerDC( handle, physdev )) { GDI_ReleaseObj( handle ); ret = 0; goto done; } - - physdev = GET_DC_PHYSDEV( dc, pSelectBitmap ); if (!physdev->funcs->pSelectBitmap( physdev, handle )) { GDI_ReleaseObj( handle ); @@ -672,7 +699,7 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle ) funcs = bmp->funcs; GDI_ReleaseObj( handle ); - if (funcs && funcs->pDeleteBitmap) funcs->pDeleteBitmap( handle ); + funcs->pDeleteBitmap( handle ); if (!(bmp = free_gdi_handle( handle ))) return FALSE; diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 02fb3a35459..a1d22fc7ed6 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -390,7 +390,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ) PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush ); if (brush->logbrush.lbStyle == BS_PATTERN) - BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc ); + BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, physdev ); GDI_inc_ref_count( handle ); GDI_ReleaseObj( handle ); diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 0fc21971ee3..2810c747c18 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -341,6 +341,7 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, { DC *dc = get_dc_ptr( hdc ); BOOL delete_hdc = FALSE; + PHYSDEV physdev; BITMAPOBJ *bitmap; INT result = 0; @@ -362,19 +363,10 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan, return 0; } - if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done; + physdev = GET_DC_PHYSDEV( dc, pSetDIBits ); + if (BITMAP_SetOwnerDC( hbitmap, physdev )) + result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, info, coloruse ); - result = lines; - if (bitmap->funcs) - { - if (bitmap->funcs != dc->funcs) - ERR( "not supported: DDB bitmap %p not belonging to device %p\n", hbitmap, hdc ); - else if (dc->funcs->pSetDIBits) - result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines, - bits, info, coloruse ); - } - - done: GDI_ReleaseObj( hbitmap ); release_dc_ptr( dc ); if (delete_hdc) DeleteDC(hdc); @@ -1081,15 +1073,10 @@ INT WINAPI GetDIBits( /* Otherwise, get bits from the XImage */ else { - if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0; - else - { - if (bmp->funcs && bmp->funcs->pGetDIBits) - lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan, - lines, bits, info, coloruse ); - else - lines = 0; /* FIXME: should copy from bmp->bitmap.bmBits */ - } + PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits ); + if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0; + else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan, + lines, bits, info, coloruse ); } } else lines = abs(height); @@ -1128,7 +1115,6 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header, LONG height; WORD planes, bpp; DWORD compr, size; - DC *dc; if (!header) return 0; @@ -1161,16 +1147,6 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header, handle = 0; } } - - else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) ) - { - if (!BITMAP_SetOwnerDC( handle, dc )) - { - DeleteObject( handle ); - handle = 0; - } - release_dc_ptr( dc ); - } } return handle; diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 281cccdc3bb..f913a47c794 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -334,6 +334,16 @@ static BOOL CDECL nulldrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT return TRUE; } +static BOOL CDECL nulldrv_CreateBitmap( PHYSDEV dev, HBITMAP bitmap, LPVOID bits ) +{ + return TRUE; +} + +static BOOL CDECL nulldrv_DeleteBitmap( HBITMAP bitmap ) +{ + return TRUE; +} + static BOOL CDECL nulldrv_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) { return TRUE; @@ -691,10 +701,10 @@ const DC_FUNCTIONS null_driver = nulldrv_ChoosePixelFormat, /* pChoosePixelFormat */ nulldrv_Chord, /* pChord */ nulldrv_CloseFigure, /* pCloseFigure */ - NULL, /* pCreateBitmap */ + nulldrv_CreateBitmap, /* pCreateBitmap */ NULL, /* pCreateDC */ NULL, /* pCreateDIBSection */ - NULL, /* pDeleteBitmap */ + nulldrv_DeleteBitmap, /* pDeleteBitmap */ NULL, /* pDeleteDC */ nulldrv_DeleteObject, /* pDeleteObject */ nulldrv_DescribePixelFormat, /* pDescribePixelFormat */ @@ -716,9 +726,9 @@ const DC_FUNCTIONS null_driver = nulldrv_FlattenPath, /* pFlattenPath */ nulldrv_FrameRgn, /* pFrameRgn */ nulldrv_GdiComment, /* pGdiComment */ - NULL, /* pGetBitmapBits */ + nulldrv_GetBitmapBits, /* pGetBitmapBits */ NULL, /* pGetCharWidth */ - NULL, /* pGetDIBits */ + nulldrv_GetDIBits, /* pGetDIBits */ NULL, /* pGetDeviceCaps */ nulldrv_GetDeviceGammaRamp, /* pGetDeviceGammaRamp */ nulldrv_GetICMProfile, /* pGetICMProfile */ @@ -763,13 +773,13 @@ const DC_FUNCTIONS null_driver = nulldrv_SelectPalette, /* pSelectPalette */ nulldrv_SelectPen, /* pSelectPen */ nulldrv_SetArcDirection, /* pSetArcDirection */ - NULL, /* pSetBitmapBits */ + nulldrv_SetBitmapBits, /* pSetBitmapBits */ nulldrv_SetBkColor, /* pSetBkColor */ nulldrv_SetBkMode, /* pSetBkMode */ nulldrv_SetDCBrushColor, /* pSetDCBrushColor */ nulldrv_SetDCPenColor, /* pSetDCPenColor */ NULL, /* pSetDIBColorTable */ - NULL, /* pSetDIBits */ + nulldrv_SetDIBits, /* pSetDIBits */ NULL, /* pSetDIBitsToDevice */ nulldrv_SetDeviceClipping, /* pSetDeviceClipping */ nulldrv_SetDeviceGammaRamp, /* pSetDeviceGammaRamp */ diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index e6daf88aab5..e4ca69cab83 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -368,7 +368,7 @@ extern BOOL BIDI_Reorder( HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags, /* bitmap.c */ extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN; -extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc ) DECLSPEC_HIDDEN; +extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN; extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) DECLSPEC_HIDDEN; /* clipping.c */ @@ -526,6 +526,8 @@ extern BOOL CDECL nulldrv_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_FillRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_FrameRgn( PHYSDEV dev, HRGN rgn, HBRUSH brush, INT width, INT height ) DECLSPEC_HIDDEN; +extern LONG CDECL nulldrv_GetBitmapBits( HBITMAP bitmap, void *bits, LONG size ) DECLSPEC_HIDDEN; +extern INT CDECL nulldrv_GetDIBits( PHYSDEV dev, HBITMAP bitmap, UINT start, UINT lines, LPVOID bits, BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN; extern COLORREF CDECL nulldrv_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN; extern INT CDECL nulldrv_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_InvertRgn( PHYSDEV dev, HRGN rgn ) DECLSPEC_HIDDEN; @@ -540,6 +542,8 @@ extern BOOL CDECL nulldrv_PolylineTo( PHYSDEV dev, const POINT *points, INT coun extern BOOL CDECL nulldrv_ScaleViewportExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_ScaleWindowExtEx( PHYSDEV dev, INT x_num, INT x_denom, INT y_num, INT y_denom, SIZE *size ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_SelectClipPath( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN; +extern LONG CDECL nulldrv_SetBitmapBits( HBITMAP bitmap, const void *bits, LONG size ) DECLSPEC_HIDDEN; +extern INT CDECL nulldrv_SetDIBits( PHYSDEV dev, HBITMAP bitmap, UINT start, UINT lines, const void *bits, const BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN; extern INT CDECL nulldrv_SetMapMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) DECLSPEC_HIDDEN; extern BOOL CDECL nulldrv_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) DECLSPEC_HIDDEN;