gdi32: Add null driver entry points for the bitmap functions.
authorAlexandre Julliard <julliard@winehq.org>
Tue, 15 Mar 2011 18:51:06 +0000 (19:51 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 16 Mar 2011 10:20:30 +0000 (11:20 +0100)
dlls/gdi32/bitmap.c
dlls/gdi32/brush.c
dlls/gdi32/dib.c
dlls/gdi32/driver.c
dlls/gdi32/gdi_private.h

index 33e55429c7f838c8df50bef3c6b0a52e7a9f8813..9f4f737749717c0787d328aa2cb9b48b7e5f9ea1 100644 (file)
@@ -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 (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)
+    if (bitmap->funcs != physdev->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;
 
index 02fb3a354595b0c09101accd06c994b30af61820..a1d22fc7ed61326a396c838b00e46e27e2b097d1 100644 (file)
@@ -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 );
index 0fc21971ee3b5f7ea0304331766ba0167b545177..2810c747c18c6269d392b4c2741255ace3bb5ea1 100644 (file)
@@ -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;
index 281cccdc3bbd62c024119ebc3e25f16b9e3d3d54..f913a47c794e58520e32f44fed43bb699a58b377 100644 (file)
@@ -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 */
index e6daf88aab5ff23f4ca5a115b028c3fbf4b2c8d7..e4ca69cab8383c9ddd681331455c5c640f034d3b 100644 (file)
@@ -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;