28package com.jogamp.nativewindow.swt;
30import com.jogamp.common.os.Platform;
32import java.io.PrintStream;
33import java.lang.reflect.Field;
34import java.lang.reflect.Method;
35import java.security.PrivilegedAction;
37import org.eclipse.swt.SWT;
38import org.eclipse.swt.graphics.GCData;
39import org.eclipse.swt.graphics.Point;
40import org.eclipse.swt.graphics.Rectangle;
41import org.eclipse.swt.internal.DPIUtil;
42import org.eclipse.swt.widgets.Control;
43import org.eclipse.swt.widgets.Display;
44import org.eclipse.swt.widgets.Scrollable;
46import com.jogamp.nativewindow.AbstractGraphicsScreen;
47import com.jogamp.nativewindow.NativeWindowException;
48import com.jogamp.nativewindow.AbstractGraphicsDevice;
49import com.jogamp.nativewindow.NativeWindowFactory;
50import com.jogamp.nativewindow.VisualIDHolder;
51import com.jogamp.common.util.ReflectionUtil;
52import com.jogamp.common.util.SecurityUtil;
53import com.jogamp.common.util.VersionNumber;
54import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
55import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
56import com.jogamp.nativewindow.x11.X11GraphicsDevice;
58import jogamp.nativewindow.macosx.OSXUtil;
59import jogamp.nativewindow.x11.X11Lib;
60import jogamp.nativewindow.Debug;
63 private static final boolean DEBUG = Debug.debug(
"SWT");
65 private static final Method swt_scrollable_clientAreaInPixels;
66 private static final Method swt_control_locationInPixels;
67 private static final Method swt_control_sizeInPixels;
68 private static final Method swt_dpiutil_getScalingFactor;
70 private static final Field swt_control_handle;
71 private static final boolean swt_uses_long_handles;
73 private static Object swt_osx_init =
new Object();
74 private static Field swt_osx_control_view =
null;
75 private static Field swt_osx_view_id =
null;
77 private static final String nwt;
78 public static final boolean isOSX;
80 public static final boolean isX11;
85 private static final String str_handle =
"handle";
88 private static final String str_osx_view =
"view";
89 private static final String str_osx_id =
"id";
92 private static final Method swt_control_internal_new_GC;
93 private static final Method swt_control_internal_dispose_GC;
94 private static final String str_internal_new_GC =
"internal_new_GC";
95 private static final String str_internal_dispose_GC =
"internal_dispose_GC";
97 private static final String str_OS_gtk_class =
"org.eclipse.swt.internal.gtk.OS";
98 private static final String str_GTK_gtk_class =
"org.eclipse.swt.internal.gtk.GTK";
99 private static final String str_GTK3_gtk_class =
"org.eclipse.swt.internal.gtk3.GTK3";
100 private static final String str_GDK_gtk_class =
"org.eclipse.swt.internal.gtk.GDK";
102 private static final String str_OS_gtk_version =
"GTK_VERSION";
105 private static final Method OS_gtk_widget_realize;
106 private static final Method OS_gtk_widget_unrealize;
107 private static final Method OS_GTK_WIDGET_WINDOW;
108 private static final Method OS_gtk_widget_get_window;
109 private static final Method OS_gdk_x11_drawable_get_xdisplay;
110 private static final Method OS_gdk_x11_display_get_xdisplay;
111 private static final Method OS_gdk_window_get_display;
112 private static final Method OS_gdk_x11_drawable_get_xid;
113 private static final Method OS_gdk_x11_window_get_xid;
115 private static final String str_gtk_widget_realize =
"gtk_widget_realize";
116 private static final String str_gtk_widget_unrealize =
"gtk_widget_unrealize";
117 private static final String str_GTK_WIDGET_WINDOW =
"GTK_WIDGET_WINDOW";
118 private static final String str_gtk_widget_get_window =
"gtk_widget_get_window";
119 private static final String str_gdk_x11_drawable_get_xdisplay =
"gdk_x11_drawable_get_xdisplay";
120 private static final String str_gdk_x11_display_get_xdisplay =
"gdk_x11_display_get_xdisplay";
121 private static final String str_gdk_window_get_display =
"gdk_window_get_display";
122 private static final String str_gdk_x11_drawable_get_xid =
"gdk_x11_drawable_get_xid";
123 private static final String str_gdk_x11_window_get_xid =
"gdk_x11_window_get_xid";
125 private static final VersionNumber GTK_VERSION_2_14_0 =
new VersionNumber(2, 14, 0);
126 private static final VersionNumber GTK_VERSION_2_24_0 =
new VersionNumber(2, 24, 0);
128 private static final VersionNumber GTK_VERSION_3_0_0 =
new VersionNumber(3, 0, 0);
131 private static VersionNumber
GTK_VERSION(
final int version) {
133 final int micro = ( version ) & 0xff;
134 final int minor = ( version >> 8 ) & 0xff;
135 final int major = ( version >> 16 ) & 0xff;
136 return new VersionNumber(major, minor, micro);
140 final int SWT_VERSION_4_20 = 4944;
144 SecurityUtil.doPrivileged(
new PrivilegedAction<Object>() {
146 public Object run() {
151 nwt = NativeWindowFactory.getNativeWindowType(
false);
152 isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
153 isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
154 isX11 = NativeWindowFactory.TYPE_X11 == nwt;
155 final int swt_version = SWT.getVersion();
158 System.err.println(
"SWT: Platform: "+SWT.getPlatform()+
", Version: "+swt_version);
163 m = Control.class.getDeclaredMethod(
"getLocationInPixels");
164 m.setAccessible(
true);
165 }
catch (
final Exception ex) {
168 System.err.println(
"SWT: getLocationInPixels not implemented: "+ex.getMessage());
171 swt_control_locationInPixels = m;
175 m = Control.class.getDeclaredMethod(
"getSizeInPixels");
176 m.setAccessible(
true);
177 }
catch (
final Exception ex) {
180 System.err.println(
"SWT: getSizeInPixels not implemented: "+ex.getMessage());
183 swt_control_sizeInPixels = m;
187 m = Scrollable.class.getDeclaredMethod(
"getClientAreaInPixels");
188 m.setAccessible(
true);
189 }
catch (
final Exception ex) {
192 System.err.println(
"SWT: getClientAreaInPixels not implemented: "+ex.getMessage());
195 swt_scrollable_clientAreaInPixels = m;
199 m = DPIUtil.class.getDeclaredMethod(
"getScalingFactor");
200 m.setAccessible(
true);
201 }
catch (
final Exception ex) {
204 System.err.println(
"SWT: getScalingFactor not implemented: "+ex.getMessage());
207 swt_dpiutil_getScalingFactor = m;
212 f = Control.class.getField(str_handle);
213 }
catch (
final Exception ex) {
214 throw new NativeWindowException(ex);
217 swt_control_handle = f;
220 if (
null != swt_control_handle) {
221 ulh = swt_control_handle.getGenericType().toString().equals(
long.
class.toString());
223 ulh = Platform.is64Bit();
225 swt_uses_long_handles = ulh;
231 m = ReflectionUtil.getMethod(Control.class, str_internal_new_GC,
new Class[] { GCData.class });
232 }
catch (
final Exception ex) {
233 throw new NativeWindowException(ex);
235 swt_control_internal_new_GC = m;
239 if(swt_uses_long_handles) {
240 m = Control.class.getDeclaredMethod(str_internal_dispose_GC,
new Class[] {
long.class, GCData.class });
242 m = Control.class.getDeclaredMethod(str_internal_dispose_GC,
new Class[] {
int.class, GCData.class });
244 }
catch (
final NoSuchMethodException ex) {
245 throw new NativeWindowException(ex);
247 swt_control_internal_dispose_GC = m;
250 VersionNumber _gtk_version =
new VersionNumber(0, 0, 0);
251 Method m1=
null, m2=
null, m3=
null, m4=
null, m5=
null, m6=
null, m7=
null, m8=
null, m9=
null;
252 final Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
256 final ClassLoader cl = SWTAccessor.class.getClassLoader();
257 cGTK = ReflectionUtil.getClass(str_OS_gtk_class,
false, cl);
258 Field field_OS_gtk_version;
261 field_OS_gtk_version = cGTK.getField(str_OS_gtk_version);
262 }
catch (
final NoSuchFieldException ex) {
265 cGTK = ReflectionUtil.getClass(str_GTK_gtk_class,
false, cl);
266 field_OS_gtk_version = cGTK.getField(str_OS_gtk_version);
267 cGDK = ReflectionUtil.getClass(str_GDK_gtk_class,
false, cl);
269 _gtk_version =
GTK_VERSION(field_OS_gtk_version.getInt(
null));
271 System.err.println(
"SWT: GTK Version: "+_gtk_version.toString());
273 m1 = cGTK.getDeclaredMethod(str_gtk_widget_realize, handleType);
274 if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
275 if (swt_version < SWT_VERSION_4_20) {
276 m4 = cGTK.getDeclaredMethod(str_gtk_widget_get_window, handleType);
278 final Class<?> cGTK3 = ReflectionUtil.getClass(str_GTK3_gtk_class,
false, cl);
279 m4 = cGTK3.getDeclaredMethod(str_gtk_widget_get_window, handleType);
282 m3 = cGTK.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
284 if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
285 m6 = cGDK.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
286 m7 = cGDK.getDeclaredMethod(str_gdk_window_get_display, handleType);
288 m5 = cGTK.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
290 if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
291 m9 = cGDK.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
293 m8 = cGTK.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
295 }
catch (
final Exception ex) {
throw new NativeWindowException(ex); }
298 m2 = cGTK.getDeclaredMethod(str_gtk_widget_unrealize, handleType);
299 }
catch (
final Exception ex) { }
303 OS_gtk_widget_realize = m1;
304 OS_gtk_widget_unrealize = m2;
305 OS_GTK_WIDGET_WINDOW = m3;
306 OS_gtk_widget_get_window = m4;
307 OS_gdk_x11_drawable_get_xdisplay = m5;
308 OS_gdk_x11_display_get_xdisplay = m6;
309 OS_gdk_window_get_display = m7;
310 OS_gdk_x11_drawable_get_xid = m8;
311 OS_gdk_x11_window_get_xid = m9;
330 private static Number getIntOrLong(
final long arg) {
331 if(swt_uses_long_handles) {
332 return Long.valueOf(arg);
334 return Integer.valueOf((
int) arg);
337 private static void callStaticMethodL2V(
final Method m,
final long arg) {
338 ReflectionUtil.callMethod(
null, m,
new Object[] { getIntOrLong(arg) });
341 @SuppressWarnings(
"unused")
342 private static
void callStaticMethodLL2V(final Method m, final
long arg0, final
long arg1) {
343 ReflectionUtil.callMethod(
null, m,
new Object[] { getIntOrLong(arg0), getIntOrLong(arg1) });
346 @SuppressWarnings(
"unused")
347 private static
void callStaticMethodLLZ2V(final Method m, final
long arg0, final
long arg1, final
boolean arg3) {
348 ReflectionUtil.callMethod(
null, m,
new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
351 private static long callStaticMethodL2L(
final Method m,
final long arg) {
352 final Object o = ReflectionUtil.callMethod(
null, m,
new Object[] { getIntOrLong(arg) });
353 if(o instanceof Number) {
354 return ((Number)o).longValue();
356 throw new InternalError(
"SWT method "+m.getName()+
" didn't return int or long but "+o.getClass());
365 return swt_uses_long_handles;
378 window = callStaticMethodL2L(OS_gtk_widget_get_window, handle);
380 window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
391 final long display = callStaticMethodL2L(OS_gdk_window_get_display, window);
393 throw new NativeWindowException(
"Null display-handle of gtk-window-handle 0x"+Long.toHexString(window));
395 xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display);
397 xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window);
400 throw new NativeWindowException(
"Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window));
408 xWindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window);
410 xWindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window);
413 throw new NativeWindowException(
"Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window));
421 public static void printInfo(
final PrintStream out,
final Display d) {
422 out.println(
"SWT: Platform: "+SWT.getPlatform()+
", Version "+SWT.getVersion());
426 final Point dpi =
null != d ? d.getDPI() :
null;
427 out.println(
"SWT: Display.DPI "+dpi+
"; DPIUtil: autoScalingFactor "+
442 if(
null != swt_dpiutil_getScalingFactor ) {
444 return (
float) swt_dpiutil_getScalingFactor.invoke(
null);
445 }
catch (
final Throwable e) {
450 final int deviceZoom = DPIUtil.getDeviceZoom();
454 return deviceZoom/100f;
463 final int deviceZoom = DPIUtil.getDeviceZoom();
467 final float scaleFactor = deviceZoom/100f;
468 return Math.round (v * scaleFactor);
477 final int deviceZoom = DPIUtil.getDeviceZoom();
481 final float scaleFactor = deviceZoom/100f;
482 return Math.round (v / scaleFactor);
501 final int deviceZoom = DPIUtil.getDeviceZoom();
502 if ( 100 == deviceZoom ) {
505 return deviceZoom/100f;
519 final int deviceZoom = DPIUtil.getDeviceZoom();
520 if (100 == deviceZoom) {
523 final float scaleFactor = deviceZoom/100f;
524 return Math.round (v * scaleFactor);
538 final int deviceZoom = DPIUtil.getDeviceZoom();
539 if (100 == deviceZoom) {
542 final float scaleFactor = deviceZoom/100f;
543 return Math.round (v / scaleFactor);
557 final int deviceZoom = DPIUtil.getDeviceZoom();
558 if (100 == deviceZoom ||
null == v) {
561 final float scaleFactor = deviceZoom/100f;
562 return v.set(Math.round(v.getX() * scaleFactor), Math.round(v.getY() * scaleFactor));
576 final int deviceZoom = DPIUtil.getDeviceZoom();
577 if (100 == deviceZoom ||
null == v) {
580 final float scaleFactor = deviceZoom/100f;
581 return v.set(Math.round(v.getX() / scaleFactor), Math.round(v.getY() / scaleFactor));
612 if(
null == swt_scrollable_clientAreaInPixels ) {
613 return DPIUtil.autoScaleUp(s.getClientArea());
616 return (Rectangle) swt_scrollable_clientAreaInPixels.invoke(s);
617 }
catch (
final Throwable e) {
623 if(
null == swt_control_locationInPixels ) {
624 return DPIUtil.autoScaleUp(c.getLocation());
627 return (Point) swt_control_locationInPixels.invoke(c);
628 }
catch (
final Throwable e) {
633 if(
null == swt_control_sizeInPixels ) {
634 return DPIUtil.autoScaleUp(c.getSize());
637 return (Point) swt_control_sizeInPixels.invoke(c);
638 }
catch (
final Throwable e) {
651 synchronized(swt_osx_init) {
653 if(
null == swt_osx_view_id) {
654 swt_osx_control_view = Control.class.getField(str_osx_view);
655 final Object view = swt_osx_control_view.get(swtControl);
656 swt_osx_view_id = view.getClass().getField(str_osx_id);
657 h = swt_osx_view_id.getLong(view);
659 h = swt_osx_view_id.getLong( swt_osx_control_view.get(swtControl) );
661 }
catch (
final Exception ex) {
667 h = swt_control_handle.getLong(swtControl);
668 }
catch (
final Exception ex) {
673 throw new NativeWindowException(
"Null widget-handle of SWT "+swtControl.getClass().getName()+
": "+swtControl.toString());
678 public static void setRealized(
final Control swtControl,
final boolean realize)
681 if(!realize && swtControl.isDisposed()) {
684 final long handle =
getHandle(swtControl);
691 callStaticMethodL2V(OS_gtk_widget_realize, handle);
692 }
else if(
null != OS_gtk_widget_unrealize) {
693 callStaticMethodL2V(OS_gtk_widget_unrealize, handle);
707 final long handle =
getHandle(swtControl);
718 throw new UnsupportedOperationException(
"n/a for this windowing system: "+nwt);
732 return X11Lib.GetVisualIDFromWindow(device.
getHandle(), windowHandle);
737 throw new UnsupportedOperationException(
"n/a for this windowing system: "+nwt);
747 final long handle =
getHandle(swtControl);
757 throw new UnsupportedOperationException(
"n/a for this windowing system: "+nwt);
760 public static long newGC(
final Control swtControl,
final GCData gcData) {
761 final Object[] o =
new Object[1];
765 o[0] = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC,
new Object[] { gcData });
768 if(o[0] instanceof Number) {
769 return ((Number)o[0]).longValue();
771 throw new InternalError(
"SWT internal_new_GC did not return int or long but "+o[0].getClass());
775 public static void disposeGC(
final Control swtControl,
final long gc,
final GCData gcData) {
779 if(swt_uses_long_handles) {
780 ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC,
new Object[] { Long.valueOf(gc), gcData });
782 ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC,
new Object[] { Integer.valueOf((
int)gc), gcData });
806 OSXUtil.RunOnMainThread(blocking,
false, runnable);
822 public static void invokeOnSWTThread(
final org.eclipse.swt.widgets.Display display,
final boolean blocking,
final Runnable runnable) {
823 if(
null == display || display.isDisposed() || Thread.currentThread() == display.getThread() ) {
825 }
else if( blocking ) {
826 display.syncExec(runnable);
828 display.asyncExec(runnable);
833 public static boolean isOnSWTThread(
final org.eclipse.swt.widgets.Display display) {
834 return null != display && Thread.currentThread() == display.getThread();
842 final long handle =
getHandle(swtControl);
847 final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.
getDevice().
getHandle(), screen.
getIndex(), visualID, width, height,
true,
true);
849 return x11WindowHandle;
853 X11Lib.SetWindowPosSize(device.
getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height);
856 X11Lib.DestroyWindow(device.
getHandle(), x11Window);
908 public static void resizeGDKWindow(
final Rectangle clientArea,
final long gdkWindow) {
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static synchronized void initSingleton()
Static one time initialization of this factory.
static AbstractGraphicsScreen createScreen(final AbstractGraphicsDevice device, int screen)
Encapsulates a graphics device on MacOSX platforms.
static boolean isOnSWTThread(final org.eclipse.swt.widgets.Display display)
Return true if the current thread is the SWT UI thread, otherwise false.
static final boolean isOSX
static void showGDKWindow(final long gdkWindow)
static void destroyGDKWindow(final long gdkWindow)
static long createCompatibleGDKChildWindow(final Control swtControl, final int visualID, final int width, final int height)
static int autoScaleUp(final int v)
Returns SWT auto scaled-up value v, compatible with DPIUtil#autoScaleUp(int).
static long createCompatibleX11ChildWindow(final AbstractGraphicsScreen screen, final Control swtControl, final int visualID, final int width, final int height)
static void invokeOnOSTKThread(final boolean blocking, final Runnable runnable)
Runs the specified action in an SWT compatible OS toolkit thread, which is:
static void initSingleton()
Call this method, if this class shall be initialized before any other of its methods are called withi...
static long newGC(final Control swtControl, final GCData gcData)
static long getWindowHandle(final Control swtControl)
static long getHandle(final Control swtControl)
static void resizeGDKWindow(final Rectangle clientArea, final long gdkWindow)
static VersionNumber GTK_VERSION()
static int deviceZoomScaleDown(final int v)
Returns SWT derived scaled-down value v, based on DPIUtil#getDeviceZoom() only, not considering highe...
static final boolean isX11GTK
static void destroyX11Window(final AbstractGraphicsDevice device, final long x11Window)
static Rectangle getClientAreaInPixels(final Scrollable s)
Returns the unscaled Scrollable#getClientArea() in pixels.
static void invokeOnSWTThread(final org.eclipse.swt.widgets.Display display, final boolean blocking, final Runnable runnable)
Runs the specified action on the SWT UI thread.
static int deviceZoomScaleUp(final int v)
Returns SWT derived scaled-up value v, based on DPIUtil#getDeviceZoom() only, not considering higher-...
static com.jogamp.nativewindow.util.Point deviceZoomScaleDown(final com.jogamp.nativewindow.util.Point v)
Returns SWT derived scaled-down value v, based on DPIUtil#getDeviceZoom() only, not considering highe...
static float getDeviceZoomScalingFactor()
Returns SWT derived scale-factor based on DPIUtil#getDeviceZoom() only, not considering higher-toolki...
static Point getLocationInPixels(final Control c)
static Point getSizeInPixels(final Control c)
static void focusGDKWindow(final long gdkWindow)
static final boolean isWindows
static com.jogamp.nativewindow.util.Point deviceZoomScaleUp(final com.jogamp.nativewindow.util.Point v)
Returns SWT derived scaled-up value v, based on DPIUtil#getDeviceZoom() only, not considering higher-...
static final boolean isX11
static void disposeGC(final Control swtControl, final long gc, final GCData gcData)
static AbstractGraphicsDevice getDevice(final Control swtControl)
static AbstractGraphicsScreen getScreen(final AbstractGraphicsDevice device, final int screen)
static void printInfo(final PrintStream out, final Display d)
static void resizeX11Window(final AbstractGraphicsDevice device, final Rectangle clientArea, final long x11Window)
static final Class<?> OS_gtk_class
static long gdk_widget_get_window(final long handle)
static int getNativeVisualID(final AbstractGraphicsDevice device, final long windowHandle)
static long gdk_window_get_xdisplay(final long window)
static void setRealized(final Control swtControl, final boolean realize)
static final boolean useCairoAutoScale
static boolean useX11GTK()
static long gdk_window_get_xwindow(final long window)
static int autoScaleDown(final int v)
Returns SWT auto scaled-down value v, compatible with DPIUtil#autoScaleDown(int).
static final VersionNumber OS_gtk_version
static boolean isUsingLongHandles()
static float getAutoScalingFactor()
Returns SWT compatible auto scale-factor, used by DPIUtil.
Encapsulates a graphics device on Windows platforms.
Encapsulates a graphics device on X11 platforms.
A interface describing a graphics device in a toolkit-independent manner.
long getHandle()
Returns the native handle of the underlying native device, if such thing exist.
static int DEFAULT_UNIT
Default unit id for the 1st device: 0.
A interface describing a graphics screen in a toolkit-independent manner.
int getIndex()
Returns the screen index this graphics screen is valid for.
AbstractGraphicsDevice getDevice()
Return the device this graphics configuration is valid for.
Visual ID holder interface.
static final int VID_UNDEFINED
getVisualID(VIDType) result indicating an undefined value, which could be cause by an unsupported que...