JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestSWTAccessor02NewtGLWindow.java
Go to the documentation of this file.
1/**
2 * Copyright 2010 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opengl.test.junit.jogl.swt;
30
31import java.lang.reflect.InvocationTargetException;
32
33import org.eclipse.swt.SWT;
34import org.eclipse.swt.graphics.Color;
35import org.eclipse.swt.graphics.Rectangle;
36import org.eclipse.swt.layout.FillLayout;
37import org.eclipse.swt.layout.GridData;
38import org.eclipse.swt.layout.GridLayout;
39import org.eclipse.swt.widgets.Canvas;
40import org.eclipse.swt.widgets.Composite;
41import org.eclipse.swt.widgets.Display;
42import org.eclipse.swt.widgets.Event;
43import org.eclipse.swt.widgets.Listener;
44import org.eclipse.swt.widgets.Shell;
45import org.eclipse.swt.widgets.Text;
46import org.junit.Assert;
47import org.junit.BeforeClass;
48import org.junit.Test;
49import org.junit.FixMethodOrder;
50import org.junit.runners.MethodSorters;
51
52import com.jogamp.common.os.Platform;
53import com.jogamp.junit.util.JunitTracer;
54import com.jogamp.nativewindow.AbstractGraphicsScreen;
55import com.jogamp.nativewindow.NativeWindow;
56import com.jogamp.nativewindow.NativeWindowFactory;
57import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos;
58import com.jogamp.nativewindow.swt.SWTAccessor;
59import com.jogamp.newt.swt.NewtCanvasSWT;
60import com.jogamp.newt.util.EDTUtil;
61import com.jogamp.newt.opengl.GLWindow;
62import com.jogamp.opengl.GLCapabilities;
63import com.jogamp.opengl.GLProfile;
64import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
65import com.jogamp.opengl.test.junit.util.GLTestUtil;
66import com.jogamp.opengl.test.junit.util.MiscUtils;
67import com.jogamp.opengl.test.junit.util.NewtTestUtil;
68import com.jogamp.opengl.test.junit.util.SWTTestUtil;
69import com.jogamp.opengl.test.junit.util.UITestCase;
70
71import jogamp.newt.swt.SWTEDTUtil;
72
73/**
74 * Tests utilizing {@link SWTAccessor#getWindowHandle(org.eclipse.swt.widgets.Control)}
75 * for NEWT native window reparenting also using GL rendering {@link GLWindow#reparentWindow(NativeWindow, int, int, int)}.
76 * <p>
77 * This tests re-creates {@link NewtCanvasSWT}'s implementation ad-hock, allowing simplified debugging.
78 * </p>
79 * <p>
80 * Enhanced version of {@link TestSWTAccessor01}.
81 * </p>
82 * <p>
83 * Bug 1362 inspired this unit test, i.e. finding the issue of SWT >= 4.10 + GTK3.
84 * </p>
85 */
86@FixMethodOrder(MethodSorters.NAME_ASCENDING)
88
89 static int duration = 250;
90
91 Display display = null;
92 Shell shell = null;
93 Composite composite = null;
94
95 protected void init() throws InterruptedException, InvocationTargetException {
96 SWTAccessor.invokeOnOSTKThread(true, new Runnable() {
97 @Override
98 public void run() {
99 display = new Display();
100 Assert.assertNotNull( display );
101 SWTAccessor.printInfo(System.err, display);
102 shell = new Shell( display );
103 Assert.assertNotNull( shell );
104 shell.setLayout( new GridLayout(3, false) );
105 shell.setBackground(new Color(display, 0, 0, 255));
106 new Text(shell, SWT.NONE).setText("1");
107 new Text(shell, SWT.NONE).setText("2");
108 new Text(shell, SWT.NONE).setText("3");
109 new Text(shell, SWT.NONE).setText("4");
110 composite = new Composite( shell, SWT.NO_BACKGROUND /** | SWT.EMBEDDED */ );
111 composite.setLayout( new FillLayout() );
112 composite.setBackground(new Color(display, 0, 255, 0));
113 final GridData gd = new GridData (GridData.FILL, GridData.FILL, true /* grabExcessHorizontalSpace */, true /* grabExcessVerticalSpace */);
114 composite.setLayoutData(gd);
115 new Text(shell, SWT.NONE).setText("6");
116 new Text(shell, SWT.NONE).setText("7");
117 new Text(shell, SWT.NONE).setText("8");
118 new Text(shell, SWT.NONE).setText("9");
119 Assert.assertNotNull( composite );
120 }});
121 }
122
123 protected void release(final GLWindow glwin) throws InterruptedException, InvocationTargetException {
124 Assert.assertNotNull( display );
125 Assert.assertNotNull( shell );
126 Assert.assertNotNull( composite );
127
128 SWTAccessor.invokeOnOSTKThread(true, () -> {
129 glwin.destroy();
130 composite.dispose();
131 shell.close();
132 shell.dispose();
133 display.dispose();
134 display = null;
135 shell = null;
136 composite = null;
137 } );
138 }
139
140 protected void runTest() throws InterruptedException, InvocationTargetException {
141 init();
142
144 final GLWindow glwin = GLWindow.create(caps);
145 final GearsES2 demo = new GearsES2();
146 glwin.addGLEventListener(demo);
147 glwin.setSize(600, 600);
148
149 // set SWT EDT and start it
150 {
151 final com.jogamp.newt.Display newtDisplay = glwin.getScreen().getDisplay();
152 final EDTUtil edtUtil = new SWTEDTUtil(newtDisplay, display);
153 edtUtil.start();
154 newtDisplay.setEDTUtil( edtUtil );
155 }
156 final Canvas canvas[] = { null };
157 try {
158 display.syncExec( new Runnable() {
159 @Override
160 public void run() {
161 canvas[0] = new Canvas (composite, SWT.NO_BACKGROUND);
162 // Bug 1362 fix or workaround: Seems SWT/GTK3 at least performs lazy initialization
163 // Minimal action required: setBackground of the parent canvas before reparenting!
164 canvas[0].setBackground(new Color(display, 255, 255, 255));
165 shell.setText( getClass().getName() );
166 shell.setBounds( 0, 0, 700, 700 );
167 shell.open();
168
169 // A full rolled-out native window reparenting example, very suitable to debug
170 final long parentWinHandle = SWTAccessor.getWindowHandle(canvas[0]);
172 final UpstreamWindowHookMutableSizePos upstreamSizePosHook = new UpstreamWindowHookMutableSizePos(0, 0, 600, 600, 600, 600);
173 final Listener listener = new Listener () {
174 @Override
175 public void handleEvent (final Event event) {
176 switch (event.type) {
177 case SWT.Paint:
178 glwin.display();
179 break;
180 case SWT.Move:
181 case SWT.Resize: {
182 final Rectangle nClientArea = canvas[0].getClientArea();
183 if( null != nClientArea ) {
184 upstreamSizePosHook.setSurfaceSize(nClientArea.width, nClientArea.height);
185 upstreamSizePosHook.setWinSize(nClientArea.width, nClientArea.height);
186 upstreamSizePosHook.setWinPos(nClientArea.x, nClientArea.y);
187 if( SWT.Resize == event.type ) {
188 glwin.setSize(nClientArea.width, nClientArea.height);
189 }
190 }
191 }
192 break;
193 case SWT.Dispose:
194 glwin.destroy();
195 break;
196 }
197 }
198 };
199 canvas[0].addListener (SWT.Move, listener);
200 canvas[0].addListener (SWT.Resize, listener);
201 canvas[0].addListener (SWT.Paint, listener);
202 canvas[0].addListener (SWT.Dispose, listener);
203
204 final Rectangle r = canvas[0].getClientArea();
205 final NativeWindow parentWindow = NativeWindowFactory.createWrappedWindow(aScreen, 0 /* surfaceHandle*/, parentWinHandle, upstreamSizePosHook);
206 glwin.setSize(r.width, r.height);
207 glwin.reparentWindow(parentWindow, 0, 0, 0);
208 glwin.setPosition(r.x, r.y);
209 glwin.setVisible(true);
210 canvas[0].redraw();
211 }});
212
213 final SWTTestUtil.WaitAction waitAction = new SWTTestUtil.WaitAction(display, true, 10);
214 Assert.assertEquals(true, NewtTestUtil.waitForVisible(glwin, true, waitAction));
215 Assert.assertEquals(true, GLTestUtil.waitForRealized(glwin, true, waitAction));
216
217 System.err.println("Window handle.1 0x"+Long.toHexString(SWTAccessor.getWindowHandle(canvas[0])));
218
219 final long lStartTime = System.currentTimeMillis();
220 final long lEndTime = lStartTime + duration;
221 while( System.currentTimeMillis() < lEndTime && !composite.isDisposed() ) {
222 waitAction.run();
223 }
224 } finally {
225 release(glwin);
226 }
227 }
228
229 @Test
230 public void test() throws InterruptedException, InvocationTargetException {
231 runTest();
232 }
233
234 public static void main(final String args[]) {
235 for(int i=0; i<args.length; i++) {
236 if(args[i].equals("-time")) {
237 duration = MiscUtils.atoi(args[++i], duration);
238 }
239 }
240 org.junit.runner.JUnitCore.main( TestSWTAccessor02NewtGLWindow.class.getName() );
241 }
242}
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static AbstractGraphicsDevice createDevice(final String displayConnection, final boolean own)
Creates a native device type, following getNativeWindowType(true).
static NativeWindow createWrappedWindow(final AbstractGraphicsScreen aScreen, final long surfaceHandle, final long windowHandle, final UpstreamWindowHookMutableSizePos hook)
Creates a wrapped NativeWindow with given native handles and AbstractGraphicsScreen.
static AbstractGraphicsScreen createScreen(final AbstractGraphicsDevice device, int screen)
final void setSurfaceSize(final int width, final int height)
Resizes the upstream surface.
final void setWinSize(final int winWidth, final int winHeight)
static void invokeOnOSTKThread(final boolean blocking, final Runnable runnable)
Runs the specified action in an SWT compatible OS toolkit thread, which is:
static long getWindowHandle(final Control swtControl)
static void printInfo(final PrintStream out, final Display d)
abstract EDTUtil setEDTUtil(EDTUtil usrEDTUtil)
Sets a new EDTUtil and returns the previous one.
abstract Display getDisplay()
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void setPosition(final int x, final int y)
Sets the location of the window's client area excluding insets (window decorations) in window units.
Definition: GLWindow.java:525
final ReparentOperation reparentWindow(final NativeWindow newParent, final int x, final int y, final int hints)
Change this window's parent window.
Definition: GLWindow.java:582
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
Tests utilizing SWTAccessor#getWindowHandle(org.eclipse.swt.widgets.Control) for NEWT native window r...
static boolean waitForRealized(final GLAutoDrawable glad, final boolean realized, final Runnable waitAction)
Definition: GLTestUtil.java:91
static int atoi(final String str, final int def)
Definition: MiscUtils.java:57
static boolean waitForVisible(final Window win, final boolean visible, final Runnable waitAction)
A interface describing a graphics screen in a toolkit-independent manner.
Extend the NativeSurface interface with windowing information such as window-handle,...
EDT stands for Event Dispatch Thread.
Definition: EDTUtil.java:53
void start()
Starts the EDT after it's creation or after stopping.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.