diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT')
6 files changed, 452 insertions, 199 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 35099e42bc..bdc8a4d524 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -2424,41 +2424,80 @@ public Rectangle getClipping() { long /*int*/ cairo = data.cairo; long /*int*/ clipRgn = data.clipRgn; long /*int*/ damageRgn = data.damageRgn; + long /*int*/ rgn = 0; if (clipRgn != 0 || damageRgn != 0 || cairo != 0) { - long /*int*/ rgn = cairo_region_create (); - GdkRectangle rect = new GdkRectangle(); - rect.width = width; - rect.height = height; - OS.gdk_region_union_with_rect(rgn, rect); - if (damageRgn != 0) { - cairo_region_intersect (rgn, damageRgn); - } - /* Intersect visible bounds with clipping */ - if (clipRgn != 0) { - /* Convert clipping to device space if needed */ - if (data.clippingTransform != null) { - clipRgn = convertRgn(clipRgn, data.clippingTransform); - cairo_region_intersect (rgn, clipRgn); - cairo_region_destroy (clipRgn); - } else { - cairo_region_intersect (rgn, clipRgn); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + rgn = Cairo.cairo_region_create (); + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.width = width; + rect.height = height; + Cairo.cairo_region_union_rectangle (rgn, rect); + if (damageRgn != 0) { + Cairo.cairo_region_intersect (rgn, damageRgn); } - } - /* Convert to user space */ - if (cairo != 0) { - double[] matrix = new double[6]; - Cairo.cairo_get_matrix(cairo, matrix); - Cairo.cairo_matrix_invert(matrix); - clipRgn = convertRgn(rgn, matrix); + /* Intersect visible bounds with clipping */ + if (clipRgn != 0) { + /* Convert clipping to device space if needed */ + if (data.clippingTransform != null) { + clipRgn = convertRgn(clipRgn, data.clippingTransform); + Cairo.cairo_region_intersect (rgn, clipRgn); + Cairo.cairo_region_destroy (clipRgn); + } else { + Cairo.cairo_region_intersect (rgn, clipRgn); + } + } + /* Convert to user space */ + if (cairo != 0) { + double[] matrix = new double[6]; + Cairo.cairo_get_matrix(cairo, matrix); + Cairo.cairo_matrix_invert(matrix); + clipRgn = convertRgn(rgn, matrix); + cairo_region_destroy (rgn); + rgn = clipRgn; + } + Cairo.cairo_region_get_extents (rgn, rect); cairo_region_destroy (rgn); - rgn = clipRgn; + x = rect.x; + y = rect.y; + width = rect.width; + height = rect.height; + } else { + rgn = OS.gdk_region_new (); + GdkRectangle rect = new GdkRectangle(); + rect.width = width; + rect.height = height; + OS.gdk_region_union_with_rect(rgn, rect); + if (damageRgn != 0) { + OS.gdk_region_intersect (rgn, damageRgn); + } + /* Intersect visible bounds with clipping */ + if (clipRgn != 0) { + /* Convert clipping to device space if needed */ + if (data.clippingTransform != null) { + clipRgn = convertRgn(clipRgn, data.clippingTransform); + OS.gdk_region_intersect (rgn, clipRgn); + OS.gdk_region_destroy (clipRgn); + } else { + OS.gdk_region_intersect (rgn, clipRgn); + } + } + /* Convert to user space */ + if (cairo != 0) { + double[] matrix = new double[6]; + Cairo.cairo_get_matrix(cairo, matrix); + Cairo.cairo_matrix_invert(matrix); + clipRgn = convertRgn(rgn, matrix); + cairo_region_destroy (rgn); + rgn = clipRgn; + } + OS.gdk_region_get_clipbox(rgn, rect); + OS.gdk_region_destroy (rgn); + x = rect.x; + y = rect.y; + width = rect.width; + height = rect.height; } - OS.gdk_region_get_clipbox(rgn, rect); - cairo_region_destroy (rgn); - x = rect.x; - y = rect.y; - width = rect.width; - height = rect.height; + } return new Rectangle(x, y, width, height); } @@ -2486,12 +2525,21 @@ public void getClipping(Region region) { long /*int*/ cairo = data.cairo; long /*int*/ clipRgn = data.clipRgn; if (clipRgn == 0) { - GdkRectangle rect = new GdkRectangle(); - int[] width = new int[1], height = new int[1]; - getSize(width, height); - rect.width = width[0]; - rect.height = height[0]; - OS.gdk_region_union_with_rect(clipping, rect); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + int[] width = new int[1], height = new int[1]; + getSize(width, height); + rect.width = width[0]; + rect.height = height[0]; + Cairo.cairo_region_union_rectangle (clipping, rect); + } else { + GdkRectangle rect = new GdkRectangle(); + int[] width = new int[1], height = new int[1]; + getSize(width, height); + rect.width = width[0]; + rect.height = height[0]; + OS.gdk_region_union_with_rect(clipping, rect); + } } else { /* Convert clipping to device space if needed */ if (data.clippingTransform != null) { @@ -3410,15 +3458,27 @@ public void setClipping(int x, int y, int width, int height) { y = y + height; height = -height; } - GdkRectangle rect = new GdkRectangle(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - long /*int*/ clipRgn = cairo_region_create (); - OS.gdk_region_union_with_rect(clipRgn, rect); - setClipping(clipRgn); - cairo_region_destroy (clipRgn); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + long /*int*/ clipRgn = cairo_region_create (); + Cairo.cairo_region_union_rectangle (clipRgn, rect); + setClipping(clipRgn); + Cairo.cairo_region_destroy (clipRgn); + } else { + GdkRectangle rect = new GdkRectangle(); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + long /*int*/ clipRgn = cairo_region_create (); + OS.gdk_region_union_with_rect(clipRgn, rect); + setClipping(clipRgn); + OS.gdk_region_destroy (clipRgn); + } } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java index 46941170a6..7069896083 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java @@ -157,12 +157,21 @@ public void add(Rectangle rect) { public void add(int x, int y, int width, int height) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (width < 0 || height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - GdkRectangle gdkRect = new GdkRectangle(); - gdkRect.x = x; - gdkRect.y = y; - gdkRect.width = width; - gdkRect.height = height; - OS.gdk_region_union_with_rect(handle, gdkRect); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t(); + cairoRect.x = x; + cairoRect.y = y; + cairoRect.width = width; + cairoRect.height = height; + Cairo.cairo_region_union_rectangle (handle, cairoRect); + } else { + GdkRectangle gdkRect = new GdkRectangle(); + gdkRect.x = x; + gdkRect.y = y; + gdkRect.width = width; + gdkRect.height = height; + OS.gdk_region_union_with_rect(handle, gdkRect); + } } /** @@ -262,9 +271,15 @@ public boolean equals(Object object) { */ public Rectangle getBounds() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - GdkRectangle gdkRect = new GdkRectangle(); - OS.gdk_region_get_clipbox(handle, gdkRect); - return new Rectangle(gdkRect.x, gdkRect.y, gdkRect.width, gdkRect.height); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t (); + Cairo.cairo_region_get_extents (handle, cairoRect); + return new Rectangle(cairoRect.x, cairoRect.y, cairoRect.width, cairoRect.height); + } else { + GdkRectangle gdkRect = new GdkRectangle(); + OS.gdk_region_get_clipbox(handle, gdkRect); + return new Rectangle(gdkRect.x, gdkRect.y, gdkRect.width, gdkRect.height); + } } /** @@ -408,12 +423,21 @@ public void intersect(Region region) { */ public boolean intersects (int x, int y, int width, int height) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - GdkRectangle gdkRect = new GdkRectangle(); - gdkRect.x = x; - gdkRect.y = y; - gdkRect.width = width; - gdkRect.height = height; - return OS.gdk_region_rect_in(handle, gdkRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t (); + cairoRect.x = x; + cairoRect.y = y; + cairoRect.width = width; + cairoRect.height = height; + return Cairo.cairo_region_contains_rectangle (handle, cairoRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + } else { + GdkRectangle gdkRect = new GdkRectangle(); + gdkRect.x = x; + gdkRect.y = y; + gdkRect.width = width; + gdkRect.height = height; + return OS.gdk_region_rect_in(handle, gdkRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + } } /** * Returns <code>true</code> if the given rectangle intersects diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java index 657ba4e705..97016231c8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java @@ -827,44 +827,86 @@ public Rectangle getBounds(int start, int end) { int[] ranges = new int[]{byteStart, byteEnd}; long /*int*/ clipRegion = OS.gdk_pango_layout_get_clip_region(layout, 0, 0, ranges, 1); if (clipRegion == 0) return new Rectangle(0, 0, 0, 0); - GdkRectangle rect = new GdkRectangle(); - - /* - * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() - * includes areas from lines outside of the requested range. The fix - * is to subtract these areas from the clip region. - */ - PangoRectangle pangoRect = new PangoRectangle(); - long /*int*/ iter = OS.pango_layout_get_iter(layout); - if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); - long /*int*/ linesRegion = cairo_region_create (); - if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int lineEnd = 0; - do { - OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); - if (OS.pango_layout_iter_next_line(iter)) { - lineEnd = OS.pango_layout_iter_get_index(iter) - 1; - } else { - lineEnd = strlen; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t(); + /* + * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() + * includes areas from lines outside of the requested range. The fix + * is to subtract these areas from the clip region. + */ + PangoRectangle pangoRect = new PangoRectangle(); + long /*int*/ iter = OS.pango_layout_get_iter(layout); + if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); + long /*int*/ linesRegion = cairo_region_create (); + if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int lineEnd = 0; + do { + OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); + if (OS.pango_layout_iter_next_line(iter)) { + lineEnd = OS.pango_layout_iter_get_index(iter) - 1; + } else { + lineEnd = strlen; + } + if (byteStart > lineEnd) continue; + rect.x = OS.PANGO_PIXELS(pangoRect.x); + rect.y = OS.PANGO_PIXELS(pangoRect.y); + rect.width = OS.PANGO_PIXELS(pangoRect.width); + rect.height = OS.PANGO_PIXELS(pangoRect.height); + Cairo.cairo_region_union_rectangle (linesRegion, rect); + } while (lineEnd + 1 <= byteEnd); + Cairo.cairo_region_intersect (clipRegion, linesRegion); + Cairo.cairo_region_destroy (linesRegion); + OS.pango_layout_iter_free(iter); + + Cairo.cairo_region_get_extents (clipRegion, rect); + Cairo.cairo_region_destroy (clipRegion); + if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { + rect.x = width() - rect.x - rect.width; } - if (byteStart > lineEnd) continue; - rect.x = OS.PANGO_PIXELS(pangoRect.x); - rect.y = OS.PANGO_PIXELS(pangoRect.y); - rect.width = OS.PANGO_PIXELS(pangoRect.width); - rect.height = OS.PANGO_PIXELS(pangoRect.height); - OS.gdk_region_union_with_rect(linesRegion, rect); - } while (lineEnd + 1 <= byteEnd); - cairo_region_intersect (clipRegion, linesRegion); - cairo_region_destroy (linesRegion); - OS.pango_layout_iter_free(iter); - - OS.gdk_region_get_clipbox(clipRegion, rect); - cairo_region_destroy (clipRegion); - if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { - rect.x = width() - rect.x - rect.width; + rect.x += Math.min (indent, wrapIndent); + return new Rectangle(rect.x, rect.y, rect.width, rect.height); + } else { + GdkRectangle rect = new GdkRectangle(); + /* + * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() + * includes areas from lines outside of the requested range. The fix + * is to subtract these areas from the clip region. + */ + PangoRectangle pangoRect = new PangoRectangle(); + long /*int*/ iter = OS.pango_layout_get_iter(layout); + if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); + long /*int*/ linesRegion = cairo_region_create (); + if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int lineEnd = 0; + do { + OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); + if (OS.pango_layout_iter_next_line(iter)) { + lineEnd = OS.pango_layout_iter_get_index(iter) - 1; + } else { + lineEnd = strlen; + } + if (byteStart > lineEnd) continue; + rect.x = OS.PANGO_PIXELS(pangoRect.x); + rect.y = OS.PANGO_PIXELS(pangoRect.y); + rect.width = OS.PANGO_PIXELS(pangoRect.width); + rect.height = OS.PANGO_PIXELS(pangoRect.height); + OS.gdk_region_union_with_rect(linesRegion, rect); + } while (lineEnd + 1 <= byteEnd); + OS.gdk_region_intersect (clipRegion, linesRegion); + OS.gdk_region_destroy (linesRegion); + OS.pango_layout_iter_free(iter); + + OS.gdk_region_get_clipbox(clipRegion, rect); + OS.gdk_region_destroy (clipRegion); + if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { + rect.x = width() - rect.x - rect.width; + } + rect.x += Math.min (indent, wrapIndent); + return new Rectangle(rect.x, rect.y, rect.width, rect.height); } - rect.x += Math.min (indent, wrapIndent); - return new Rectangle(rect.x, rect.y, rect.width, rect.height); + + + } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java index d0602e5e97..6d7f448b10 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java @@ -13,6 +13,7 @@ package org.eclipse.swt.widgets; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.cairo.Cairo; +import org.eclipse.swt.internal.cairo.cairo_rectangle_int_t; import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.*; @@ -252,76 +253,150 @@ public void scroll (int destX, int destY, int x, int y, int width, int height, b if (isFocus) caret.killFocus (); long /*int*/ window = paintWindow (); long /*int*/ visibleRegion = OS.gdk_drawable_get_visible_region (window); - GdkRectangle srcRect = new GdkRectangle (); - srcRect.x = x; - srcRect.y = y; - srcRect.width = width; - srcRect.height = height; - long /*int*/ copyRegion = OS.gdk_region_rectangle (srcRect); - cairo_region_intersect (copyRegion, visibleRegion); - long /*int*/ invalidateRegion = OS.gdk_region_rectangle (srcRect); - cairo_region_subtract (invalidateRegion, visibleRegion); - cairo_region_translate (invalidateRegion, deltaX, deltaY); - GdkRectangle copyRect = new GdkRectangle(); - OS.gdk_region_get_clipbox (copyRegion, copyRect); - if (copyRect.width != 0 && copyRect.height != 0) { - update (); - } - Control control = findBackgroundControl (); - if (control == null) control = this; - if (control.backgroundImage != null) { - redrawWidget (x, y, width, height, false, false, false); - redrawWidget (destX, destY, width, height, false, false, false); - } else { -// GC gc = new GC (this); -// gc.copyArea (x, y, width, height, destX, destY); -// gc.dispose (); - if (OS.USE_CAIRO) { - OS.gdk_window_invalidate_rect(window, copyRect, true); - long /*int*/ cairo = OS.gdk_cairo_create (window); - OS.gdk_cairo_set_source_window (cairo, window, 0, 0); - Cairo.cairo_rectangle(cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); - Cairo.cairo_fill (cairo); - Cairo.cairo_destroy (cairo); - }else{ - long /*int*/ gdkGC = OS.gdk_gc_new (window); - OS.gdk_gc_set_exposures (gdkGC, true); - OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); - OS.g_object_unref (gdkGC); + if(OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t srcRect = new cairo_rectangle_int_t(); + srcRect.x = x; + srcRect.y = y; + srcRect.width = width; + srcRect.height = height; + long /*int*/ copyRegion = Cairo.cairo_region_create_rectangle (srcRect); + Cairo.cairo_region_intersect (copyRegion, visibleRegion); + long /*int*/ invalidateRegion = Cairo.cairo_region_create_rectangle (srcRect); + Cairo.cairo_region_subtract (invalidateRegion, visibleRegion); + Cairo.cairo_region_translate (invalidateRegion, deltaX, deltaY); + cairo_rectangle_int_t copyRect = new cairo_rectangle_int_t (); + Cairo.cairo_region_get_extents (copyRegion, copyRect); + if (copyRect.width != 0 && copyRect.height != 0) { + update (); } - boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); - if (disjoint) { - GdkRectangle rect = new GdkRectangle (); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - OS.gdk_region_union_with_rect (invalidateRegion, rect); + Control control = findBackgroundControl (); + if (control == null) control = this; + if (control.backgroundImage != null) { + redrawWidget (x, y, width, height, false, false, false); + redrawWidget (destX, destY, width, height, false, false, false); } else { - GdkRectangle rect = new GdkRectangle (); - if (deltaX != 0) { - int newX = destX - deltaX; - if (deltaX < 0) newX = destX + width; - rect.x = newX; +// GC gc = new GC (this); +// gc.copyArea (x, y, width, height, destX, destY); +// gc.dispose (); + if (OS.USE_CAIRO) { + OS.gdk_window_invalidate_region (window, copyRegion, true); + long /*int*/ cairo = OS.gdk_cairo_create (window); + OS.gdk_cairo_set_source_window (cairo, window, 0, 0); + Cairo.cairo_rectangle (cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + Cairo.cairo_fill (cairo); + Cairo.cairo_destroy (cairo); + } else { + long /*int*/ gdkGC = OS.gdk_gc_new (window); + OS.gdk_gc_set_exposures (gdkGC, true); + OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + OS.g_object_unref (gdkGC); + } + boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); + if (disjoint) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.x = x; rect.y = y; - rect.width = Math.abs(deltaX); + rect.width = width; rect.height = height; - OS.gdk_region_union_with_rect (invalidateRegion, rect); + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } else { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + if (deltaX != 0) { + int newX = destX - deltaX; + if (deltaX < 0) newX = destX + width; + rect.x = newX; + rect.y = y; + rect.width = Math.abs(deltaX); + rect.height = height; + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } + if (deltaY != 0) { + int newY = destY - deltaY; + if (deltaY < 0) newY = destY + height; + rect.x = x; + rect.y = newY; + rect.width = width; + rect.height = Math.abs(deltaY); + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } + } + OS.gdk_window_invalidate_region(window, invalidateRegion, all); + Cairo.cairo_region_destroy (visibleRegion); + Cairo.cairo_region_destroy (copyRegion); + Cairo.cairo_region_destroy (invalidateRegion); + } + } else { + GdkRectangle srcRect = new GdkRectangle (); + srcRect.x = x; + srcRect.y = y; + srcRect.width = width; + srcRect.height = height; + long /*int*/ copyRegion = OS.gdk_region_rectangle (srcRect); + OS.gdk_region_intersect(copyRegion, visibleRegion); + long /*int*/ invalidateRegion = OS.gdk_region_rectangle (srcRect); + OS.gdk_region_subtract (invalidateRegion, visibleRegion); + OS.gdk_region_offset (invalidateRegion, deltaX, deltaY); + GdkRectangle copyRect = new GdkRectangle(); + OS.gdk_region_get_clipbox (copyRegion, copyRect); + if (copyRect.width != 0 && copyRect.height != 0) { + update (); + } + Control control = findBackgroundControl (); + if (control == null) control = this; + if (control.backgroundImage != null) { + redrawWidget (x, y, width, height, false, false, false); + redrawWidget (destX, destY, width, height, false, false, false); + } else { +// GC gc = new GC (this); +// gc.copyArea (x, y, width, height, destX, destY); +// gc.dispose (); + if (OS.USE_CAIRO) { + OS.gdk_window_invalidate_region (window, copyRegion, true); + long /*int*/ cairo = OS.gdk_cairo_create (window); + OS.gdk_cairo_set_source_window (cairo, window, 0, 0); + Cairo.cairo_rectangle (cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + Cairo.cairo_fill (cairo); + Cairo.cairo_destroy (cairo); + } else { + long /*int*/ gdkGC = OS.gdk_gc_new (window); + OS.gdk_gc_set_exposures (gdkGC, true); + OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + OS.g_object_unref (gdkGC); } - if (deltaY != 0) { - int newY = destY - deltaY; - if (deltaY < 0) newY = destY + height; + boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); + if (disjoint) { + GdkRectangle rect = new GdkRectangle (); rect.x = x; - rect.y = newY; + rect.y = y; rect.width = width; - rect.height = Math.abs(deltaY); + rect.height = height; OS.gdk_region_union_with_rect (invalidateRegion, rect); - } - } - OS.gdk_window_invalidate_region(window, invalidateRegion, all); - cairo_region_destroy (visibleRegion); - cairo_region_destroy (copyRegion); - cairo_region_destroy (invalidateRegion); + } else { + GdkRectangle rect = new GdkRectangle (); + if (deltaX != 0) { + int newX = destX - deltaX; + if (deltaX < 0) newX = destX + width; + rect.x = newX; + rect.y = y; + rect.width = Math.abs(deltaX); + rect.height = height; + OS.gdk_region_union_with_rect (invalidateRegion, rect); + } + if (deltaY != 0) { + int newY = destY - deltaY; + if (deltaY < 0) newY = destY + height; + rect.x = x; + rect.y = newY; + rect.width = width; + rect.height = Math.abs(deltaY); + OS.gdk_region_union_with_rect (invalidateRegion, rect); + } + } + OS.gdk_window_invalidate_region(window, invalidateRegion, all); + OS.gdk_region_destroy (visibleRegion); + OS.gdk_region_destroy (copyRegion); + OS.gdk_region_destroy (invalidateRegion); + } } if (all) { Control [] children = _getChildren (); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index b63026b264..e5de893029 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -731,25 +731,48 @@ long /*int*/ gtk_expose_event (long /*int*/ widget, long /*int*/ eventPtr) { long /*int*/ [] rectangles = new long /*int*/ [1]; int [] n_rectangles = new int [1]; OS.gdk_region_get_rectangles (gdkEvent.region, rectangles, n_rectangles); - GdkRectangle rect = new GdkRectangle (); - for (int i=0; i<n_rectangles[0]; i++) { - Event event = new Event (); - OS.memmove (rect, rectangles [0] + i * GdkRectangle.sizeof, GdkRectangle.sizeof); - event.x = rect.x; - event.y = rect.y; - event.width = rect.width; - event.height = rect.height; - if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.width - event.x; - long /*int*/ damageRgn = cairo_region_create (); - OS.gdk_region_union_with_rect (damageRgn, rect); - GCData data = new GCData (); - data.damageRgn = damageRgn; - GC gc = event.gc = GC.gtk_new (this, data); - sendEvent (SWT.Paint, event); - gc.dispose (); - cairo_region_destroy (damageRgn); - event.gc = null; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + for (int i=0; i<n_rectangles[0]; i++) { + Event event = new Event (); + Cairo.memmove (rect, rectangles [0] + i * cairo_rectangle_int_t.sizeof, cairo_rectangle_int_t.sizeof); + event.x = rect.x; + event.y = rect.y; + event.width = rect.width; + event.height = rect.height; + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.width - event.x; + long /*int*/ damageRgn = cairo_region_create (); + Cairo.cairo_region_union_rectangle (damageRgn, rect); + GCData data = new GCData (); + data.damageRgn = damageRgn; + GC gc = event.gc = GC.gtk_new (this, data); + sendEvent (SWT.Paint, event); + gc.dispose (); + cairo_region_destroy (damageRgn); + event.gc = null; + } + } else { + GdkRectangle rect = new GdkRectangle (); + for (int i=0; i<n_rectangles[0]; i++) { + Event event = new Event (); + OS.memmove (rect, rectangles [0] + i * GdkRectangle.sizeof, GdkRectangle.sizeof); + event.x = rect.x; + event.y = rect.y; + event.width = rect.width; + event.height = rect.height; + if ((style & SWT.MIRRORED) != 0) event.x = getClientWidth () - event.width - event.x; + long /*int*/ damageRgn = cairo_region_create (); + OS.gdk_region_union_with_rect (damageRgn, rect); + GCData data = new GCData (); + data.damageRgn = damageRgn; + GC gc = event.gc = GC.gtk_new (this, data); + sendEvent (SWT.Paint, event); + gc.dispose (); + cairo_region_destroy (damageRgn); + event.gc = null; + } } + OS.g_free (rectangles [0]); return 0; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 5202b30295..b114f9f021 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -413,31 +413,60 @@ void printWidget (GC gc, long /*int*/ drawable, int depth, int x, int y) { void printWindow (boolean first, Control control, GC gc, long /*int*/ drawable, int depth, long /*int*/ window, int x, int y) { if (OS.gdk_drawable_get_depth (window) != depth) return; - GdkRectangle rect = new GdkRectangle (); - int [] width = new int [1], height = new int [1]; - gdk_window_get_size (window, width, height); - rect.width = width [0]; - rect.height = height [0]; - OS.gdk_window_begin_paint_rect (window, rect); long /*int*/ [] real_drawable = new long /*int*/ [1]; int [] x_offset = new int [1], y_offset = new int [1]; - OS.gdk_window_get_internal_paint_info (window, real_drawable, x_offset, y_offset); - long /*int*/ [] userData = new long /*int*/ [1]; - OS.gdk_window_get_user_data (window, userData); - if (userData [0] != 0) { - long /*int*/ eventPtr = OS.gdk_event_new (OS.GDK_EXPOSE); - GdkEventExpose event = new GdkEventExpose (); - event.type = OS.GDK_EXPOSE; - event.window = OS.g_object_ref (window); - event.area_width = rect.width; - event.area_height = rect.height; - event.region = OS.gdk_region_rectangle (rect); - OS.memmove (eventPtr, event, GdkEventExpose.sizeof); - OS.gtk_widget_send_expose (userData [0], eventPtr); - OS.gdk_event_free (eventPtr); + int [] width = new int [1], height = new int [1]; + int srcX, srcY, destX, destY, destWidth, destHeight; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + gdk_window_get_size (window, width, height); + rect.width = width [0]; + rect.height = height [0]; + long /*int*/ cr = Cairo.cairo_region_create_rectangle (rect); + OS.gdk_window_begin_paint_region(window, cr); + OS.gdk_window_get_internal_paint_info (window, real_drawable, x_offset, y_offset); + long /*int*/ [] userData = new long /*int*/ [1]; + OS.gdk_window_get_user_data (window, userData); + if (userData [0] != 0) { + long /*int*/ eventPtr = OS.gdk_event_new (OS.GDK_EXPOSE); + GdkEventExpose event = new GdkEventExpose (); + event.type = OS.GDK_EXPOSE; + event.window = OS.g_object_ref (window); + event.area_width = rect.width; + event.area_height = rect.height; + event.region = Cairo.cairo_region_create_rectangle (rect); + OS.memmove (eventPtr, event, GdkEventExpose.sizeof); + OS.gtk_widget_send_expose (userData [0], eventPtr); + OS.gdk_event_free (eventPtr); + } + } else { + GdkRectangle rect = new GdkRectangle (); + gdk_window_get_size (window, width, height); + rect.width = width [0]; + rect.height = height [0]; + OS.gdk_window_begin_paint_rect (window, rect); + OS.gdk_window_get_internal_paint_info (window, real_drawable, x_offset, y_offset); + long /*int*/ [] userData = new long /*int*/ [1]; + OS.gdk_window_get_user_data (window, userData); + if (userData [0] != 0) { + long /*int*/ eventPtr = OS.gdk_event_new (OS.GDK_EXPOSE); + GdkEventExpose event = new GdkEventExpose (); + event.type = OS.GDK_EXPOSE; + event.window = OS.g_object_ref (window); + event.area_width = rect.width; + event.area_height = rect.height; + event.region = OS.gdk_region_rectangle (rect); + OS.memmove (eventPtr, event, GdkEventExpose.sizeof); + OS.gtk_widget_send_expose (userData [0], eventPtr); + OS.gdk_event_free (eventPtr); + } } - int srcX = x_offset [0], srcY = y_offset [0]; - int destX = x, destY = y, destWidth = width [0], destHeight = height [0]; + srcX = x_offset [0]; + srcY = y_offset [0]; + destX = x; + destY = y; + destWidth = width [0]; + destHeight = height [0]; if (!first) { int [] cX = new int [1], cY = new int [1]; OS.gdk_window_get_position (window, cX, cY); |