Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c20
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.c2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.h2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java10
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java62
11 files changed, 123 insertions, 8 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c
index dc39bccf20..9733cccad0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c
@@ -875,6 +875,26 @@ JNIEXPORT jboolean JNICALL Cairo_NATIVE(_1cairo_1region_1contains_1point)
}
#endif
+#ifndef NO__1cairo_1region_1copy
+JNIEXPORT jintLong JNICALL Cairo_NATIVE(_1cairo_1region_1copy)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ Cairo_NATIVE_ENTER(env, that, _1cairo_1region_1copy_FUNC);
+/*
+ rc = (jintLong)cairo_region_copy(arg0);
+*/
+ {
+ Cairo_LOAD_FUNCTION(fp, cairo_region_copy)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ Cairo_NATIVE_EXIT(env, that, _1cairo_1region_1copy_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1cairo_1region_1get_1rectangle
JNIEXPORT void JNICALL Cairo_NATIVE(_1cairo_1region_1get_1rectangle)
(JNIEnv *env, jclass that, jintLong arg0, jint arg1, jintLong arg2)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h
index 2554ab6068..fecaef595a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h
@@ -32,6 +32,7 @@
#define cairo_ps_surface_set_size_LIB LIB_CAIRO
#define cairo_region_num_rectangles_LIB LIB_CAIRO
#define cairo_region_contains_point_LIB LIB_CAIRO
+#define cairo_region_copy_LIB LIB_CAIRO
#define cairo_region_get_rectangle_LIB LIB_CAIRO
#define cairo_surface_set_device_scale_LIB LIB_CAIRO
#define cairo_surface_get_device_scale_LIB LIB_CAIRO
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c
index 68d31d2c6a..4153701dea 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c
@@ -97,6 +97,7 @@ char * Cairo_nativeFunctionNames[] = {
"_1cairo_1rectangle",
"_1cairo_1reference",
"_1cairo_1region_1contains_1point",
+ "_1cairo_1region_1copy",
"_1cairo_1region_1get_1rectangle",
"_1cairo_1region_1num_1rectangles",
"_1cairo_1reset_1clip",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h
index 13f3005169..1eae730340 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h
@@ -107,6 +107,7 @@ typedef enum {
_1cairo_1rectangle_FUNC,
_1cairo_1reference_FUNC,
_1cairo_1region_1contains_1point_FUNC,
+ _1cairo_1region_1copy_FUNC,
_1cairo_1region_1get_1rectangle_FUNC,
_1cairo_1region_1num_1rectangles_FUNC,
_1cairo_1reset_1clip_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.c
index a54a37e80d..6f5afd45c9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.c
@@ -15,7 +15,7 @@
*
* IBM
* - Binding to permit interfacing between Cairo and SWT
- * - Copyright (C) 2005, 2016 IBM Corp. All Rights Reserved.
+ * - Copyright (C) 2005, 2018 IBM Corp. All Rights Reserved.
*
* ***** END LICENSE BLOCK ***** */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.h
index 6ffd32cb80..5faf6e80d8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_structs.h
@@ -15,7 +15,7 @@
*
* IBM
* - Binding to permit interfacing between Cairo and SWT
- * - Copyright (C) 2005, 2016 IBM Corp. All Rights Reserved.
+ * - Copyright (C) 2005, 2018 IBM Corp. All Rights Reserved.
*
* ***** END LICENSE BLOCK ***** */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java
index 27918325ef..2af4e020fa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java
@@ -1276,6 +1276,16 @@ public static final int cairo_region_num_rectangles(long /*int*/ region) {
}
}
/** @method flags=dynamic */
+public static final native long /*int*/ _cairo_region_copy(long /*int*/ region);
+public static final long /*int*/ cairo_region_copy(long /*int*/ region) {
+ lock.lock();
+ try {
+ return _cairo_region_copy(region);
+ } finally {
+ lock.unlock();
+ }
+}
+/** @method flags=dynamic */
public static final native boolean _cairo_region_contains_point(long /*int*/ region, int x, int y);
public static final boolean cairo_region_contains_point(long /*int*/ region, int x, int y) {
lock.lock();
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 127e1e216e..7a4642f963 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
@@ -206,6 +206,23 @@ static int checkStyle (int style) {
}
/**
+ * Convenience method that applies a region to the Control using cairo_clip.
+ *
+ * @param cairo the cairo context to apply the region to
+ */
+void cairoClipRegion (long /*int*/ cairo) {
+ if (cairo == 0) return;
+ GdkRectangle rect = new GdkRectangle ();
+ GDK.gdk_cairo_get_clip_rectangle (cairo, rect);
+ long /*int*/ regionHandle = data.regionSet;
+ long /*int*/ actualRegion = GDK.gdk_region_rectangle(rect);
+ GDK.gdk_region_subtract(actualRegion, regionHandle);
+ GDK.gdk_cairo_region(cairo, actualRegion);
+ Cairo.cairo_clip(cairo);
+ Cairo.cairo_paint(cairo);
+}
+
+/**
* Invokes platform specific functionality to wrap a graphics context.
* <p>
* <b>IMPORTANT:</b> This method is <em>not</em> part of the public
@@ -1741,7 +1758,11 @@ void fillRectangleInPixels(int x, int y, int width, int height) {
height = -height;
}
long /*int*/ cairo = data.cairo;
- Cairo.cairo_rectangle(cairo, x, y, width, height);
+ if (data.regionSet != 0) {
+ cairoClipRegion(cairo);
+ } else {
+ Cairo.cairo_rectangle(cairo, x, y, width, height);
+ }
Cairo.cairo_fill(cairo);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
index b6e8b7a799..f9fa5a7efe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
@@ -69,7 +69,7 @@ public final class GCData {
public int interpolation = SWT.DEFAULT;
public Image image;
- public long /*int*/ clipRgn, context, layout, damageRgn, drawable, cairo;
+ public long /*int*/ clipRgn, context, layout, damageRgn, drawable, cairo, regionSet;
public double cairoXoffset, cairoYoffset;
public boolean disposeCairo;
public double[] identity, clippingTransform;
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 cf786af88b..6aebd3ac7b 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
@@ -124,6 +124,13 @@ Composite () {
*/
public Composite (Composite parent, int style) {
super (parent, checkStyle (style));
+ /*
+ * Cache the NO_BACKGROUND flag for use in the Cairo setRegion()
+ * implementation. Only relevant to GTK3.10+, see bug 475784.
+ */
+ if (GTK.GTK_VERSION >= OS.VERSION(3, 10, 0) && (style & SWT.NO_BACKGROUND) != 0) {
+ cachedNoBackground = true;
+ }
}
static int checkStyle (int style) {
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 ed9b3ae3f4..05167c35ac 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
@@ -60,6 +60,11 @@ public abstract class Control extends Widget implements Drawable {
Font font;
Region region;
long /*int*/ eventRegion;
+ /**
+ * The handle to the Region, which is neccessary in the case
+ * that <code>region</code> is disposed before this Control.
+ */
+ long /*int*/ regionHandle;
String toolTipText;
Object layoutData;
Accessible accessible;
@@ -67,6 +72,12 @@ public abstract class Control extends Widget implements Drawable {
String cssBackground, cssForeground = " ";
boolean drawRegion;
/**
+ * Cache the NO_BACKGROUND flag as it gets removed automatically in
+ * Composite. Only relevant for GTK3.10+ as we need it for Cairo setRegion()
+ * functionality. See bug 475784.
+ */
+ boolean cachedNoBackground;
+ /**
* Point for storing the (x, y) coordinate of the last input (click/scroll/etc.).
* This is useful for checking input event coordinates in methods that act on input,
* but do not receive coordinates (like gtk_clicked, for example). See bug 529431.
@@ -172,6 +183,13 @@ void drawBackground (Control control, long /*int*/ window, long /*int*/ region,
void drawBackground (Control control, long /*int*/ window, long /*int*/ cr, long /*int*/ region, int x, int y, int width, int height) {
long /*int*/ cairo = cr != 0 ? cr : GDK.gdk_cairo_create(window);
+ /*
+ * It's possible that a client is using an SWT.NO_BACKGROUND Composite with custom painting
+ * and a region to provide "overlay" functionality. In this case we don't want to paint
+ * any background color, as it will likely break desired behavior. The fix is to paint
+ * this Control as transparent. See bug 475784.
+ */
+ boolean noBackgroundRegion = drawRegion && hooks(SWT.Paint) && cachedNoBackground;
if (cairo == 0) error (SWT.ERROR_NO_HANDLES);
if (region != 0) {
GDK.gdk_cairo_region(cairo, region);
@@ -195,7 +213,11 @@ void drawBackground (Control control, long /*int*/ window, long /*int*/ cr, long
GdkRGBA rgba;
if (GTK.GTK3) {
rgba = control.getBackgroundGdkRGBA();
- Cairo.cairo_set_source_rgba (cairo, rgba.red, rgba.green, rgba.blue, rgba.alpha);
+ if (noBackgroundRegion) {
+ Cairo.cairo_set_source_rgba (cairo, 0.0, 0.0, 0.0, 0.0);
+ } else {
+ Cairo.cairo_set_source_rgba (cairo, rgba.red, rgba.green, rgba.blue, rgba.alpha);
+ }
} else {
GdkColor color = control.getBackgroundGdkColor ();
Cairo.cairo_set_source_rgba_compatibility (cairo, color);
@@ -1376,6 +1398,11 @@ public void setRegion (Region region) {
GDK.gdk_window_shape_combine_region (window, shape_region, 0, 0);
} else {
drawRegion = (this.region != null && this.region.handle != 0);
+ if (drawRegion) {
+ cairoCopyRegion(this.region);
+ } else {
+ cairoDisposeRegion();
+ }
GTK.gtk_widget_queue_draw(topHandle());
}
}
@@ -3580,6 +3607,24 @@ long /*int*/ gtk_event_after (long /*int*/ widget, long /*int*/ gdkEvent) {
}
/**
+ * Copies the region at the Cairo level, as we need to re-use these resources
+ * after the Region object is disposed.
+ *
+ * @param region the Region object to copy to this Control
+ */
+void cairoCopyRegion (Region region) {
+ if (region == null || region.isDisposed() || region.handle == 0) return;
+ regionHandle = Cairo.cairo_region_copy(region.handle);
+ return;
+}
+
+void cairoDisposeRegion () {
+ if (regionHandle != 0) GDK.gdk_region_destroy(regionHandle);
+ if (eventRegion != 0) GDK.gdk_region_destroy(eventRegion);
+ regionHandle = 0;
+ eventRegion = 0;
+}
+/**
* Convenience method that applies a region to the Control using cairo_clip.
*
* @param cairo the cairo context to apply the region to
@@ -3587,13 +3632,16 @@ long /*int*/ gtk_event_after (long /*int*/ widget, long /*int*/ gdkEvent) {
void cairoClipRegion (long /*int*/ cairo) {
GdkRectangle rect = new GdkRectangle ();
GDK.gdk_cairo_get_clip_rectangle (cairo, rect);
- long /*int*/ regionHandle = this.region.handle;
- GdkRectangle regionRect = new GdkRectangle();
+ long /*int*/ regionHandle = this.regionHandle;
+ // Disposal check just in case
+ if (regionHandle == 0) {
+ drawRegion = false;
+ return;
+ }
/*
* These gdk_region_* functions actually map to the proper
* cairo_* functions in os.h.
*/
- GDK.gdk_region_get_clipbox(regionHandle, regionRect);
long /*int*/ actualRegion = GDK.gdk_region_rectangle(rect);
GDK.gdk_region_subtract(actualRegion, regionHandle);
// Draw the Shell bg using cairo, only if it's a different color
@@ -3631,6 +3679,11 @@ long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) {
if ((style & SWT.MIRRORED) != 0) eventBounds.x = DPIUtil.autoScaleDown (getClientWidth ()) - eventBounds.width - eventBounds.x;
event.setBounds (eventBounds);
GCData data = new GCData ();
+ /*
+ * Pass the region into the GCData so that GC.fill* methods can be aware of the region
+ * and clip themselves accordingly. Only relevant on GTK3.10+, see bug 475784.
+ */
+ if (drawRegion) data.regionSet = eventRegion;
// data.damageRgn = gdkEvent.region;
if (GTK.GTK_VERSION <= OS.VERSION (3, 9, 0) || (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0) && OS.CAIRO_CONTEXT_REUSE)) {
data.cairo = cairo;
@@ -4310,6 +4363,7 @@ void releaseHandle () {
super.releaseHandle ();
fixedHandle = 0;
parent = null;
+ cairoDisposeRegion();
}
@Override

Back to the top