summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2002-11-24 23:54:01 +0000
committerTor Lillqvist <tml@src.gnome.org>2002-11-24 23:54:01 +0000
commit08fc500e8dae74025fcae6353c150598b663bd52 (patch)
treed92f8a1f4d15fbe0d642bc19e4f3fcbc6e89f9cf /gdk
parent65cce90c27fe5ed60ca467ed0ba411355ef1de4c (diff)
downloadgdk-pixbuf-08fc500e8dae74025fcae6353c150598b663bd52.tar.gz
Merge from stable:
2002-11-24 Tor Lillqvist <tml@iki.fi> Merge from stable: Implement tiles and stipples for all drawing methids (except the deprecated draw_text() and draw_text_wc()). * gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out code that didn't use generic_draw(). (generic_draw): When drawing into the mask (for tiled/stippled fill styles), copy the line attributes from the actual GC. Also ask for text drawing setup if needed. Use differently set up HDCs in the normal and tiled/stippled cases. (draw_lines, gdk_win32_draw_lines, draw_polygon, gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments, draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus implementing tiled and stippled fill styles for lines, polygons, segments, and args. (gdk_win32_draw_points): Use Rectangle() instead of SetPixel(). Rectangle() uses the function (raster op) set for the HDC, SetPixel() doesn't. (widen_bounds): New function, refactoring. * gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code. (predraw_set_foreground, gdk_win32_hdc_get): Some code moved around. Call SetROP2() only if necessary. Call SetTextColor() only if GDK_GC_FOREGROUND flag present. Don't handle GDK_OPAQUE_STIPPLED here, has been superseded by the code in generic_draw(). Always create a solid brush. Remove background color handling from here. The background color of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill style, which it is already handled in generic_draw(), and GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly anyway. Calling SetBkColor() is unnecessary as we always use TRANSPARENT text output. (gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as these are public functions. * gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't synthesize expose events for GDK_INPUT_ONLY windows. (gdk_event_translate): On WM_SIZE, call gdk_synthesize_window_state() if window was iconified, restored or maximized. (#98983, Arnaud Charlet) * gtk+/gdk/win32/gdkwindow-win32.c (gdk_window_get_frame_extents): Fix typo in setting y. (#98983, Arnaud Charlet)
Diffstat (limited to 'gdk')
-rw-r--r--gdk/win32/gdkdrawable-win32.c823
-rw-r--r--gdk/win32/gdkevents-win32.c22
-rw-r--r--gdk/win32/gdkgc-win32.c269
-rw-r--r--gdk/win32/gdkwindow-win32.c2
4 files changed, 515 insertions, 601 deletions
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index 7af4cedb1..0a638d3fb 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -25,8 +25,6 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#define USE_GENERIC_DRAW
-
#include <math.h>
#include <stdio.h>
#include <glib.h>
@@ -41,6 +39,9 @@
#define ROP3_DPSao 0x00EA02E9
#define ROP3_DSna 0x00220326
+#define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
+ GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
+
static void gdk_win32_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
gboolean filled,
@@ -414,7 +415,7 @@ generic_draw (GdkDrawable *drawable,
{
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- HDC hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ HDC hdc;
va_list args;
va_start (args, region);
@@ -432,6 +433,8 @@ generic_draw (GdkDrawable *drawable,
gcwin32->values_mask & GDK_GC_STIPPLE &&
gcwin32->stipple != NULL)))
{
+ const GdkGCValuesMask blitting_mask = 0;
+ GdkGCValuesMask drawing_mask = GDK_GC_FOREGROUND;
gint ts_x_origin = 0, ts_y_origin = 0;
gint width = region->extents.x2 - region->extents.x1;
@@ -448,11 +451,16 @@ generic_draw (GdkDrawable *drawable,
GdkGC *tile_gc = gdk_gc_new (tile_pixmap);
HDC mask_hdc;
- HDC tile_hdc = CreateCompatibleDC (hdc);
+ HDC tile_hdc;
HGDIOBJ old_mask_hbm;
HGDIOBJ old_tile_hbm;
+ GdkGCValues gcvalues;
+
+ hdc = gdk_win32_hdc_get (drawable, gc, blitting_mask);
+ tile_hdc = CreateCompatibleDC (hdc);
+
if (gcwin32->values_mask & GDK_GC_TS_X_ORIGIN)
ts_x_origin = gc->ts_x_origin;
if (gcwin32->values_mask & GDK_GC_TS_Y_ORIGIN)
@@ -471,10 +479,32 @@ generic_draw (GdkDrawable *drawable,
fg.pixel = 1;
gdk_gc_set_foreground (mask_gc, &fg);
- mask_hdc = gdk_win32_hdc_get (mask_pixmap, mask_gc, GDK_GC_FOREGROUND);
+ /* If the drawing function uses line attributes, set them as in
+ * the real GC.
+ */
+ if (mask & LINE_ATTRIBUTES)
+ {
+ gdk_gc_get_values (gc, &gcvalues);
+ if (gcvalues.line_width != 0 ||
+ gcvalues.line_style != GDK_LINE_SOLID ||
+ gcvalues.cap_style != GDK_CAP_BUTT ||
+ gcvalues.join_style != GDK_JOIN_MITER)
+ gdk_gc_set_line_attributes (mask_gc,
+ gcvalues.line_width,
+ gcvalues.line_style,
+ gcvalues.cap_style,
+ gcvalues.join_style);
+ drawing_mask |= LINE_ATTRIBUTES;
+ }
+
+ /* Ditto, if the drawing function draws text, set up for that. */
+ if (mask & GDK_GC_FONT)
+ drawing_mask |= GDK_GC_FONT;
+
+ mask_hdc = gdk_win32_hdc_get (mask_pixmap, mask_gc, drawing_mask);
(*function) (GDK_GC_WIN32 (mask_gc), mask_hdc,
region->extents.x1, region->extents.y1, args);
- gdk_win32_hdc_release (mask_pixmap, mask_gc, GDK_GC_FOREGROUND);
+ gdk_win32_hdc_release (mask_pixmap, mask_gc, drawing_mask);
if (gcwin32->fill_style == GDK_TILED)
{
@@ -615,12 +645,31 @@ generic_draw (GdkDrawable *drawable,
GDI_CALL (DeleteDC, (tile_hdc));
gdk_drawable_unref (mask_pixmap);
gdk_drawable_unref (tile_pixmap);
+
+ gdk_win32_hdc_release (drawable, gc, blitting_mask);
}
else
- (*function) (gcwin32, hdc, 0, 0, args);
-
+ {
+ hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ (*function) (gcwin32, hdc, 0, 0, args);
+ gdk_win32_hdc_release (drawable, gc, mask);
+ }
va_end (args);
- gdk_win32_hdc_release (drawable, gc, mask);
+}
+
+static GdkRegion *
+widen_bounds (GdkRectangle *bounds,
+ gint pen_width)
+{
+ if (pen_width == 0)
+ pen_width = 1;
+
+ bounds->x -= pen_width;
+ bounds->y -= pen_width;
+ bounds->width += 2 * pen_width;
+ bounds->height += 2 * pen_width;
+
+ return gdk_region_rectangle (bounds);
}
static void
@@ -631,13 +680,13 @@ draw_rectangle (GdkGCWin32 *gcwin32,
va_list args)
{
HGDIOBJ old_pen_or_brush;
- gint filled;
+ gboolean filled;
gint x;
gint y;
gint width;
gint height;
- filled = va_arg (args, gint);
+ filled = va_arg (args, gboolean);
x = va_arg (args, gint);
y = va_arg (args, gint);
width = va_arg (args, gint);
@@ -690,11 +739,8 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable,
gint width,
gint height)
{
-#ifdef USE_GENERIC_DRAW
-
GdkRectangle bounds;
GdkRegion *region;
- gint pen_width;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n",
_gdk_win32_drawable_description (drawable),
@@ -702,158 +748,46 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable,
(filled ? "fill " : ""),
width, height, x, y));
- pen_width = GDK_GC_WIN32 (gc)->pen_width;
- if (pen_width == 0)
- pen_width = 1;
-
- bounds.x = x - pen_width;
- bounds.y = y - pen_width;
- bounds.width = width + 2 * pen_width;
- bounds.height = height + 2 * pen_width;
- region = gdk_region_rectangle (&bounds);
+ bounds.x = x;
+ bounds.y = y;
+ bounds.width = width;
+ bounds.height = height;
+ region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
- generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_BACKGROUND,
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
draw_rectangle, region, filled, x, y, width, height);
gdk_region_destroy (region);
-
-#else /* !USE_GENERIC_DRAW */
-
- GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
- HDC hdc;
- HGDIOBJ old_pen_or_brush;
- POINT pts[4];
- gboolean ok = TRUE;
-
- GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n",
- _gdk_win32_drawable_description (drawable),
- gcwin32,
- (filled ? "fill " : ""),
- width, height, x, y));
-
- if (filled
- && (gcwin32->values_mask & GDK_GC_TILE)
- && (gcwin32->tile)
- && (gcwin32->values_mask & GDK_GC_FILL)
- && (gcwin32->fill_style == GDK_TILED))
- {
- draw_tiles (drawable, gc, SRCCOPY,
- gcwin32->tile,
- x, y,
- gc->ts_x_origin,
- gc->ts_y_origin,
- width, height);
- return;
- }
-
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
-
- if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
- {
- if (!BeginPath (hdc))
- WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
-
- /* Win9x doesn't support Rectangle calls in a path,
- * thus use Polyline.
- */
-
- pts[0].x = x;
- pts[0].y = y;
- pts[1].x = x + width + 1;
- pts[1].y = y;
- pts[2].x = x + width + 1;
- pts[2].y = y + height + 1;
- pts[3].x = x;
- pts[3].y = y + height + 1;
-
- if (ok)
- MoveToEx (hdc, x, y, NULL);
-
- if (ok && !Polyline (hdc, pts, 4))
- WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
-
- if (ok && !CloseFigure (hdc))
- WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
-
- if (ok && !EndPath (hdc))
- WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
-
- if (ok && !filled)
- if (!WidenPath (hdc))
- WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
-
- if (ok && !FillPath (hdc))
- WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
- }
- else
- {
- if (!filled && gcwin32->pen_dashes && !IS_WIN_NT ())
- {
- ok = ok && render_line_vertical (hdc, x, y, y+height+1,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- ok = ok && render_line_horizontal (hdc, x, x+width+1, y,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- ok = ok && render_line_vertical (hdc, x+width+1, y, y+height+1,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- ok = ok && render_line_horizontal (hdc, x, x+width+1, y+height+1,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- }
- else
- {
- if (filled)
- old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN));
- else
- old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
- if (old_pen_or_brush == NULL)
- WIN32_GDI_FAILED ("SelectObject");
- if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
- WIN32_GDI_FAILED ("Rectangle");
- if (old_pen_or_brush)
- SelectObject (hdc, old_pen_or_brush);
- }
- }
-
- gdk_win32_hdc_release (drawable, gc, mask);
-
-#endif /* !USE_GENERIC_DRAW */
}
static void
-gdk_win32_draw_arc (GdkDrawable *drawable,
- GdkGC *gc,
- gboolean filled,
- gint x,
- gint y,
- gint width,
- gint height,
- gint angle1,
- gint angle2)
+draw_arc (GdkGCWin32 *gcwin32,
+ HDC hdc,
+ gint x_offset,
+ gint y_offset,
+ va_list args)
{
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
- HDC hdc;
+ HGDIOBJ old_pen;
+ gboolean filled;
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+ gint angle1;
+ gint angle2;
int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
- GDK_NOTE (MISC, g_print ("gdk_draw_arc: %s %d,%d,%d,%d %d %d\n",
- _gdk_win32_drawable_description (drawable),
- x, y, width, height, angle1, angle2));
-
- /* Seems that drawing arcs with width or height <= 2 fails, at least
- * with my TNT card.
- */
- if (width <= 2 || height <= 2 || angle2 == 0)
- return;
-
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ filled = va_arg (args, gboolean);
+ x = va_arg (args, gint);
+ y = va_arg (args, gint);
+ width = va_arg (args, gint);
+ height = va_arg (args, gint);
+ angle1 = va_arg (args, gint);
+ angle2 = va_arg (args, gint);
+ x -= x_offset;
+ y -= y_offset;
+
if (angle2 >= 360*64)
{
nXStartArc = nYStartArc = nXEndArc = nYEndArc = 0;
@@ -874,17 +808,16 @@ gdk_win32_draw_arc (GdkDrawable *drawable,
nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
}
- /* GDK_OPAQUE_STIPPLED arcs not implemented. */
-
if (filled)
{
+ old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
x, y, x+width, y+height,
nXStartArc, nYStartArc,
nXEndArc, nYEndArc));
- if (!Pie (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- WIN32_GDI_FAILED ("Pie");
+ GDI_CALL (Pie, (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc));
+ GDI_CALL (SelectObject, (hdc, old_pen));
}
else
{
@@ -892,11 +825,71 @@ gdk_win32_draw_arc (GdkDrawable *drawable,
x, y, x+width, y+height,
nXStartArc, nYStartArc,
nXEndArc, nYEndArc));
- if (!Arc (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- WIN32_GDI_FAILED ("Arc");
+ GDI_CALL (Arc, (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc));
}
- gdk_win32_hdc_release (drawable, gc, mask);
+}
+
+static void
+gdk_win32_draw_arc (GdkDrawable *drawable,
+ GdkGC *gc,
+ gboolean filled,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ gint angle1,
+ gint angle2)
+{
+ GdkRectangle bounds;
+ GdkRegion *region;
+
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_arc: %s %d,%d,%d,%d %d %d\n",
+ _gdk_win32_drawable_description (drawable),
+ x, y, width, height, angle1, angle2));
+
+ if (width <= 2 || height <= 2 || angle2 == 0)
+ return;
+
+ bounds.x = x;
+ bounds.y = y;
+ bounds.width = width;
+ bounds.height = height;
+ region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
+
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
+ draw_arc, region, filled, x, y, width, height, angle1, angle2);
+
+ gdk_region_destroy (region);
+}
+
+static void
+draw_polygon (GdkGCWin32 *gcwin32,
+ HDC hdc,
+ gint x_offset,
+ gint y_offset,
+ va_list args)
+{
+ gboolean filled;
+ POINT *pts;
+ gint npoints;
+ gint i;
+
+ filled = va_arg (args, gboolean);
+ pts = va_arg (args, POINT *);
+ npoints = va_arg (args, gint);
+
+ if (x_offset != 0 || y_offset != 0)
+ for (i = 0; i < npoints; i++)
+ {
+ pts[i].x -= x_offset;
+ pts[i].y -= y_offset;
+ }
+
+ if (filled)
+ GDI_CALL (Polygon, (hdc, pts, npoints));
+ else
+ GDI_CALL (Polyline, (hdc, pts, npoints));
}
static void
@@ -906,80 +899,50 @@ gdk_win32_draw_polygon (GdkDrawable *drawable,
GdkPoint *points,
gint npoints)
{
- GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
- HDC hdc;
+ GdkRectangle bounds;
+ GdkRegion *region;
POINT *pts;
- gboolean ok = TRUE;
int i;
- GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %s (%p) %d\n",
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %s %d points\n",
_gdk_win32_drawable_description (drawable),
- gcwin32,
npoints));
if (npoints < 2)
return;
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ bounds.x = G_MAXINT;
+ bounds.y = G_MAXINT;
+ bounds.width = 0;
+ bounds.height = 0;
+
pts = g_new (POINT, npoints+1);
for (i = 0; i < npoints; i++)
{
+ bounds.x = MIN (bounds.x, points[i].x);
+ bounds.y = MIN (bounds.y, points[i].y);
+ bounds.width = MAX (bounds.width, points[i].x - bounds.x);
+ bounds.height = MAX (bounds.height, points[i].y - bounds.y);
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
-
- if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
- {
- if (!BeginPath (hdc))
- WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
-
- if (ok)
- MoveToEx (hdc, points[0].x, points[0].y, NULL);
-
- if (pts[0].x == pts[npoints-1].x && pts[0].y == pts[npoints-1].y)
- npoints--;
- if (ok && !Polyline (hdc, pts, 4))
- WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
-
- if (ok && !CloseFigure (hdc))
- WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
-
- if (ok && !EndPath (hdc))
- WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
-
- if (ok && !filled)
- if (!WidenPath (hdc))
- WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
-
- if (ok && !FillPath (hdc))
- WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
- }
- else
+ if (points[0].x != points[npoints-1].x ||
+ points[0].y != points[npoints-1].y)
{
- if (points[0].x != points[npoints-1].x
- || points[0].y != points[npoints-1].y)
- {
- pts[npoints].x = points[0].x;
- pts[npoints].y = points[0].y;
- npoints++;
- }
-
- if (filled)
- {
- if (!Polygon (hdc, pts, npoints))
- WIN32_GDI_FAILED ("Polygon");
- }
- else
- {
- if (!Polyline (hdc, pts, npoints))
- WIN32_GDI_FAILED ("Polyline");
- }
+ pts[npoints].x = points[0].x;
+ pts[npoints].y = points[0].y;
+ npoints++;
}
+
+ region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
+
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
+ draw_polygon, region, filled, pts, npoints);
+
+ gdk_region_destroy (region);
g_free (pts);
- gdk_win32_hdc_release (drawable, gc, mask);
}
typedef struct
@@ -1038,7 +1001,7 @@ gdk_win32_draw_text (GdkDrawable *drawable,
arg.y = y;
arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
- GDK_NOTE (MISC, g_print ("gdk_draw_text: %s (%d,%d) \"%.*s\" (len %d)\n",
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_text: %s (%d,%d) \"%.*s\" (len %d)\n",
_gdk_win32_drawable_description (drawable),
x, y,
(text_length > 10 ? 10 : text_length),
@@ -1087,7 +1050,7 @@ gdk_win32_draw_text_wc (GdkDrawable *drawable,
arg.y = y;
arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
- GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %s (%d,%d) len: %d\n",
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_text_wc: %s (%d,%d) len: %d\n",
_gdk_win32_drawable_description (drawable),
x, y, text_length));
@@ -1134,263 +1097,245 @@ gdk_win32_draw_points (GdkDrawable *drawable,
gint npoints)
{
HDC hdc;
- COLORREF fg;
- GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
+ HGDIOBJ old_pen;
int i;
- hdc = gdk_win32_hdc_get (drawable, gc, 0);
+ hdc = gdk_win32_hdc_get (drawable, gc, GDK_GC_FOREGROUND);
- fg = _gdk_win32_colormap_color (impl->colormap, gcwin32->foreground);
-
- GDK_NOTE (MISC, g_print ("gdk_draw_points: %s %dx%.06x\n",
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_points: %s %d points\n",
_gdk_win32_drawable_description (drawable),
- npoints, (guint) fg));
+ npoints));
+
+ /* The X11 version uses XDrawPoint(), which doesn't use the fill
+ * mode, so don't use generic_draw. But we should use the current
+ * function, so we can't use SetPixel(). Draw single-pixel
+ * rectangles (sigh).
+ */
+ old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
for (i = 0; i < npoints; i++)
- SetPixel (hdc, points[i].x, points[i].y, fg);
+ Rectangle (hdc, points[i].x, points[i].y,
+ points[i].x + 2, points[i].y + 2);
- gdk_win32_hdc_release (drawable, gc, 0);
+ SelectObject (hdc, old_pen);
+ gdk_win32_hdc_release (drawable, gc, GDK_GC_FOREGROUND);
}
static void
-gdk_win32_draw_segments (GdkDrawable *drawable,
- GdkGC *gc,
- GdkSegment *segs,
- gint nsegs)
+draw_segments (GdkGCWin32 *gcwin32,
+ HDC hdc,
+ gint x_offset,
+ gint y_offset,
+ va_list args)
{
- GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
- HDC hdc;
- gboolean ok = TRUE;
- int i;
+ GdkSegment *segs;
+ gint nsegs;
+ gint i;
- GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %s nsegs: %d\n",
- _gdk_win32_drawable_description (drawable), nsegs));
+ segs = va_arg (args, GdkSegment *);
+ nsegs = va_arg (args, gint);
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ if (x_offset != 0 || y_offset != 0)
+ for (i = 0; i < nsegs; i++)
+ {
+ segs[i].x1 -= x_offset;
+ segs[i].y1 -= y_offset;
+ segs[i].x2 -= x_offset;
+ segs[i].y2 -= y_offset;
+ }
- if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
+ if (gcwin32->pen_dashes && !IS_WIN_NT ())
{
- if (!BeginPath (hdc))
- WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
-
- for (i = 0; ok && i < nsegs; i++)
+ for (i = 0; i < nsegs; i++)
{
- if (ok && !MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
- WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
- if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
-
- /* Draw end pixel */
- if (ok && gcwin32->pen_width <= 1)
- if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+ if (segs[i].x1 == segs[i].x2)
+ {
+ int y1, y2;
+
+ if (segs[i].y1 <= segs[i].y2)
+ y1 = segs[i].y1, y2 = segs[i].y2;
+ else
+ y1 = segs[i].y2, y2 = segs[i].y1;
+
+ render_line_vertical (hdc,
+ segs[i].x1, y1, y2,
+ gcwin32->pen_width,
+ gcwin32->pen_dashes,
+ gcwin32->pen_num_dashes);
+ }
+ else if (segs[i].y1 == segs[i].y2)
+ {
+ int x1, x2;
+
+ if (segs[i].x1 <= segs[i].x2)
+ x1 = segs[i].x1, x2 = segs[i].x2;
+ else
+ x1 = segs[i].x2, x2 = segs[i].x1;
+
+ render_line_horizontal (hdc,
+ x1, x2, segs[i].y1,
+ gcwin32->pen_width,
+ gcwin32->pen_dashes,
+ gcwin32->pen_num_dashes);
+ }
+ else
+ GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
+ GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2)) &&
+ (gcwin32->pen_width <= 1 &&
+ GDI_CALL (LineTo, (hdc, segs[i].x2 + 1, segs[i].y2 + 1)));
}
-
- if (ok && !EndPath (hdc))
- WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
-
- if (ok && !WidenPath (hdc))
- WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
-
- if (ok && !FillPath (hdc))
- WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
}
else
{
- if (gcwin32->pen_dashes && !IS_WIN_NT ())
- {
- /* code very similar to the IMHO questionable optimization
- * below. This one draws dashed vertical/horizontal lines
- * with the limited Win9x GDI. --hb
- */
- for (i = 0; ok && i < nsegs; i++)
- {
- if (segs[i].x1 == segs[i].x2)
- {
- int y1, y2;
-
- if (segs[i].y1 <= segs[i].y2)
- y1 = segs[i].y1, y2 = segs[i].y2;
- else
- y1 = segs[i].y2, y2 = segs[i].y1;
-
- ok = render_line_vertical (hdc,
- segs[i].x1, y1, y2,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- }
- else if (segs[i].y1 == segs[i].y2)
- {
- int x1, x2;
-
- if (segs[i].x1 <= segs[i].x2)
- x1 = segs[i].x1, x2 = segs[i].x2;
- else
- x1 = segs[i].x2, x2 = segs[i].x1;
-
- ok = render_line_horizontal (hdc,
- x1, x2, segs[i].y1,
- gcwin32->pen_width,
- gcwin32->pen_dashes,
- gcwin32->pen_num_dashes);
- }
- else
- {
- if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
- WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
- if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
-
- /* Draw end pixel */
- if (ok && gcwin32->pen_width <= 1)
- if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
- }
- }
- }
- else
- {
- const gboolean maybe_patblt =
- gcwin32->rop2 == R2_COPYPEN &&
- gcwin32->pen_width <= 1 &&
- (gcwin32->pen_style & PS_STYLE_MASK) == PS_SOLID;
-
- for (i = 0; ok && i < nsegs; i++)
- {
- /* PatBlt() is much faster than LineTo(), says
- * jpe@archaeopteryx.com. Hmm. Use it if we have a solid
- * colour pen, then we know that the brush is also solid and
- * of the same colour.
- */
- if (maybe_patblt && segs[i].x1 == segs[i].x2)
- {
- int y1, y2;
-
- if (segs[i].y1 <= segs[i].y2)
- y1 = segs[i].y1, y2 = segs[i].y2;
- else
- y1 = segs[i].y2, y2 = segs[i].y1;
-
- if (!PatBlt (hdc, segs[i].x1, y1,
- 1, y2 - y1 + 1, PATCOPY))
- WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
- }
- else if (maybe_patblt && segs[i].y1 == segs[i].y2)
- {
- int x1, x2;
-
- if (segs[i].x1 <= segs[i].x2)
- x1 = segs[i].x1, x2 = segs[i].x2;
- else
- x1 = segs[i].x2, x2 = segs[i].x1;
-
- if (!PatBlt (hdc, x1, segs[i].y1,
- x2 - x1 + 1, 1, PATCOPY))
- WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
- }
- else
- {
- if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
- WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
- if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
-
- /* Draw end pixel */
- if (ok && gcwin32->pen_width <= 1)
- if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
- }
- }
- }
+ for (i = 0; i < nsegs; i++)
+ GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
+ GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2)) &&
+ (gcwin32->pen_width <= 1 &&
+ GDI_CALL (LineTo, (hdc, segs[i].x2 + 1, segs[i].y2 + 1)));
}
- gdk_win32_hdc_release (drawable, gc, mask);
}
static void
-gdk_win32_draw_lines (GdkDrawable *drawable,
- GdkGC *gc,
- GdkPoint *points,
- gint npoints)
+gdk_win32_draw_segments (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *segs,
+ gint nsegs)
{
- GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
- HDC hdc;
- POINT *pts;
- int i;
- gboolean ok = TRUE;
+ GdkRectangle bounds;
+ GdkRegion *region;
+ gint i;
- if (npoints < 2)
- return;
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %s %d segs\n",
+ _gdk_win32_drawable_description (drawable),
+ nsegs));
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
+ bounds.x = G_MAXINT;
+ bounds.y = G_MAXINT;
+ bounds.width = 0;
+ bounds.height = 0;
+ for (i = 0; i < nsegs; i++)
+ {
+ bounds.x = MIN (bounds.x, segs[i].x1);
+ bounds.x = MIN (bounds.x, segs[i].x2);
+ bounds.y = MIN (bounds.y, segs[i].y1);
+ bounds.y = MIN (bounds.y, segs[i].y2);
+ bounds.width = MAX (bounds.width, segs[i].x1 - bounds.x);
+ bounds.width = MAX (bounds.width, segs[i].x2 - bounds.x);
+ bounds.height = MAX (bounds.height, segs[i].y1 - bounds.y);
+ bounds.height = MAX (bounds.height, segs[i].y2 - bounds.y);
+ }
+
+ region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
+
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
+ draw_segments, region, segs, nsegs);
+
+ gdk_region_destroy (region);
+}
+
+static void
+draw_lines (GdkGCWin32 *gcwin32,
+ HDC hdc,
+ gint x_offset,
+ gint y_offset,
+ va_list args)
+{
+ POINT *pts;
+ gint npoints;
+ gint i;
+
+ pts = va_arg (args, POINT *);
+ npoints = va_arg (args, gint);
+
+ if (x_offset != 0 || y_offset != 0)
+ for (i = 0; i < npoints; i++)
+ {
+ pts[i].x -= x_offset;
+ pts[i].y -= y_offset;
+ }
+
if (gcwin32->pen_dashes && !IS_WIN_NT ())
{
for (i = 0; i < npoints - 1; i++)
{
- if (points[i].x == points[i+1].x)
+ if (pts[i].x == pts[i+1].x)
{
int y1, y2;
- if (points[i].y > points[i+1].y)
- y1 = points[i+1].y, y2 = points[i].y;
+ if (pts[i].y > pts[i+1].y)
+ y1 = pts[i+1].y, y2 = pts[i].y;
else
- y1 = points[i].y, y2 = points[i+1].y;
-
- render_line_vertical (hdc, points[i].x, y1, y2,
+ y1 = pts[i].y, y2 = pts[i+1].y;
+
+ render_line_vertical (hdc, pts[i].x, y1, y2,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
}
- else if (points[i].y == points[i+1].y)
+ else if (pts[i].y == pts[i+1].y)
{
int x1, x2;
- if (points[i].x > points[i+1].x)
- x1 = points[i+1].x, x2 = points[i].x;
+ if (pts[i].x > pts[i+1].x)
+ x1 = pts[i+1].x, x2 = pts[i].x;
else
- x1 = points[i].x, x2 = points[i+1].x;
+ x1 = pts[i].x, x2 = pts[i+1].x;
- render_line_horizontal (hdc, x1, x2, points[i].y,
+ render_line_horizontal (hdc, x1, x2, pts[i].y,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
}
else
- {
- if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
- WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
- if (ok && !LineTo (hdc, points[i+1].x, points[i+1].y))
- WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
- }
+ GDI_CALL (MoveToEx, (hdc, pts[i].x, pts[i].y, NULL)) &&
+ GDI_CALL (LineTo, (hdc, pts[i+1].x, pts[i+1].y));
}
}
else
- {
- pts = g_new (POINT, npoints);
+ GDI_CALL (Polyline, (hdc, pts, npoints));
+}
- for (i = 0; i < npoints; i++)
- {
- pts[i].x = points[i].x;
- pts[i].y = points[i].y;
- }
-
- if (!Polyline (hdc, pts, npoints))
- WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
-
- g_free (pts);
-
- /* Draw end pixel */
- if (ok && gcwin32->pen_width <= 1)
- {
- MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
- if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
- WIN32_GDI_FAILED ("LineTo");
- }
+static void
+gdk_win32_draw_lines (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPoint *points,
+ gint npoints)
+{
+ GdkRectangle bounds;
+ GdkRegion *region;
+ POINT *pts;
+ int i;
+
+ GDK_NOTE (MISC, g_print ("gdk_win32_draw_lines: %s %d points\n",
+ _gdk_win32_drawable_description (drawable),
+ npoints));
+
+ if (npoints < 2)
+ return;
+
+ bounds.x = G_MAXINT;
+ bounds.y = G_MAXINT;
+ bounds.width = 0;
+ bounds.height = 0;
+
+ pts = g_new (POINT, npoints);
+
+ for (i = 0; i < npoints; i++)
+ {
+ bounds.x = MIN (bounds.x, points[i].x);
+ bounds.y = MIN (bounds.y, points[i].y);
+ bounds.width = MAX (bounds.width, points[i].x - bounds.x);
+ bounds.height = MAX (bounds.height, points[i].y - bounds.y);
+ pts[i].x = points[i].x;
+ pts[i].y = points[i].y;
}
- gdk_win32_hdc_release (drawable, gc, mask);
+ region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
+
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
+ draw_lines, region, pts, npoints);
+
+ gdk_region_destroy (region);
+ g_free (pts);
}
static void
@@ -1413,13 +1358,6 @@ draw_glyphs (GdkGCWin32 *gcwin32,
x -= x_offset;
y -= y_offset;
- /* HB: Maybe there should be a GDK_GC_PANGO flag for hdc_get */
- /* default write mode is transparent (leave background) */
- GDI_CALL (SetBkMode, (hdc, TRANSPARENT));
-
- if (GDI_ERROR == SetTextAlign (hdc, TA_LEFT|TA_BASELINE|TA_NOUPDATECP))
- WIN32_GDI_FAILED ("SetTextAlign");
-
pango_win32_render (hdc, font, glyphs, x, y);
}
@@ -1431,8 +1369,6 @@ gdk_win32_draw_glyphs (GdkDrawable *drawable,
gint y,
PangoGlyphString *glyphs)
{
-#ifdef USE_GENERIC_DRAW
-
GdkRectangle bounds;
GdkRegion *region;
PangoRectangle ink_rect;
@@ -1445,31 +1381,10 @@ gdk_win32_draw_glyphs (GdkDrawable *drawable,
bounds.height = PANGO_PIXELS (ink_rect.height) + 2;
region = gdk_region_rectangle (&bounds);
- generic_draw (drawable, gc, GDK_GC_FOREGROUND,
+ generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT,
draw_glyphs, region, font, x, y, glyphs);
gdk_region_destroy (region);
-
-#else
-
- const GdkGCValuesMask mask = GDK_GC_FOREGROUND;
- HDC hdc;
-
- hdc = gdk_win32_hdc_get (drawable, gc, mask);
-
- /* HB: Maybe there should be a GDK_GC_PANGO flag for hdc_get */
- /* default write mode is transparent (leave background) */
- if (SetBkMode (hdc, TRANSPARENT) == 0)
- WIN32_GDI_FAILED ("SetBkMode");
-
- if (GDI_ERROR == SetTextAlign (hdc, TA_LEFT|TA_BASELINE|TA_NOUPDATECP))
- WIN32_GDI_FAILED ("SetTextAlign");
-
- pango_win32_render (hdc, font, glyphs, x, y);
-
- gdk_win32_hdc_release (drawable, gc, mask);
-
-#endif
}
static void
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index f500871e0..586e0a75d 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1368,7 +1368,9 @@ synthesize_expose_events (GdkWindow *window)
g_list_free (head);
- if (!(hdc = GetDC (impl->handle)))
+ if (((GdkWindowObject *) window)->input_only)
+ ;
+ else if (!(hdc = GetDC (impl->handle)))
WIN32_GDI_FAILED ("GetDC");
else
{
@@ -2979,6 +2981,11 @@ gdk_event_translate (GdkDisplay *display,
if (k_grab_window == window)
gdk_keyboard_ungrab (msg->time);
+ if (window && GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_MAXIMIZED,
+ GDK_WINDOW_STATE_ICONIFIED);
+
return_val = !GDK_WINDOW_DESTROYED (window);
}
else if ((msg->wParam == SIZE_RESTORED
@@ -2988,9 +2995,6 @@ gdk_event_translate (GdkDisplay *display,
#endif
)
{
- if (LOWORD (msg->lParam) == 0)
- break;
-
event->configure.type = GDK_CONFIGURE;
event->configure.window = window;
pt.x = 0;
@@ -3005,6 +3009,16 @@ gdk_event_translate (GdkDisplay *display,
GDK_WINDOW_IMPL_WIN32 (private->impl)->width = event->configure.width;
GDK_WINDOW_IMPL_WIN32 (private->impl)->height = event->configure.height;
+ if (msg->wParam == SIZE_RESTORED)
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_ICONIFIED |
+ GDK_WINDOW_STATE_MAXIMIZED,
+ 0);
+ else if (msg->wParam == SIZE_MAXIMIZED)
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_ICONIFIED,
+ GDK_WINDOW_STATE_MAXIMIZED);
+
if (private->resize_count > 1)
private->resize_count -= 1;
diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c
index e3dde1efb..70c1ad2da 100644
--- a/gdk/win32/gdkgc-win32.c
+++ b/gdk/win32/gdkgc-win32.c
@@ -25,6 +25,9 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
+ GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
+
#include <string.h>
#include "gdkgc.h"
@@ -767,15 +770,12 @@ _gdk_win32_colormap_color (GdkColormap *colormap,
}
}
-static void
+static COLORREF
predraw_set_foreground (GdkGC *gc,
GdkColormap *colormap,
gboolean *ok)
{
COLORREF fg;
- LOGBRUSH logbrush;
- HPEN hpen;
- HBRUSH hbr;
GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
GdkColormapPrivateWin32 *colormap_private;
gint k;
@@ -800,92 +800,59 @@ predraw_set_foreground (GdkGC *gc,
fg = _gdk_win32_colormap_color (colormap, win32_gc->foreground);
GDK_NOTE (GC, g_print ("predraw_set_foreground: fg=%06lx\n", fg));
-
- if (SetTextColor (win32_gc->hdc, fg) == CLR_INVALID)
- WIN32_GDI_FAILED ("SetTextColor"), *ok = FALSE;
-
- /* Create and select pen and brush. */
-
- logbrush.lbStyle = BS_SOLID;
- logbrush.lbColor = fg;
- logbrush.lbHatch = 0;
-
- if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ())
- {
- /* The Win9x GDI is rather limited so we either draw dotted
- * lines ourselve (only horizontal and vertical) or let them
- * be drawn solid to avoid implementing a whole line renderer
- */
- if (*ok && (hpen = ExtCreatePen (
- (win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
- (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
- &logbrush,
- 0, NULL)) == NULL)
- WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
- }
- else
- {
- if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style,
- (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
- &logbrush,
- win32_gc->pen_num_dashes,
- win32_gc->pen_dashes)) == NULL)
- WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
- }
-
- if (*ok && SelectObject (win32_gc->hdc, hpen) == NULL)
- WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE;
-
- switch (win32_gc->fill_style)
- {
- case GDK_OPAQUE_STIPPLED:
- if (*ok && (hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (win32_gc->stipple))) == NULL)
- WIN32_GDI_FAILED ("CreatePatternBrush"), *ok = FALSE;
- if (*ok && win32_gc->values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN) &&
- !SetBrushOrgEx(win32_gc->hdc,
- win32_gc->values_mask & GDK_GC_TS_X_ORIGIN ? gc->ts_x_origin : 0,
- win32_gc->values_mask & GDK_GC_TS_Y_ORIGIN ? gc->ts_y_origin : 0,
- NULL))
- WIN32_GDI_FAILED ("SetBrushOrgEx"), *ok = FALSE;
-
- break;
-
- case GDK_SOLID:
- default:
- if (*ok && (hbr = CreateSolidBrush (fg)) == NULL)
- WIN32_GDI_FAILED ("CreateSolidBrush"), *ok = FALSE;
- break;
- }
-
- if (*ok)
- {
- HBRUSH old_hbr = SelectObject (win32_gc->hdc, hbr);
- if (old_hbr == NULL)
- WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE;
- }
-}
-
-static void
-predraw_set_background (GdkGC *gc,
- GdkColormap *colormap,
- gboolean *ok)
-{
- GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
-
- if (win32_gc->values_mask & GDK_GC_BACKGROUND)
- {
- COLORREF bg = _gdk_win32_colormap_color (colormap, win32_gc->background);
-
- if (SetBkColor (win32_gc->hdc, bg) == CLR_INVALID)
- WIN32_GDI_FAILED ("SetBkColor"), *ok = FALSE;
- }
- else
- {
- if (!SetBkMode (win32_gc->hdc, TRANSPARENT))
- WIN32_GDI_FAILED ("SetBkMode"), *ok = FALSE;
- }
+ return fg;
}
+/**
+ * gdk_win32_hdc_get:
+ * @drawable: destination #GdkDrawable
+ * @gc: #GdkGC to use for drawing on @drawable
+ * @usage: mask indicating what properties needs to be set up
+ *
+ * Allocates a Windows device context handle (HDC) for drawing into
+ * @drawable, and sets it up appropriately according to @usage.
+ *
+ * Each #GdkGC can at one time have only one HDC associated with it.
+ *
+ * The following flags in @mask are handled:
+ *
+ * If %GDK_GC_FOREGROUND is set in @mask, a solid brush of the
+ * foreground color in @gc is selected into the HDC. The text color of
+ * the HDC is also set. If the @drawable has a palette (256-color
+ * mode), the palette is selected and realized.
+ *
+ * If any of the line attribute flags (%GDK_GC_LINE_WIDTH,
+ * %GDK_GC_LINE_STYLE, %GDK_GC_CAP_STYLE and %GDK_GC_JOIN_STYLE) is
+ * set in @mask, a solid pen of the foreground color and appropriate
+ * width and stule is created and selected into the HDC. Note that the
+ * dash properties are not completely implemented.
+ *
+ * If the %GDK_GC_FONT flag is set, the background mix mode is set to
+ * %TRANSPARENT. and the text alignment is set to
+ * %TA_BASELINE|%TA_LEFT. Note that no font gets selected into the HDC
+ * by this function.
+ *
+ * Some things are done regardless of @mask: If the function in @gc is
+ * any other than %GDK_COPY, the raster operation of the HDC is
+ * set. If @gc has a clip mask, the clip region of the HDC is set.
+ *
+ * Note that the fill style, tile, stipple, and tile and stipple
+ * origins in the @gc are ignored by this function. (In general, tiles
+ * and stipples can't be implemented directly on Win32; you need to do
+ * multiple pass drawing and blitting to implement tiles or
+ * stipples. GDK does just that when you call the GDK drawing
+ * functions with a GC that asks for tiles or stipples.)
+ *
+ * When the HDC is no longer used, it should be released by calling
+ * <function>gdk_win32_hdc_release()</function> with the same
+ * parameters.
+ *
+ * If you modify the HDC by calling <function>SelectObject</function>
+ * you should undo those modifications before calling
+ * <function>gdk_win32_hdc_release()</function>.
+ *
+ * Return value: The HDC.
+ **/
HDC
gdk_win32_hdc_get (GdkDrawable *drawable,
GdkGC *gc,
@@ -894,6 +861,10 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
GdkDrawableImplWin32 *impl = NULL;
gboolean ok = TRUE;
+ COLORREF fg = RGB (0, 0, 0);
+ LOGBRUSH logbrush;
+ HPEN hpen;
+ HBRUSH hbr;
g_assert (win32_gc->hdc == NULL);
@@ -929,21 +900,62 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
}
if (ok && (usage & GDK_GC_FOREGROUND))
- predraw_set_foreground (gc, impl->colormap, &ok);
+ {
+ fg = predraw_set_foreground (gc, impl->colormap, &ok);
+ if (ok && (hbr = CreateSolidBrush (fg)) == NULL)
+ WIN32_GDI_FAILED ("CreateSolidBrush"), ok = FALSE;
+
+ if (ok && SelectObject (win32_gc->hdc, hbr) == NULL)
+ WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
+
+ if (ok && SetTextColor (win32_gc->hdc, fg) == CLR_INVALID)
+ WIN32_GDI_FAILED ("SetTextColor"), ok = FALSE;
+ }
+
+ if (ok && (usage & LINE_ATTRIBUTES))
+ {
+ /* Create and select pen */
+ logbrush.lbStyle = BS_SOLID;
+ logbrush.lbColor = fg;
+ logbrush.lbHatch = 0;
+
+ if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ())
+ {
+ /* The Win9x GDI is rather limited so we either draw dashed
+ * lines ourselves (only horizontal and vertical) or let them be
+ * drawn solid to avoid implementing a whole line renderer.
+ */
+ if ((hpen = ExtCreatePen (
+ (win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
+ MAX (win32_gc->pen_width, 1),
+ &logbrush,
+ 0, NULL)) == NULL)
+ WIN32_GDI_FAILED ("ExtCreatePen"), ok = FALSE;
+ }
+ else
+ {
+ if ((hpen = ExtCreatePen (win32_gc->pen_style,
+ MAX (win32_gc->pen_width, 1),
+ &logbrush,
+ win32_gc->pen_num_dashes,
+ win32_gc->pen_dashes)) == NULL)
+ WIN32_GDI_FAILED ("ExtCreatePen"), ok = FALSE;
+ }
+
+ if (ok && SelectObject (win32_gc->hdc, hpen) == NULL)
+ WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
+ }
- if (ok && (usage & GDK_GC_BACKGROUND))
- predraw_set_background (gc, impl->colormap, &ok);
-
if (ok && (usage & GDK_GC_FONT))
{
if (SetBkMode (win32_gc->hdc, TRANSPARENT) == 0)
WIN32_GDI_FAILED ("SetBkMode"), ok = FALSE;
- if (ok && SetTextAlign (win32_gc->hdc, TA_BASELINE) == GDI_ERROR)
+ if (ok && SetTextAlign (win32_gc->hdc, TA_BASELINE|TA_LEFT|TA_NOUPDATECP) == GDI_ERROR)
WIN32_GDI_FAILED ("SetTextAlign"), ok = FALSE;
}
- if (ok && (win32_gc->values_mask & GDK_GC_FUNCTION))
+ if (ok && win32_gc->rop2 != R2_COPYPEN)
if (SetROP2 (win32_gc->hdc, win32_gc->rop2) == 0)
WIN32_GDI_FAILED ("SetROP2"), ok = FALSE;
@@ -954,33 +966,6 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
if (SelectClipRgn (win32_gc->hdc, win32_gc->hcliprgn) == ERROR)
WIN32_API_FAILED ("SelectClipRgn"), ok = FALSE;
-#if 0 /* No, this is totally bogus. The stipple should replicate in x
- * and y directions, not be just one copy of the bitmap. We must
- * handle stipples elsewhere.
- */
- /* Combine the fillmode-stipple with the clip region */
- if (ok &&
- (win32_gc->values_mask & GDK_GC_STIPPLE) &&
- (win32_gc->values_mask & GDK_GC_FILL) &&
- (win32_gc->fill_style == GDK_STIPPLED))
- {
- HRGN hstipplergn;
-
- if ((hstipplergn = _gdk_win32_bitmap_to_hrgn (win32_gc->stipple)) == NULL)
- ;
- else if (win32_gc->values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN) &&
- OffsetRgn (hstipplergn,
- win32_gc->values_mask & GDK_GC_TS_X_ORIGIN ? gc->ts_x_origin : 0,
- win32_gc->values_mask & GDK_GC_TS_Y_ORIGIN ? gc->ts_y_origin : 0) == ERROR)
- WIN32_API_FAILED ("OffsetRgn");
- else if (ExtSelectClipRgn (win32_gc->hdc, hstipplergn, RGN_AND) == ERROR)
- WIN32_API_FAILED ("ExtSelectClipRgn");
-
- if (hstipplergn != NULL && !DeleteObject (hstipplergn))
- WIN32_API_FAILED ("DeleteObject");
- }
-#endif
-
if (ok && win32_gc->values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN) &&
OffsetClipRgn (win32_gc->hdc,
win32_gc->values_mask & GDK_GC_CLIP_X_ORIGIN ? gc->clip_x_origin : 0,
@@ -995,6 +980,16 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
return win32_gc->hdc;
}
+/**
+ * gdk_win32_hdc_release:
+ * @drawable: destination #GdkDrawable
+ * @gc: #GdkGC to use for drawing on @drawable
+ * @usage: mask indicating what properties were set up
+ *
+ * This function deallocates the Windows device context allocated by
+ * <funcion>gdk_win32_hdc_get()</function>. It should be called with
+ * the same parameters.
+ **/
void
gdk_win32_hdc_release (GdkDrawable *drawable,
GdkGC *gc,
@@ -1032,36 +1027,26 @@ gdk_win32_hdc_release (GdkDrawable *drawable,
win32_gc->holdpal = NULL;
}
+ if (usage & LINE_ATTRIBUTES)
+ if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL)
+ WIN32_GDI_FAILED ("GetCurrentObject");
+
if (usage & GDK_GC_FOREGROUND)
- {
- if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL)
- WIN32_GDI_FAILED ("GetCurrentObject");
-
- if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL)
- WIN32_GDI_FAILED ("GetCurrentObject");
- }
+ if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL)
+ WIN32_GDI_FAILED ("GetCurrentObject");
- if (!RestoreDC (win32_gc->hdc, win32_gc->saved_dc))
- WIN32_GDI_FAILED ("RestoreDC");
+ GDI_CALL (RestoreDC, (win32_gc->hdc, win32_gc->saved_dc));
if (GDK_IS_PIXMAP_IMPL_WIN32 (impl))
- {
- if (!DeleteDC (win32_gc->hdc))
- WIN32_GDI_FAILED ("DeleteDC");
- }
+ GDI_CALL (DeleteDC, (win32_gc->hdc));
else
- {
- if (!ReleaseDC (win32_gc->hwnd, win32_gc->hdc))
- WIN32_GDI_FAILED ("ReleaseDC");
- }
+ GDI_CALL (ReleaseDC, (win32_gc->hwnd, win32_gc->hdc));
if (hpen != NULL)
- if (!DeleteObject (hpen))
- WIN32_GDI_FAILED ("DeleteObject");
+ GDI_CALL (DeleteObject, (hpen));
if (hbr != NULL)
- if (!DeleteObject (hbr))
- WIN32_GDI_FAILED ("DeleteObject");
+ GDI_CALL (DeleteObject, (hbr));
win32_gc->hdc = NULL;
}
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 0bcaa2aaf..182126355 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1850,7 +1850,7 @@ gdk_window_get_frame_extents (GdkWindow *window,
WIN32_API_FAILED ("GetWindowRect");
rect->x = r.left;
- rect->y = r.right;
+ rect->y = r.top;
rect->width = r.right - r.left;
rect->height = r.bottom - r.top;
}