]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkpixmap-win32.c
Generate gtk/makefile.mingw.
[~andy/gtk] / gdk / win32 / gdkpixmap-win32.c
index e8a6c0260bc61b58aa168e094ff2eac76dabfb23..c0fc790e1c1ed144700a9e90476435da1c80edfe 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
-#include "gdk.h"
-#include "gdkprivate.h"
+#include "gdkpixmap.h"
+#include "gdkinternals.h"
+#include "gdkprivate-win32.h"
 
-typedef struct
+static void gdk_pixmap_impl_win32_get_size   (GdkDrawable        *drawable,
+                                             gint               *width,
+                                             gint               *height);
+
+static void gdk_pixmap_impl_win32_init       (GdkPixmapImplWin32      *pixmap);
+static void gdk_pixmap_impl_win32_class_init (GdkPixmapImplWin32Class *klass);
+static void gdk_pixmap_impl_win32_finalize   (GObject                 *object);
+
+static gpointer parent_class = NULL;
+
+GType
+gdk_pixmap_impl_win32_get_type (void)
+{
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      static const GTypeInfo object_info =
+      {
+        sizeof (GdkPixmapImplWin32Class),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gdk_pixmap_impl_win32_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (GdkPixmapImplWin32),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) gdk_pixmap_impl_win32_init,
+      };
+      
+      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
+                                            "GdkPixmapImplWin32",
+                                            &object_info);
+    }
+  
+  return object_type;
+}
+
+GType
+_gdk_pixmap_impl_get_type (void)
+{
+  return gdk_pixmap_impl_win32_get_type ();
+}
+
+static void
+gdk_pixmap_impl_win32_init (GdkPixmapImplWin32 *impl)
 {
-  gchar *color_string;
-  GdkColor color;
-  gint transparent;
-} _GdkPixmapColor;
+  impl->width = 1;
+  impl->height = 1;
+}
 
-typedef struct
+static void
+gdk_pixmap_impl_win32_class_init (GdkPixmapImplWin32Class *klass)
 {
-  guint ncolors;
-  GdkColormap *colormap;
-  gulong pixels[1];
-} _GdkPixmapInfo;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
+  
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = gdk_pixmap_impl_win32_finalize;
+
+  drawable_class->get_size = gdk_pixmap_impl_win32_get_size;
+}
+
+static void
+gdk_pixmap_impl_win32_finalize (GObject *object)
+{
+  GdkPixmapImplWin32 *impl = GDK_PIXMAP_IMPL_WIN32 (object);
+  GdkPixmap *wrapper = GDK_PIXMAP (GDK_DRAWABLE_IMPL_WIN32 (impl)->wrapper);
+
+  GDK_NOTE (MISC, g_print ("gdk_pixmap_impl_win32_finalize: %#x\n",
+                          GDK_PIXMAP_HBITMAP (object)));
+
+  if (!DeleteObject (GDK_PIXMAP_HBITMAP (object)))
+    WIN32_GDI_FAILED ("DeleteObject");
+
+  gdk_win32_handle_table_remove (GDK_PIXMAP_HBITMAP (object));
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_pixmap_impl_win32_get_size (GdkDrawable *drawable,
+                               gint        *width,
+                               gint        *height)
+{
+  if (width)
+    *width = GDK_PIXMAP_IMPL_WIN32 (drawable)->width;
+  if (height)
+    *height = GDK_PIXMAP_IMPL_WIN32 (drawable)->height;
+}
 
 GdkPixmap*
 gdk_pixmap_new (GdkWindow *window,
@@ -55,8 +134,10 @@ gdk_pixmap_new (GdkWindow *window,
                gint       depth)
 {
   GdkPixmap *pixmap;
-  GdkWindowPrivate *private;
-  GdkWindowPrivate *window_private;
+  GdkDrawableImplWin32 *draw_impl;
+  GdkPixmapImplWin32 *pix_impl;
+  GdkVisual *visual;
+
   struct {
     BITMAPINFOHEADER bmiHeader;
     union {
@@ -67,80 +148,55 @@ gdk_pixmap_new (GdkWindow *window,
   } bmi;
   UINT iUsage;
   HDC hdc;
-  GdkVisual *visual;
+
   guchar *bits;
   gint i;
 
+  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
   g_return_val_if_fail ((window != NULL) || (depth != -1), NULL);
+#if 1
   g_return_val_if_fail ((width != 0) && (height != 0), NULL);
-
-  if (!window)
-    window = (GdkWindow*) &gdk_root_parent;
-
-  window_private = (GdkWindowPrivate*) window;
-  if (window_private->destroyed)
-    return NULL;
-
-  if (depth == -1)
-    depth = gdk_window_get_visual (window)->depth;
-
-  GDK_NOTE (MISC, g_print ("gdk_pixmap_new: %dx%dx%d\n", width, height, depth));
-
-  private = g_new0 (GdkWindowPrivate, 1);
-  pixmap = (GdkPixmap*) private;
-
-  private->window_type = GDK_WINDOW_PIXMAP;
-
-  visual = gdk_window_get_visual (window);
-
-#if 0
-  if (depth == 1)
+#else
+  /* HB: Not The Right Thing to do, but a nice way to debug
+   * the backing store facility without immediate crashes ...
+   */
+  if (width == 0 || height == 0)
     {
-      if ((private->xwindow =
-          CreateBitmap (width, height, 1, 1, NULL)) == NULL)
-       {
-         g_warning ("gdk_pixmap_new: CreateBitmap failed");
-         g_free (private);
-         return NULL;
-       }
-
-      private->colormap = NULL;
+      g_warning("gdk_pixmap_new: size requested: %ld %ld", width, height);
+      /* testing: where does it crash next? */
+      if (width == 0) width = 1;
+      if (height == 0) height = 1;
     }
-  else
-    {
-      if (depth != visual->depth)
-       g_warning ("gdk_pixmap_new: depth %d doesn't match display depth %d",
-                  depth, visual->depth);
-
-      if ((hdc = GetDC (window_private->xwindow)) == NULL)
-       {
-         g_warning ("gdk_pixmap_new: GetDC failed");
-         g_free (private);
-         return NULL;
-       }
+#endif
 
-      if ((private->xwindow =
-          CreateCompatibleBitmap (hdc, width, height)) == NULL)
-       {
-         g_warning ("gdk_pixmap_new: %dx%d CreateCompatibleBitmap failed",
-                    width, height);
-         ReleaseDC (window_private->xwindow, hdc);
-         g_free (private);
-         return NULL;
-       }
+  if (!window)
+    window = gdk_parent_root;
 
-      ReleaseDC (window_private->xwindow, hdc);
+  if (GDK_WINDOW_DESTROYED (window))
+    return NULL;
 
-      private->colormap = window_private->colormap;
-      if (private->colormap == NULL)
-       private->colormap = gdk_colormap_get_system ();
-    }
-#else
+  visual = gdk_drawable_get_visual (window);
 
-  if ((hdc = GetDC (window_private->xwindow)) == NULL)
+  if (depth == -1)
+    depth = visual->depth;
+
+  GDK_NOTE (MISC, g_print ("gdk_pixmap_new: %dx%dx%d\n",
+                          width, height, depth));
+
+  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
+  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  pix_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
+  
+  pix_impl->is_foreign = FALSE;
+  pix_impl->width = width;
+  pix_impl->height = height;
+  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
+
+  if ((hdc = GetDC (GDK_WINDOW_HWND (window))) == NULL)
     {
-      g_warning ("gdk_pixmap_new: GetDC failed");
-      g_free (private);
+      WIN32_GDI_FAILED ("GetDC");
+      g_object_unref ((GObject *) pixmap);
       return NULL;
     }
 
@@ -152,11 +208,9 @@ gdk_pixmap_new (GdkWindow *window,
     bmi.bmiHeader.biBitCount = 16;
   else
     bmi.bmiHeader.biBitCount = depth;
-#if 1
   if (depth == 16)
     bmi.bmiHeader.biCompression = BI_BITFIELDS;
   else
-#endif
     bmi.bmiHeader.biCompression = BI_RGB;
   bmi.bmiHeader.biSizeImage = 0;
   bmi.bmiHeader.biXPelsPerMeter =
@@ -174,15 +228,15 @@ gdk_pixmap_new (GdkWindow *window,
 
       bmi.u.bmiColors[1].rgbBlue =
        bmi.u.bmiColors[1].rgbGreen =
-      bmi.u.bmiColors[1].rgbRed = 0xFF;
+       bmi.u.bmiColors[1].rgbRed = 0xFF;
       bmi.u.bmiColors[1].rgbReserved = 0x00;
-      private->colormap = NULL;
+      draw_impl->colormap = NULL;
     }
   else
     {
-      private->colormap = window_private->colormap;
-      if (private->colormap == NULL)
-       private->colormap = gdk_colormap_get_system ();
+      draw_impl->colormap = GDK_DRAWABLE_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->colormap;
+      if (draw_impl->colormap == NULL)
+       draw_impl->colormap = gdk_colormap_get_system ();
 
       if (depth == 8)
        {
@@ -195,94 +249,28 @@ gdk_pixmap_new (GdkWindow *window,
          if (depth != visual->depth)
            g_warning ("gdk_pixmap_new: depth %d doesn't match display depth %d",
                       depth, visual->depth);
-#if 1
          if (depth == 16)
            {
              bmi.u.bmiMasks[0] = visual->red_mask;
              bmi.u.bmiMasks[1] = visual->green_mask;
              bmi.u.bmiMasks[2] = visual->blue_mask;
            }
-#endif
        }
     }
-  if ((private->xwindow =
-       CreateDIBSection (hdc, (BITMAPINFO *) &bmi,
-                        iUsage, &bits, NULL, 0)) == NULL)
+  if ((draw_impl->handle = CreateDIBSection (hdc, (BITMAPINFO *) &bmi,
+                                            iUsage, (PVOID *) &bits,
+                                            NULL, 0)) == NULL)
     {
-      g_warning ("gdk_pixmap_new: CreateDIBSection failed: %d", GetLastError ());
-      ReleaseDC (window_private->xwindow, hdc);
-      g_free (private);
+      WIN32_GDI_FAILED ("CreateDIBSection");
+      ReleaseDC (GDK_WINDOW_HWND (window), hdc);
+      g_object_unref ((GObject *) pixmap);
       return NULL;
     }
-  ReleaseDC (window_private->xwindow, hdc);
+  ReleaseDC (GDK_WINDOW_HWND (window), hdc);
 
-#endif
-
-  GDK_NOTE (MISC, g_print ("... = %#x\n", private->xwindow));
-
-  private->parent = NULL;
-  private->x = 0;
-  private->y = 0;
-  private->width = width;
-  private->height = height;
-  private->resize_count = 0;
-  private->ref_count = 1;
-  private->destroyed = 0;
+  GDK_NOTE (MISC, g_print ("... = %#x\n", GDK_PIXMAP_HBITMAP (pixmap)));
 
-  gdk_xid_table_insert (&private->xwindow, pixmap);
-
-  return pixmap;
-}
-
-GdkPixmap *
-gdk_pixmap_create_on_shared_image (GdkImage **image_return,
-                                  GdkWindow *window,
-                                  GdkVisual *visual,
-                                  gint       width,
-                                  gint       height,
-                                  gint       depth)
-{
-  GdkPixmap *pixmap;
-  GdkImagePrivate *image_private;
-  GdkWindowPrivate *private;
-  GdkWindowPrivate *window_private;
-
-  g_return_val_if_fail (window != NULL, NULL);
-
-  window_private = (GdkWindowPrivate *) window;
-
-  if (depth == 1)
-    *image_return = gdk_image_bitmap_new (GDK_IMAGE_SHARED_PIXMAP, visual, width, height);
-  else
-    {
-      g_return_val_if_fail (depth == visual->depth, NULL);
-      *image_return = gdk_image_new (GDK_IMAGE_SHARED_PIXMAP, visual, width, height);
-    }
-
-  g_return_val_if_fail (*image_return != NULL, NULL);
-
-  image_private = (GdkImagePrivate *) *image_return;
-
-  private = g_new0 (GdkWindowPrivate, 1);
-  pixmap = (GdkPixmap*) private;
-
-  private->xwindow = image_private->ximage;
-  private->window_type = GDK_WINDOW_PIXMAP;
-  private->colormap = window_private->colormap;
-  private->parent = NULL;
-  private->x = 0;
-  private->y = 0;
-  private->width = width;
-  private->height = height;
-  private->resize_count = 0;
-  private->ref_count = 1;
-  private->destroyed = 0;
-
-  gdk_xid_table_insert (&private->xwindow, pixmap);
-
-  GDK_NOTE (MISC,
-           g_print ("gdk_pixmap_create_on_shared_image: %dx%dx%d = %#x\n",
-                    width, height, depth, private->xwindow));
+  gdk_win32_handle_table_insert (GDK_PIXMAP_HBITMAP (pixmap), pixmap);
 
   return pixmap;
 }
@@ -329,33 +317,30 @@ gdk_bitmap_create_from_data (GdkWindow   *window,
                             gint         height)
 {
   GdkPixmap *pixmap;
-  GdkWindowPrivate *private;
-  GdkWindowPrivate *window_private;
+  GdkDrawableImplWin32 *draw_impl;
+  GdkPixmapImplWin32 *pix_impl;
   gint i, j, bpl, aligned_bpl;
   guchar *bits;
 
   g_return_val_if_fail (data != NULL, NULL);
   g_return_val_if_fail ((width != 0) && (height != 0), NULL);
+  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
 
   if (!window)
-    window = (GdkWindow*) &gdk_root_parent;
+    window = gdk_parent_root;
 
-  window_private = (GdkWindowPrivate*) window;
-  if (window_private->destroyed)
+  if (GDK_WINDOW_DESTROYED (window))
     return NULL;
 
-  private = g_new0 (GdkWindowPrivate, 1);
-  pixmap = (GdkPixmap*) private;
+  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
+  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  pix_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
 
-  private->parent = NULL;
-  private->window_type = GDK_WINDOW_PIXMAP;
-  private->x = 0;
-  private->y = 0;
-  private->width = width;
-  private->height = height;
-  private->resize_count = 0;
-  private->ref_count = 1;
-  private->destroyed = FALSE;
+  pix_impl->is_foreign = FALSE;
+  pix_impl->width = width;
+  pix_impl->height = height;
+  GDK_PIXMAP_OBJECT (pixmap)->depth = 1;
 
   bpl = ((width - 1) / 8 + 1);
   aligned_bpl = ((bpl - 1) / 2 + 1) * 2;
@@ -363,15 +348,16 @@ gdk_bitmap_create_from_data (GdkWindow   *window,
   for (i = 0; i < height; i++)
     for (j = 0; j < bpl; j++)
       bits[i*aligned_bpl + j] = mirror[(guchar) data[i*bpl + j]];
-  private->xwindow = CreateBitmap (width, height, 1, 1, bits);
+
+  draw_impl->handle = CreateBitmap (width, height, 1, 1, bits);
 
   GDK_NOTE (MISC, g_print ("gdk_bitmap_create_from_data: %dx%d = %#x\n",
-                          width, height, private->xwindow));
+                          width, height, GDK_PIXMAP_HBITMAP (pixmap)));
 
   g_free (bits);
 
-  private->colormap = NULL;
-  gdk_xid_table_insert (&private->xwindow, pixmap);
+  draw_impl->colormap = NULL;
+  gdk_win32_handle_table_insert (GDK_PIXMAP_HBITMAP (pixmap), pixmap);
 
   return pixmap;
 }
@@ -397,663 +383,51 @@ gdk_pixmap_create_from_data (GdkWindow   *window,
   GdkGC *gc = gdk_gc_new (result);
   gdk_gc_set_foreground (gc, fg);
   gdk_gc_set_background (gc, bg);
-  gdk_draw_pixmap (result, gc, source, 0, 0, 0, 0, width, height);
-  gdk_pixmap_unref (source);
+  gdk_draw_drawable (result, gc, source, 0, 0, 0, 0, width, height);
+  gdk_drawable_unref (source);
   gdk_gc_unref (gc);
 
   GDK_NOTE (MISC, g_print ("gdk_pixmap_create_from_data: %dx%dx%d = %#x\n",
                           width, height, depth,
-                          ((GdkPixmapPrivate *) result)->xwindow));
-  return result;
-}
+                          GDK_PIXMAP_HBITMAP (result)));
 
-static gint
-gdk_pixmap_seek_string (FILE  *infile,
-                        const gchar *str,
-                        gint   skip_comments)
-{
-  char instr[1024];
-
-  while (!feof (infile))
-    {
-      fscanf (infile, "%1023s", instr);
-      if (skip_comments == TRUE && strcmp (instr, "/*") == 0)
-        {
-          fscanf (infile, "%1023s", instr);
-          while (!feof (infile) && strcmp (instr, "*/") != 0)
-            fscanf (infile, "%1023s", instr);
-          fscanf(infile, "%1023s", instr);
-        }
-      if (strcmp (instr, str)==0)
-        return TRUE;
-    }
-
-  return FALSE;
-}
-
-static gint
-gdk_pixmap_seek_char (FILE  *infile,
-                      gchar  c)
-{
-  gint b, oldb;
-
-  while ((b = getc(infile)) != EOF)
-    {
-      if (c != b && b == '/')
-       {
-         b = getc (infile);
-         if (b == EOF)
-           return FALSE;
-         else if (b == '*')    /* we have a comment */
-           {
-             b = -1;
-             do
-               {
-                 oldb = b;
-                 b = getc (infile);
-                 if (b == EOF)
-                   return FALSE;
-               }
-             while (!(oldb == '*' && b == '/'));
-           }
-        }
-      else if (c == b)
-       return TRUE;
-    }
-  return FALSE;
-}
-
-static gint
-gdk_pixmap_read_string (FILE  *infile,
-                        gchar **buffer,
-                       guint *buffer_size)
-{
-  gint c;
-  guint cnt = 0, bufsiz, ret = FALSE;
-  gchar *buf;
-
-  buf = *buffer;
-  bufsiz = *buffer_size;
-  if (buf == NULL)
-    {
-      bufsiz = 10 * sizeof (gchar);
-      buf = g_new(gchar, bufsiz);
-    }
-
-  do
-    c = getc (infile);
-  while (c != EOF && c != '"');
-
-  if (c != '"')
-    goto out;
-
-  while ((c = getc(infile)) != EOF)
-    {
-      if (cnt == bufsiz)
-       {
-         guint new_size = bufsiz * 2;
-         if (new_size > bufsiz)
-           bufsiz = new_size;
-         else
-           goto out;
-       
-         buf = (gchar *) g_realloc (buf, bufsiz);
-         buf[bufsiz-1] = '\0';
-       }
-
-      if (c != '"')
-        buf[cnt++] = c;
-      else
-        {
-          buf[cnt] = 0;
-         ret = TRUE;
-         break;
-        }
-    }
-
- out:
-  buf[bufsiz-1] = '\0';                /* ensure null termination for errors */
-  *buffer = buf;
-  *buffer_size = bufsiz;
-  return ret;
-}
-
-static gchar*
-gdk_pixmap_skip_whitespaces (gchar *buffer)
-{
-  gint32 index = 0;
-
-  while (buffer[index] != 0 && (buffer[index] == 0x20 || buffer[index] == 0x09))
-    index++;
-
-  return &buffer[index];
-}
-
-static gchar*
-gdk_pixmap_skip_string (gchar *buffer)
-{
-  gint32 index = 0;
-
-  while (buffer[index] != 0 && buffer[index] != 0x20 && buffer[index] != 0x09)
-    index++;
-
-  return &buffer[index];
-}
-
-#define MAX_COLOR_LEN 120
-
-static gchar*
-gdk_pixmap_extract_color (gchar *buffer)
-{
-  gint counter, numnames;
-  gchar *ptr = NULL, ch, temp[128];
-  gchar color[MAX_COLOR_LEN], *retcol;
-  gint space;
-
-  counter = 0;
-  while (ptr == NULL)
-    {
-      if (buffer[counter] == 'c')
-        {
-          ch = buffer[counter + 1];
-          if (ch == 0x20 || ch == 0x09)
-            ptr = &buffer[counter + 1];
-        }
-      else if (buffer[counter] == 0)
-        return NULL;
-
-      counter++;
-    }
-
-  ptr = gdk_pixmap_skip_whitespaces (ptr);
-
-  if (ptr[0] == 0)
-    return NULL;
-  else if (ptr[0] == '#')
-    {
-      counter = 1;
-      while (ptr[counter] != 0 &&
-             ((ptr[counter] >= '0' && ptr[counter] <= '9') ||
-              (ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
-              (ptr[counter] >= 'A' && ptr[counter] <= 'F')))
-        counter++;
-
-      retcol = g_new (gchar, counter+1);
-      strncpy (retcol, ptr, counter);
-
-      retcol[counter] = 0;
-
-      return retcol;
-    }
-
-  color[0] = 0;
-  numnames = 0;
-
-  space = MAX_COLOR_LEN - 1;
-  while (space > 0)
-    {
-      sscanf (ptr, "%127s", temp);
-
-      if (((gint)ptr[0] == 0) ||
-         (strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) ||
-          (strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0))
-       {
-         break;
-       }
-      else
-        {
-          if (numnames > 0)
-           {
-             space -= 1;
-             strcat (color, " ");
-           }
-         strncat (color, temp, space);
-         space -= MIN (space, strlen (temp));
-          ptr = gdk_pixmap_skip_string (ptr);
-          ptr = gdk_pixmap_skip_whitespaces (ptr);
-          numnames++;
-        }
-    }
-
-  retcol = g_strdup (color);
-  return retcol;
-}
-
-
-enum buffer_op
-{
-  op_header,
-  op_cmap,
-  op_body
-};
-
-
-static void
-gdk_xpm_destroy_notify (gpointer data)
-{
-  _GdkPixmapInfo *info = (_GdkPixmapInfo *)data;
-  GdkColor color;
-  int i;
-
-  for (i=0; i<info->ncolors; i++)
-    {
-      color.pixel = info->pixels[i];
-      gdk_colormap_free_colors (info->colormap, &color, 1);
-    }
-
-  gdk_colormap_unref (info->colormap);
-  g_free (info);
-}
-
-static GdkPixmap *
-_gdk_pixmap_create_from_xpm (GdkWindow  *window,
-                            GdkColormap *colormap,
-                            GdkBitmap **mask,
-                            GdkColor   *transparent_color,
-                            gchar *   (*get_buf) (enum buffer_op op,
-                                                  gpointer       handle),
-                            gpointer    handle)
-{
-  GdkPixmap *pixmap = NULL;
-  GdkImage *image = NULL;
-  GdkVisual *visual;
-  GdkGC *gc = NULL;
-  GdkColor tmp_color;
-  gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
-  gchar *buffer, pixel_str[32];
-  gchar *name_buf;
-  _GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
-  _GdkPixmapColor *colors = NULL;
-  gulong index;
-  GHashTable *color_hash = NULL;
-  _GdkPixmapInfo *color_info = NULL;
-
-  if ((window == NULL) && (colormap == NULL))
-    g_warning ("Creating pixmap from xpm with NULL window and colormap");
-
-  if (window == NULL)
-    window = (GdkWindow *)&gdk_root_parent;
-
-  if (colormap == NULL)
-    {
-      colormap = gdk_window_get_colormap (window);
-      visual = gdk_window_get_visual (window);
-    }
-  else
-    visual = ((GdkColormapPrivate *)colormap)->visual;
-
-  buffer = (*get_buf) (op_header, handle);
-  if (buffer == NULL)
-    return NULL;
-
-  sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp);
-  if (cpp >= 32)
-    {
-      g_warning ("Pixmap has more than 31 characters per color");
-      return NULL;
-    }
-
-  color_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
-  if (transparent_color == NULL)
-    {
-      gdk_color_white (colormap, &tmp_color);
-      transparent_color = &tmp_color;
-    }
-
-  /* For pseudo-color and grayscale visuals, we have to remember
-   * the colors we allocated, so we can free them later.
-   */
-  if ((visual->type == GDK_VISUAL_PSEUDO_COLOR) ||
-      (visual->type == GDK_VISUAL_GRAYSCALE))
-    {
-      color_info = g_malloc (sizeof (_GdkPixmapInfo) +
-                            sizeof(gulong) * (num_cols - 1));
-      color_info->ncolors = num_cols;
-      color_info->colormap = colormap;
-      gdk_colormap_ref (colormap);
-    }
-
-  name_buf = g_new (gchar, num_cols * (cpp+1));
-  colors = g_new (_GdkPixmapColor, num_cols);
-
-  for (cnt = 0; cnt < num_cols; cnt++)
-    {
-      gchar *color_name;
-
-      buffer = (*get_buf) (op_cmap, handle);
-      if (buffer == NULL)
-       goto error;
-
-      color = &colors[cnt];
-      color->color_string = &name_buf [cnt * (cpp + 1)];
-      strncpy (color->color_string, buffer, cpp);
-      color->color_string[cpp] = 0;
-      buffer += strlen (color->color_string);
-      color->transparent = FALSE;
-
-      color_name = gdk_pixmap_extract_color (buffer);
-
-      if (color_name == NULL ||
-         gdk_color_parse (color_name, &color->color) == FALSE)
-       {
-         color->color = *transparent_color;
-         color->transparent = TRUE;
-       }
-
-      g_free (color_name);
-
-      /* FIXME: The remaining slowness appears to happen in this
-         function. */
-      gdk_color_alloc (colormap, &color->color);
-
-      if (color_info)
-       color_info->pixels[cnt] = color->color.pixel;
-
-      g_hash_table_insert (color_hash, color->color_string, color);
-      if (cnt == 0)
-       fallbackcolor = color;
-    }
-
-  index = 0;
-  image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
-
-  if (mask)
-    {
-      /* The pixmap mask is just a bits pattern.
-       * Color 0 is used for background and 1 for foreground.
-       * We don't care about the colormap, we just need 0 and 1.
-       */
-      GdkColor mask_pattern;
-
-      *mask = gdk_pixmap_new (window, width, height, 1);
-      gc = gdk_gc_new (*mask);
-
-      mask_pattern.pixel = 0;
-      gdk_gc_set_foreground (gc, &mask_pattern);
-      gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
-
-      mask_pattern.pixel = 1;
-      gdk_gc_set_foreground (gc, &mask_pattern);
-    }
-
-  wbytes = width * cpp;
-  for (ycnt = 0; ycnt < height; ycnt++)
-    {
-      buffer = (*get_buf) (op_body, handle);
-
-      /* FIXME: this slows things down a little - it could be
-       * integrated into the strncpy below, perhaps. OTOH, strlen
-       * is fast.
-       */
-      if ((buffer == NULL) || strlen (buffer) < wbytes)
-       continue;
-
-      for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++)
-       {
-         strncpy (pixel_str, &buffer[n], cpp);
-         pixel_str[cpp] = 0;
-         ns = 0;
-       
-         color = g_hash_table_lookup (color_hash, pixel_str);
-       
-         if (!color) /* screwed up XPM file */
-           color = fallbackcolor;
-       
-         gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel);
-       
-         if (mask && color->transparent)
-           {
-             if (cnt < xcnt)
-               gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
-             cnt = xcnt + 1;
-           }
-       }
-
-      if (mask && (cnt < xcnt))
-       gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
-    }
-
- error:
-
-  if (mask)
-    gdk_gc_destroy (gc);
-
-  if (image != NULL)
-    {
-      pixmap = gdk_pixmap_new (window, width, height, visual->depth);
-
-      if (color_info)
-       gdk_drawable_set_data (pixmap, "gdk-xpm", color_info,
-                              gdk_xpm_destroy_notify);
-
-      gc = gdk_gc_new (pixmap);
-      gdk_gc_set_foreground (gc, transparent_color);
-      gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height);
-      gdk_gc_destroy (gc);
-      gdk_image_destroy (image);
-    }
-  else if (color_info)
-    gdk_xpm_destroy_notify (color_info);
-
-  if (color_hash != NULL)
-    g_hash_table_destroy (color_hash);
-
-  if (colors != NULL)
-    g_free (colors);
-
-  if (name_buf != NULL)
-    g_free (name_buf);
-
-  return pixmap;
-}
-
-
-struct file_handle
-{
-  FILE *infile;
-  gchar *buffer;
-  guint buffer_size;
-};
-
-
-static gchar *
-file_buffer (enum buffer_op op, gpointer handle)
-{
-  struct file_handle *h = handle;
-
-  switch (op)
-    {
-    case op_header:
-      if (gdk_pixmap_seek_string (h->infile, "XPM", FALSE) != TRUE)
-       break;
-
-      if (gdk_pixmap_seek_char (h->infile,'{') != TRUE)
-       break;
-      /* Fall through to the next gdk_pixmap_seek_char. */
-
-    case op_cmap:
-      gdk_pixmap_seek_char (h->infile, '"');
-      fseek (h->infile, -1, SEEK_CUR);
-      /* Fall through to the gdk_pixmap_read_string. */
-
-    case op_body:
-      gdk_pixmap_read_string (h->infile, &h->buffer, &h->buffer_size);
-      return h->buffer;
-    }
-  return 0;
-}
-
-GdkPixmap*
-gdk_pixmap_colormap_create_from_xpm (GdkWindow   *window,
-                                    GdkColormap *colormap,
-                                    GdkBitmap  **mask,
-                                    GdkColor    *transparent_color,
-                                    const gchar *filename)
-{
-  struct file_handle h;
-  GdkPixmap *pixmap = NULL;
-
-  memset (&h, 0, sizeof (h));
-  h.infile = fopen (filename, "rb");
-  if (h.infile != NULL)
-    {
-      pixmap = _gdk_pixmap_create_from_xpm (window, colormap, mask,
-                                           transparent_color,
-                                           file_buffer, &h);
-      fclose (h.infile);
-      g_free (h.buffer);
-    }
-
-  return pixmap;
-}
-
-GdkPixmap*
-gdk_pixmap_create_from_xpm (GdkWindow  *window,
-                           GdkBitmap **mask,
-                           GdkColor   *transparent_color,
-                           const gchar *filename)
-{
-  return gdk_pixmap_colormap_create_from_xpm (window, NULL, mask,
-                                      transparent_color, filename);
-}
-
-struct mem_handle
-{
-  gchar **data;
-  int offset;
-};
-
-
-static gchar *
-mem_buffer (enum buffer_op op, gpointer handle)
-{
-  struct mem_handle *h = handle;
-  switch (op)
-    {
-    case op_header:
-    case op_cmap:
-    case op_body:
-      if (h->data[h->offset])
-       return h->data[h->offset ++];
-    }
-  return 0;
-}
-
-GdkPixmap*
-gdk_pixmap_colormap_create_from_xpm_d (GdkWindow  *window,
-                                      GdkColormap *colormap,
-                                      GdkBitmap **mask,
-                                      GdkColor   *transparent_color,
-                                      gchar     **data)
-{
-  struct mem_handle h;
-  GdkPixmap *pixmap = NULL;
-
-  memset (&h, 0, sizeof (h));
-  h.data = data;
-  pixmap = _gdk_pixmap_create_from_xpm (window, colormap, mask,
-                                       transparent_color,
-                                       mem_buffer, &h);
-  return pixmap;
-}
-
-GdkPixmap*
-gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
-                             GdkBitmap **mask,
-                             GdkColor   *transparent_color,
-                             gchar     **data)
-{
-  return gdk_pixmap_colormap_create_from_xpm_d (window, NULL, mask,
-                                               transparent_color, data);
+  return result;
 }
 
 GdkPixmap*
-gdk_pixmap_foreign_new (guint32 anid)
+gdk_pixmap_foreign_new (GdkNativeWindow anid)
 {
   GdkPixmap *pixmap;
-  GdkWindowPrivate *window_private;
-  GdkWindowPrivate *private;
-  HBITMAP xpixmap;
+  GdkDrawableImplWin32 *draw_impl;
+  GdkPixmapImplWin32 *pix_impl;
+  HBITMAP hbitmap;
   SIZE size;
   unsigned int x_ret, y_ret, w_ret, h_ret, bw_ret, depth_ret;
 
-  /* check to make sure we were passed something at
-     least a little sane */
-  g_return_val_if_fail((anid != 0), NULL);
+  /* check to make sure we were passed a HBITMAP */
+  g_return_val_if_fail(GetObjectType ((HGDIOBJ) anid) == OBJ_BITMAP, NULL);
 
   /* set the pixmap to the passed in value */
-  xpixmap = (HBITMAP) anid;
-  /* get the root window */
-  window_private = &gdk_root_parent;
+  hbitmap = (HBITMAP) anid;
 
-  /* get information about the BITMAP to fill in the structure for
+  /* get information about the bitmap to fill in the structure for
      the gdk window */
-  GetBitmapDimensionEx (xpixmap, &size);
+  GetBitmapDimensionEx (hbitmap, &size);
   w_ret = size.cx;
   h_ret = size.cy;
 
   /* allocate a new gdk pixmap */
-  private = g_new(GdkWindowPrivate, 1);
-  pixmap = (GdkPixmap *)private;
-
-  private->window_type = GDK_WINDOW_PIXMAP;
-  private->xwindow = xpixmap;
-  private->colormap = NULL;
-  private->parent = NULL;
-  private->x = 0;
-  private->y = 0;
-  private->width = w_ret;
-  private->height = h_ret;
-  private->resize_count = 0;
-  private->ref_count = 1;
-  private->destroyed = 0;
-
-  gdk_xid_table_insert(&private->xwindow, pixmap);
-
-  return pixmap;
-}
-
-GdkPixmap*
-gdk_pixmap_ref (GdkPixmap *pixmap)
-{
-  GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap;
-  g_return_val_if_fail (pixmap != NULL, NULL);
+  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
+  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  pix_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
+  
+  draw_impl->handle = hbitmap;
+  draw_impl->colormap = NULL;
+  pix_impl->width = w_ret;
+  pix_impl->height = h_ret;
+
+  gdk_win32_handle_table_insert (GDK_PIXMAP_HBITMAP (pixmap), pixmap);
 
-  private->ref_count += 1;
   return pixmap;
 }
-
-void
-gdk_pixmap_unref (GdkPixmap *pixmap)
-{
-  GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap;
-  g_return_if_fail(pixmap != NULL);
-
-  private->ref_count -= 1;
-
-  GDK_NOTE (MISC, g_print ("gdk_pixmap_unref: %#x %d%s\n",
-                          private->xwindow, private->ref_count,
-                          (private->ref_count == 0 ? " freeing" : "")));
-
-  if (private->ref_count == 0)
-    {
-      if (!DeleteObject (private->xwindow))
-       g_warning ("gdk_pixmap_unref: DeleteObject failed");
-      gdk_xid_table_remove (private->xwindow);
-      g_dataset_destroy (private);
-      g_free (private);
-    }
-}
-
-GdkBitmap *
-gdk_bitmap_ref (GdkBitmap *bitmap)
-{
-  return (GdkBitmap *)gdk_pixmap_ref ((GdkPixmap *)bitmap);
-}
-
-void
-gdk_bitmap_unref (GdkBitmap *bitmap)
-{
-  gdk_pixmap_unref ((GdkPixmap *)bitmap);
-}