Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLakshmi Shanmugam2016-03-12 23:49:39 +0000
committerLakshmi Shanmugam2016-03-14 18:37:24 +0000
commitb784258052e3ced6e92c72a28e1f035a0c72a2f3 (patch)
tree53a102791d397aec1d82ca04f622fdfbb9544d22
parentf271d7c0549510dc005f60e3450f591cf62c6679 (diff)
downloadeclipse.platform.swt-b784258052e3ced6e92c72a28e1f035a0c72a2f3.tar.gz
eclipse.platform.swt-b784258052e3ced6e92c72a28e1f035a0c72a2f3.tar.xz
eclipse.platform.swt-b784258052e3ced6e92c72a28e1f035a0c72a2f3.zip
Bug 480852 - [Cocoa] GC.copyArea() crashes application on OSX 10.11
Use NSView APIs instead of Quartz APIs to copy area from a view onto an image
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras9
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSView.java11
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java55
4 files changed, 54 insertions, 23 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
index d8858677a4..290c4a5091 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
@@ -3927,9 +3927,18 @@
<arg swt_gen="true"></arg>
<retval swt_gen="true"></retval>
</method>
+ <method selector="bitmapImageRepForCachingDisplayInRect:" swt_gen="true">
+ <arg swt_gen="true"></arg>
+ <retval swt_gen="true"></retval>
+ </method>
<method selector="bounds" swt_gen="true">
<retval swt_gen="true"></retval>
</method>
+ <method selector="cacheDisplayInRect:toBitmapImageRep:" swt_gen="true">
+ <arg swt_gen="true"></arg>
+ <arg swt_gen="true"></arg>
+ <retval swt_gen="true"></retval>
+ </method>
<method selector="canBecomeKeyView" swt_gen="true">
<retval swt_gen="true"></retval>
</method>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSView.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSView.java
index 853ff943f6..61efe09316 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSView.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -48,12 +48,21 @@ public void beginPageInRect(NSRect aRect, NSPoint location) {
OS.objc_msgSend(this.id, OS.sel_beginPageInRect_atPlacement_, aRect, location);
}
+public NSBitmapImageRep bitmapImageRepForCachingDisplayInRect(NSRect rect) {
+ long /*int*/ result = OS.objc_msgSend(this.id, OS.sel_bitmapImageRepForCachingDisplayInRect_, rect);
+ return result != 0 ? new NSBitmapImageRep(result) : null;
+}
+
public NSRect bounds() {
NSRect result = new NSRect();
OS.objc_msgSend_stret(result, this.id, OS.sel_bounds);
return result;
}
+public void cacheDisplayInRect(NSRect rect, NSBitmapImageRep bitmapImageRep) {
+ OS.objc_msgSend(this.id, OS.sel_cacheDisplayInRect_toBitmapImageRep_, rect, bitmapImageRep != null ? bitmapImageRep.id : 0);
+}
+
public boolean canBecomeKeyView() {
return OS.objc_msgSend_bool(this.id, OS.sel_canBecomeKeyView);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
index fb2e9f57c0..4bda5dc6a9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
@@ -1059,6 +1059,7 @@ public static final long /*int*/ sel_bezierPathByFlatteningPath = sel_registerNa
public static final long /*int*/ sel_bezierPathWithRect_ = sel_registerName("bezierPathWithRect:");
public static final long /*int*/ sel_bitmapData = sel_registerName("bitmapData");
public static final long /*int*/ sel_bitmapFormat = sel_registerName("bitmapFormat");
+public static final long /*int*/ sel_bitmapImageRepForCachingDisplayInRect_ = sel_registerName("bitmapImageRepForCachingDisplayInRect:");
public static final long /*int*/ sel_bitsPerPixel = sel_registerName("bitsPerPixel");
public static final long /*int*/ sel_bitsPerSample = sel_registerName("bitsPerSample");
public static final long /*int*/ sel_blackColor = sel_registerName("blackColor");
@@ -1077,6 +1078,7 @@ public static final long /*int*/ sel_buttonNumber = sel_registerName("buttonNumb
public static final long /*int*/ sel_bytes = sel_registerName("bytes");
public static final long /*int*/ sel_bytesPerPlane = sel_registerName("bytesPerPlane");
public static final long /*int*/ sel_bytesPerRow = sel_registerName("bytesPerRow");
+public static final long /*int*/ sel_cacheDisplayInRect_toBitmapImageRep_ = sel_registerName("cacheDisplayInRect:toBitmapImageRep:");
public static final long /*int*/ sel_calendarDate = sel_registerName("calendarDate");
public static final long /*int*/ sel_canBecomeKeyView = sel_registerName("canBecomeKeyView");
public static final long /*int*/ sel_canBecomeKeyWindow = sel_registerName("canBecomeKeyWindow");
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
index 5222eeeaee..e87ea58129 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java
@@ -448,29 +448,19 @@ public void copyArea(Image image, int x, int y) {
return;
}
if (data.view != null) {
- NSPoint pt = new NSPoint();
- pt.x = x;
- pt.y = y;
- NSWindow window = data.view.window();
- pt = data.view.convertPoint_toView_(pt, window.contentView().superview());
- NSRect frame = window.frame();
- pt.y = frame.height - pt.y;
NSSize size = image.handle.size();
- CGRect destRect = new CGRect();
- destRect.size.width = size.width;
- destRect.size.height = size.height;
- CGRect srcRect = new CGRect();
- srcRect.origin.x = pt.x;
- srcRect.origin.y = pt.y;
- srcRect.size.width = size.width;
- srcRect.size.height = size.height;
- NSBitmapImageRep imageRep = image.getRepresentation();
- NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(imageRep);
- NSGraphicsContext.static_saveGraphicsState();
- NSGraphicsContext.setCurrentContext(context);
- long /*int*/ contextID = OS.objc_msgSend(NSApplication.sharedApplication().id, OS.sel_contextID);
- OS.CGContextCopyWindowContentsToRect(context.graphicsPort(), destRect, contextID, window.windowNumber(), srcRect);
- NSGraphicsContext.static_restoreGraphicsState();
+ NSView topView = getTopView(data.view);
+ NSRect rect = new NSRect();
+ rect.x = x;
+ rect.y = y;
+ rect.width = size.width;
+ rect.height = size.height;
+ NSBitmapImageRep imageRep = topView.bitmapImageRepForCachingDisplayInRect(rect);
+ imageRep.setSize(size);
+ topView.cacheDisplayInRect(rect, imageRep);
+ NSBitmapImageRep rep = image.getRepresentation();
+ image.handle.addRepresentation(imageRep);
+ image.handle.removeRepresentation(rep);
return;
}
if (handle.isDrawingToScreen()) {
@@ -2849,6 +2839,27 @@ public int getTextAntialias() {
return data.textAntialias;
}
+// Internal methos that returns the topView of the Control. It's the same view that would be returned
+// by Control.topView(). But, we don't use Control.topView() since classes in the graphics package
+// are not supposed to reference the classes in widgets package.
+NSView getTopView(NSView view) {
+ if (view != null) {
+ NSView contentView = view.superview();
+ if (contentView != null && contentView.isKindOfClass(OS.class_NSClipView)) {
+ NSView superView = contentView.superview();
+ if (superView != null && superView.isKindOfClass(OS.class_NSScrollView)) {
+ NSScrollView scrollView = new NSScrollView(superView.id);
+ if (scrollView.documentView() != null) {
+ if (scrollView.documentView().id == view.id) {
+ return superView;
+ }
+ }
+ }
+ }
+ }
+ return view;
+}
+
/**
* Sets the parameter to the transform that is currently being
* used by the receiver.

Back to the top