diff options
author | Sven Gothel <[email protected]> | 2010-05-04 06:35:37 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-05-04 06:35:37 +0200 |
commit | 9e792dcef900de7039cd277459c0629abfab9f21 (patch) | |
tree | 81adfd1e07e2118675d62836e1289225f408bb00 /src | |
parent | a677e9db03ea44ea353fb9de61e2a86a6e063d0f (diff) |
NEWT Fixes:
- Common native in NewtCommon.c/.h
- Add simple NEWTEventFiFo, providing a pattern
to spool events by an EventListener and to process them
where it impacts (GLEventListener ..)
- Window [X11|Windows]: setSize/setPosition:
- always store the values,
- only act if valid and !fullscreen
- Window [X11]:
- Add requestFocus
- Add setTitle
- Fix parent/child window creation
- Fix parent/child window fullscreen (reparenting)
- JUnit Test: ParentTest:
- Shows parent and client window animation
- Client window shall be able to go into fullscreen,
ie disconnect/reconnect from its parent.
Test: Focus-client + type-'f'
- Both windows receive/dispatch events properly
Diffstat (limited to 'src')
-rw-r--r-- | src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java | 4 | ||||
-rw-r--r-- | src/junit/com/jogamp/test/junit/newt/KeyAction.java | 50 | ||||
-rwxr-xr-x | src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java | 70 | ||||
-rwxr-xr-x | src/newt/classes/com/jogamp/newt/Window.java | 3 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java | 66 | ||||
-rwxr-xr-x | src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java | 12 | ||||
-rwxr-xr-x | src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java | 80 | ||||
-rw-r--r-- | src/newt/native/NewtCommon.c | 13 | ||||
-rw-r--r-- | src/newt/native/NewtCommon.h | 10 | ||||
-rwxr-xr-x | src/newt/native/WindowsWindow.c | 21 | ||||
-rwxr-xr-x | src/newt/native/X11Window.c | 175 |
11 files changed, 395 insertions, 109 deletions
diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java index a5bf3fda7..1fa49be8c 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java @@ -64,8 +64,8 @@ public class Gears implements GLEventListener { gl.glEnable(GL2.GL_NORMALIZE); - MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter()); - // MouseListener gearsMouse = new GearsMouseAdapter(); + // MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter()); + MouseListener gearsMouse = new GearsMouseAdapter(); if (drawable instanceof Component) { Component comp = (Component) drawable; diff --git a/src/junit/com/jogamp/test/junit/newt/KeyAction.java b/src/junit/com/jogamp/test/junit/newt/KeyAction.java new file mode 100644 index 000000000..29b3d2ee2 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/KeyAction.java @@ -0,0 +1,50 @@ + +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.jogamp.test.junit.newt; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.newt.event.*; + +class KeyAction extends KeyAdapter { + NEWTEventFiFo eventFifo; + + public KeyAction(NEWTEventFiFo eventFifo) { + this.eventFifo = eventFifo; + } + + public void keyTyped(KeyEvent e) { + eventFifo.put(e); + } +} + diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java index 6415d553b..474025835 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java @@ -60,6 +60,7 @@ import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01NEWT { static int width, height; + static long durationPerTest = 500; @BeforeClass public static void initClass() { @@ -88,7 +89,7 @@ public class TestParenting01NEWT { Assert.assertTrue(true==window.isVisible()); Assert.assertTrue(width==window.getWidth()); Assert.assertTrue(height==window.getHeight()); - // System.out.println("Created: "+window); + System.out.println("Created: "+window); // // Create native OpenGL resources .. XGL/WGL/CGL .. @@ -120,7 +121,7 @@ public class TestParenting01NEWT { } @Test - public void testWindowParentingNewtOnNewt() throws InterruptedException { + public void testWindowParenting01NewtOnNewtParentChildDraw() throws InterruptedException { GLCapabilities caps = new GLCapabilities(null); Assert.assertNotNull(caps); Display display = NewtFactory.createDisplay(null); // local display @@ -128,39 +129,75 @@ public class TestParenting01NEWT { Screen screen = NewtFactory.createScreen(display, 0); // screen 0 Assert.assertNotNull(screen); - Window window1 = createWindow( null, screen, caps, width, height, true /* onscreen */, false /* undecorated */); - Window window2 = createWindow(window1, screen, caps, width/2, height/2, true /* onscreen */, false /* undecorated */); + int x = 1; + int y = 1; + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + Window window1 = createWindow( null, screen, caps, width, height, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window1); + window1.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - PARENT"); + window1.setPosition(x,y); + window1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); GLWindow glWindow1 = GLWindow.create(window1); Assert.assertNotNull(glWindow1); + + Window window2 = createWindow(window1, screen, caps, width/2, height/2, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window2); + window2.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - CHILD"); + window2.setPosition(window1.getWidth()/2, window1.getHeight()/2); + window2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); + GLWindow glWindow2 = GLWindow.create(window2); + Assert.assertNotNull(glWindow2); + GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, window1, glWindow1, false); glWindow1.addGLEventListener(demo1); - GLWindow glWindow2 = GLWindow.create(window2); - Assert.assertNotNull(glWindow2); GLEventListener demo2 = new Gears(); setDemoFields(demo2, window2, glWindow2, false); glWindow2.addGLEventListener(demo2); - glWindow1.setVisible(true); + window2.setVisible(true); + window1.setVisible(true); + glWindow2.setVisible(true); + glWindow1.setVisible(true); + + glWindow2.display(); + glWindow1.display(); - int x = window1.getX(); - int y = window1.getY(); - long duration = 2000; + long duration = durationPerTest; long step = 20; - while (duration>0) { - // glWindow1.display(); + KeyEvent keyEvent; + boolean shouldQuit = false; + + while (duration>0 && !shouldQuit) { + while( null != ( keyEvent = (KeyEvent) eventFifo.get() ) ) { + Window source = (Window) keyEvent.getSource(); + switch(keyEvent.getKeyChar()) { + case 'q': + System.out.println(keyEvent); + shouldQuit = true; + break; + case 'f': + System.out.println(keyEvent); + source.setFullscreen(!source.isFullscreen()); + break; + } + } + + glWindow1.display(); glWindow2.display(); Thread.sleep(step); // 1000 ms duration -= step; - x += 10; - y += 10; - // window1.setPosition(x,y); + x += 1; + y += 1; + window1.setPosition(x,y); + window2.setPosition(window1.getWidth()/2,window1.getHeight()/2-y); } destroyWindow(null, null, window2, glWindow2); - destroyWindow(display, screen, window1, null); + destroyWindow(display, screen, window1, glWindow1); } public static void setDemoFields(GLEventListener demo, Window window, GLWindow glWindow, boolean debug) { @@ -176,6 +213,7 @@ public class TestParenting01NEWT { } public static void main(String args[]) throws IOException { + durationPerTest = 5000; String tstname = TestParenting01NEWT.class.getName(); org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 1802cab8e..653d76522 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -254,6 +254,9 @@ public abstract class Window implements NativeWindow } public void setTitle(String title) { + if (title == null) { + title = ""; + } this.title = title; } diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java b/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java new file mode 100644 index 000000000..976085aa6 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ +package com.jogamp.newt.event; + +import com.jogamp.newt.*; +import java.util.LinkedList; + +public class NEWTEventFiFo +{ + private LinkedList/*<NEWTEvent>*/ events = new LinkedList/*<NEWTEvent>*/(); + + /** Add NEWTEvent to tail */ + public synchronized void put(NEWTEvent event) { + events.addLast(event); + notifyAll(); + } + + /** Remove NEWTEvent from head */ + public synchronized NEWTEvent get() { + if (0 == events.size()) { + return null; + } + + return (NEWTEvent) events.removeFirst(); + } + + /** Get NEWTEvents in queue */ + public synchronized int size() { + return events.size(); + } + + /** Clear all NEWTEvents from queue */ + public synchronized void clear() { + events.clear(); + } + +} diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index dc870f43d..ce1a0ad2e 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -157,27 +157,31 @@ public class WindowsWindow extends Window { // @Override public void setSize(int width, int height) { - if (0!=windowHandle && (width != this.width || this.height != height)) { + if (width != this.width || this.height != height) { if(!fullscreen) { nfs_width=width; nfs_height=height; } this.width = width; this.height = height; - setSize0(parentWindowHandle, windowHandle, x, y, width, height); + if(0!=windowHandle && !fullscreen) { + setSize0(parentWindowHandle, windowHandle, x, y, width, height); + } } } //@Override public void setPosition(int x, int y) { - if (0!=windowHandle && (this.x != x || this.y != y)) { + if ( this.x != x || this.y != y ) { if(!fullscreen) { nfs_x=x; nfs_y=y; } this.x = x; this.y = y; - setPosition(parentWindowHandle, windowHandle, x , y); + if(0!=windowHandle && !fullscreen) { + setPosition(parentWindowHandle, windowHandle, x , y); + } } } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index c7401ef23..cd089ccfb 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -61,7 +61,8 @@ public class X11Window extends Window { long visualID = x11config.getVisualID(); long w = CreateWindow(parentWindowHandle, display.getHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), x, y, width, height); + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + x, y, width, height, undecorated||0!=parentWindowHandle); if (w == 0 || w!=windowHandle) { throw new NativeWindowException("Error creating window: "+w); } @@ -93,24 +94,22 @@ public class X11Window extends Window { } } - public void requestFocus() { - super.requestFocus(); - } - public void setSize(int width, int height) { if(DEBUG_IMPLEMENTATION) { System.err.println("X11Window setSize: "+this.x+"/"+this.y+" "+this.width+"x"+this.height+" -> "+width+"x"+height); // Exception e = new Exception("XXXXXXXXXX"); // e.printStackTrace(); } - this.width = width; - this.height = height; - if(!fullscreen) { - nfs_width=width; - nfs_height=height; - } - if(0!=windowHandle) { - setSize0(parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, width, height, (undecorated||fullscreen)?-1:1, false); + if (width != this.width || this.height != height) { + this.width = width; + this.height = height; + if(!fullscreen) { + nfs_width=width; + nfs_height=height; + } + if(0!=windowHandle && !fullscreen) { + setSize0(getDisplayHandle(), windowHandle, width, height); + } } } @@ -120,14 +119,16 @@ public class X11Window extends Window { // Exception e = new Exception("XXXXXXXXXX"); // e.printStackTrace(); } - this.x = x; - this.y = y; - if(!fullscreen) { - nfs_x=x; - nfs_y=y; - } - if(0!=windowHandle) { - setPosition0(getDisplayHandle(), windowHandle, x, y); + if ( this.x != x || this.y != y ) { + this.x = x; + this.y = y; + if(!fullscreen) { + nfs_x=x; + nfs_y=y; + } + if(0!=windowHandle && !fullscreen) { + setPosition0(parentWindowHandle, getDisplayHandle(), windowHandle, x, y); + } } } @@ -148,23 +149,50 @@ public class X11Window extends Window { if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h); } - setSize0(parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, w, h, (undecorated||fullscreen)?-1:1, false); + setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, w, h, (undecorated||fullscreen)?-1:1); + if(fullscreen) { + requestFocus0(getDisplayHandle(), windowHandle); + } } return fullscreen; } + // @Override + public void requestFocus() { + super.requestFocus(); + if (windowHandle != 0L) { + requestFocus0(getDisplayHandle(), windowHandle); + } + } + + // @Override + public void setTitle(String title) { + if (title == null) { + title = ""; + } + if (0!=windowHandle && !title.equals(getTitle())) { + super.setTitle(title); + setTitle0(getDisplayHandle(), windowHandle, title); + } + } + + //---------------------------------------------------------------------- // Internals only // protected static native boolean initIDs(); private native long CreateWindow(long parentWindowHandle, long display, int screen_index, - long visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height); + long visualID, long javaObjectAtom, long windowDeleteAtom, + int x, int y, int width, int height, boolean undecorated); private native void CloseWindow(long display, long windowHandle, long javaObjectAtom); private native void setVisible0(long display, long windowHandle, boolean visible); - private native void setSize0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, int width, int height, int decorationToggle, boolean setVisible); - private native void setPosition0(long display, long windowHandle, int x, int y); + private native void setSize0(long display, long windowHandle, int width, int height); + private native void setPosSizeDecor0(long parentWindowHandle, long display, int screen_index, long windowHandle, + int x, int y, int width, int height, int decorationToggle); + private native void setTitle0(long display, long windowHandle, String title); + private native void requestFocus0(long display, long windowHandle); + private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y); private void windowChanged(int newX, int newY, int newWidth, int newHeight) { if(width != newWidth || height != newHeight) { diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c new file mode 100644 index 000000000..8b64ec37f --- /dev/null +++ b/src/newt/native/NewtCommon.c @@ -0,0 +1,13 @@ + +#include "NewtCommon.h" + +jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h new file mode 100644 index 000000000..46a0d57cf --- /dev/null +++ b/src/newt/native/NewtCommon.h @@ -0,0 +1,10 @@ + +#ifndef NEWT_COMMON_H +#define NEWT_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +#endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 82eb81d99..69b87d39d 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -96,6 +96,8 @@ #include "InputEvent.h" #include "KeyEvent.h" +#include "NewtCommon.h" + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -460,17 +462,6 @@ static void BuildDynamicKeyMapTable() } // for each VK_OEM_* } -// Really need to factor this out in to a separate run-time file -static jchar* GetNullTerminatedStringChars(JNIEnv* env, jstring str) -{ - jchar* strChars = NULL; - strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); - if (strChars != NULL) { - (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); - } - return strChars; -} - static jint GetModifiers() { jint modifiers = 0; // have to do &0xFFFF to avoid runtime assert caused by compiling with @@ -932,7 +923,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Dispatch JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_LoadLibraryW (JNIEnv *env, jclass clazz, jstring dllName) { - jchar* _dllName = GetNullTerminatedStringChars(env, dllName); + jchar* _dllName = NewtCommon_GetNullTerminatedStringChars(env, dllName); HMODULE lib = LoadLibraryW(_dllName); free(_dllName); return (jlong) (intptr_t) lib; @@ -965,7 +956,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Register wc.hbrBackground = GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; #ifdef UNICODE - wc.lpszClassName = GetNullTerminatedStringChars(env, wndClassName); + wc.lpszClassName = NewtCommon_GetNullTerminatedStringChars(env, wndClassName); #else _wndClassName = (*env)->GetStringUTFChars(env, wndClassName, NULL); wc.lpszClassName = strdup(_wndClassName); @@ -1062,7 +1053,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi HWND window = NULL; #ifdef UNICODE - wndName = GetNullTerminatedStringChars(env, jWndName); + wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); #else wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); #endif @@ -1281,7 +1272,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle { HWND hwnd = (HWND) (intptr_t) window; if (title != NULL) { - jchar *titleString = GetNullTerminatedStringChars(env, title); + jchar *titleString = NewtCommon_GetNullTerminatedStringChars(env, title); if (titleString != NULL) { SetWindowTextW(hwnd, titleString); free(titleString); diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 70fc421e8..e46742aac 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -53,6 +53,8 @@ #include "KeyEvent.h" #include "WindowEvent.h" +#include "NewtCommon.h" + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -158,8 +160,7 @@ static void _FatalError(JNIEnv *env, const char* msg, ...) vsnprintf(buffer, sizeof(buffer), msg, ap); va_end(ap); - fprintf(stderr, buffer); - fprintf(stderr, "\n"); + fprintf(stderr, "%s\n", buffer); (*env)->FatalError(env, buffer); } @@ -209,10 +210,10 @@ static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e) if (e->error_code == BadAtom) { - fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", e->resourceid); + fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid); } else if (e->error_code == BadWindow) { - fprintf(stderr, " BadWindow (%p): Window probably already removed\n", e->resourceid); + fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid); } else { _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X", dpy, e->error_code); } @@ -443,7 +444,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages if(NULL==jwindow) { fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for invalid X11 window %p\n", - dpy, evt.type, evt.xany.window); + (void*)dpy, evt.type, (void*)evt.xany.window); XUnlockDisplay(dpy) ; // DBG_PRINT1( "X11: DispatchMessages 0x%X - Leave 2\n", dpy); return; @@ -630,7 +631,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow (JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index, jlong visualID, jlong javaObjectAtom, jlong windowDeleteAtom, - jint x, jint y, jint width, jint height) + jint x, jint y, jint width, jint height, + jboolean undecorated) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; @@ -696,15 +698,15 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow windowParent = XRootWindowOfScreen(scrn); } - attrMask = (CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect) ; + attrMask = ( CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); - xswa.override_redirect = False; // decorated - xswa.border_pixel = 0; + xswa.override_redirect = ( JNI_TRUE == undecorated || 0 != parent ) ? True : False ; + xswa.border_pixel = 255; xswa.background_pixel = 0; xswa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask; xswa.colormap = XCreateColormap(dpy, - XRootWindow(dpy, scrn_idx), + windowParent, // XRootWindow(dpy, scrn_idx), visual, AllocNone); @@ -724,21 +726,14 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); - XClearWindow(dpy, window); XSync(dpy, False); { long xevent_mask = 0; xevent_mask |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; xevent_mask |= KeyPressMask|KeyReleaseMask; - xevent_mask |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ; + xevent_mask |= ExposureMask | StructureNotifyMask | VisibilityNotify ; XSelectInput(dpy, window, xevent_mask); - - /** - XGrabPointer(dpy, window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, - GrabModeAsync, GrabModeAsync, window, None, CurrentTime); - XGrabKeyboard(dpy, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); - */ } XUnlockDisplay(dpy) ; @@ -778,10 +773,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow (*env)->DeleteGlobalRef(env, jwindow); XSync(dpy, False); - /** - XUngrabPointer(dpy, CurrentTime); - XUngrabKeyboard(dpy, CurrentTime); - */ XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); XSync(dpy, False); @@ -813,19 +804,39 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 XSync(dpy, False); if(visible==JNI_TRUE) { XMapRaised(dpy, w); - XSync(dpy, False); - - // XSetInputFocus(dpy, w, RevertToParent, CurrentTime); - // XSync(dpy, False); - } else { - /** - XUngrabPointer(dpy, CurrentTime); - XUngrabKeyboard(dpy, CurrentTime); - */ XUnmapWindow(dpy, w); - XSync(dpy, False); } + XSync(dpy, False); + XUnlockDisplay(dpy) ; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Window + * Method: setSize0 + * Signature: (JJII)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 + (JNIEnv *env, jobject obj, jlong display, jlong window, jint width, jint height) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XWindowChanges xwc; + + DBG_PRINT5( "X11: setSize0 %d/%d %dx%d, dec %d\n", x, y, width, height, decorationToggle); + + if(dpy==NULL) { + _FatalError(env, "invalid display connection.."); + } + XLockDisplay(dpy) ; + + XSync(dpy, False); + memset(&xwc, 0, sizeof(XWindowChanges)); + xwc.width=width; + xwc.height=height; + XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); + + XSync(dpy, False); XUnlockDisplay(dpy) ; } @@ -838,11 +849,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 /* * Class: com_jogamp_newt_impl_x11_X11Window - * Method: setSize0 + * Method: setPosSizeDecor0 * Signature: (JIJIIIIIZ)V */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 - (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, jint width, jint height, jint decorationToggle, jboolean setVisible) +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 + (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, + jint x, jint y, jint width, jint height, jint decorationToggle) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -851,19 +863,17 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XWindowChanges xwc; - DBG_PRINT6( "X11: setSize0 %d/%d %dx%d, dec %d, vis %d\n", x, y, width, height, decorationToggle, setVisible); + DBG_PRINT5( "X11: setSize0 %d/%d %dx%d, dec %d\n", x, y, width, height, decorationToggle); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } XLockDisplay(dpy) ; - XSync(dpy, False); - - if(setVisible==JNI_TRUE) { - XMapRaised(dpy, w); - XSync(dpy, False); - } + // we need to reparent the window, + // to allow a child window to go fullscreen and back. + XReparentWindow( dpy, w, parent, x, y ); + XRaiseWindow(dpy, w); if(0!=decorationToggle) { #ifdef MWM_FULLSCREEN @@ -878,6 +888,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XSetWindowAttributes xswa; unsigned long attrMask=CWOverrideRedirect; + memset(&xswa, 0, sizeof(XSetWindowAttributes)); if(decorationToggle<0) { /* undecorated */ xswa.override_redirect = True; @@ -890,12 +901,15 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 #endif } XSync(dpy, False); + + memset(&xwc, 0, sizeof(XWindowChanges)); + xwc.x=x; + xwc.y=y; xwc.width=width; xwc.height=height; - XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); - XReparentWindow( dpy, w, parent, x, y ); - + XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); XSync(dpy, False); + XUnlockDisplay(dpy) ; } @@ -905,7 +919,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 * Signature: (JJII)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jint x, jint y) + (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -917,6 +931,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 } XLockDisplay(dpy) ; + memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; XConfigureWindow(dpy, w, CWX|CWY, &xwc); @@ -925,3 +940,71 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 XUnlockDisplay(dpy) ; } +/* + * Class: com_jogamp_newt_impl_x11_X11Window + * Method: requestFocus0 + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0 + (JNIEnv *env, jobject obj, jlong display, jlong window) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XWindowAttributes attributes; + + XLockDisplay(dpy) ; + + // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable + XGetWindowAttributes(dpy, w, &attributes); + if(attributes.map_state == IsViewable) { + XSetInputFocus(dpy, w, RevertToParent, CurrentTime); + XSync(dpy, False); + } + + XUnlockDisplay(dpy) ; +} + +/* + * Class: Java_com_jogamp_newt_impl_x11_X11Window + * Method: setTitle0 + * Signature: (JJLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 + (JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + + XLockDisplay(dpy) ; +#if 1 + const char* title_str; + if (NULL != title) { + title_str = (*env)->GetStringUTFChars(env, title, NULL); + if(NULL != title_str) { + XStoreName(dpy, w, title_str); + (*env)->ReleaseStringUTFChars(env, title, title_str); + } + } +#else + char *str_list[] = { NULL }; + XTextProperty text_prop; + if (NULL != title) { + str_list[0] = (char *) NewtCommon_GetNullTerminatedStringChars(env, title); + if (str_list[0] != NULL) { + memset(&text_prop, 0, sizeof(XTextProperty)); + if ( Success != XmbTextListToTextProperty(dpy, str_list, 1, XStringStyle, &text_prop) ) { + DBG_PRINT0( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + fprintf(stderr, "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + } + if(NULL!=text_prop.value) { + XSetWMName(dpy, w, &text_prop); + XFree(text_prop.value); + } + free(str_list[0]); + } + } +#endif + XUnlockDisplay(dpy) ; +} + + |