Bug 536542 - [HiDPI][GTK] Eclipse Photon is unusable on Plasma with a
display scale factor of 2

- Fixes issue on KDT on i3wm.
- checks whether the cairo scaling factor is same as the GTK scaling
factor if equal uses cairo scaling algorithm other wise the code follows
custom scaling mechanism used till 4.7.

Change-Id: If9a62d7e18d27a03b2ba2c3482c6e9e06976bbd7
Signed-off-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
index 470dec5..d2b044c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
@@ -40,7 +40,7 @@
 	private static AutoScaleMethod autoScaleMethod = AutoScaleMethod.NEAREST;
 
 	private static String autoScaleValue;
-	private static boolean isGtk3 = false;
+	private static boolean useCairoAutoScale = false;
 
 	/**
 	 * System property that controls the autoScale functionality.
@@ -375,7 +375,7 @@
  * @return float scaling factor
  */
 private static float getScalingFactor () {
-	if (isGtk3) {
+	if (useCairoAutoScale) {
 		return 1;
 	}
 	return deviceZoom / 100f;
@@ -440,10 +440,13 @@
 	}
 }
 
-public static void setIsGtk3 (boolean gtk3) {
-	isGtk3 = gtk3;
+public static void setUseCairoAutoScale (boolean cairoAutoScale) {
+	useCairoAutoScale = cairoAutoScale;
 }
 
+public static boolean useCairoAutoScale() {
+	return useCairoAutoScale;
+}
 
 public static int getZoomForAutoscaleProperty (int nativeDeviceZoom) {
 	int zoom = 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
index 6c573ce..5f62485 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
@@ -17,6 +17,7 @@
 
 import org.eclipse.swt.*;
 import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.cairo.*;
 import org.eclipse.swt.internal.gtk.*;
 
 /**
@@ -588,7 +589,6 @@
 	this.dpi = getDPI();
 	this.scaleFactor = getDeviceZoom ();
 	DPIUtil.setDeviceZoom (scaleFactor);
-	DPIUtil.setIsGtk3(GTK.GTK3);
 
 	//TODO: Remove; temporary code only
 	boolean fixAIX = OS.IsAIX && C.PTR_SIZEOF == 8;
@@ -661,6 +661,15 @@
 	if (shellHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 	GTK.gtk_widget_realize(shellHandle);
 
+	if (GTK.GTK_VERSION >= OS.VERSION(3, 22, 0)) {
+		long /*int*/ surface = GDK.gdk_window_create_similar_surface(GDK.gdk_get_default_root_window(), Cairo.CAIRO_CONTENT_COLOR, 10, 10);
+		double sx[] = new double[1];
+		double sy[] = new double[1];
+		Cairo.cairo_surface_get_device_scale(surface, sx, sy);
+
+		DPIUtil.setUseCairoAutoScale((sx[0]*100) == scaleFactor);
+	}
+
 	/* Initialize the system font slot */
 	long /*int*/ [] defaultFontArray = new long /*int*/ [1];
 	long /*int*/ defaultFont;
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 76e7e0f..6721281 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
@@ -1581,16 +1581,19 @@
 	}
 	long /*int*/ cairo = data.cairo;
 	long /*int*/ pattern;
-	/*
-	 * Here the co-ordinates passed are in points for GTK3.
-	 * That means the user is expecting surface to be at
-	 * device scale equal to current scale factor. So need
-	 * to set the device scale to current scale factor
-	 */
-	long /*int*/ surface = Cairo.cairo_get_target(cairo);
-	if ((GTK.GTK3)&&(surface != 0)) {
-		float scaleFactor = DPIUtil.getDeviceZoom() / 100f;
-		Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
+
+	if (DPIUtil.useCairoAutoScale() ) {
+		/*
+		 * Here the co-ordinates passed are in points for GTK3.
+		 * That means the user is expecting surface to be at
+		 * device scale equal to current scale factor. So need
+		 * to set the device scale to current scale factor
+		 */
+		long /*int*/ surface = Cairo.cairo_get_target(cairo);
+		if ((GTK.GTK3)&&(surface != 0)) {
+			float scaleFactor = DPIUtil.getDeviceZoom() / 100f;
+			Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
+		}
 	}
 
 	if (fromRGB.equals(toRGB)) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
index 1c31c6d..75fd29e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
@@ -300,7 +300,7 @@
 	boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32;
 	surface = Cairo.cairo_image_surface_create(format, width, height);
 	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	if (GTK.GTK3) {
+	if (GTK.GTK3 && DPIUtil.useCairoAutoScale()) {
 		double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
 		Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
 	}
@@ -825,7 +825,7 @@
 	int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24;
 	surface = Cairo.cairo_image_surface_create(format, width, height);
 	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	if (GTK.GTK3) {
+	if (GTK.GTK3&&DPIUtil.useCairoAutoScale()) {
 		double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
 		Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
 	}
@@ -1394,11 +1394,11 @@
 	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 	// When we create a blank image we need to set it to 100 in GTK3 as we draw using 100% scale.
 	// Cairo will take care of scaling for us when image needs to be scaled.
-	if (!GTK.GTK3) {
-		currentDeviceZoom = DPIUtil.getDeviceZoom();
-	} else {
+	if (GTK.GTK3 && DPIUtil.useCairoAutoScale()) {
 		currentDeviceZoom = 100;
 		Cairo.cairo_surface_set_device_scale(surface, 1f, 1f);
+	} else {
+		currentDeviceZoom = DPIUtil.getDeviceZoom();
 	}
 	long /*int*/ cairo = Cairo.cairo_create(surface);
 	if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
@@ -1422,7 +1422,7 @@
 	int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24;
 	surface = Cairo.cairo_image_surface_create(format, width, height);
 	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	if (GTK.GTK3) {
+	if (GTK.GTK3 && DPIUtil.useCairoAutoScale()) {
 		double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
 		Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
 	}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java
index 0f38b3f..3a09b2f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java
@@ -30,12 +30,17 @@
 	long /*int*/ newSurface = image.surface;
 	int type = Cairo.cairo_surface_get_type(newSurface);
 	if (type != Cairo.CAIRO_SURFACE_TYPE_IMAGE) {
-		Rectangle bounds = image.getBounds();
+		Rectangle bounds;
+		if (GTK.GTK3 && DPIUtil.useCairoAutoScale()) {
+			bounds = image.getBounds();
+		} else {
+			bounds = image.getBoundsInPixels();
+		}
 		int format = Cairo.cairo_surface_get_content(newSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32;
 		newSurface = Cairo.cairo_image_surface_create(format, bounds.width, bounds.height);
 		if (newSurface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 		//retain device scale set in the original surface
-		if (GTK.GTK3) {
+		if (GTK.GTK3 && DPIUtil.useCairoAutoScale()) {
 			double sx[] = new double[1];
 			double sy[] = new double[1];
 			Cairo.cairo_surface_get_device_scale(image.surface, sx, sy);