From c9b2958b6c64583a74ac566824646ad4b59628af Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Sat, 10 Jul 1999 00:26:54 +0000 Subject: [PATCH] Don't draw anything if width or height is zero. Don't print a warning if MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * 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. --- ChangeLog | 34 ++++++++++ ChangeLog.pre-2-0 | 34 ++++++++++ ChangeLog.pre-2-10 | 34 ++++++++++ ChangeLog.pre-2-2 | 34 ++++++++++ ChangeLog.pre-2-4 | 34 ++++++++++ ChangeLog.pre-2-6 | 34 ++++++++++ ChangeLog.pre-2-8 | 34 ++++++++++ gdk/win32/gdkdraw.c | 117 +++++++++++++++++++++++++-------- gdk/win32/gdkdrawable-win32.c | 117 +++++++++++++++++++++++++-------- gdk/win32/gdkevents-win32.c | 7 +- gdk/win32/gdkevents.c | 7 +- gdk/win32/gdkproperty-win32.c | 5 ++ gdk/win32/gdkproperty.c | 5 ++ gdk/win32/gdkregion-win32.c | 45 +++++++++---- gdk/win32/gdkregion.c | 45 +++++++++---- gdk/win32/gdkselection-win32.c | 23 ++++++- gdk/win32/gdkselection.c | 23 ++++++- gdk/win32/gdkwindow-win32.c | 5 +- gdk/win32/gdkwindow.c | 5 +- gtk/gtk.def | 3 + gtk/gtkrc.c | 2 + 21 files changed, 553 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5eff88275..ab3544618 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 5eff88275..ab3544618 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,37 @@ +1999-07-09 Tor Lillqvist + + * 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. + 1999-07-04 Tor Lillqvist * gdk/win32/gdkevents.c (gdk_event_translate): Handle diff --git a/gdk/win32/gdkdraw.c b/gdk/win32/gdkdraw.c index fb347c4ca..514172095 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 fb347c4ca..514172095 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 e197e006e..d867e0c03 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 e197e006e..d867e0c03 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 721225eea..5b90c169a 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 721225eea..5b90c169a 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 55f5e98fb..2b417ea0b 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 55f5e98fb..2b417ea0b 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 94b66fa5b..7085c94ba 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 94b66fa5b..7085c94ba 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 12926f6d2..83d9b99c1 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 12926f6d2..83d9b99c1 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 diff --git a/gtk/gtk.def b/gtk/gtk.def index b32eae1e3..8f8ee6499 100755 --- a/gtk/gtk.def +++ b/gtk/gtk.def @@ -691,6 +691,7 @@ EXPORTS gtk_menu_bar_prepend gtk_menu_bar_set_shadow_type gtk_menu_detach + gtk_menu_ensure_uline_accel_group gtk_menu_factory_add_entries gtk_menu_factory_add_subfactory gtk_menu_factory_destroy @@ -699,9 +700,11 @@ EXPORTS gtk_menu_factory_remove_entries gtk_menu_factory_remove_paths gtk_menu_factory_remove_subfactory + gtk_menu_get_accel_group gtk_menu_get_active gtk_menu_get_attach_widget gtk_menu_get_type + gtk_menu_get_uline_accel_group gtk_menu_insert gtk_menu_item_activate gtk_menu_item_configure diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c index e030d270a..2ea620124 100644 --- a/gtk/gtkrc.c +++ b/gtk/gtkrc.c @@ -607,6 +607,8 @@ gtk_rc_parse_file (const gchar *filename, gboolean reload) dir = g_strdup(rc_file->canonical_name); for (i = strlen(dir) - 1; (i >= 0) && (dir[i] != G_DIR_SEPARATOR); i--) dir[i] = 0; + if (i >= 0 && dir[i] == G_DIR_SEPARATOR) + dir[i] = 0; gtk_rc_append_pixmap_path(dir); g_free(dir); } -- 2.43.2