diff options
author | rhatcher <[email protected]> | 2012-12-06 11:48:05 -0600 |
---|---|---|
committer | rhatcher <[email protected]> | 2012-12-06 11:48:05 -0600 |
commit | 603609c54139ccb1791b10bef5672f22f030d6a4 (patch) | |
tree | b0c68726a4e6ecf45e1623c7f275b382725c567c /src/nativewindow | |
parent | 811e3791b98fea0dfa3b7d301cb532c54df8dc82 (diff) | |
parent | 7a6f6b7a5b028e918a843de9fe16c38da75edba9 (diff) |
Merge branch 'master' of https://github.com/sgothel/jogl
Diffstat (limited to 'src/nativewindow')
3 files changed, 455 insertions, 99 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java index fca132f3f..eba26c7d3 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java @@ -34,6 +34,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import org.eclipse.swt.graphics.GCData; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import javax.media.nativewindow.AbstractGraphicsScreen; @@ -44,6 +45,7 @@ import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.VisualIDHolder; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.VersionNumber; import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsDevice; @@ -53,53 +55,93 @@ import jogamp.nativewindow.macosx.OSXUtil; import jogamp.nativewindow.x11.X11Lib; public class SWTAccessor { - static final Field swt_control_handle; - static final boolean swt_uses_long_handles; + private static final boolean DEBUG = true; + + private static final Field swt_control_handle; + private static final boolean swt_uses_long_handles; + + private static Object swt_osx_init = new Object(); + private static Field swt_osx_control_view = null; + private static Field swt_osx_view_id = null; + + private static final String nwt; + private static final boolean isOSX; + private static final boolean isWindows; + private static final boolean isX11; + private static final boolean isX11GTK; // X11/GTK, Windows/GDI, .. - static final String str_handle = "handle"; + private static final String str_handle = "handle"; // OSX/Cocoa - static final String str_view = "view"; // OSX - static final String str_id = "id"; // OSX + private static final String str_osx_view = "view"; // OSX + private static final String str_osx_id = "id"; // OSX // static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView"; - static final Method swt_control_internal_new_GC; - static final Method swt_control_internal_dispose_GC; - static final String str_internal_new_GC = "internal_new_GC"; - static final String str_internal_dispose_GC = "internal_dispose_GC"; + private static final Method swt_control_internal_new_GC; + private static final Method swt_control_internal_dispose_GC; + private static final String str_internal_new_GC = "internal_new_GC"; + private static final String str_internal_dispose_GC = "internal_dispose_GC"; - static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS"; - static final Class<?> OS_gtk_class; - static final Method OS_gtk_widget_realize; - static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3) - static final Method OS_GTK_WIDGET_WINDOW; - static final Method OS_gdk_x11_drawable_get_xdisplay; - static final Method OS_gdk_x11_drawable_get_xid; - static final String str_gtk_widget_realize = "gtk_widget_realize"; - static final String str_gtk_widget_unrealize = "gtk_widget_unrealize"; - static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW"; - static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay"; - static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid"; + private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS"; + public static final Class<?> OS_gtk_class; + private static final String str_OS_gtk_version = "GTK_VERSION"; + public static final VersionNumber OS_gtk_version; + + private static final Method OS_gtk_widget_realize; + private static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3) + private static final Method OS_GTK_WIDGET_WINDOW; + private static final Method OS_gtk_widget_get_window; + private static final Method OS_gdk_x11_drawable_get_xdisplay; + private static final Method OS_gdk_x11_display_get_xdisplay; + private static final Method OS_gdk_window_get_display; + private static final Method OS_gdk_x11_drawable_get_xid; + private static final Method OS_gdk_x11_window_get_xid; + private static final Method OS_gdk_window_set_back_pixmap; + + private static final String str_gtk_widget_realize = "gtk_widget_realize"; + private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize"; + private static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW"; + private static final String str_gtk_widget_get_window = "gtk_widget_get_window"; + private static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay"; + private static final String str_gdk_x11_display_get_xdisplay = "gdk_x11_display_get_xdisplay"; + private static final String str_gdk_window_get_display = "gdk_window_get_display"; + private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid"; + private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid"; + private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap"; + + private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0); + private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0); + private static final VersionNumber GTK_VERSION_3_0_0 = new VersionNumber(3, 0, 0); + + private static VersionNumber GTK_VERSION(int version) { + // return (major << 16) + (minor << 8) + micro; + final int micro = ( version ) & 0x0f; + final int minor = ( version >> 8 ) & 0x0f; + final int major = ( version >> 16 ) & 0x0f; + return new VersionNumber(major, minor, micro); + } static { - Field f = null; - AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { NativeWindowFactory.initSingleton(); // last resort .. return null; } } ); - final String nwt = NativeWindowFactory.getNativeWindowType(false); - - if(NativeWindowFactory.TYPE_MACOSX != nwt ) { + nwt = NativeWindowFactory.getNativeWindowType(false); + isOSX = NativeWindowFactory.TYPE_MACOSX == nwt; + isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt; + isX11 = NativeWindowFactory.TYPE_X11 == nwt; + + Field f = null; + if( !isOSX ) { try { f = Control.class.getField(str_handle); } catch (Exception ex) { throw new NativeWindowException(ex); } - } + } swt_control_handle = f; // maybe null ! boolean ulh; @@ -131,17 +173,34 @@ public class SWTAccessor { } swt_control_internal_dispose_GC = m; - Class<?> c=null; - Method m1=null, m2=null, m3=null, m4=null, m5=null; - Class<?> handleType = swt_uses_long_handles ? long.class : int.class ; - if( NativeWindowFactory.TYPE_X11 == nwt ) { + Class<?> c=null; + VersionNumber _gtk_version = new VersionNumber(0, 0, 0); + Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null; + final Class<?> handleType = swt_uses_long_handles ? long.class : int.class ; + if( isX11 ) { // mandatory try { c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader()); + Field field_OS_gtk_version = c.getField(str_OS_gtk_version); + _gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null)); m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType); - m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType); - m4 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType); - m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType); + if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) { + m4 = c.getDeclaredMethod(str_gtk_widget_get_window, handleType); + } else { + m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType); + } + if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) { + m6 = c.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType); + m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType); + } else { + m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType); + } + if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) { + m9 = c.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType); + } else { + m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType); + } + ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class); } catch (Exception ex) { throw new NativeWindowException(ex); } // optional try { @@ -149,25 +208,41 @@ public class SWTAccessor { } catch (Exception ex) { } } OS_gtk_class = c; + OS_gtk_version = _gtk_version; OS_gtk_widget_realize = m1; OS_gtk_widget_unrealize = m2; OS_GTK_WIDGET_WINDOW = m3; - OS_gdk_x11_drawable_get_xdisplay = m4; - OS_gdk_x11_drawable_get_xid = m5; + OS_gtk_widget_get_window = m4; + OS_gdk_x11_drawable_get_xdisplay = m5; + OS_gdk_x11_display_get_xdisplay = m6; + OS_gdk_window_get_display = m7; + OS_gdk_x11_drawable_get_xid = m8; + OS_gdk_x11_window_get_xid = m9; + OS_gdk_window_set_back_pixmap = ma; + + isX11GTK = isX11 && null != OS_gtk_class; + + if(DEBUG) { + System.err.println("SWTAccessor.<init>: GTK Version: "+OS_gtk_version); + } } - - static Object getIntOrLong(long arg) { + + private static Number getIntOrLong(long arg) { if(swt_uses_long_handles) { return new Long(arg); } return new Integer((int) arg); } - static void callStaticMethodL2V(Method m, long arg) { + private static void callStaticMethodL2V(Method m, long arg) { ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) }); } - static long callStaticMethodL2L(Method m, long arg) { + private static void callStaticMethodLLZ2V(Method m, long arg0, long arg1, boolean arg3) { + ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) }); + } + + private static long callStaticMethodL2L(Method m, long arg) { Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) }); if(o instanceof Number) { return ((Number)o).longValue(); @@ -175,33 +250,114 @@ public class SWTAccessor { throw new InternalError("SWT method "+m.getName()+" didn't return int or long but "+o.getClass()); } } - + + // + // Public properties + // + public static boolean isUsingLongHandles() { return swt_uses_long_handles; } - public static long getHandle(Control swtControl) { + public static boolean useX11GTK() { return isX11GTK; } + public static VersionNumber GTK_VERSION() { return OS_gtk_version; } + + // + // Common GTK + // + + public static long gdk_widget_get_window(long handle) { + final long window; + if (OS_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) { + window = callStaticMethodL2L(OS_gtk_widget_get_window, handle); + } else { + window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); + } + if(0 == window) { + throw new NativeWindowException("Null gtk-window-handle of SWT handle 0x"+Long.toHexString(handle)); + } + return window; + } + + public static long gdk_window_get_xdisplay(long window) { + final long xdisplay; + if (OS_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) { + final long display = callStaticMethodL2L(OS_gdk_window_get_display, window); + if(0 == display) { + throw new NativeWindowException("Null display-handle of gtk-window-handle 0x"+Long.toHexString(window)); + } + xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display); + } else { + xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window); + } + if(0 == xdisplay) { + throw new NativeWindowException("Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window)); + } + return xdisplay; + } + + public static long gdk_window_get_xwindow(long window) { + final long xWindow; + if (OS_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) { + xWindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window); + } else { + xWindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window); + } + if(0 == xWindow) { + throw new NativeWindowException("Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window)); + } + return xWindow; + } + + public static void gdk_window_set_back_pixmap(long window, long pixmap, boolean parent_relative) { + callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative); + } + + // + // Common any toolkit + // + + /** + * @param swtControl the SWT Control to retrieve the native widget-handle from + * @return the native widget-handle + * @throws NativeWindowException if the widget handle is null + */ + public static long getHandle(Control swtControl) throws NativeWindowException { long h = 0; - if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) { + if( isOSX ) { + synchronized(swt_osx_init) { + try { + if(null == swt_osx_view_id) { + swt_osx_control_view = Control.class.getField(str_osx_view); + Object view = swt_osx_control_view.get(swtControl); + swt_osx_view_id = view.getClass().getField(str_osx_id); + h = swt_osx_view_id.getLong(view); + } else { + h = swt_osx_view_id.getLong( swt_osx_control_view.get(swtControl) ); + } + } catch (Exception ex) { + throw new NativeWindowException(ex); + } + } + } else { try { - Field fView = Control.class.getField(str_view); - Object view = fView.get(swtControl); - Field fId = view.getClass().getField(str_id); - return fId.getLong(view); + h = swt_control_handle.getLong(swtControl); } catch (Exception ex) { throw new NativeWindowException(ex); - } + } } - - try { - h = swt_control_handle.getLong(swtControl); - } catch (Exception ex) { - throw new NativeWindowException(ex); + if(0 == h) { + throw new NativeWindowException("Null widget-handle of SWT "+swtControl.getClass().getName()+": "+swtControl.toString()); } return h; } - public static void setRealized(final Control swtControl, final boolean realize) { + public static void setRealized(final Control swtControl, final boolean realize) + throws NativeWindowException + { + if(!realize && swtControl.isDisposed()) { + return; + } final long handle = getHandle(swtControl); if(null != OS_gtk_class) { @@ -216,55 +372,77 @@ public class SWTAccessor { }); } } - - public static AbstractGraphicsDevice getDevice(Control swtControl) { - long handle = getHandle(swtControl); - if( null != OS_gtk_class ) { - long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); - long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle); - return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */); + + /** + * @param swtControl the SWT Control to retrieve the native device handle from + * @return the AbstractGraphicsDevice w/ the native device handle + * @throws NativeWindowException if the widget handle is null + * @throws UnsupportedOperationException if the windowing system is not supported + */ + public static AbstractGraphicsDevice getDevice(Control swtControl) throws NativeWindowException, UnsupportedOperationException { + final long handle = getHandle(swtControl); + if( isX11GTK ) { + final long xdisplay0 = gdk_window_get_xdisplay( gdk_widget_get_window( handle ) ); + return new X11GraphicsDevice(xdisplay0, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */); } - final String nwt = NativeWindowFactory.getNativeWindowType(false); - if( NativeWindowFactory.TYPE_WINDOWS == nwt ) { + if( isWindows ) { return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); } - if( NativeWindowFactory.TYPE_MACOSX == nwt ) { + if( isOSX ) { return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); } throw new UnsupportedOperationException("n/a for this windowing system: "+nwt); } - public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) { - if( null != OS_gtk_class ) { - return new X11GraphicsScreen((X11GraphicsDevice)device, screen); + + /** + * + * @param device + * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen + * @return + * @throws UnsupportedOperationException + */ + public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) throws UnsupportedOperationException { + if( isX11 ) { + X11GraphicsDevice x11Device = (X11GraphicsDevice)device; + if(0 > screen) { + screen = x11Device.getDefaultScreen(); + } + return new X11GraphicsScreen(x11Device, screen); } - final String nwt = NativeWindowFactory.getNativeWindowType(false); - if( NativeWindowFactory.TYPE_WINDOWS == nwt || - NativeWindowFactory.TYPE_MACOSX == nwt ) { + if(0 > screen) { + screen = 0; // FIXME: Needs native API utilization + } + if( isWindows || isOSX ) { return new DefaultGraphicsScreen(device, screen); } throw new UnsupportedOperationException("n/a for this windowing system: "+nwt); } + public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) { - if( null != OS_gtk_class ) { + if( isX11 ) { return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle); } - final String nwt = NativeWindowFactory.getNativeWindowType(false); - if( NativeWindowFactory.TYPE_WINDOWS == nwt || - NativeWindowFactory.TYPE_MACOSX == nwt ) { + if( isWindows || isOSX ) { return VisualIDHolder.VID_UNDEFINED; } throw new UnsupportedOperationException("n/a for this windowing system: "+nwt); } - public static long getWindowHandle(Control swtControl) { - long handle = getHandle(swtControl); - if( null != OS_gtk_class ) { - long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); - return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle); + /** + * @param swtControl the SWT Control to retrieve the native window handle from + * @return the native window handle + * @throws NativeWindowException if the widget handle is null + * @throws UnsupportedOperationException if the windowing system is not supported + */ + public static long getWindowHandle(Control swtControl) throws NativeWindowException, UnsupportedOperationException { + final long handle = getHandle(swtControl); + if(0 == handle) { + throw new NativeWindowException("Null SWT handle of SWT control "+swtControl); + } + if( isX11GTK ) { + return gdk_window_get_xwindow( gdk_widget_get_window( handle ) ); } - final String nwt = NativeWindowFactory.getNativeWindowType(false); - if( NativeWindowFactory.TYPE_WINDOWS == nwt || - NativeWindowFactory.TYPE_MACOSX == nwt ) { + if( isWindows || isOSX ) { return handle; } throw new UnsupportedOperationException("n/a for this windowing system: "+nwt); @@ -283,7 +461,7 @@ public class SWTAccessor { throw new InternalError("SWT internal_new_GC did not return int or long but "+o[0].getClass()); } } - + public static void disposeGC(final Control swtControl, final long gc, final GCData gcData) { invoke(true, new Runnable() { public void run() { @@ -313,7 +491,7 @@ public class SWTAccessor { * @see Platform#getOSType() */ public static void invoke(boolean wait, Runnable runnable) { - if( Platform.OS_TYPE == Platform.OSType.MACOS ) { + if( isOSX ) { // Use SWT main thread! Only reliable config w/ -XStartOnMainThread !? OSXUtil.RunOnMainThread(wait, runnable); } else { @@ -321,4 +499,85 @@ public class SWTAccessor { } } + // + // Specific X11 GTK ChildWindow - Using plain X11 native parenting (works well) + // + + public static long createCompatibleX11ChildWindow(AbstractGraphicsScreen screen, Control swtControl, int visualID, int width, int height) { + final long handle = getHandle(swtControl); + final long parentWindow = gdk_widget_get_window( handle ); + gdk_window_set_back_pixmap (parentWindow, 0, false); + + final long x11ParentHandle = gdk_window_get_xwindow(parentWindow); + final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.getDevice().getHandle(), screen.getIndex(), visualID, width, height, true, true); + + return x11WindowHandle; + } + + public static void resizeX11Window(AbstractGraphicsDevice device, Rectangle clientArea, long x11Window) { + X11Lib.SetWindowPosSize(device.getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height); + } + public static void destroyX11Window(AbstractGraphicsDevice device, long x11Window) { + X11Lib.DestroyWindow(device.getHandle(), x11Window); + } + + // + // Specific X11 SWT/GTK ChildWindow - Using SWT/GTK native parenting (buggy - sporadic resize flickering, sporadic drop of rendering) + // + // FIXME: Need to use reflection for 32bit access as well ! + // + + // public static final int GDK_WA_TYPE_HINT = 1 << 9; + // public static final int GDK_WA_VISUAL = 1 << 6; + + public static long createCompatibleGDKChildWindow(Control swtControl, int visualID, int width, int height) { + return 0; + /** + final long handle = SWTAccessor.getHandle(swtControl); + final long parentWindow = gdk_widget_get_window( handle ); + + final long screen = OS.gdk_screen_get_default (); + final long gdkvisual = OS.gdk_x11_screen_lookup_visual (screen, visualID); + + final GdkWindowAttr attrs = new GdkWindowAttr(); + attrs.width = width > 0 ? width : 1; + attrs.height = height > 0 ? height : 1; + attrs.event_mask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK | + OS.GDK_FOCUS_CHANGE_MASK | OS.GDK_POINTER_MOTION_MASK | + OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK | + OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK | + OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK | + OS.GDK_POINTER_MOTION_HINT_MASK; + attrs.window_type = OS.GDK_WINDOW_CHILD; + attrs.visual = gdkvisual; + + final long childWindow = OS.gdk_window_new (parentWindow, attrs, OS.GDK_WA_VISUAL|GDK_WA_TYPE_HINT); + OS.gdk_window_set_user_data (childWindow, handle); + OS.gdk_window_set_back_pixmap (parentWindow, 0, false); + + OS.gdk_window_show (childWindow); + OS.gdk_flush(); + return childWindow; */ + } + + public static void showGDKWindow(long gdkWindow) { + /* OS.gdk_window_show (gdkWindow); + OS.gdk_flush(); */ + } + public static void focusGDKWindow(long gdkWindow) { + /* + OS.gdk_window_show (gdkWindow); + OS.gdk_window_focus(gdkWindow, 0); + OS.gdk_flush(); */ + } + public static void resizeGDKWindow(Rectangle clientArea, long gdkWindow) { + /** + OS.gdk_window_move (gdkWindow, clientArea.x, clientArea.y); + OS.gdk_window_resize (gdkWindow, clientArea.width, clientArea.height); + OS.gdk_flush(); */ + } + + public static void destroyGDKWindow(long gdkWindow) { + // OS.gdk_window_destroy (gdkWindow); + } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java index 67a33e55c..827862002 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java @@ -37,7 +37,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ); } if( 0 == s.getSurfaceHandle() ) { - final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64); + final long windowHandle = X11Lib.CreateWindow(0, device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64, false, false); if(0 == windowHandle) { throw new NativeWindowException("Creating dummy window failed w/ "+cfg); } @@ -59,7 +59,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize } device.lock(); try { - X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle()); + X11Lib.DestroyWindow(device.getHandle(), s.getSurfaceHandle()); s.setSurfaceHandle(0); s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); } finally { diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index c73952693..a8d45f288 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -31,6 +31,8 @@ #include "jogamp_nativewindow_x11_X11Lib.h" #include "jogamp_nativewindow_x11_X11Util.h" +#include <X11/Xatom.h> + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -85,6 +87,8 @@ Bool XF86VidModeSetGammaRamp( #define RTLD_DEFAULT NULL #endif +#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask) + static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; @@ -436,17 +440,62 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused return _res; } +static void NativewindowX11_setNormalWindowEWMH (Display *dpy, Window w) { + Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False ); + Atom types[1]={0}; + types[0] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False ); + XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1); + XSync(dpy, False); +} + +#define DECOR_USE_MWM 1 // works for known WMs +// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated) + +/* see <http://tonyobryan.com/index.php?article=9> */ +#define MWM_HINTS_DECORATIONS (1L << 1) +#define PROP_MWM_HINTS_ELEMENTS 5 + +static void NativewindowX11_setDecorations (Display *dpy, Window w, Bool decorated) { + +#ifdef DECOR_USE_MWM + unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status + Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False ); +#endif + +#ifdef DECOR_USE_EWMH + Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False ); + Atom types[3]={0}; + int ntypes=0; + if(True==decorated) { + types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False ); + } else { + types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False ); + } +#endif + +#ifdef DECOR_USE_MWM + XChangeProperty( dpy, w, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS); +#endif + +#ifdef DECOR_USE_EWMH + XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); +#endif + + XSync(dpy, False); +} + /* * Class: jogamp_nativewindow_x11_X11Lib - * Method: CreateDummyWindow - * Signature: (JIIII)J + * Method: CreateWindow + * Signature: (JJIIIIZZ)J */ -JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow - (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height) +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow + (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; - Window windowParent = 0; + Window root = RootWindow(dpy, scrn_idx); + Window windowParent = (Window) parent; Window window = 0; XVisualInfo visualTemplate; @@ -473,6 +522,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0); scrn = ScreenOfDisplay(dpy, scrn_idx); + if(0==windowParent) { + windowParent = root; + } // try given VisualID on screen memset(&visualTemplate, 0, sizeof(XVisualInfo)); @@ -500,9 +552,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow pVisualQuery=NULL; } - if(0==windowParent) { - windowParent = XRootWindowOfScreen(scrn); - } attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; @@ -514,15 +563,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ xswa.backing_planes=0; /* planes to be preserved if possible */ xswa.backing_pixel=0; /* value to use in restoring planes */ + if( input ) { + xswa.event_mask = X11_MOUSE_EVENT_MASK; + xswa.event_mask |= KeyPressMask | KeyReleaseMask ; + } + if( visible ) { + xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ; + } xswa.colormap = XCreateColormap(dpy, - XRootWindow(dpy, scrn_idx), + windowParent, visual, AllocNone); window = XCreateWindow(dpy, windowParent, - 0, 0, + 0, 0, // only a hint, WM most likely will override width, height, 0, // border width depth, @@ -530,9 +586,25 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow visual, attrMask, &xswa); + if(0==window) { + NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!"); + return 0; + } + + NativewindowX11_setNormalWindowEWMH(dpy, window); + NativewindowX11_setDecorations(dpy, window, False); + + if( visible ) { + XEvent event; + + XMapWindow(dpy, window); + } + XSync(dpy, False); - XSelectInput(dpy, window, 0); // no events + if( !input ) { + XSelectInput(dpy, window, 0); // no events + } // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1); @@ -544,10 +616,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow /* * Class: jogamp_nativewindow_x11_X11Lib - * Method: DestroyDummyWindow + * Method: DestroyWindow * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow +JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow (JNIEnv *env, jclass unused, jlong display, jlong window) { Display * dpy = (Display *)(intptr_t)display; @@ -559,12 +631,37 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0); + XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1); } +JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_SetWindowPosSize + (JNIEnv *env, jclass unused, jlong display, jlong window, jint x, jint y, jint width, jint height) { + Display * dpy = (Display *)(intptr_t)display; + Window w = (Window) window; + XWindowChanges xwc; + int flags = 0; + + memset(&xwc, 0, sizeof(XWindowChanges)); + + if(0<=x && 0<=y) { + flags |= CWX | CWY; + xwc.x=x; + xwc.y=y; + } + + if(0<width && 0<height) { + flags |= CWWidth | CWHeight; + xwc.width=width; + xwc.height=height; + } + XConfigureWindow(dpy, w, flags, &xwc); + XSync(dpy, False); +} + /* * Class: jogamp_nativewindow_x11_X11Lib * Method: GetRelativeLocation |