diff options
Diffstat (limited to 'src')
5 files changed, 259 insertions, 12 deletions
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h index f570b7d39..c74599335 100644 --- a/src/newt/native/X11Common.h +++ b/src/newt/native/X11Common.h @@ -1,5 +1,5 @@ /** - * Copyright 2011 JogAmp Community. All rights reserved. + * Copyright 2011-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -83,6 +83,7 @@ typedef struct { #define XI_TOUCHCOORD_COUNT 10 typedef struct { + Window parentWindow; Window window; jobject jwindow; Atom * allAtoms; diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 8457e4b63..a2fba9b7f 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -1,5 +1,5 @@ /** - * Copyright 2011 JogAmp Community. All rights reserved. + * Copyright 2011-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -764,11 +764,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage Window winRoot, winTopParent; Bool translated = False; if( 0 != NewtWindows_getRootAndParent(dpy, evt.xconfigure.window, &winRoot, &winTopParent) ) { + DBG_PRINT( "X11: event . ConfigureNotify call %p (root %p, top %p)\n", + (void*)evt.xconfigure.window, (void*)winRoot, (void*)winTopParent); int x_return=-1, y_return=-1; + Window winDest = ( winTopParent == jw->parentWindow ) ? winTopParent : winRoot; Window child; - if( True == XTranslateCoordinates(dpy, evt.xconfigure.window, winRoot, 0, 0, &x_return, &y_return, &child) ) { - DBG_PRINT( "X11: event . ConfigureNotify call %p POS (Xtrans) %d/%d -> %d/%d\n", - (void*)evt.xconfigure.window, x_pos, y_pos, x_return, y_return); + if( True == XTranslateCoordinates(dpy, evt.xconfigure.window, winDest, 0, 0, &x_return, &y_return, &child) ) { + DBG_PRINT( "X11: event . ConfigureNotify call %p of dest %p POS (Xtrans) %d/%d -> %d/%d (child %p)\n", + (void*)evt.xconfigure.window, winDest, x_pos, y_pos, x_return, y_return, child); x_pos = x_return; y_pos = y_return; translated = True; diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index b93bbe24f..b53b596cc 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -1,6 +1,6 @@ /* + * Copyright (c) 2010-2023 JogAmp Community. All rights reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -198,7 +198,7 @@ uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, JavaWindow *w) { return res; } -static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window root, Window window, +static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window root, Window parentWindow, Window window, jlong javaObjectAtom, jlong windowDeleteAtom, jobject obj, Bool verbose) { jobject jwindow = (*env)->NewGlobalRef(env, obj); JavaWindow * res; @@ -210,6 +210,7 @@ static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window ro return NULL; } res = calloc(1, sizeof(JavaWindow)); + res->parentWindow = parentWindow; res->window = window; res->jwindow = jwindow; res->allAtoms = allAtoms; @@ -920,7 +921,7 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind // XClearWindow(dpy, window); XSetWMProtocols(dpy, window, &wm_delete_atom, 1); // windowDeleteAtom - javaWindow = createJavaWindowProperty(env, dpy, root, window, javaObjectAtom, windowDeleteAtom, obj, verbose); + javaWindow = createJavaWindowProperty(env, dpy, root, (Window)parent, window, javaObjectAtom, windowDeleteAtom, obj, verbose); NewtWindows_setWindowTypeEWMH(dpy, javaWindow, _NET_WM_WINDOW_TYPE_NORMAL_IDX); NewtWindows_setDecorations(dpy, javaWindow, TST_FLAG_IS_UNDECORATED(flags) ? False : True ); @@ -1215,8 +1216,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo fsEWMHFlags |= _MASK_NET_WM_STATE_BELOW; // toggle below } - DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, isChild %d, undecorated[change %d, val %d], fullscreen[change %d, val %d (span %d)], alwaysOn[Top[change %d, val %d], Bottom[change %d, val %d]], visible[change %d, val %d, tempInvisible %d], resizable[change %d, val %d], sticky[change %d, val %d], fsEWMHFlags %d\n", - (void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)jw->window, + DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p -> %p (%p), win %p, %d/%d %dx%d, parentChange %d, isChild %d, undecorated[change %d, val %d], fullscreen[change %d, val %d (span %d)], alwaysOn[Top[change %d, val %d], Bottom[change %d, val %d]], visible[change %d, val %d, tempInvisible %d], resizable[change %d, val %d], sticky[change %d, val %d], fsEWMHFlags %d\n", + (void*)dpy, screen_index, (void*)jw->parentWindow, (void*) jparent, (void*)parent, (void*)jw->window, x, y, width, height, TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_IS_CHILD(flags), TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), @@ -1267,7 +1268,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_IS_CHILD(flags) ) { // TOP: in -> out - DBG_PRINT( "X11: reconfigureWindow0 PARENTING in->out\n"); + DBG_PRINT( "X11: reconfigureWindow0 PARENTING in->out %p -> %p\n", (void*)jw->parentWindow, (void*)jparent); + jw->parentWindow = (Window)jparent; XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) jw->window ); @@ -1313,7 +1315,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( TST_FLAG_CHANGE_PARENTING(flags) && TST_FLAG_IS_CHILD(flags) ) { // CHILD: out -> in - DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n"); + DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in %p -> %p\n", (void*)jw->parentWindow, (void*)jparent); + jw->parentWindow = (Window)jparent; XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call XFlush(dpy); #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestBug1431NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestBug1431NewtCanvasAWT.java new file mode 100644 index 000000000..b02359d5b --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestBug1431NewtCanvasAWT.java @@ -0,0 +1,237 @@ +package com.jogamp.opengl.test.junit.jogl.demos.es2.newt; + +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.SwingUtilities; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.jogamp.nativewindow.util.DimensionImmutable; +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GL2; +import com.jogamp.opengl.GL2ES1; +import com.jogamp.opengl.GL2ES3; +import com.jogamp.opengl.GLAutoDrawable; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLEventListener; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.fixedfunc.GLLightingFunc; +import com.jogamp.opengl.fixedfunc.GLMatrixFunc; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.NewtTestUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; + +/** + * Self-contained example (within a single class only to keep it simple) + * displaying a rotating quad + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestBug1431NewtCanvasAWT extends UITestCase { + + public static class JOGLQuadNewt implements GLEventListener { + final int[] exp_gl_viewport = { -1, -1, -1, -1 }; + final int[] has_gl_viewport = { -1, -1, -1, -1 }; + private float rotateT = 0.0f; + + @Override + public void display(final GLAutoDrawable gLDrawable) + { + final GL2 gl = gLDrawable.getGL().getGL2(); + gl.glClear(GL.GL_COLOR_BUFFER_BIT); + gl.glClear(GL.GL_DEPTH_BUFFER_BIT); + gl.glLoadIdentity(); + gl.glTranslatef(0.0f, 0.0f, -5.0f); + + // rotate about the three axes + gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f); + gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f); + gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f); + + // Draw A Quad + gl.glBegin(GL2ES3.GL_QUADS); + gl.glColor3f(0.0f, 1.0f, 1.0f); // set the color of the quad + gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left + gl.glVertex3f(1.0f, 1.0f, 0.0f); // Top Right + gl.glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right + gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left + // Done Drawing The Quad + gl.glEnd(); + + // increasing rotation for the next iteration + rotateT += 0.2f; + } + + @Override + public void init(final GLAutoDrawable glDrawable) + { + final GL2 gl = glDrawable.getGL().getGL2(); + gl.glShadeModel(GLLightingFunc.GL_SMOOTH); + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + gl.glClearDepth(1.0f); + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glDepthFunc(GL.GL_LEQUAL); + gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); + } + + @Override + public void reshape(final GLAutoDrawable glDrawable, final int x, final int y, final int width, final int height) + { + final GL2 gl = glDrawable.getGL().getGL2(); + exp_gl_viewport[0] = x; + exp_gl_viewport[1] = y; + exp_gl_viewport[2] = width; + exp_gl_viewport[3] = height; + gl.glGetIntegerv(GL.GL_VIEWPORT, has_gl_viewport, 0); + System.err.println("GLEL reshape: Surface "+glDrawable.getSurfaceWidth()+"x"+glDrawable.getSurfaceWidth()+ + ", reshape "+x+"/"+y+" "+width+"x"+height); + System.err.println("GLEL reshape: Viewport "+has_gl_viewport[0]+"/"+has_gl_viewport[1]+", "+has_gl_viewport[2]+"x"+has_gl_viewport[3]); + + final float aspect = (float) width / (float) height; + gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + gl.glLoadIdentity(); + final float fh = 0.5f; + final float fw = fh * aspect; + gl.glFrustumf(-fw, fw, -fh, fh, 1.0f, 1000.0f); + gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + gl.glLoadIdentity(); + } + + @Override + public void dispose(final GLAutoDrawable gLDrawable) + {} + } + + static long duration = 500; // ms + + static void setFrameSize(final Frame frame, final boolean frameLayout, final int newWith, final int newHeight) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + final java.awt.Dimension d = new java.awt.Dimension(newWith, newHeight); + frame.setSize(d); + if( frameLayout ) { + frame.validate(); + } + } } ); + } catch( final Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + @Test + public void test01() throws InterruptedException, InvocationTargetException { + // System.setProperty("sun.awt.noerasebackground", "true"); + final GLProfile profile = GLProfile.getDefault(); + final GLCapabilities glCapabilities = new GLCapabilities(profile); + final GLWindow glWindow = GLWindow.create(glCapabilities); + final GLEventListener demo = new JOGLQuadNewt(); + // final GLEventListener demo = new RedSquareES2(1); + glWindow.addGLEventListener( demo ); + + final SnapshotGLEventListener snap = new SnapshotGLEventListener(); + snap.setPostSNDetail(getClass().getSimpleName()); + glWindow.addGLEventListener(snap); + + glWindow.addWindowListener(new com.jogamp.newt.event.WindowAdapter() { + @Override + public void windowResized(final com.jogamp.newt.event.WindowEvent e) { + System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); + } + @Override + public void windowMoved(final com.jogamp.newt.event.WindowEvent e) { + System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); + } + }); + + final NewtCanvasAWT canvas = new NewtCanvasAWT(glWindow); + final Frame frame = new Frame(getClass().getSimpleName()); + final Animator animator = new Animator(glWindow); + final boolean[] isClosed = { false }; + + frame.add(canvas); + frame.setSize(640, 480); + // frame.setResizable(false); + frame.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(final java.awt.event.WindowEvent e) + { + isClosed[0] = true; + animator.stop(); + frame.dispose(); + } + }); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame.validate(); + frame.setVisible(true); + } + }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true, null)); + Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow, true, null)); + + animator.start(); + Assert.assertTrue(animator.isAnimating()); + Assert.assertTrue(animator.isStarted()); + + System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); + System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); + System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); + System.err.println("XXXX"); + + canvas.requestFocus(); + snap.setMakeSnapshot(); + + Thread.sleep(100); + setFrameSize(frame, false /* frameLayout */, 800, 600); + snap.setMakeSnapshot(); + Thread.sleep(10); + snap.setMakeSnapshot(); + + final long t0 = System.currentTimeMillis(); + long t1 = t0; + while(!isClosed[0] && t1-t0<duration) { + Thread.sleep(100); + t1 = System.currentTimeMillis(); + } + + if( !isClosed[0] ) { + animator.stop(); + Assert.assertFalse(animator.isAnimating()); + Assert.assertFalse(animator.isStarted()); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame.dispose(); + } + }); + glWindow.destroy(); + Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow, false, null)); + } + } + + public static void main(final String[] args) + { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } + } + System.err.println("duration "+duration); + org.junit.runner.JUnitCore.main(TestBug1431NewtCanvasAWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java index f88da18d3..dd693a45d 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java @@ -116,6 +116,9 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { if(null == wsize) { wsize = new Dimension(640, 480); } + if(null == rwsize) { + rwsize = new Dimension(800, 600); + } } @AfterClass |