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/.
32 #include <pango/pangowin32.h>
34 #include "gdkscreen.h" /* gdk_screen_get_default() */
35 #include "gdkregion-generic.h"
36 #include "gdkprivate-win32.h"
38 #define ROP3_D 0x00AA0029
39 #define ROP3_DSna 0x00220326
40 #define ROP3_DSPDxax 0x00E20746
42 #define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
43 GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
45 static void gdk_win32_draw_rectangle (GdkDrawable *drawable,
52 static void gdk_win32_draw_arc (GdkDrawable *drawable,
61 static void gdk_win32_draw_polygon (GdkDrawable *drawable,
66 static void gdk_win32_draw_text (GdkDrawable *drawable,
73 static void gdk_win32_draw_text_wc (GdkDrawable *drawable,
80 static void gdk_win32_draw_drawable (GdkDrawable *drawable,
89 static void gdk_win32_draw_points (GdkDrawable *drawable,
93 static void gdk_win32_draw_segments (GdkDrawable *drawable,
97 static void gdk_win32_draw_lines (GdkDrawable *drawable,
101 static void gdk_win32_draw_glyphs (GdkDrawable *drawable,
106 PangoGlyphString *glyphs);
107 static void gdk_win32_draw_image (GdkDrawable *drawable,
117 static void gdk_win32_set_colormap (GdkDrawable *drawable,
118 GdkColormap *colormap);
120 static GdkColormap* gdk_win32_get_colormap (GdkDrawable *drawable);
122 static gint gdk_win32_get_depth (GdkDrawable *drawable);
124 static GdkScreen * gdk_win32_get_screen (GdkDrawable *drawable);
126 static GdkVisual* gdk_win32_get_visual (GdkDrawable *drawable);
128 static void gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass);
130 static void gdk_drawable_impl_win32_finalize (GObject *object);
132 static gpointer parent_class = NULL;
135 gdk_drawable_impl_win32_get_type (void)
137 static GType object_type = 0;
141 static const GTypeInfo object_info =
143 sizeof (GdkDrawableImplWin32Class),
144 (GBaseInitFunc) NULL,
145 (GBaseFinalizeFunc) NULL,
146 (GClassInitFunc) gdk_drawable_impl_win32_class_init,
147 NULL, /* class_finalize */
148 NULL, /* class_data */
149 sizeof (GdkDrawableImplWin32),
151 (GInstanceInitFunc) NULL,
154 object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
155 "GdkDrawableImplWin32",
163 gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass)
165 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
166 GObjectClass *object_class = G_OBJECT_CLASS (klass);
168 parent_class = g_type_class_peek_parent (klass);
170 object_class->finalize = gdk_drawable_impl_win32_finalize;
172 drawable_class->create_gc = _gdk_win32_gc_new;
173 drawable_class->draw_rectangle = gdk_win32_draw_rectangle;
174 drawable_class->draw_arc = gdk_win32_draw_arc;
175 drawable_class->draw_polygon = gdk_win32_draw_polygon;
176 drawable_class->draw_text = gdk_win32_draw_text;
177 drawable_class->draw_text_wc = gdk_win32_draw_text_wc;
178 drawable_class->draw_drawable = gdk_win32_draw_drawable;
179 drawable_class->draw_points = gdk_win32_draw_points;
180 drawable_class->draw_segments = gdk_win32_draw_segments;
181 drawable_class->draw_lines = gdk_win32_draw_lines;
182 drawable_class->draw_glyphs = gdk_win32_draw_glyphs;
183 drawable_class->draw_image = gdk_win32_draw_image;
185 drawable_class->set_colormap = gdk_win32_set_colormap;
186 drawable_class->get_colormap = gdk_win32_get_colormap;
188 drawable_class->get_depth = gdk_win32_get_depth;
189 drawable_class->get_screen = gdk_win32_get_screen;
190 drawable_class->get_visual = gdk_win32_get_visual;
192 drawable_class->_copy_to_image = _gdk_win32_copy_to_image;
196 gdk_drawable_impl_win32_finalize (GObject *object)
198 gdk_drawable_set_colormap (GDK_DRAWABLE (object), NULL);
200 G_OBJECT_CLASS (parent_class)->finalize (object);
203 /*****************************************************
204 * Win32 specific implementations of generic functions *
205 *****************************************************/
208 gdk_win32_get_colormap (GdkDrawable *drawable)
210 return GDK_DRAWABLE_IMPL_WIN32 (drawable)->colormap;
214 gdk_win32_set_colormap (GdkDrawable *drawable,
215 GdkColormap *colormap)
217 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
219 if (impl->colormap == colormap)
223 gdk_colormap_unref (impl->colormap);
224 impl->colormap = colormap;
226 gdk_colormap_ref (impl->colormap);
233 * Render a dashed line 'by hand' cause the Win9x GDI is
234 * too limited to do so
236 static inline gboolean
237 render_line_horizontal (HDC hdc,
247 for (n = 0; x1 < x2; n++)
249 int len = dashes[n % num_dashes];
254 if (!GDI_CALL (PatBlt, (hdc, x1, y - pen_width / 2,
259 x1 += dashes[n % num_dashes];
265 static inline gboolean
266 render_line_vertical (HDC hdc,
276 for (n = 0; y1 < y2; n++)
278 int len = dashes[n % num_dashes];
282 if (!GDI_CALL (PatBlt, (hdc, x - pen_width / 2, y1,
287 y1 += dashes[n % num_dashes];
294 draw_tiles_lowlevel (HDC dest,
308 GDK_NOTE (MISC, g_print ("draw_tiles_lowlevel: %p +%d+%d tile=%p:%dx%d@+%d+%d %dx%d\n",
311 tile, tile_width, tile_height,
312 tile_x_origin, tile_y_origin,
315 y = tile_y_origin % tile_height;
318 while (y < dest_y + height)
320 if (y + tile_height >= dest_y)
322 x = tile_x_origin % tile_width;
325 while (x < dest_x + width)
327 if (x + tile_width >= dest_x)
329 gint src_x = MAX (0, dest_x - x);
330 gint src_y = MAX (0, dest_y - y);
332 if (!GDI_CALL (BitBlt, (dest, x + src_x, y + src_y,
333 MIN (tile_width, dest_x + width - (x + src_x)),
334 MIN (tile_height, dest_y + height - (y + src_y)),
348 draw_tiles (GdkDrawable *drawable,
359 const GdkGCValuesMask mask = GDK_GC_FOREGROUND;
360 gint tile_width, tile_height;
362 HDC dest_hdc, tile_hdc;
364 gc_copy = gdk_gc_new (tile);
365 gdk_gc_copy (gc_copy, gc);
366 dest_hdc = gdk_win32_hdc_get (drawable, gc, mask);
367 tile_hdc = gdk_win32_hdc_get (tile, gc_copy, mask);
369 gdk_drawable_get_size (tile, &tile_width, &tile_height);
371 draw_tiles_lowlevel (dest_hdc, tile_hdc, rop3,
372 dest_x, dest_y, tile_x_origin, tile_y_origin,
373 width, height, tile_width, tile_height);
375 gdk_win32_hdc_release (drawable, gc, mask);
376 gdk_win32_hdc_release (tile, gc_copy, mask);
377 gdk_gc_unref (gc_copy);
381 rop2_to_rop3 (int rop2)
385 /* Oh, Microsoft's silly names for binary and ternary rops. */
386 #define CASE(rop2,rop3) case R2_##rop2: return rop3
387 CASE (BLACK, BLACKNESS);
388 CASE (NOTMERGEPEN, NOTSRCERASE);
389 CASE (MASKNOTPEN, 0x00220326);
390 CASE (NOTCOPYPEN, NOTSRCCOPY);
391 CASE (MASKPENNOT, SRCERASE);
392 CASE (NOT, DSTINVERT);
393 CASE (XORPEN, SRCINVERT);
394 CASE (NOTMASKPEN, 0x007700E6);
395 CASE (MASKPEN, SRCAND);
396 CASE (NOTXORPEN, 0x00990066);
397 CASE (NOP, 0x00AA0029);
398 CASE (MERGENOTPEN, MERGEPAINT);
399 CASE (COPYPEN, SRCCOPY);
400 CASE (MERGEPENNOT, 0x00DD0228);
401 CASE (MERGEPEN, SRCPAINT);
402 CASE (WHITE, WHITENESS);
404 default: return SRCCOPY;
409 generic_draw (GdkDrawable *drawable,
411 GdkGCValuesMask mask,
412 void (*function) (GdkGCWin32 *, HDC, gint, gint, va_list),
413 const GdkRegion *region,
416 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
417 GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
421 va_start (args, region);
423 /* If tiled or stippled, draw to a temp pixmap and do blitting magic.
426 if (gcwin32->values_mask & GDK_GC_FILL &&
427 ((gcwin32->fill_style == GDK_TILED &&
428 gcwin32->values_mask & GDK_GC_TILE &&
429 gcwin32->tile != NULL)
431 ((gcwin32->fill_style == GDK_OPAQUE_STIPPLED ||
432 gcwin32->fill_style == GDK_STIPPLED) &&
433 gcwin32->values_mask & GDK_GC_STIPPLE &&
434 gcwin32->stipple != NULL)))
436 const GdkGCValuesMask blitting_mask = 0;
437 GdkGCValuesMask drawing_mask = GDK_GC_FOREGROUND;
438 gint ts_x_origin = 0, ts_y_origin = 0;
440 gint width = region->extents.x2 - region->extents.x1;
441 gint height = region->extents.y2 - region->extents.y1;
443 GdkPixmap *mask_pixmap =
444 gdk_pixmap_new (drawable, width, height, 1);
445 GdkPixmap *tile_pixmap =
446 gdk_pixmap_new (drawable, width, height, -1);
447 GdkPixmap *stipple_bitmap = NULL;
450 GdkGC *mask_gc = gdk_gc_new (mask_pixmap);
451 GdkGC *tile_gc = gdk_gc_new (tile_pixmap);
456 HGDIOBJ old_mask_hbm;
457 HGDIOBJ old_tile_hbm;
459 GdkGCValues gcvalues;
461 hdc = gdk_win32_hdc_get (drawable, gc, blitting_mask);
462 tile_hdc = CreateCompatibleDC (hdc);
464 if (gcwin32->values_mask & GDK_GC_TS_X_ORIGIN)
465 ts_x_origin = gc->ts_x_origin;
466 if (gcwin32->values_mask & GDK_GC_TS_Y_ORIGIN)
467 ts_y_origin = gc->ts_y_origin;
469 ts_x_origin -= region->extents.x1;
470 ts_y_origin -= region->extents.y1;
472 /* Fill mask bitmap with zeros */
473 gdk_gc_set_function (mask_gc, GDK_CLEAR);
474 gdk_draw_rectangle (mask_pixmap, mask_gc, TRUE,
475 0, 0, width, height);
477 /* Paint into mask bitmap, drawing ones */
478 gdk_gc_set_function (mask_gc, GDK_COPY);
480 gdk_gc_set_foreground (mask_gc, &fg);
482 /* If the drawing function uses line attributes, set them as in
485 if (mask & LINE_ATTRIBUTES)
487 gdk_gc_get_values (gc, &gcvalues);
488 if (gcvalues.line_width != 0 ||
489 gcvalues.line_style != GDK_LINE_SOLID ||
490 gcvalues.cap_style != GDK_CAP_BUTT ||
491 gcvalues.join_style != GDK_JOIN_MITER)
492 gdk_gc_set_line_attributes (mask_gc,
496 gcvalues.join_style);
497 drawing_mask |= LINE_ATTRIBUTES;
500 /* Ditto, if the drawing function draws text, set up for that. */
501 if (mask & GDK_GC_FONT)
502 drawing_mask |= GDK_GC_FONT;
504 mask_hdc = gdk_win32_hdc_get (mask_pixmap, mask_gc, drawing_mask);
505 (*function) (GDK_GC_WIN32 (mask_gc), mask_hdc,
506 region->extents.x1, region->extents.y1, args);
507 gdk_win32_hdc_release (mask_pixmap, mask_gc, drawing_mask);
509 if (gcwin32->fill_style == GDK_TILED)
511 /* Tile pixmap with tile */
512 draw_tiles (tile_pixmap, tile_gc, SRCCOPY,
514 0, 0, ts_x_origin, ts_y_origin,
519 /* Tile with stipple */
522 stipple_bitmap = gdk_pixmap_new (NULL, width, height, 1);
523 stipple_gc = gdk_gc_new (stipple_bitmap);
525 /* Tile stipple bitmap */
526 draw_tiles (stipple_bitmap, stipple_gc, SRCCOPY,
528 0, 0, ts_x_origin, ts_y_origin,
531 if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
533 /* Fill tile pixmap with background */
534 fg.pixel = gcwin32->background;
535 gdk_gc_set_foreground (tile_gc, &fg);
536 gdk_draw_rectangle (tile_pixmap, tile_gc, TRUE,
537 0, 0, width, height);
539 gdk_gc_unref (stipple_gc);
542 gdk_gc_unref (mask_gc);
543 gdk_gc_unref (tile_gc);
545 mask_hdc = CreateCompatibleDC (hdc);
547 if ((old_mask_hbm = SelectObject (mask_hdc, GDK_PIXMAP_HBITMAP (mask_pixmap))) == NULL)
548 WIN32_GDI_FAILED ("SelectObject");
550 if ((old_tile_hbm = SelectObject (tile_hdc, GDK_PIXMAP_HBITMAP (tile_pixmap))) == NULL)
551 WIN32_GDI_FAILED ("SelectObject");
553 if (gcwin32->fill_style == GDK_STIPPLED ||
554 gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
557 HGDIOBJ old_stipple_hbm;
559 HGDIOBJ old_tile_brush;
561 if ((stipple_hdc = CreateCompatibleDC (hdc)) == NULL)
562 WIN32_GDI_FAILED ("CreateCompatibleDC");
564 if ((old_stipple_hbm =
565 SelectObject (stipple_hdc,
566 GDK_PIXMAP_HBITMAP (stipple_bitmap))) == NULL)
567 WIN32_GDI_FAILED ("SelectObject");
569 if ((fg_brush = CreateSolidBrush
570 (_gdk_win32_colormap_color (impl->colormap,
571 gcwin32->foreground))) == NULL)
572 WIN32_GDI_FAILED ("CreateSolidBrush");
574 if ((old_tile_brush = SelectObject (tile_hdc, fg_brush)) == NULL)
575 WIN32_GDI_FAILED ("SelectObject");
577 /* Paint tile with foreround where stipple is one
579 * Desired ternary ROP: (P=foreground, S=stipple, D=destination)
590 * Reading bottom-up: 11100010 = 0xE2. PSDK docs say this is
591 * known as DSPDxax, with hex value 0x00E20746.
593 GDI_CALL (BitBlt, (tile_hdc, 0, 0, width, height,
594 stipple_hdc, 0, 0, ROP3_DSPDxax));
596 if (gcwin32->fill_style == GDK_STIPPLED)
598 /* Punch holes in mask where stipple is zero */
599 GDI_CALL (BitBlt, (mask_hdc, 0, 0, width, height,
600 stipple_hdc, 0, 0, SRCAND));
603 GDI_CALL (SelectObject, (tile_hdc, old_tile_brush));
604 GDI_CALL (DeleteObject, (fg_brush));
605 GDI_CALL (SelectObject, (stipple_hdc, old_stipple_hbm));
606 GDI_CALL (DeleteDC, (stipple_hdc));
607 gdk_drawable_unref (stipple_bitmap);
610 /* Tile pixmap now contains the pattern that we should paint in
611 * the areas where mask is one. (It is filled with said pattern.)
616 GDI_CALL (MaskBlt, (hdc, region->extents.x1, region->extents.y1,
619 GDK_PIXMAP_HBITMAP (mask_pixmap), 0, 0,
620 MAKEROP4 (rop2_to_rop3 (gcwin32->rop2), ROP3_D)));
624 GdkPixmap *temp1_pixmap =
625 gdk_pixmap_new (drawable, width, height, -1);
626 GdkPixmap *temp2_pixmap =
627 gdk_pixmap_new (drawable, width, height, -1);
628 HDC temp1_hdc = CreateCompatibleDC (hdc);
629 HDC temp2_hdc = CreateCompatibleDC (hdc);
630 HGDIOBJ old_temp1_hbm =
631 SelectObject (temp1_hdc, GDK_PIXMAP_HBITMAP (temp1_pixmap));
632 HGDIOBJ old_temp2_hbm =
633 SelectObject (temp2_hdc, GDK_PIXMAP_HBITMAP (temp2_pixmap));
635 /* Grab copy of dest region to temp1 */
636 GDI_CALL (BitBlt,(temp1_hdc, 0, 0, width, height,
637 hdc, region->extents.x1, region->extents.y1, SRCCOPY));
639 /* Paint tile to temp1 using correct function */
640 GDI_CALL (BitBlt, (temp1_hdc, 0, 0, width, height,
641 tile_hdc, 0, 0, rop2_to_rop3 (gcwin32->rop2)));
643 /* Mask out temp1 where function didn't paint */
644 GDI_CALL (BitBlt, (temp1_hdc, 0, 0, width, height,
645 mask_hdc, 0, 0, SRCAND));
647 /* Grab another copy of dest region to temp2 */
648 GDI_CALL (BitBlt, (temp2_hdc, 0, 0, width, height,
649 hdc, region->extents.x1, region->extents.y1, SRCCOPY));
651 /* Mask out temp2 where function did paint */
652 GDI_CALL (BitBlt, (temp2_hdc, 0, 0, width, height,
653 mask_hdc, 0, 0, ROP3_DSna));
655 /* Combine temp1 with temp2 */
656 GDI_CALL (BitBlt, (temp2_hdc, 0, 0, width, height,
657 temp1_hdc, 0, 0, SRCPAINT));
660 GDI_CALL (BitBlt, (hdc, region->extents.x1, region->extents.y1, width, height,
661 temp2_hdc, 0, 0, SRCCOPY));
664 GDI_CALL (SelectObject, (temp1_hdc, old_temp1_hbm));
665 GDI_CALL (SelectObject, (temp2_hdc, old_temp2_hbm));
666 GDI_CALL (DeleteDC, (temp1_hdc));
667 GDI_CALL (DeleteDC, (temp2_hdc));
668 gdk_drawable_unref (temp1_pixmap);
669 gdk_drawable_unref (temp2_pixmap);
673 GDI_CALL (SelectObject, (mask_hdc, old_mask_hbm));
674 GDI_CALL (SelectObject, (tile_hdc, old_tile_hbm));
675 GDI_CALL (DeleteDC, (mask_hdc));
676 GDI_CALL (DeleteDC, (tile_hdc));
677 gdk_drawable_unref (mask_pixmap);
678 gdk_drawable_unref (tile_pixmap);
680 gdk_win32_hdc_release (drawable, gc, blitting_mask);
684 hdc = gdk_win32_hdc_get (drawable, gc, mask);
685 (*function) (gcwin32, hdc, 0, 0, args);
686 gdk_win32_hdc_release (drawable, gc, mask);
692 widen_bounds (GdkRectangle *bounds,
698 bounds->x -= pen_width;
699 bounds->y -= pen_width;
700 bounds->width += 2 * pen_width;
701 bounds->height += 2 * pen_width;
703 return gdk_region_rectangle (bounds);
707 draw_rectangle (GdkGCWin32 *gcwin32,
713 HGDIOBJ old_pen_or_brush;
720 filled = va_arg (args, gboolean);
721 x = va_arg (args, gint);
722 y = va_arg (args, gint);
723 width = va_arg (args, gint);
724 height = va_arg (args, gint);
729 if (!filled && gcwin32->pen_dashes && !IS_WIN_NT ())
731 render_line_vertical (hdc, x, y, y+height+1,
734 gcwin32->pen_num_dashes) &&
735 render_line_horizontal (hdc, x, x+width+1, y,
738 gcwin32->pen_num_dashes) &&
739 render_line_vertical (hdc, x+width+1, y, y+height+1,
742 gcwin32->pen_num_dashes) &&
743 render_line_horizontal (hdc, x, x+width+1, y+height+1,
746 gcwin32->pen_num_dashes);
751 old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN));
753 old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
754 if (old_pen_or_brush == NULL)
755 WIN32_GDI_FAILED ("SelectObject");
757 GDI_CALL (Rectangle, (hdc, x, y, x+width+1, y+height+1));
759 if (old_pen_or_brush != NULL)
760 GDI_CALL (SelectObject, (hdc, old_pen_or_brush));
765 gdk_win32_draw_rectangle (GdkDrawable *drawable,
776 GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n",
777 _gdk_win32_drawable_description (drawable),
779 (filled ? "fill " : ""),
780 width, height, x, y));
784 bounds.width = width;
785 bounds.height = height;
786 region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
788 generic_draw (drawable, gc,
789 GDK_GC_FOREGROUND | (filled ? 0 : LINE_ATTRIBUTES),
790 draw_rectangle, region, filled, x, y, width, height);
792 gdk_region_destroy (region);
796 draw_arc (GdkGCWin32 *gcwin32,
810 int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
812 filled = va_arg (args, gboolean);
813 x = va_arg (args, gint);
814 y = va_arg (args, gint);
815 width = va_arg (args, gint);
816 height = va_arg (args, gint);
817 angle1 = va_arg (args, gint);
818 angle2 = va_arg (args, gint);
823 if (angle2 >= 360*64)
825 nXStartArc = nYStartArc = nXEndArc = nYEndArc = 0;
829 /* The 100. is just an arbitrary value */
830 nXStartArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
831 nYStartArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
832 nXEndArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
833 nYEndArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
837 nXEndArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
838 nYEndArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
839 nXStartArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
840 nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
845 old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
846 GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
847 x, y, x+width, y+height,
848 nXStartArc, nYStartArc,
849 nXEndArc, nYEndArc));
850 GDI_CALL (Pie, (hdc, x, y, x+width, y+height,
851 nXStartArc, nYStartArc, nXEndArc, nYEndArc));
852 GDI_CALL (SelectObject, (hdc, old_pen));
856 GDK_NOTE (MISC, g_print ("...Arc(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
857 x, y, x+width, y+height,
858 nXStartArc, nYStartArc,
859 nXEndArc, nYEndArc));
860 GDI_CALL (Arc, (hdc, x, y, x+width, y+height,
861 nXStartArc, nYStartArc, nXEndArc, nYEndArc));
866 gdk_win32_draw_arc (GdkDrawable *drawable,
879 GDK_NOTE (MISC, g_print ("gdk_win32_draw_arc: %s %d,%d,%d,%d %d %d\n",
880 _gdk_win32_drawable_description (drawable),
881 x, y, width, height, angle1, angle2));
883 if (width <= 2 || height <= 2 || angle2 == 0)
888 bounds.width = width;
889 bounds.height = height;
890 region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
892 generic_draw (drawable, gc,
893 GDK_GC_FOREGROUND | (filled ? 0 : LINE_ATTRIBUTES),
894 draw_arc, region, filled, x, y, width, height, angle1, angle2);
896 gdk_region_destroy (region);
900 draw_polygon (GdkGCWin32 *gcwin32,
911 filled = va_arg (args, gboolean);
912 pts = va_arg (args, POINT *);
913 npoints = va_arg (args, gint);
915 if (x_offset != 0 || y_offset != 0)
916 for (i = 0; i < npoints; i++)
918 pts[i].x -= x_offset;
919 pts[i].y -= y_offset;
923 GDI_CALL (Polygon, (hdc, pts, npoints));
925 GDI_CALL (Polyline, (hdc, pts, npoints));
929 gdk_win32_draw_polygon (GdkDrawable *drawable,
940 GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %s %d points\n",
941 _gdk_win32_drawable_description (drawable),
952 pts = g_new (POINT, npoints+1);
954 for (i = 0; i < npoints; i++)
956 bounds.x = MIN (bounds.x, points[i].x);
957 bounds.y = MIN (bounds.y, points[i].y);
958 bounds.width = MAX (bounds.width, points[i].x - bounds.x);
959 bounds.height = MAX (bounds.height, points[i].y - bounds.y);
960 pts[i].x = points[i].x;
961 pts[i].y = points[i].y;
964 if (points[0].x != points[npoints-1].x ||
965 points[0].y != points[npoints-1].y)
967 pts[npoints].x = points[0].x;
968 pts[npoints].y = points[0].y;
972 region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
974 generic_draw (drawable, gc,
975 GDK_GC_FOREGROUND | (filled ? 0 : LINE_ATTRIBUTES),
976 draw_polygon, region, filled, pts, npoints);
978 gdk_region_destroy (region);
989 gdk_draw_text_handler (GdkWin32SingleFont *singlefont,
990 const wchar_t *wcstr,
996 gdk_draw_text_arg *argp = (gdk_draw_text_arg *) arg;
1001 if ((oldfont = SelectObject (argp->hdc, singlefont->hfont)) == NULL)
1003 WIN32_GDI_FAILED ("SelectObject");
1007 if (!TextOutW (argp->hdc, argp->x, argp->y, wcstr, wclen))
1008 WIN32_GDI_FAILED ("TextOutW");
1009 GetTextExtentPoint32W (argp->hdc, wcstr, wclen, &size);
1012 SelectObject (argp->hdc, oldfont);
1016 gdk_win32_draw_text (GdkDrawable *drawable,
1024 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
1027 gdk_draw_text_arg arg;
1029 if (text_length == 0)
1032 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
1036 arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
1038 GDK_NOTE (MISC, g_print ("gdk_win32_draw_text: %s (%d,%d) \"%.*s\" (len %d)\n",
1039 _gdk_win32_drawable_description (drawable),
1041 (text_length > 10 ? 10 : text_length),
1042 text, text_length));
1044 if (text_length == 1)
1046 /* For single characters, don't try to interpret as UTF-8. */
1047 wc = (guchar) text[0];
1048 _gdk_wchar_text_handle (font, &wc, 1, gdk_draw_text_handler, &arg);
1052 wcstr = g_new (wchar_t, text_length);
1053 if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
1054 g_warning ("gdk_win32_draw_text: _gdk_utf8_to_ucs2 failed");
1056 _gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
1061 gdk_win32_hdc_release (drawable, gc, mask);
1065 gdk_win32_draw_text_wc (GdkDrawable *drawable,
1070 const GdkWChar *text,
1073 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
1076 gdk_draw_text_arg arg;
1078 if (text_length == 0)
1081 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
1085 arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
1087 GDK_NOTE (MISC, g_print ("gdk_win32_draw_text_wc: %s (%d,%d) len: %d\n",
1088 _gdk_win32_drawable_description (drawable),
1089 x, y, text_length));
1091 if (sizeof (wchar_t) != sizeof (GdkWChar))
1093 wcstr = g_new (wchar_t, text_length);
1094 for (i = 0; i < text_length; i++)
1098 wcstr = (wchar_t *) text;
1100 _gdk_wchar_text_handle (font, wcstr, text_length,
1101 gdk_draw_text_handler, &arg);
1103 if (sizeof (wchar_t) != sizeof (GdkWChar))
1106 gdk_win32_hdc_release (drawable, gc, mask);
1110 gdk_win32_draw_drawable (GdkDrawable *drawable,
1120 g_assert (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable));
1122 _gdk_win32_blit (FALSE, (GdkDrawableImplWin32 *) drawable,
1123 gc, src, xsrc, ysrc,
1124 xdest, ydest, width, height);
1128 gdk_win32_draw_points (GdkDrawable *drawable,
1137 hdc = gdk_win32_hdc_get (drawable, gc, GDK_GC_FOREGROUND);
1139 GDK_NOTE (MISC, g_print ("gdk_win32_draw_points: %s %d points\n",
1140 _gdk_win32_drawable_description (drawable),
1143 /* The X11 version uses XDrawPoint(), which doesn't use the fill
1144 * mode, so don't use generic_draw. But we should use the current
1145 * function, so we can't use SetPixel(). Draw single-pixel
1146 * rectangles (sigh).
1149 old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
1150 for (i = 0; i < npoints; i++)
1151 Rectangle (hdc, points[i].x, points[i].y,
1152 points[i].x + 2, points[i].y + 2);
1154 SelectObject (hdc, old_pen);
1155 gdk_win32_hdc_release (drawable, gc, GDK_GC_FOREGROUND);
1159 draw_segments (GdkGCWin32 *gcwin32,
1169 segs = va_arg (args, GdkSegment *);
1170 nsegs = va_arg (args, gint);
1172 if (x_offset != 0 || y_offset != 0)
1173 for (i = 0; i < nsegs; i++)
1175 segs[i].x1 -= x_offset;
1176 segs[i].y1 -= y_offset;
1177 segs[i].x2 -= x_offset;
1178 segs[i].y2 -= y_offset;
1181 if (gcwin32->pen_dashes && !IS_WIN_NT ())
1183 for (i = 0; i < nsegs; i++)
1185 if (segs[i].x1 == segs[i].x2)
1189 if (segs[i].y1 <= segs[i].y2)
1190 y1 = segs[i].y1, y2 = segs[i].y2;
1192 y1 = segs[i].y2, y2 = segs[i].y1;
1194 render_line_vertical (hdc,
1197 gcwin32->pen_dashes,
1198 gcwin32->pen_num_dashes);
1200 else if (segs[i].y1 == segs[i].y2)
1204 if (segs[i].x1 <= segs[i].x2)
1205 x1 = segs[i].x1, x2 = segs[i].x2;
1207 x1 = segs[i].x2, x2 = segs[i].x1;
1209 render_line_horizontal (hdc,
1212 gcwin32->pen_dashes,
1213 gcwin32->pen_num_dashes);
1216 GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
1217 GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2));
1222 for (i = 0; i < nsegs; i++)
1223 GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
1224 GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2));
1229 gdk_win32_draw_segments (GdkDrawable *drawable,
1234 GdkRectangle bounds;
1238 GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %s %d segs\n",
1239 _gdk_win32_drawable_description (drawable),
1242 bounds.x = G_MAXINT;
1243 bounds.y = G_MAXINT;
1247 for (i = 0; i < nsegs; i++)
1249 bounds.x = MIN (bounds.x, segs[i].x1);
1250 bounds.x = MIN (bounds.x, segs[i].x2);
1251 bounds.y = MIN (bounds.y, segs[i].y1);
1252 bounds.y = MIN (bounds.y, segs[i].y2);
1253 bounds.width = MAX (bounds.width, segs[i].x1 - bounds.x);
1254 bounds.width = MAX (bounds.width, segs[i].x2 - bounds.x);
1255 bounds.height = MAX (bounds.height, segs[i].y1 - bounds.y);
1256 bounds.height = MAX (bounds.height, segs[i].y2 - bounds.y);
1259 region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
1261 generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
1262 draw_segments, region, segs, nsegs);
1264 gdk_region_destroy (region);
1268 draw_lines (GdkGCWin32 *gcwin32,
1278 pts = va_arg (args, POINT *);
1279 npoints = va_arg (args, gint);
1281 if (x_offset != 0 || y_offset != 0)
1282 for (i = 0; i < npoints; i++)
1284 pts[i].x -= x_offset;
1285 pts[i].y -= y_offset;
1288 if (gcwin32->pen_dashes && !IS_WIN_NT ())
1290 for (i = 0; i < npoints - 1; i++)
1292 if (pts[i].x == pts[i+1].x)
1295 if (pts[i].y > pts[i+1].y)
1296 y1 = pts[i+1].y, y2 = pts[i].y;
1298 y1 = pts[i].y, y2 = pts[i+1].y;
1300 render_line_vertical (hdc, pts[i].x, y1, y2,
1302 gcwin32->pen_dashes,
1303 gcwin32->pen_num_dashes);
1305 else if (pts[i].y == pts[i+1].y)
1308 if (pts[i].x > pts[i+1].x)
1309 x1 = pts[i+1].x, x2 = pts[i].x;
1311 x1 = pts[i].x, x2 = pts[i+1].x;
1313 render_line_horizontal (hdc, x1, x2, pts[i].y,
1315 gcwin32->pen_dashes,
1316 gcwin32->pen_num_dashes);
1319 GDI_CALL (MoveToEx, (hdc, pts[i].x, pts[i].y, NULL)) &&
1320 GDI_CALL (LineTo, (hdc, pts[i+1].x, pts[i+1].y));
1324 GDI_CALL (Polyline, (hdc, pts, npoints));
1328 gdk_win32_draw_lines (GdkDrawable *drawable,
1333 GdkRectangle bounds;
1338 GDK_NOTE (MISC, g_print ("gdk_win32_draw_lines: %s %d points\n",
1339 _gdk_win32_drawable_description (drawable),
1345 bounds.x = G_MAXINT;
1346 bounds.y = G_MAXINT;
1350 pts = g_new (POINT, npoints);
1352 for (i = 0; i < npoints; i++)
1354 bounds.x = MIN (bounds.x, points[i].x);
1355 bounds.y = MIN (bounds.y, points[i].y);
1356 bounds.width = MAX (bounds.width, points[i].x - bounds.x);
1357 bounds.height = MAX (bounds.height, points[i].y - bounds.y);
1358 pts[i].x = points[i].x;
1359 pts[i].y = points[i].y;
1362 region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
1364 generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
1365 draw_lines, region, pts, npoints);
1367 gdk_region_destroy (region);
1372 draw_glyphs (GdkGCWin32 *gcwin32,
1381 PangoGlyphString *glyphs;
1383 font = va_arg (args, PangoFont *);
1384 x = va_arg (args, gint);
1385 y = va_arg (args, gint);
1386 glyphs = va_arg (args, PangoGlyphString *);
1391 pango_win32_render (hdc, font, glyphs, x, y);
1395 gdk_win32_draw_glyphs (GdkDrawable *drawable,
1400 PangoGlyphString *glyphs)
1402 GdkRectangle bounds;
1404 PangoRectangle ink_rect;
1406 pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
1408 bounds.x = x + PANGO_PIXELS (ink_rect.x) - 1;
1409 bounds.y = y + PANGO_PIXELS (ink_rect.y) - 1;
1410 bounds.width = PANGO_PIXELS (ink_rect.width) + 2;
1411 bounds.height = PANGO_PIXELS (ink_rect.height) + 2;
1412 region = gdk_region_rectangle (&bounds);
1414 generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT,
1415 draw_glyphs, region, font, x, y, glyphs);
1417 gdk_region_destroy (region);
1421 blit_from_pixmap (gboolean use_fg_bg,
1422 GdkDrawableImplWin32 *dest,
1424 GdkPixmapImplWin32 *src,
1425 GdkGCWin32 *gcwin32,
1435 RGBQUAD oldtable[256], newtable[256];
1438 gint newtable_size = 0, oldtable_size = 0;
1441 GDK_NOTE (MISC, g_print ("blit_from_pixmap\n"));
1443 if (!(srcdc = CreateCompatibleDC (NULL)))
1445 WIN32_GDI_FAILED ("CreateCompatibleDC");
1449 if (!(holdbitmap = SelectObject (srcdc, ((GdkDrawableImplWin32 *) src)->handle)))
1450 WIN32_GDI_FAILED ("SelectObject");
1453 if (GDK_PIXMAP_OBJECT (src->parent_instance.wrapper)->depth <= 8)
1455 /* Blitting from a 1, 4 or 8-bit pixmap */
1457 if ((oldtable_size = GetDIBColorTable (srcdc, 0, 256, oldtable)) == 0)
1458 WIN32_GDI_FAILED ("GetDIBColorTable");
1459 else if (GDK_PIXMAP_OBJECT (src->parent_instance.wrapper)->depth == 1)
1461 /* Blitting from an 1-bit pixmap */
1467 bgix = gcwin32->background;
1468 fgix = gcwin32->foreground;
1476 if (GDK_IS_PIXMAP_IMPL_WIN32 (dest) &&
1477 GDK_PIXMAP_OBJECT (dest->wrapper)->depth <= 8)
1479 /* Destination is also pixmap, get fg and bg from
1480 * its palette. Either use the foreground and
1481 * background pixel values in the GC (only in the
1482 * case of gdk_image_put(), cf. XPutImage()), or 0
1483 * and 1 to index the palette.
1485 if (!GDI_CALL (GetDIBColorTable, (hdc, bgix, 1, newtable)) ||
1486 !GDI_CALL (GetDIBColorTable, (hdc, fgix, 1, newtable+1)))
1491 /* Destination is a window, get fg and bg from its
1495 bg = _gdk_win32_colormap_color (dest->colormap, bgix);
1496 fg = _gdk_win32_colormap_color (dest->colormap, fgix);
1497 newtable[0].rgbBlue = GetBValue (bg);
1498 newtable[0].rgbGreen = GetGValue (bg);
1499 newtable[0].rgbRed = GetRValue (bg);
1500 newtable[0].rgbReserved = 0;
1501 newtable[1].rgbBlue = GetBValue (fg);
1502 newtable[1].rgbGreen = GetGValue (fg);
1503 newtable[1].rgbRed = GetRValue (fg);
1504 newtable[1].rgbReserved = 0;
1507 GDK_NOTE (MISC, g_print ("bg: %02x %02x %02x "
1508 "fg: %02x %02x %02x\n",
1510 newtable[0].rgbGreen,
1511 newtable[0].rgbBlue,
1513 newtable[1].rgbGreen,
1514 newtable[1].rgbBlue));
1517 else if (GDK_IS_PIXMAP_IMPL_WIN32 (dest))
1519 /* Destination is pixmap, get its color table */
1521 if ((newtable_size = GetDIBColorTable (hdc, 0, 256, newtable)) == 0)
1522 WIN32_GDI_FAILED ("GetDIBColorTable"), ok = FALSE;
1525 /* If blitting between pixmaps, set source's color table */
1526 if (ok && newtable_size > 0)
1528 GDK_NOTE (MISC_OR_COLORMAP,
1529 g_print ("blit_from_pixmap: set color table"
1530 " hdc=%p count=%d\n",
1531 srcdc, newtable_size));
1532 if (!GDI_CALL (SetDIBColorTable, (srcdc, 0, newtable_size, newtable)))
1538 GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height,
1539 srcdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));
1541 /* Restore source's color table if necessary */
1542 if (ok && newtable_size > 0 && oldtable_size > 0)
1544 GDK_NOTE (MISC_OR_COLORMAP,
1545 g_print ("blit_from_pixmap: reset color table"
1546 " hdc=%p count=%d\n",
1547 srcdc, oldtable_size));
1548 GDI_CALL (SetDIBColorTable, (srcdc, 0, oldtable_size, oldtable));
1551 GDI_CALL (SelectObject, (srcdc, holdbitmap));
1553 GDI_CALL (DeleteDC, (srcdc));
1557 blit_inside_window (HDC hdc,
1558 GdkGCWin32 *gcwin32,
1567 GDK_NOTE (MISC, g_print ("blit_inside_window\n"));
1569 GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height,
1570 hdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));
1574 blit_from_window (HDC hdc,
1575 GdkGCWin32 *gcwin32,
1576 GdkDrawableImplWin32 *src,
1585 HPALETTE holdpal = NULL;
1586 GdkColormap *cmap = gdk_colormap_get_system ();
1588 GDK_NOTE (MISC, g_print ("blit_from_window\n"));
1590 if ((srcdc = GetDC (src->handle)) == NULL)
1592 WIN32_GDI_FAILED ("GetDC");
1596 if (cmap->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
1597 cmap->visual->type == GDK_VISUAL_STATIC_COLOR)
1601 if (!(holdpal = SelectPalette (srcdc, GDK_WIN32_COLORMAP_DATA (cmap)->hpal, FALSE)))
1602 WIN32_GDI_FAILED ("SelectPalette");
1603 else if ((k = RealizePalette (srcdc)) == GDI_ERROR)
1604 WIN32_GDI_FAILED ("RealizePalette");
1606 GDK_NOTE (MISC_OR_COLORMAP,
1607 g_print ("blit_from_window: realized %d\n", k));
1610 GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height,
1611 srcdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));
1613 if (holdpal != NULL)
1614 GDI_CALL (SelectPalette, (srcdc, holdpal, FALSE));
1616 GDI_CALL (ReleaseDC, (src->handle, srcdc));
1620 _gdk_win32_blit (gboolean use_fg_bg,
1621 GdkDrawableImplWin32 *drawable,
1632 HRGN src_rgn, draw_rgn, outside_rgn;
1634 GdkDrawableImplWin32 *draw_impl;
1635 GdkDrawableImplWin32 *src_impl = NULL;
1636 gint src_width, src_height;
1638 GDK_NOTE (MISC, g_print ("_gdk_win32_blit: src:%s %dx%d@+%d+%d\n"
1639 " dst:%s @+%d+%d use_fg_bg=%d\n",
1640 _gdk_win32_drawable_description (src),
1641 width, height, xsrc, ysrc,
1642 _gdk_win32_drawable_description ((GdkDrawable *) drawable),
1646 draw_impl = (GdkDrawableImplWin32 *) drawable;
1648 if (GDK_IS_DRAWABLE_IMPL_WIN32 (src))
1649 src_impl = (GdkDrawableImplWin32 *) src;
1650 else if (GDK_IS_WINDOW (src))
1651 src_impl = (GdkDrawableImplWin32 *) GDK_WINDOW_OBJECT (src)->impl;
1652 else if (GDK_IS_PIXMAP (src))
1653 src_impl = (GdkDrawableImplWin32 *) GDK_PIXMAP_OBJECT (src)->impl;
1655 g_assert_not_reached ();
1657 hdc = gdk_win32_hdc_get ((GdkDrawable *) drawable, gc, GDK_GC_FOREGROUND);
1659 gdk_drawable_get_size (src, &src_width, &src_height);
1661 if ((src_rgn = CreateRectRgn (0, 0, src_width + 1, src_height + 1)) == NULL)
1662 WIN32_GDI_FAILED ("CreateRectRgn");
1663 else if ((draw_rgn = CreateRectRgn (xsrc, ysrc,
1665 ysrc + height + 1)) == NULL)
1666 WIN32_GDI_FAILED ("CreateRectRgn");
1669 if (GDK_IS_WINDOW_IMPL_WIN32 (draw_impl))
1673 /* If we are drawing on a window, calculate the region that is
1674 * outside the source pixmap, and invalidate that, causing it to
1675 * be cleared. Not completely sure whether this is always needed. XXX
1678 outside_rgn = CreateRectRgnIndirect (&r);
1680 if ((comb = CombineRgn (outside_rgn,
1682 RGN_DIFF)) == ERROR)
1683 WIN32_GDI_FAILED ("CombineRgn");
1684 else if (comb != NULLREGION)
1686 OffsetRgn (outside_rgn, xdest, ydest);
1687 GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
1688 g_print ("...calling InvalidateRgn, "
1689 "bbox: %ldx%ld@+%ld+%ld\n",
1690 r.right - r.left - 1, r.bottom - r.top - 1,
1692 InvalidateRgn (draw_impl->handle, outside_rgn, TRUE);
1694 GDI_CALL (DeleteObject, (outside_rgn));
1697 #if 1 /* Don't know if this is necessary XXX */
1698 if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
1699 g_warning ("gdk_win32_blit: CombineRgn returned a COMPLEXREGION");
1701 GetRgnBox (draw_rgn, &r);
1702 if (r.left != xsrc || r.top != ysrc ||
1703 r.right != xsrc + width + 1 || r.bottom != ysrc + height + 1)
1705 xdest += r.left - xsrc;
1707 ydest += r.top - ysrc;
1709 width = r.right - xsrc - 1;
1710 height = r.bottom - ysrc - 1;
1712 GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
1714 width, height, xsrc, ysrc,
1719 GDI_CALL (DeleteObject, (src_rgn));
1720 GDI_CALL (DeleteObject, (draw_rgn));
1723 if (GDK_IS_PIXMAP_IMPL_WIN32 (src_impl))
1724 blit_from_pixmap (use_fg_bg, draw_impl, hdc,
1725 (GdkPixmapImplWin32 *) src_impl, GDK_GC_WIN32 (gc),
1726 xsrc, ysrc, xdest, ydest, width, height);
1727 else if (draw_impl->handle == src_impl->handle)
1728 blit_inside_window (hdc, GDK_GC_WIN32 (gc), xsrc, ysrc, xdest, ydest, width, height);
1730 blit_from_window (hdc, GDK_GC_WIN32 (gc), src_impl, xsrc, ysrc, xdest, ydest, width, height);
1731 gdk_win32_hdc_release ((GdkDrawable *) drawable, gc, GDK_GC_FOREGROUND);
1735 gdk_win32_draw_image (GdkDrawable *drawable,
1745 g_assert (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable));
1747 _gdk_win32_blit (TRUE, (GdkDrawableImplWin32 *) drawable,
1748 gc, (GdkPixmap *) image->windowing_data,
1749 xsrc, ysrc, xdest, ydest, width, height);
1753 gdk_win32_get_depth (GdkDrawable *drawable)
1755 /* This is a bit bogus but I'm not sure the other way is better */
1757 return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper);
1761 gdk_win32_get_screen (GdkDrawable *drawable)
1763 return gdk_screen_get_default ();
1767 gdk_win32_get_visual (GdkDrawable *drawable)
1769 return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper);
1773 gdk_win32_drawable_get_handle (GdkDrawable *drawable)
1775 return GDK_DRAWABLE_HANDLE (drawable);