1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2002 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #include "gdkpixmap.h"
30 #include "gdkscreen.h" /* gdk_screen_get_default() */
31 #include "gdkprivate-win32.h"
33 static GList *image_list = NULL;
34 static gpointer parent_class = NULL;
36 static void gdk_win32_image_destroy (GdkImage *image);
37 static void gdk_image_init (GdkImage *image);
38 static void gdk_image_class_init (GdkImageClass *klass);
39 static void gdk_image_finalize (GObject *object);
42 gdk_image_get_type (void)
44 static GType object_type = 0;
48 static const GTypeInfo object_info =
50 sizeof (GdkImageClass),
52 (GBaseFinalizeFunc) NULL,
53 (GClassInitFunc) gdk_image_class_init,
54 NULL, /* class_finalize */
55 NULL, /* class_data */
58 (GInstanceInitFunc) gdk_image_init,
61 object_type = g_type_register_static (G_TYPE_OBJECT,
70 gdk_image_init (GdkImage *image)
72 image->windowing_data = NULL;
76 gdk_image_class_init (GdkImageClass *klass)
78 GObjectClass *object_class = G_OBJECT_CLASS (klass);
80 parent_class = g_type_class_peek_parent (klass);
82 object_class->finalize = gdk_image_finalize;
86 gdk_image_finalize (GObject *object)
88 GdkImage *image = GDK_IMAGE (object);
90 gdk_win32_image_destroy (image);
92 G_OBJECT_CLASS (parent_class)->finalize (object);
96 _gdk_image_exit (void)
102 image = image_list->data;
103 gdk_win32_image_destroy (image);
108 _gdk_win32_setup_pixmap_image (GdkPixmap *pixmap,
117 image = g_object_new (gdk_image_get_type (), NULL);
118 image->windowing_data = pixmap;
119 image->type = GDK_IMAGE_SHARED;
120 image->visual = gdk_drawable_get_visual (window);
121 image->byte_order = GDK_LSB_FIRST;
122 image->width = width;
123 image->height = height;
124 image->depth = depth;
146 g_warning ("_gdk_win32_setup_pixmap_image: depth=%d", image->depth);
147 g_assert_not_reached ();
150 image->bpl = ((width - 1)/32 + 1)*4;
152 image->bpl = ((width - 1)/8 + 1)*4;
154 image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
155 image->bits_per_pixel = image->depth;
162 gdk_image_new_bitmap (GdkVisual *visual,
169 gint data_bpl = (w-1)/8 + 1;
172 pixmap = gdk_pixmap_new (NULL, w, h, 1);
177 image = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl)->image;
179 GDK_NOTE (IMAGE, g_print ("gdk_image_new_bitmap: %dx%d=%p\n",
180 w, h, GDK_PIXMAP_HBITMAP (pixmap)));
182 if (data_bpl != image->bpl)
184 for (i = 0; i < h; i++)
185 memmove ((guchar *) image->mem + i*image->bpl, ((guchar *) data) + i*data_bpl, data_bpl);
188 memmove (image->mem, data, data_bpl*h);
194 _gdk_windowing_image_init (void)
196 /* Nothing needed AFAIK */
200 _gdk_image_new_for_depth (GdkScreen *screen,
209 g_return_val_if_fail (!visual || GDK_IS_VISUAL (visual), NULL);
210 g_return_val_if_fail (visual || depth != -1, NULL);
211 g_return_val_if_fail (screen == gdk_screen_get_default (), NULL);
214 depth = visual->depth;
216 pixmap = gdk_pixmap_new (NULL, width, height, depth);
221 GDK_NOTE (IMAGE, g_print ("_gdk_image_new_for_depth: %dx%dx%d=%p\n",
222 width, height, depth, GDK_PIXMAP_HBITMAP (pixmap)));
224 return GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl)->image;
228 _gdk_win32_copy_to_image (GdkDrawable *drawable,
238 GdkScreen *screen = gdk_drawable_get_screen (drawable);
240 g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable), NULL);
241 g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
243 GDK_NOTE (IMAGE, g_print ("_gdk_win32_copy_to_image: %p\n",
244 GDK_DRAWABLE_HANDLE (drawable)));
247 image = _gdk_image_new_for_depth (screen, GDK_IMAGE_FASTEST, NULL, width, height,
248 gdk_drawable_get_depth (drawable));
250 gc = gdk_gc_new ((GdkDrawable *) image->windowing_data);
253 GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (image->windowing_data)->impl),
254 gc, drawable, src_x, src_y, dest_x, dest_y, width, height);
261 gdk_image_get_pixel (GdkImage *image,
267 g_return_val_if_fail (image != NULL, 0);
268 g_return_val_if_fail (x >= 0 && x < image->width, 0);
269 g_return_val_if_fail (y >= 0 && y < image->height, 0);
271 if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
274 if (image->depth == 1)
275 return (((guchar *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
277 if (image->depth == 4)
279 pixelp = (guchar *) image->mem + y * image->bpl + (x >> 1);
281 return (*pixelp) & 0x0F;
283 return (*pixelp) >> 4;
286 pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
293 /* Windows is always LSB, no need to check image->byte_order. */
295 return pixelp[0] | (pixelp[1] << 8);
298 return pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
301 return pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
303 g_assert_not_reached ();
308 gdk_image_put_pixel (GdkImage *image,
315 g_return_if_fail (image != NULL);
316 g_return_if_fail (x >= 0 && x < image->width);
317 g_return_if_fail (y >= 0 && y < image->height);
319 if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
323 if (image->depth == 1)
325 ((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
327 ((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
328 else if (image->depth == 4)
330 pixelp = (guchar *) image->mem + y * image->bpl + (x >> 1);
335 *pixelp |= (pixel & 0x0F);
340 *pixelp |= (pixel << 4);
345 pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
347 /* Windows is always LSB, no need to check image->byte_order. */
353 pixelp[2] = ((pixel >> 16) & 0xFF);
355 pixelp[1] = ((pixel >> 8) & 0xFF);
357 pixelp[0] = (pixel & 0xFF);
363 gdk_win32_image_destroy (GdkImage *image)
367 g_return_if_fail (GDK_IS_IMAGE (image));
369 pixmap = image->windowing_data;
371 if (pixmap == NULL) /* This means that _gdk_image_exit()
372 * destroyed the image already, and
373 * now we're called a second time from
378 GDK_NOTE (IMAGE, g_print ("gdk_win32_image_destroy: %p\n",
379 GDK_PIXMAP_HBITMAP (pixmap)));
381 gdk_pixmap_unref (pixmap);
382 image->windowing_data = NULL;
386 _gdk_windowing_get_bits_for_depth (GdkDisplay *display,
389 g_return_val_if_fail (display == gdk_display_get_default (), 0);
417 g_assert_not_reached ();