win32: Fix 16bit pixmaps

This reverts to the old dibsection creation code for 16bit depth.
This makes the non-cairo stuff work, we then access the bits as
a cairo image surface, which isn't 100% right, but might be good
enough.

Fixes bug 665013
This commit is contained in:
Alexander Larsson
2011-12-06 11:27:53 +01:00
parent 4fc684943b
commit ba8c4bb049

View File

@@ -138,7 +138,6 @@ _gdk_pixmap_new (GdkDrawable *drawable,
gint depth)
{
HDC hdc;
HPALETTE holdpal = NULL;
HBITMAP hbitmap;
GdkPixmap *pixmap;
GdkDrawableImplWin32 *drawable_impl;
@@ -147,6 +146,7 @@ _gdk_pixmap_new (GdkDrawable *drawable,
gint window_depth;
cairo_surface_t *dib_surface, *image_surface;
cairo_format_t format;
guchar *bits;
g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
@@ -175,6 +175,11 @@ _gdk_pixmap_new (GdkDrawable *drawable,
format = CAIRO_FORMAT_A8;
break;
case 15:
case 16:
format = CAIRO_FORMAT_RGB16_565;
break;
case 24:
case 32:
format = CAIRO_FORMAT_RGB24;
@@ -203,16 +208,93 @@ _gdk_pixmap_new (GdkDrawable *drawable,
gdk_drawable_set_colormap (pixmap, cmap);
}
dib_surface = cairo_win32_surface_create_with_dib (format, width, height);
if (dib_surface == NULL)
if (depth != 15 && depth != 16)
{
g_object_unref ((GObject *) pixmap);
return NULL;
}
dib_surface = cairo_win32_surface_create_with_dib (format, width, height);
if (dib_surface == NULL)
{
g_object_unref ((GObject *) pixmap);
return NULL;
}
/* We need to have cairo create the dibsection for us, because
creating a cairo surface from a hdc only works for rgb24 format */
hdc = cairo_win32_surface_get_dc (dib_surface);
/* We need to have cairo create the dibsection for us, because
creating a cairo surface from a hdc only works for rgb24 format */
hdc = cairo_win32_surface_get_dc (dib_surface);
/* Get the bitmap from the cairo hdc */
hbitmap = GetCurrentObject (hdc, OBJ_BITMAP);
image_surface = cairo_win32_surface_get_image (dib_surface);
bits = cairo_image_surface_get_data (image_surface);
}
else
{
/* 16 bpp not supported by win32 cairo surface */
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[256];
DWORD bmiMasks[3];
RGBQUAD bmiColors[256];
} u;
} bmi;
UINT iUsage;
HWND hwnd;
GdkVisual *visual;
if (GDK_IS_WINDOW (drawable))
hwnd = GDK_WINDOW_HWND (drawable);
else
hwnd = GetDesktopWindow ();
if ((hdc = GetDC (hwnd)) == NULL)
{
WIN32_GDI_FAILED ("GetDC");
g_object_unref ((GObject *) pixmap);
return NULL;
}
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 16;
bmi.bmiHeader.biCompression = BI_BITFIELDS;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
iUsage = DIB_RGB_COLORS;
visual = gdk_visual_get_system ();
bmi.u.bmiMasks[0] = visual->red_mask;
bmi.u.bmiMasks[1] = visual->green_mask;
bmi.u.bmiMasks[2] = visual->blue_mask;
hbitmap = CreateDIBSection (hdc, (BITMAPINFO *) &bmi,
iUsage, (PVOID *) &bits, NULL, 0);
GDI_CALL (ReleaseDC, (hwnd, hdc));
if (hbitmap == NULL)
{
WIN32_GDI_FAILED ("CreateDIBSection");
g_object_unref ((GObject *) pixmap);
return NULL;
}
dib_surface = cairo_image_surface_create_for_data (bits,
format, width, height,
(width * 2 + 3) & ~3);
hdc = CreateCompatibleDC (NULL);
if (!hdc)
{
WIN32_GDI_FAILED ("CreateCompatibleDC");
g_object_unref ((GObject *) pixmap);
return NULL;
}
SelectObject (hdc, hbitmap);
}
/* We need to use the same hdc, because only one hdc
can render to the same bitmap */
@@ -221,13 +303,8 @@ _gdk_pixmap_new (GdkDrawable *drawable,
/* No need to create a new surface when needed, as we have one already */
drawable_impl->cairo_surface = dib_surface;
/* Get the bitmap from the cairo hdc */
hbitmap = GetCurrentObject (hdc, OBJ_BITMAP);
drawable_impl->handle = hbitmap;
image_surface = cairo_win32_surface_get_image (dib_surface);
pixmap_impl->bits = cairo_image_surface_get_data (image_surface);
pixmap_impl->bits = bits;
gdk_win32_handle_table_insert (&GDK_PIXMAP_HBITMAP (pixmap), pixmap);