Blame gdk/win32/gdkpixmap-win32.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 * Copyright (C) 1998-2002 Tor Lillqvist
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <stdlib.h>
Packit Service fb6fa5
#include <stdio.h>
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkpixmap.h"
Packit Service fb6fa5
#include "gdkdisplay.h"
Packit Service fb6fa5
#include "gdkscreen.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkprivate-win32.h"
Packit Service fb6fa5
#include <cairo-win32.h>
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_pixmap_impl_win32_get_size   (GdkDrawable        *drawable,
Packit Service fb6fa5
					      gint               *width,
Packit Service fb6fa5
					      gint               *height);
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_pixmap_impl_win32_init       (GdkPixmapImplWin32      *pixmap);
Packit Service fb6fa5
static void gdk_pixmap_impl_win32_class_init (GdkPixmapImplWin32Class *klass);
Packit Service fb6fa5
static void gdk_pixmap_impl_win32_finalize   (GObject                 *object);
Packit Service fb6fa5
Packit Service fb6fa5
static gpointer parent_class = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
_gdk_pixmap_impl_win32_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GType object_type = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!object_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      const GTypeInfo object_info =
Packit Service fb6fa5
      {
Packit Service fb6fa5
        sizeof (GdkPixmapImplWin32Class),
Packit Service fb6fa5
        (GBaseInitFunc) NULL,
Packit Service fb6fa5
        (GBaseFinalizeFunc) NULL,
Packit Service fb6fa5
        (GClassInitFunc) gdk_pixmap_impl_win32_class_init,
Packit Service fb6fa5
        NULL,           /* class_finalize */
Packit Service fb6fa5
        NULL,           /* class_data */
Packit Service fb6fa5
        sizeof (GdkPixmapImplWin32),
Packit Service fb6fa5
        0,              /* n_preallocs */
Packit Service fb6fa5
        (GInstanceInitFunc) gdk_pixmap_impl_win32_init,
Packit Service fb6fa5
      };
Packit Service fb6fa5
      
Packit Service fb6fa5
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
Packit Service fb6fa5
                                            "GdkPixmapImplWin32",
Packit Service fb6fa5
                                            &object_info, 0);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return object_type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
_gdk_pixmap_impl_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return _gdk_pixmap_impl_win32_get_type ();
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_pixmap_impl_win32_init (GdkPixmapImplWin32 *impl)
Packit Service fb6fa5
{
Packit Service fb6fa5
  impl->width = 1;
Packit Service fb6fa5
  impl->height = 1;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_pixmap_impl_win32_class_init (GdkPixmapImplWin32Class *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service fb6fa5
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
Packit Service fb6fa5
  
Packit Service fb6fa5
  parent_class = g_type_class_peek_parent (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  object_class->finalize = gdk_pixmap_impl_win32_finalize;
Packit Service fb6fa5
Packit Service fb6fa5
  drawable_class->get_size = gdk_pixmap_impl_win32_get_size;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_pixmap_impl_win32_finalize (GObject *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmapImplWin32 *impl = GDK_PIXMAP_IMPL_WIN32 (object);
Packit Service fb6fa5
  GdkDrawableImplWin32 *drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
Packit Service fb6fa5
  GdkPixmap *wrapper = GDK_PIXMAP (drawable_impl->wrapper);
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (PIXMAP, g_print ("gdk_pixmap_impl_win32_finalize: %p\n",
Packit Service fb6fa5
			     GDK_PIXMAP_HBITMAP (wrapper)));
Packit Service fb6fa5
Packit Service fb6fa5
  if (!impl->is_foreign)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Only decrement count if we did set the hdc */
Packit Service fb6fa5
      if (drawable_impl->hdc)
Packit Service fb6fa5
	drawable_impl->hdc_count--;
Packit Service fb6fa5
Packit Service fb6fa5
      if (drawable_impl->cairo_surface)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* Tell outstanding owners that the surface is useless */
Packit Service fb6fa5
	  cairo_surface_finish (drawable_impl->cairo_surface);
Packit Service fb6fa5
Packit Service fb6fa5
	  /* Drop our reference */
Packit Service fb6fa5
	  cairo_surface_destroy (drawable_impl->cairo_surface);
Packit Service fb6fa5
	  drawable_impl->cairo_surface = NULL;
Packit Service fb6fa5
	  if (impl->is_allocated)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      GDI_CALL (DeleteDC, (drawable_impl->hdc));
Packit Service fb6fa5
	      GDI_CALL (DeleteObject, (GDK_PIXMAP_HBITMAP (wrapper)));
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  _gdk_win32_drawable_finish (GDK_DRAWABLE (object));
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_win32_handle_table_remove (GDK_PIXMAP_HBITMAP (wrapper));
Packit Service fb6fa5
Packit Service fb6fa5
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_pixmap_impl_win32_get_size (GdkDrawable *drawable,
Packit Service fb6fa5
				gint        *width,
Packit Service fb6fa5
				gint        *height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (width)
Packit Service fb6fa5
    *width = GDK_PIXMAP_IMPL_WIN32 (drawable)->width;
Packit Service fb6fa5
  if (height)
Packit Service fb6fa5
    *height = GDK_PIXMAP_IMPL_WIN32 (drawable)->height;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap*
Packit Service fb6fa5
_gdk_pixmap_new (GdkDrawable *drawable,
Packit Service fb6fa5
		gint         width,
Packit Service fb6fa5
		gint         height,
Packit Service fb6fa5
		gint         depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  HDC hdc;
Packit Service fb6fa5
  HBITMAP hbitmap;
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
  GdkDrawableImplWin32 *drawable_impl;
Packit Service fb6fa5
  GdkPixmapImplWin32 *pixmap_impl;
Packit Service fb6fa5
  GdkColormap *cmap;
Packit Service fb6fa5
  gint window_depth;
Packit Service fb6fa5
  cairo_surface_t *dib_surface, *image_surface;
Packit Service fb6fa5
  cairo_format_t format;
Packit Service fb6fa5
  guchar *bits;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
Packit Service fb6fa5
  g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
Packit Service fb6fa5
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (!drawable)
Packit Service fb6fa5
    drawable = _gdk_root;
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  window_depth = gdk_drawable_get_depth (GDK_DRAWABLE (drawable));
Packit Service fb6fa5
  if (depth == -1)
Packit Service fb6fa5
    depth = window_depth;
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (PIXMAP, g_print ("gdk_pixmap_new: %dx%dx%d drawable=%p\n",
Packit Service fb6fa5
			     width, height, depth, drawable));
Packit Service fb6fa5
Packit Service fb6fa5
  switch (depth)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 1:
Packit Service fb6fa5
      format = CAIRO_FORMAT_A1;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case 8:
Packit Service fb6fa5
      format = CAIRO_FORMAT_A8;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case 15:
Packit Service fb6fa5
    case 16:
Packit Service fb6fa5
      format = CAIRO_FORMAT_RGB16_565;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case 24:
Packit Service fb6fa5
    case 32:
Packit Service fb6fa5
      format = CAIRO_FORMAT_RGB24;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_warning ("gdk_win32_pixmap_new: depth = %d not supported", depth);
Packit Service fb6fa5
      return NULL;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
Packit Service fb6fa5
  drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit Service fb6fa5
  pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit Service fb6fa5
  drawable_impl->wrapper = GDK_DRAWABLE (pixmap);
Packit Service fb6fa5
  
Packit Service fb6fa5
  pixmap_impl->is_foreign = FALSE;
Packit Service fb6fa5
  pixmap_impl->width = width;
Packit Service fb6fa5
  pixmap_impl->height = height;
Packit Service fb6fa5
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
Packit Service fb6fa5
Packit Service fb6fa5
  if (depth == window_depth)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      cmap = gdk_drawable_get_colormap (drawable);
Packit Service fb6fa5
      if (cmap)
Packit Service fb6fa5
        gdk_drawable_set_colormap (pixmap, cmap);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (depth != 15 && depth != 16)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      dib_surface = cairo_win32_surface_create_with_dib (format, width, height);
Packit Service fb6fa5
      if (dib_surface == NULL ||
Packit Service fb6fa5
	  cairo_surface_status (dib_surface) != CAIRO_STATUS_SUCCESS)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_object_unref ((GObject *) pixmap);
Packit Service fb6fa5
	  return NULL;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      /* We need to have cairo create the dibsection for us, because
Packit Service fb6fa5
	 creating a cairo surface from a hdc only works for rgb24 format */
Packit Service fb6fa5
      hdc = cairo_win32_surface_get_dc (dib_surface);
Packit Service fb6fa5
Packit Service fb6fa5
      /* Get the bitmap from the cairo hdc */
Packit Service fb6fa5
      hbitmap = GetCurrentObject (hdc, OBJ_BITMAP);
Packit Service fb6fa5
Packit Service fb6fa5
      /* Cairo_win32_surface_get_image() returns NULL on failure, but
Packit Service fb6fa5
	 this is likely an oversight and future versions will return a
Packit Service fb6fa5
	 "nil" surface.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      image_surface = cairo_win32_surface_get_image (dib_surface);
Packit Service fb6fa5
      if (image_surface == NULL ||
Packit Service fb6fa5
	  cairo_surface_status (image_surface) != CAIRO_STATUS_SUCCESS)
Packit Service fb6fa5
      {
Packit Service fb6fa5
	cairo_surface_destroy (dib_surface);
Packit Service fb6fa5
	g_object_unref ((GObject*) pixmap);
Packit Service fb6fa5
	return NULL;
Packit Service fb6fa5
      }
Packit Service fb6fa5
      bits = cairo_image_surface_get_data (image_surface);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* 16 bpp not supported by win32 cairo surface */
Packit Service fb6fa5
      struct {
Packit Service fb6fa5
	BITMAPINFOHEADER bmiHeader;
Packit Service fb6fa5
	union {
Packit Service fb6fa5
	  WORD bmiIndices[256];
Packit Service fb6fa5
	  DWORD bmiMasks[3];
Packit Service fb6fa5
	  RGBQUAD bmiColors[256];
Packit Service fb6fa5
	} u;
Packit Service fb6fa5
      } bmi;
Packit Service fb6fa5
      UINT iUsage;
Packit Service fb6fa5
      HWND hwnd;
Packit Service fb6fa5
      GdkVisual *visual;
Packit Service fb6fa5
Packit Service fb6fa5
      if (GDK_IS_WINDOW (drawable))
Packit Service fb6fa5
	hwnd = GDK_WINDOW_HWND (drawable);
Packit Service fb6fa5
      else
Packit Service fb6fa5
	hwnd = GetDesktopWindow ();
Packit Service fb6fa5
      if ((hdc = GetDC (hwnd)) == NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  WIN32_GDI_FAILED ("GetDC");
Packit Service fb6fa5
	  g_object_unref ((GObject *) pixmap);
Packit Service fb6fa5
	  return NULL;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
Packit Service fb6fa5
      bmi.bmiHeader.biWidth = width;
Packit Service fb6fa5
      bmi.bmiHeader.biHeight = -height;
Packit Service fb6fa5
      bmi.bmiHeader.biPlanes = 1;
Packit Service fb6fa5
      bmi.bmiHeader.biBitCount = 16;
Packit Service fb6fa5
      bmi.bmiHeader.biCompression = BI_BITFIELDS;
Packit Service fb6fa5
      bmi.bmiHeader.biSizeImage = 0;
Packit Service fb6fa5
      bmi.bmiHeader.biXPelsPerMeter =
Packit Service fb6fa5
	bmi.bmiHeader.biYPelsPerMeter = 0;
Packit Service fb6fa5
      bmi.bmiHeader.biClrUsed = 0;
Packit Service fb6fa5
      bmi.bmiHeader.biClrImportant = 0;
Packit Service fb6fa5
Packit Service fb6fa5
      iUsage = DIB_RGB_COLORS;
Packit Service fb6fa5
      visual = gdk_visual_get_system ();
Packit Service fb6fa5
      bmi.u.bmiMasks[0] = visual->red_mask;
Packit Service fb6fa5
      bmi.u.bmiMasks[1] = visual->green_mask;
Packit Service fb6fa5
      bmi.u.bmiMasks[2] = visual->blue_mask;
Packit Service fb6fa5
Packit Service fb6fa5
      if ((hbitmap = CreateDIBSection (hdc, (BITMAPINFO *) &bmi,
Packit Service fb6fa5
				       iUsage, (PVOID *) &bits, NULL, 0)) == NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  WIN32_GDI_FAILED ("CreateDIBSection");
Packit Service fb6fa5
	  GDI_CALL (ReleaseDC, (hwnd, hdc));
Packit Service fb6fa5
	  g_object_unref ((GObject *) pixmap);
Packit Service fb6fa5
	  return NULL;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      GDI_CALL (ReleaseDC, (hwnd, hdc));
Packit Service fb6fa5
Packit Service fb6fa5
      dib_surface = cairo_image_surface_create_for_data (bits,
Packit Service fb6fa5
							 format, width, height,
Packit Service fb6fa5
							 (width * 2 + 3) & ~3);
Packit Service fb6fa5
Packit Service fb6fa5
      hdc = CreateCompatibleDC (NULL);
Packit Service fb6fa5
      if (!hdc)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  WIN32_GDI_FAILED ("CreateCompatibleDC");
Packit Service fb6fa5
	  g_object_unref ((GObject *) pixmap);
Packit Service fb6fa5
	  return NULL;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      SelectObject (hdc, hbitmap);
Packit Service fb6fa5
      pixmap_impl->is_allocated = TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* We need to use the same hdc, because only one hdc
Packit Service fb6fa5
     can render to the same bitmap */
Packit Service fb6fa5
  drawable_impl->hdc = hdc;
Packit Service fb6fa5
  drawable_impl->hdc_count = 1; /* Ensure we never free the cairo surface HDC */
Packit Service fb6fa5
Packit Service fb6fa5
  /* No need to create a new surface when needed, as we have one already */
Packit Service fb6fa5
  drawable_impl->cairo_surface = dib_surface;
Packit Service fb6fa5
  drawable_impl->handle = hbitmap;
Packit Service fb6fa5
  pixmap_impl->bits = bits;
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_win32_handle_table_insert (&GDK_PIXMAP_HBITMAP (pixmap), pixmap);
Packit Service fb6fa5
Packit Service fb6fa5
  return pixmap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static const unsigned char mirror[256] = {
Packit Service fb6fa5
  0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
Packit Service fb6fa5
  0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
Packit Service fb6fa5
  0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
Packit Service fb6fa5
  0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
Packit Service fb6fa5
  0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
Packit Service fb6fa5
  0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
Packit Service fb6fa5
  0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
Packit Service fb6fa5
  0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
Packit Service fb6fa5
  0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
Packit Service fb6fa5
  0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
Packit Service fb6fa5
  0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
Packit Service fb6fa5
  0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
Packit Service fb6fa5
  0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
Packit Service fb6fa5
  0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
Packit Service fb6fa5
  0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
Packit Service fb6fa5
  0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
Packit Service fb6fa5
  0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
Packit Service fb6fa5
  0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
Packit Service fb6fa5
  0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
Packit Service fb6fa5
  0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
Packit Service fb6fa5
  0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
Packit Service fb6fa5
  0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
Packit Service fb6fa5
  0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
Packit Service fb6fa5
  0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
Packit Service fb6fa5
  0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
Packit Service fb6fa5
  0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
Packit Service fb6fa5
  0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
Packit Service fb6fa5
  0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
Packit Service fb6fa5
  0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
Packit Service fb6fa5
  0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
Packit Service fb6fa5
  0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
Packit Service fb6fa5
  0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap *
Packit Service fb6fa5
_gdk_bitmap_create_from_data (GdkDrawable *drawable,
Packit Service fb6fa5
			     const gchar *data,
Packit Service fb6fa5
			     gint         width,
Packit Service fb6fa5
			     gint         height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
  GdkPixmapImplWin32 *pixmap_impl;
Packit Service fb6fa5
  gint i, j, data_bpl, pixmap_bpl;
Packit Service fb6fa5
  guchar *bits;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (data != NULL, NULL);
Packit Service fb6fa5
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (!drawable)
Packit Service fb6fa5
    drawable = _gdk_root;
Packit Service fb6fa5
  else if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap = gdk_pixmap_new (drawable, width, height, 1);
Packit Service fb6fa5
Packit Service fb6fa5
  if (pixmap == NULL)
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit Service fb6fa5
  bits = pixmap_impl->bits;
Packit Service fb6fa5
  data_bpl = ((width - 1) / 8 + 1);
Packit Service fb6fa5
  pixmap_bpl = ((width - 1)/32 + 1)*4;
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < height; i++)
Packit Service fb6fa5
    for (j = 0; j < data_bpl; j++)
Packit Service fb6fa5
      bits[i*pixmap_bpl + j] = mirror[(guchar) data[i*data_bpl + j]];
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (PIXMAP, g_print ("gdk_bitmap_create_from_data: %dx%d=%p\n",
Packit Service fb6fa5
			     width, height, GDK_PIXMAP_HBITMAP (pixmap)));
Packit Service fb6fa5
Packit Service fb6fa5
  return pixmap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap*
Packit Service fb6fa5
_gdk_pixmap_create_from_data (GdkDrawable    *drawable,
Packit Service fb6fa5
			     const gchar    *data,
Packit Service fb6fa5
			     gint            width,
Packit Service fb6fa5
			     gint            height,
Packit Service fb6fa5
			     gint            depth,
Packit Service fb6fa5
			     const GdkColor *fg,
Packit Service fb6fa5
			     const GdkColor *bg)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* Oh wow. I struggled with dozens of lines of code trying to get
Packit Service fb6fa5
   * this right using a monochrome Win32 bitmap created from data, and
Packit Service fb6fa5
   * a colour DIB section as the result, trying setting pens,
Packit Service fb6fa5
   * background colors, whatnot and BitBlt:ing.  Nope. Then finally I
Packit Service fb6fa5
   * realized it's much easier to do it using gdk...:
Packit Service fb6fa5
   */
Packit Service fb6fa5
Packit Service fb6fa5
  GdkPixmap *result;
Packit Service fb6fa5
  GdkPixmap *source;
Packit Service fb6fa5
  GdkGC *gc;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (data != NULL, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (fg != NULL, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (bg != NULL, NULL);
Packit Service fb6fa5
  g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
Packit Service fb6fa5
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  result = gdk_pixmap_new (drawable, width, height, depth);
Packit Service fb6fa5
  source = gdk_bitmap_create_from_data (drawable, data, width, height);
Packit Service fb6fa5
  gc = gdk_gc_new (result);
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_gc_set_foreground (gc, fg);
Packit Service fb6fa5
  gdk_gc_set_background (gc, bg);
Packit Service fb6fa5
  _gdk_win32_blit
Packit Service fb6fa5
    (TRUE,
Packit Service fb6fa5
     GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (result)->impl),
Packit Service fb6fa5
     gc, source, 0, 0, 0, 0, width, height);
Packit Service fb6fa5
  g_object_unref (source);
Packit Service fb6fa5
  g_object_unref (gc);
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (PIXMAP, g_print ("gdk_pixmap_create_from_data: %dx%dx%d=%p\n",
Packit Service fb6fa5
			     width, height, depth,
Packit Service fb6fa5
			     GDK_PIXMAP_HBITMAP (result)));
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap *
Packit Service fb6fa5
gdk_pixmap_foreign_new_for_display (GdkDisplay      *display,
Packit Service fb6fa5
				    GdkNativeWindow  anid)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (display == _gdk_display, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return gdk_pixmap_foreign_new (anid);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap *
Packit Service fb6fa5
gdk_pixmap_foreign_new_for_screen (GdkScreen       *screen,
Packit Service fb6fa5
				   GdkNativeWindow  anid,
Packit Service fb6fa5
				   gint             width,
Packit Service fb6fa5
				   gint             height,
Packit Service fb6fa5
				   gint             depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return gdk_pixmap_foreign_new (anid);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap*
Packit Service fb6fa5
gdk_pixmap_foreign_new (GdkNativeWindow anid)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixmap *pixmap;
Packit Service fb6fa5
  GdkDrawableImplWin32 *draw_impl;
Packit Service fb6fa5
  GdkPixmapImplWin32 *pix_impl;
Packit Service fb6fa5
  HBITMAP hbitmap;
Packit Service fb6fa5
  SIZE size;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Check to make sure we were passed a HBITMAP */
Packit Service fb6fa5
  g_return_val_if_fail (GetObjectType ((HGDIOBJ) anid) == OBJ_BITMAP, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  hbitmap = (HBITMAP) anid;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Get information about the bitmap to fill in the structure for the
Packit Service fb6fa5
   * GDK window.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  GetBitmapDimensionEx (hbitmap, &size);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Allocate a new GDK pixmap */
Packit Service fb6fa5
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
Packit Service fb6fa5
  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit Service fb6fa5
  pix_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit Service fb6fa5
  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
Packit Service fb6fa5
  
Packit Service fb6fa5
  draw_impl->handle = hbitmap;
Packit Service fb6fa5
  draw_impl->colormap = NULL;
Packit Service fb6fa5
  pix_impl->is_foreign = TRUE;
Packit Service fb6fa5
  pix_impl->width = size.cx;
Packit Service fb6fa5
  pix_impl->height = size.cy;
Packit Service fb6fa5
  pix_impl->bits = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_win32_handle_table_insert (&GDK_PIXMAP_HBITMAP (pixmap), pixmap);
Packit Service fb6fa5
Packit Service fb6fa5
  return pixmap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap*
Packit Service fb6fa5
gdk_pixmap_lookup (GdkNativeWindow anid)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return (GdkPixmap*) gdk_win32_handle_table_lookup (anid);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkPixmap*
Packit Service fb6fa5
gdk_pixmap_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (display == _gdk_display, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return gdk_pixmap_lookup (anid);
Packit Service fb6fa5
}