Alexandre Julliard : winex11: Add an implementation for the PutImage entry point.

Alexandre Julliard julliard at winehq.org
Thu Jul 14 13:08:12 CDT 2011


Module: wine
Branch: master
Commit: ce9a5c6659df7cff8515c8a153b6ff47ead4d06d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ce9a5c6659df7cff8515c8a153b6ff47ead4d06d

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul 14 12:59:48 2011 +0200

winex11: Add an implementation for the PutImage entry point.

---

 dlls/winex11.drv/bitblt.c |  112 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/init.c   |    2 +-
 dlls/winex11.drv/x11drv.h |    2 +
 3 files changed, 115 insertions(+), 1 deletions(-)

diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 3e2ef2c..21a664c 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1721,6 +1721,118 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
 }
 
 /***********************************************************************
+ *           X11DRV_PutImage
+ */
+DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits,
+                       const RECT *rect, DWORD rop )
+{
+    X11DRV_PDEVICE *physdev;
+    X_PHYSBITMAP *bitmap;
+    DWORD ret = ERROR_SUCCESS;
+    XImage *image;
+    int depth;
+    struct gdi_image_bits dst_bits;
+    const XPixmapFormatValues *format;
+    const ColorShifts *color_shifts;
+
+    if (hbitmap)
+    {
+        if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE;
+        physdev = NULL;
+        depth = bitmap->pixmap_depth;
+        color_shifts = &bitmap->pixmap_color_shifts;
+    }
+    else
+    {
+        physdev = get_x11drv_dev( dev );
+        bitmap = NULL;
+        depth = physdev->depth;
+        color_shifts = physdev->color_shifts;
+    }
+    format = pixmap_formats[depth];
+
+    if (info->bmiHeader.biPlanes != 1) goto update_format;
+    if (info->bmiHeader.biBitCount != format->bits_per_pixel) goto update_format;
+    if (info->bmiHeader.biHeight > 0) goto update_format; /* bottom-up not supported */
+
+    if (info->bmiHeader.biCompression == BI_BITFIELDS)
+    {
+        DWORD *masks = (DWORD *)((char *)info + info->bmiHeader.biSize);
+        if (color_shifts->logicalRed.max << color_shifts->logicalRed.shift != masks[0] ||
+            color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift != masks[1] ||
+            color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift != masks[2])
+            goto update_format;
+    }
+    else if (info->bmiHeader.biCompression == BI_RGB)
+    {
+        switch (info->bmiHeader.biBitCount)
+        {
+        case 16:
+            if (color_shifts->logicalRed.max << color_shifts->logicalRed.shift     != 0x7c00 ||
+                color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift != 0x03e0 ||
+                color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift   != 0x001f)
+                goto update_format;
+            break;
+        case 24:
+        case 32:
+            if (color_shifts->logicalRed.max << color_shifts->logicalRed.shift     != 0xff0000 ||
+                color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift != 0x00ff00 ||
+                color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift   != 0x0000ff)
+                goto update_format;
+            break;
+        }
+    }
+    else goto update_format;
+
+    if (!bits) return ret;  /* just querying the format */
+
+    wine_tsx11_lock();
+    image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
+                          info->bmiHeader.biWidth, -info->bmiHeader.biHeight, 32, 0 );
+    wine_tsx11_unlock();
+    if (!image) return ERROR_OUTOFMEMORY;
+
+    ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits );
+
+    if (!ret)
+    {
+        image->data = dst_bits.ptr;
+        if (bitmap)
+        {
+            wine_tsx11_lock();
+            XPutImage( gdi_display, bitmap->pixmap, get_bitmap_gc(depth), image, dst_bits.offset, 0,
+                       rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top );
+            wine_tsx11_unlock();
+        }
+        else
+        {
+            /* FIXME: copy rop handling from BitBlt here */
+            X11DRV_LockDIBSection( physdev, DIB_Status_GdiMod );
+            wine_tsx11_lock();
+            XPutImage( gdi_display, physdev->drawable, physdev->gc, image, dst_bits.offset, 0,
+                       physdev->dc_rect.left + rect->left, physdev->dc_rect.top + rect->top,
+                       rect->right - rect->left, rect->bottom - rect->top );
+            wine_tsx11_unlock();
+            X11DRV_UnlockDIBSection( physdev, !ret );
+        }
+        image->data = NULL;
+    }
+
+    wine_tsx11_lock();
+    XDestroyImage( image );
+    wine_tsx11_unlock();
+    if (dst_bits.free) dst_bits.free( &dst_bits );
+    return ret;
+
+update_format:
+    info->bmiHeader.biPlanes   = 1;
+    info->bmiHeader.biBitCount = format->bits_per_pixel;
+    if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
+    set_color_info( physdev->color_shifts, info );
+    return ERROR_BAD_FORMAT;
+}
+
+/***********************************************************************
  *           X11DRV_GetImage
  */
 DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index f78e20e..5562fb9 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -512,7 +512,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
     X11DRV_Polygon,                     /* pPolygon */
     X11DRV_Polyline,                    /* pPolyline */
     NULL,                               /* pPolylineTo */
-    NULL,                               /* pPutImage */
+    X11DRV_PutImage,                    /* pPutImage */
     X11DRV_RealizeDefaultPalette,       /* pRealizeDefaultPalette */
     X11DRV_RealizePalette,              /* pRealizePalette */
     X11DRV_Rectangle,                   /* pRectangle */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index ecf608e..d1fbbf3 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -221,6 +221,8 @@ extern BOOL X11DRV_Polyline( PHYSDEV dev,const POINT* pt,INT count) DECLSPEC_HID
 extern BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
 extern BOOL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) DECLSPEC_HIDDEN;
 extern BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines) DECLSPEC_HIDDEN;
+extern DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const struct gdi_image_bits *bits,
+                              const RECT *rect, DWORD rop ) DECLSPEC_HIDDEN;
 extern UINT X11DRV_RealizeDefaultPalette( PHYSDEV dev ) DECLSPEC_HIDDEN;
 extern UINT X11DRV_RealizePalette( PHYSDEV dev, HPALETTE hpal, BOOL primary ) DECLSPEC_HIDDEN;
 extern BOOL X11DRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list