summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorTor Lillqvist <tml@src.gnome.org>1999-07-10 00:26:54 +0000
committerTor Lillqvist <tml@src.gnome.org>1999-07-10 00:26:54 +0000
commitc9b2958b6c64583a74ac566824646ad4b59628af (patch)
tree52850e54ec2e13f4382301cd84b01f49c544c676 /gdk
parent68f895bd68e08c538db73dccec428d09aa96988e (diff)
downloadgtk+-c9b2958b6c64583a74ac566824646ad4b59628af.tar.gz
Don't draw anything if width or height is zero. Don't print a warning if
* gdk/win32/gdkdraw.c (gdk_draw_arc): Don't draw anything if width or height is zero. Don't print a warning if Pie or Arc fails, they always fail (?) for very narrow ellipses. * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Call InvalidateRgn for the part or the destination window corresponding to source area outside of the source drawable's boundary. * gdk/win32/gdkdraw.c (gdk_draw_lines, gdk_draw_polygon): Don't do anything if less than two points. * gdk/win32/gdkselection.c (gdk_selection_owner_get): Always return NULL. Gtk cut-and-paste inside a single program works better this way. (It always gets the clipboard contents from Windows, not from its own copy, which is cleared anyway. I can't say I fully understand what happens... Emulating the X selection and property stuff is a bit of a mess.) * gdk/win32/gdkevents.c * gdk/win32/gdkproperty.c: A bít more verbose logging. * gdk/win32/gdkregion.c: Fix some memory leaks (temporary regions that never got deleted). Revamp gdk_region_shrink. * gdk/win32/gdkregion.c: Fix memory leak, delete temporary regions after use. * gtk/gtk.def: Add some missing entry points. * gtk/gtkrc.c: Strip trailing directory separator from pixmap path component.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/win32/gdkdraw.c117
-rw-r--r--gdk/win32/gdkdrawable-win32.c117
-rw-r--r--gdk/win32/gdkevents-win32.c7
-rw-r--r--gdk/win32/gdkevents.c7
-rw-r--r--gdk/win32/gdkproperty-win32.c5
-rw-r--r--gdk/win32/gdkproperty.c5
-rw-r--r--gdk/win32/gdkregion-win32.c45
-rw-r--r--gdk/win32/gdkregion.c45
-rw-r--r--gdk/win32/gdkselection-win32.c23
-rw-r--r--gdk/win32/gdkselection.c23
-rw-r--r--gdk/win32/gdkwindow-win32.c5
-rw-r--r--gdk/win32/gdkwindow.c5
12 files changed, 310 insertions, 94 deletions
diff --git a/gdk/win32/gdkdraw.c b/gdk/win32/gdkdraw.c
index fb347c4cad..514172095e 100644
--- a/gdk/win32/gdkdraw.c
+++ b/gdk/win32/gdkdraw.c
@@ -203,26 +203,27 @@ gdk_draw_arc (GdkDrawable *drawable,
if (height == -1)
height = drawable_private->height;
- hdc = gdk_gc_predraw (drawable_private, gc_private);
-
- nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
- nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
- nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
- nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
-
- if (filled)
+ if (width != 0 && height != 0)
{
- if (!Pie (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- g_warning ("gdk_draw_arc: Pie failed");
- }
- else
- {
- if (!Arc (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- g_warning ("gdk_draw_arc: Arc failed");
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+
+ nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
+ nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
+ nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
+ nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
+
+ if (filled)
+ {
+ Pie (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc);
+ }
+ else
+ {
+ Arc (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc);
+ }
+ gdk_gc_postdraw (drawable_private, gc_private);
}
- gdk_gc_postdraw (drawable_private, gc_private);
}
void
@@ -246,13 +247,16 @@ gdk_draw_polygon (GdkDrawable *drawable,
return;
gc_private = (GdkGCPrivate*) gc;
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- pts = g_malloc ((npoints+1) * sizeof (POINT));
-
GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
drawable_private->xwindow, gc_private,
npoints));
+ if (npoints < 2)
+ return;
+
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+ pts = g_malloc ((npoints+1) * sizeof (POINT));
+
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
@@ -424,6 +428,8 @@ gdk_draw_pixmap (GdkDrawable *drawable,
HDC hdc;
HDC srcdc;
HGDIOBJ hgdiobj;
+ HRGN src_rgn, draw_rgn, outside_rgn;
+ RECT r;
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
@@ -436,17 +442,70 @@ gdk_draw_pixmap (GdkDrawable *drawable,
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
- width = src_private->width;
+ width = src_private->width; /* Or should we subtract xsrc? */
if (height == -1)
- height = src_private->height;
-
- hdc = gdk_gc_predraw (drawable_private, gc_private);
+ height = src_private->height; /* Ditto? */
GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
- "src: %#x %dx%d@+%d+%d\n",
+ "src: %#x %dx%d@+%d+%d"
+ " dest: %#x @+%d+%d\n",
drawable_private->xwindow, gc_private, hdc,
src_private->xwindow,
- width, height, xdest, ydest));
+ width, height, xsrc, ysrc,
+ drawable_private->xwindow, xdest, ydest));
+
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+
+ src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
+ draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
+ SetRectEmpty (&r);
+ outside_rgn = CreateRectRgnIndirect (&r);
+
+ if (drawable_private->window_type != GDK_WINDOW_PIXMAP)
+ {
+ /* If we are drawing on a window, calculate the region that is
+ * outside the source pixmap, and invalidate that, causing it to
+ * be cleared. XXX
+ */
+ if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
+ {
+ OffsetRgn (outside_rgn, xdest, ydest);
+ GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
+ g_print ("...calling InvalidateRgn, "
+ "bbox: %dx%d@+%d+%d\n",
+ r.right - r.left - 1, r.bottom - r.top - 1,
+ r.left, r.top)));
+ InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
+ }
+ }
+
+#if 1 /* Don't know if this is necessary */
+ if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
+ g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
+
+ GetRgnBox (draw_rgn, &r);
+ if (r.left != xsrc
+ || r.top != ysrc
+ || r.right != xsrc + width + 1
+ || r.bottom != ysrc + height + 1)
+ {
+ xdest += r.left - xsrc;
+ xsrc = r.left;
+ ydest += r.top - ysrc;
+ ysrc = r.top;
+ width = r.right - xsrc - 1;
+ height = r.bottom - ysrc - 1;
+
+ GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
+ "dest: @+%d+%d\n",
+ width, height, xsrc, ysrc,
+ xdest, ydest));
+ }
+#endif
+
+ DeleteObject (src_rgn);
+ DeleteObject (draw_rgn);
+ DeleteObject (outside_rgn);
/* Strangely enough, this function is called also to bitblt
* from a window.
@@ -602,7 +661,7 @@ gdk_draw_lines (GdkDrawable *drawable,
POINT *pts;
int i;
- if (npoints <= 0)
+ if (npoints < 2)
return;
g_return_if_fail (drawable != NULL);
@@ -623,7 +682,7 @@ gdk_draw_lines (GdkDrawable *drawable,
}
if (!Polyline (hdc, pts, npoints))
- g_warning ("gdk_draw_lines: Polyline failed");
+ g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
g_free (pts);
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index fb347c4cad..514172095e 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -203,26 +203,27 @@ gdk_draw_arc (GdkDrawable *drawable,
if (height == -1)
height = drawable_private->height;
- hdc = gdk_gc_predraw (drawable_private, gc_private);
-
- nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
- nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
- nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
- nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
-
- if (filled)
+ if (width != 0 && height != 0)
{
- if (!Pie (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- g_warning ("gdk_draw_arc: Pie failed");
- }
- else
- {
- if (!Arc (hdc, x, y, x+width, y+height,
- nXStartArc, nYStartArc, nXEndArc, nYEndArc))
- g_warning ("gdk_draw_arc: Arc failed");
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+
+ nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
+ nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
+ nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
+ nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
+
+ if (filled)
+ {
+ Pie (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc);
+ }
+ else
+ {
+ Arc (hdc, x, y, x+width, y+height,
+ nXStartArc, nYStartArc, nXEndArc, nYEndArc);
+ }
+ gdk_gc_postdraw (drawable_private, gc_private);
}
- gdk_gc_postdraw (drawable_private, gc_private);
}
void
@@ -246,13 +247,16 @@ gdk_draw_polygon (GdkDrawable *drawable,
return;
gc_private = (GdkGCPrivate*) gc;
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- pts = g_malloc ((npoints+1) * sizeof (POINT));
-
GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
drawable_private->xwindow, gc_private,
npoints));
+ if (npoints < 2)
+ return;
+
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+ pts = g_malloc ((npoints+1) * sizeof (POINT));
+
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
@@ -424,6 +428,8 @@ gdk_draw_pixmap (GdkDrawable *drawable,
HDC hdc;
HDC srcdc;
HGDIOBJ hgdiobj;
+ HRGN src_rgn, draw_rgn, outside_rgn;
+ RECT r;
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
@@ -436,17 +442,70 @@ gdk_draw_pixmap (GdkDrawable *drawable,
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
- width = src_private->width;
+ width = src_private->width; /* Or should we subtract xsrc? */
if (height == -1)
- height = src_private->height;
-
- hdc = gdk_gc_predraw (drawable_private, gc_private);
+ height = src_private->height; /* Ditto? */
GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
- "src: %#x %dx%d@+%d+%d\n",
+ "src: %#x %dx%d@+%d+%d"
+ " dest: %#x @+%d+%d\n",
drawable_private->xwindow, gc_private, hdc,
src_private->xwindow,
- width, height, xdest, ydest));
+ width, height, xsrc, ysrc,
+ drawable_private->xwindow, xdest, ydest));
+
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+
+ src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
+ draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
+ SetRectEmpty (&r);
+ outside_rgn = CreateRectRgnIndirect (&r);
+
+ if (drawable_private->window_type != GDK_WINDOW_PIXMAP)
+ {
+ /* If we are drawing on a window, calculate the region that is
+ * outside the source pixmap, and invalidate that, causing it to
+ * be cleared. XXX
+ */
+ if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
+ {
+ OffsetRgn (outside_rgn, xdest, ydest);
+ GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
+ g_print ("...calling InvalidateRgn, "
+ "bbox: %dx%d@+%d+%d\n",
+ r.right - r.left - 1, r.bottom - r.top - 1,
+ r.left, r.top)));
+ InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
+ }
+ }
+
+#if 1 /* Don't know if this is necessary */
+ if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
+ g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
+
+ GetRgnBox (draw_rgn, &r);
+ if (r.left != xsrc
+ || r.top != ysrc
+ || r.right != xsrc + width + 1
+ || r.bottom != ysrc + height + 1)
+ {
+ xdest += r.left - xsrc;
+ xsrc = r.left;
+ ydest += r.top - ysrc;
+ ysrc = r.top;
+ width = r.right - xsrc - 1;
+ height = r.bottom - ysrc - 1;
+
+ GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
+ "dest: @+%d+%d\n",
+ width, height, xsrc, ysrc,
+ xdest, ydest));
+ }
+#endif
+
+ DeleteObject (src_rgn);
+ DeleteObject (draw_rgn);
+ DeleteObject (outside_rgn);
/* Strangely enough, this function is called also to bitblt
* from a window.
@@ -602,7 +661,7 @@ gdk_draw_lines (GdkDrawable *drawable,
POINT *pts;
int i;
- if (npoints <= 0)
+ if (npoints < 2)
return;
g_return_if_fail (drawable != NULL);
@@ -623,7 +682,7 @@ gdk_draw_lines (GdkDrawable *drawable,
}
if (!Polyline (hdc, pts, npoints))
- g_warning ("gdk_draw_lines: Polyline failed");
+ g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
g_free (pts);
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index e197e006ee..d867e0c037 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -2325,9 +2325,12 @@ gdk_event_translate (GdkEvent *event,
if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
{
COLORREF bg;
- GDK_NOTE (EVENTS, g_print ("...BG_PIXEL %s\n",
- gdk_color_to_string (&window_private->bg_pixel)));
GetClipBox (hdc, &rect);
+ GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ rect.left, rect.top,
+ gdk_color_to_string (&window_private->bg_pixel)));
#ifdef MULTIPLE_WINDOW_CLASSES
bg = PALETTEINDEX (window_private->bg_pixel.pixel);
#else
diff --git a/gdk/win32/gdkevents.c b/gdk/win32/gdkevents.c
index e197e006ee..d867e0c037 100644
--- a/gdk/win32/gdkevents.c
+++ b/gdk/win32/gdkevents.c
@@ -2325,9 +2325,12 @@ gdk_event_translate (GdkEvent *event,
if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
{
COLORREF bg;
- GDK_NOTE (EVENTS, g_print ("...BG_PIXEL %s\n",
- gdk_color_to_string (&window_private->bg_pixel)));
GetClipBox (hdc, &rect);
+ GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ rect.left, rect.top,
+ gdk_color_to_string (&window_private->bg_pixel)));
#ifdef MULTIPLE_WINDOW_CLASSES
bg = PALETTEINDEX (window_private->bg_pixel.pixel);
#else
diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c
index 721225eeab..5b90c169a7 100644
--- a/gdk/win32/gdkproperty-win32.c
+++ b/gdk/win32/gdkproperty-win32.c
@@ -165,6 +165,8 @@ gdk_property_change (GdkWindow *window,
if (*ptr++ == '\n')
length++;
#if 1
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n",
+ private->xwindow));
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_property_change: OpenClipboard failed");
@@ -183,10 +185,13 @@ gdk_property_change (GdkWindow *window,
}
*ptr++ = '\0';
GlobalUnlock (hdata);
+ GDK_NOTE (SELECTION, g_print ("...SetClipboardData(CF_TEXT, %#x)\n",
+ hdata));
if (!SetClipboardData(CF_TEXT, hdata))
g_warning ("gdk_property_change: SetClipboardData failed: %d",
GetLastError ());
#if 1
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
if (!CloseClipboard ())
{
g_warning ("gdk_property_change: CloseClipboard failed");
diff --git a/gdk/win32/gdkproperty.c b/gdk/win32/gdkproperty.c
index 721225eeab..5b90c169a7 100644
--- a/gdk/win32/gdkproperty.c
+++ b/gdk/win32/gdkproperty.c
@@ -165,6 +165,8 @@ gdk_property_change (GdkWindow *window,
if (*ptr++ == '\n')
length++;
#if 1
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n",
+ private->xwindow));
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_property_change: OpenClipboard failed");
@@ -183,10 +185,13 @@ gdk_property_change (GdkWindow *window,
}
*ptr++ = '\0';
GlobalUnlock (hdata);
+ GDK_NOTE (SELECTION, g_print ("...SetClipboardData(CF_TEXT, %#x)\n",
+ hdata));
if (!SetClipboardData(CF_TEXT, hdata))
g_warning ("gdk_property_change: SetClipboardData failed: %d",
GetLastError ());
#if 1
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
if (!CloseClipboard ())
{
g_warning ("gdk_property_change: CloseClipboard failed");
diff --git a/gdk/win32/gdkregion-win32.c b/gdk/win32/gdkregion-win32.c
index 55f5e98fb2..2b417ea0bd 100644
--- a/gdk/win32/gdkregion-win32.c
+++ b/gdk/win32/gdkregion-win32.c
@@ -36,9 +36,11 @@ gdk_region_new (void)
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
+ RECT emptyRect;
/* Create an empty region */
- xregion = CreateRectRgn (1, 1, 0, 0);
+ SetRectEmpty (&emptyRect);
+ xregion = CreateRectRgnIndirect (&emptyRect);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion*) private;
@@ -207,28 +209,40 @@ gdk_region_shrink (GdkRegion *region,
gint dy)
{
GdkRegionPrivate *private;
+ HRGN shrunken_bbox;
RECT r;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
- /* Is it correct just to intersect it with a smaller bounding box? */
- GetRgnBox (private->xregion, &r);
-
- if (-dx > r.right - r.left)
+ if (dx > 0 || dy > 0)
{
- r.left += dx/2;
- r.right -= dx/2;
+ /* We want to shrink it in one or both dimensions.
+ * Is it correct just to intersect it with a smaller bounding box?
+ * XXX
+ */
+ GetRgnBox (private->xregion, &r);
+ if (dx > 0)
+ {
+ r.left += dx - dx/2;
+ r.right -= dx/2;
+ }
+ if (dy > 0)
+ {
+ r.top += dy - dy/2;
+ r.bottom -= dy/2;
+ }
+
+ shrunken_bbox = CreateRectRgnIndirect (&r);
+ CombineRgn (private->xregion, private->xregion,
+ shrunken_bbox, RGN_AND);
+ DeleteObject (shrunken_bbox);
}
- if (-dy > r.bottom - r.top)
+ else
{
- r.top += dy/2;
- r.bottom -= dy/2;
+ /* Do nothing if the regions is expanded? XXX */
}
-
- CombineRgn (private->xregion, private->xregion,
- CreateRectRgnIndirect (&r), RGN_AND);
}
GdkRegion*
@@ -239,6 +253,7 @@ gdk_region_union_with_rect (GdkRegion *region,
GdkRegion *res;
GdkRegionPrivate *res_private;
RECT xrect;
+ HRGN rectangle;
g_return_val_if_fail (region != NULL, NULL);
@@ -252,8 +267,10 @@ gdk_region_union_with_rect (GdkRegion *region,
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
+ rectangle = CreateRectRgnIndirect (&xrect);
CombineRgn (res_private->xregion, private->xregion,
- CreateRectRgnIndirect (&xrect), RGN_OR);
+ rectangle, RGN_OR);
+ DeleteObject (rectangle);
return res;
}
diff --git a/gdk/win32/gdkregion.c b/gdk/win32/gdkregion.c
index 55f5e98fb2..2b417ea0bd 100644
--- a/gdk/win32/gdkregion.c
+++ b/gdk/win32/gdkregion.c
@@ -36,9 +36,11 @@ gdk_region_new (void)
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
+ RECT emptyRect;
/* Create an empty region */
- xregion = CreateRectRgn (1, 1, 0, 0);
+ SetRectEmpty (&emptyRect);
+ xregion = CreateRectRgnIndirect (&emptyRect);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion*) private;
@@ -207,28 +209,40 @@ gdk_region_shrink (GdkRegion *region,
gint dy)
{
GdkRegionPrivate *private;
+ HRGN shrunken_bbox;
RECT r;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
- /* Is it correct just to intersect it with a smaller bounding box? */
- GetRgnBox (private->xregion, &r);
-
- if (-dx > r.right - r.left)
+ if (dx > 0 || dy > 0)
{
- r.left += dx/2;
- r.right -= dx/2;
+ /* We want to shrink it in one or both dimensions.
+ * Is it correct just to intersect it with a smaller bounding box?
+ * XXX
+ */
+ GetRgnBox (private->xregion, &r);
+ if (dx > 0)
+ {
+ r.left += dx - dx/2;
+ r.right -= dx/2;
+ }
+ if (dy > 0)
+ {
+ r.top += dy - dy/2;
+ r.bottom -= dy/2;
+ }
+
+ shrunken_bbox = CreateRectRgnIndirect (&r);
+ CombineRgn (private->xregion, private->xregion,
+ shrunken_bbox, RGN_AND);
+ DeleteObject (shrunken_bbox);
}
- if (-dy > r.bottom - r.top)
+ else
{
- r.top += dy/2;
- r.bottom -= dy/2;
+ /* Do nothing if the regions is expanded? XXX */
}
-
- CombineRgn (private->xregion, private->xregion,
- CreateRectRgnIndirect (&r), RGN_AND);
}
GdkRegion*
@@ -239,6 +253,7 @@ gdk_region_union_with_rect (GdkRegion *region,
GdkRegion *res;
GdkRegionPrivate *res_private;
RECT xrect;
+ HRGN rectangle;
g_return_val_if_fail (region != NULL, NULL);
@@ -252,8 +267,10 @@ gdk_region_union_with_rect (GdkRegion *region,
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
+ rectangle = CreateRectRgnIndirect (&xrect);
CombineRgn (res_private->xregion, private->xregion,
- CreateRectRgnIndirect (&xrect), RGN_OR);
+ rectangle, RGN_OR);
+ DeleteObject (rectangle);
return res;
}
diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c
index 94b66fa5b8..7085c94ba1 100644
--- a/gdk/win32/gdkselection-win32.c
+++ b/gdk/win32/gdkselection-win32.c
@@ -103,11 +103,13 @@ gdk_selection_owner_set (GdkWindow *owner,
else
xwindow = NULL;
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n", xwindow));
if (!OpenClipboard (xwindow))
{
g_warning ("gdk_selection_owner_set: OpenClipboard failed");
return FALSE;
}
+ GDK_NOTE (SELECTION, g_print ("...EmptyClipboard()\n"));
if (!EmptyClipboard ())
{
g_warning ("gdk_selection_owner_set: EmptyClipboard failed");
@@ -119,6 +121,7 @@ gdk_selection_owner_set (GdkWindow *owner,
if (xwindow != NULL)
SetClipboardData (CF_TEXT, NULL);
#endif
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
if (!CloseClipboard ())
{
g_warning ("gdk_selection_owner_set: CloseClipboard failed");
@@ -143,12 +146,20 @@ gdk_selection_owner_get (GdkAtom selection)
GdkWindowPrivate *private;
gchar *sel_name;
+#if 1
+ /* XXX Hmm, gtk selections seem to work best with this. This causes
+ * gtk to always get the clipboard contents from Windows, and not
+ * from the editable's own stashed-away copy.
+ */
+ return NULL;
+#else
if (selection != gdk_clipboard_atom)
window = NULL;
else
window = gdk_window_lookup (GetClipboardOwner ());
private = (GdkWindowPrivate *) window;
+#endif
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
@@ -191,12 +202,15 @@ gdk_selection_convert (GdkWindow *requestor,
* contents of the clipboard. Get the clipboard data,
* and store it for later.
*/
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n",
+ private->xwindow));
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_selection_convert: OpenClipboard failed");
return;
}
+ GDK_NOTE (SELECTION, g_print ("...GetClipboardData(CF_TEXT)\n"));
if ((hdata = GetClipboardData (CF_TEXT)) != NULL)
{
if ((ptr = GlobalLock (hdata)) != NULL)
@@ -234,6 +248,7 @@ gdk_selection_convert (GdkWindow *requestor,
GlobalUnlock (hdata);
}
}
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
CloseClipboard ();
@@ -340,12 +355,18 @@ gdk_selection_send_notify (guint32 requestor,
g_free (tgt_name),
g_free (prop_name)));
- /* Send ourselves a selection clear message sot that gtk thinks we doen't
+ /* Send ourselves a selection clear message so that gtk thinks we don't
* have the selection, and will claim it anew when needed, and
* we thus get a chance to store data in the Windows clipboard.
* Otherwise, if a gtkeditable does a copy to clipboard several times
* only the first one actually gets copied to the Windows clipboard,
* as only he first one causes a call to gdk_property_change.
+ *
+ * Hmm, there is something fishy with this. Cut and paste inside the
+ * same app didn't work, the gtkeditable immediately forgot the
+ * clipboard contents in gtk_editable_selection_clear as a result of
+ * this message. OTOH, when I changed gdk_selection_owner_get to
+ * always return NULL, it works. Sigh.
*/
SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0);
diff --git a/gdk/win32/gdkselection.c b/gdk/win32/gdkselection.c
index 94b66fa5b8..7085c94ba1 100644
--- a/gdk/win32/gdkselection.c
+++ b/gdk/win32/gdkselection.c
@@ -103,11 +103,13 @@ gdk_selection_owner_set (GdkWindow *owner,
else
xwindow = NULL;
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n", xwindow));
if (!OpenClipboard (xwindow))
{
g_warning ("gdk_selection_owner_set: OpenClipboard failed");
return FALSE;
}
+ GDK_NOTE (SELECTION, g_print ("...EmptyClipboard()\n"));
if (!EmptyClipboard ())
{
g_warning ("gdk_selection_owner_set: EmptyClipboard failed");
@@ -119,6 +121,7 @@ gdk_selection_owner_set (GdkWindow *owner,
if (xwindow != NULL)
SetClipboardData (CF_TEXT, NULL);
#endif
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
if (!CloseClipboard ())
{
g_warning ("gdk_selection_owner_set: CloseClipboard failed");
@@ -143,12 +146,20 @@ gdk_selection_owner_get (GdkAtom selection)
GdkWindowPrivate *private;
gchar *sel_name;
+#if 1
+ /* XXX Hmm, gtk selections seem to work best with this. This causes
+ * gtk to always get the clipboard contents from Windows, and not
+ * from the editable's own stashed-away copy.
+ */
+ return NULL;
+#else
if (selection != gdk_clipboard_atom)
window = NULL;
else
window = gdk_window_lookup (GetClipboardOwner ());
private = (GdkWindowPrivate *) window;
+#endif
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
@@ -191,12 +202,15 @@ gdk_selection_convert (GdkWindow *requestor,
* contents of the clipboard. Get the clipboard data,
* and store it for later.
*/
+ GDK_NOTE (SELECTION, g_print ("...OpenClipboard(%#x)\n",
+ private->xwindow));
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_selection_convert: OpenClipboard failed");
return;
}
+ GDK_NOTE (SELECTION, g_print ("...GetClipboardData(CF_TEXT)\n"));
if ((hdata = GetClipboardData (CF_TEXT)) != NULL)
{
if ((ptr = GlobalLock (hdata)) != NULL)
@@ -234,6 +248,7 @@ gdk_selection_convert (GdkWindow *requestor,
GlobalUnlock (hdata);
}
}
+ GDK_NOTE (SELECTION, g_print ("...CloseClipboard()\n"));
CloseClipboard ();
@@ -340,12 +355,18 @@ gdk_selection_send_notify (guint32 requestor,
g_free (tgt_name),
g_free (prop_name)));
- /* Send ourselves a selection clear message sot that gtk thinks we doen't
+ /* Send ourselves a selection clear message so that gtk thinks we don't
* have the selection, and will claim it anew when needed, and
* we thus get a chance to store data in the Windows clipboard.
* Otherwise, if a gtkeditable does a copy to clipboard several times
* only the first one actually gets copied to the Windows clipboard,
* as only he first one causes a call to gdk_property_change.
+ *
+ * Hmm, there is something fishy with this. Cut and paste inside the
+ * same app didn't work, the gtkeditable immediately forgot the
+ * clipboard contents in gtk_editable_selection_clear as a result of
+ * this message. OTOH, when I changed gdk_selection_owner_get to
+ * always return NULL, it works. Sigh.
*/
SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0);
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 12926f6d2a..83d9b99c1e 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -2346,7 +2346,7 @@ gdk_propagate_shapes (HANDLE win,
WINDOWPLACEMENT placement;
placement.length = sizeof (WINDOWPLACEMENT);
- /* go through all child windows and create/insert spans */
+ /* go through all child windows and combine regions */
for (i = 0; i < num; i++)
{
GetWindowPlacement (list[i], &placement);
@@ -2355,10 +2355,13 @@ gdk_propagate_shapes (HANDLE win,
childRegion = CreateRectRgnIndirect (&emptyRect);
GetWindowRgn (list[i], childRegion);
CombineRgn (region, region, childRegion, RGN_OR);
+ DeleteObject (childRegion);
}
}
SetWindowRgn (win, region, TRUE);
}
+ else
+ DeleteObject (region);
}
void
diff --git a/gdk/win32/gdkwindow.c b/gdk/win32/gdkwindow.c
index 12926f6d2a..83d9b99c1e 100644
--- a/gdk/win32/gdkwindow.c
+++ b/gdk/win32/gdkwindow.c
@@ -2346,7 +2346,7 @@ gdk_propagate_shapes (HANDLE win,
WINDOWPLACEMENT placement;
placement.length = sizeof (WINDOWPLACEMENT);
- /* go through all child windows and create/insert spans */
+ /* go through all child windows and combine regions */
for (i = 0; i < num; i++)
{
GetWindowPlacement (list[i], &placement);
@@ -2355,10 +2355,13 @@ gdk_propagate_shapes (HANDLE win,
childRegion = CreateRectRgnIndirect (&emptyRect);
GetWindowRgn (list[i], childRegion);
CombineRgn (region, region, childRegion, RGN_OR);
+ DeleteObject (childRegion);
}
}
SetWindowRgn (win, region, TRUE);
}
+ else
+ DeleteObject (region);
}
void