diff options
author | Sven Gothel <[email protected]> | 2012-10-31 04:04:39 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-10-31 04:04:39 +0100 |
commit | b62e1d027c289877686d6008ea8dd40e4e1541ec (patch) | |
tree | f0af41cb2c9bdd92c37192880439843de1b85f32 /src/test | |
parent | dda5e1611fc41089a5f8d486435d3d2d7e9b76d6 (diff) |
Fix NEWT KeyEvent: Deliver keyChar w/ pressed and released; Deliver proper modified flags and modifier-key events; Simplify Windows key handling
Preface: Modifier-keys are SHIFT, CTRL, ALT and META and they have a matching modifier-bit.
- Simplify Windows key handling
- Employ MapVirtualKey(..) for virtual-key to character and scancode to virtual-key mappings,
allowing to drop tracking of keyCode to keyChar in java code.
This also removes the platform restriction of delivering keyChar at TYPED only.
- Deliver keyChar w/ pressed and released
- Due to the lift restriction on the Windows platform (see above),
we can deliver keyChar w/ all key events on all platforms.
- Deliver proper modified flags and modifier-key events
All modifier-keys deliver pressed, released and typed events
with their modifier-bit set.
The above is covered by unit tests, which passed on X11, Windows and OSX (manual test run).
Diffstat (limited to 'src/test')
12 files changed, 402 insertions, 96 deletions
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java new file mode 100644 index 000000000..b06788386 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java @@ -0,0 +1,275 @@ +/** + * Copyright 2012 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import org.junit.After; +import org.junit.Assert; +import org.junit.AfterClass; +import org.junit.Assume; +import org.junit.Before; + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.lang.reflect.InvocationTargetException; +import java.util.EventObject; +import java.util.List; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLEventListener; +import javax.swing.JFrame; + +import java.io.IOException; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.event.InputEvent; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; + +import com.jogamp.opengl.test.junit.util.*; + +/** + * Testing combinations of key code modifiers of key event. + */ +public class TestNewtKeyCodeModifiersAWT extends UITestCase { + static int width, height; + static long durationPerTest = 100; + static long awtWaitTimeout = 1000; + + static GLCapabilities glCaps; + + @BeforeClass + public static void initClass() { + width = 640; + height = 480; + glCaps = new GLCapabilities(null); + } + + @AfterClass + public static void release() { + } + + @Before + public void initTest() { + } + + @After + public void releaseTest() { + } + + @Test + public void test01NEWT() throws AWTException, InterruptedException, InvocationTargetException { + GLWindow glWindow = GLWindow.create(glCaps); + glWindow.setSize(width, height); + glWindow.setVisible(true); + + testImpl(glWindow); + + glWindow.destroy(); + } + + @Test + public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException { + GLWindow glWindow = GLWindow.create(glCaps); + + // Wrap the window in a canvas. + final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow); + + // Add the canvas to a frame, and make it all visible. + final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "+ glWindow.getTitle()); + frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER); + frame1.setSize(width, height); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.setVisible(true); + } } ); + + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true)); + + testImpl(glWindow); + + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.setVisible(false); + frame1.dispose(); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + glWindow.destroy(); + } + + static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, int modifierKey, int modifierMask) { + keyAdapter.reset(); + AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P + AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P + robot.waitForIdle(); + for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected + robot.delay(100); + } + + AWTRobotUtil.keyPress(0, robot, true, modifierKey, 10); // press MOD + AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P + AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 10); // release+typed P + AWTRobotUtil.keyPress(0, robot, false, modifierKey, 100); // release+typed MOD + robot.waitForIdle(); + for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3+6; j++) { // wait until events are collected + robot.delay(100); + } + NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3+6, 0); + + final List<EventObject> queue = keyAdapter.getQueued(); + int i=0; + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, KeyEvent.VK_P); + + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, modifierMask, modifierKey); + } + + static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) { + final int m1k = KeyEvent.VK_ALT; + final int m1m = InputEvent.ALT_MASK; + final int m2k = KeyEvent.VK_CONTROL; + final int m2m = InputEvent.CTRL_MASK; + final int m3k = KeyEvent.VK_SHIFT; + final int m3m = InputEvent.SHIFT_MASK; + + keyAdapter.reset(); + AWTRobotUtil.keyPress(0, robot, true, m1k, 10); // press MOD1 + AWTRobotUtil.keyPress(0, robot, true, m2k, 10); // press MOD2 + AWTRobotUtil.keyPress(0, robot, true, m3k, 10); // press MOD3 + AWTRobotUtil.keyPress(0, robot, true, KeyEvent.VK_P, 10); // press P + + AWTRobotUtil.keyPress(0, robot, false, KeyEvent.VK_P, 100); // release+typed P + AWTRobotUtil.keyPress(0, robot, false, m3k, 10); // release+typed MOD + AWTRobotUtil.keyPress(0, robot, false, m2k, 10); // release+typed MOD + AWTRobotUtil.keyPress(0, robot, false, m1k, 10); // release+typed MOD + + robot.waitForIdle(); + for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3*4; j++) { // wait until events are collected + robot.delay(100); + } + NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 3*4, 0); + + final List<EventObject> queue = keyAdapter.getQueued(); + int i=0; + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m, m1k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m, m2k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, m3k); + + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_P); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_P); + + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, m3k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m|m2m, m2k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k); + NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, m1m, m1k); + } + + void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException { + final Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + + GLEventListener demo1 = new RedSquareES2(); + TestListenerCom01AWT.setDemoFields(demo1, glWindow, false); + glWindow.addGLEventListener(demo1); + + // NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1"); + // glWindow.addWindowListener(glWindow1FA); + NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1"); + glWindow1KA.setVerbose(false); + glWindow.addKeyListener(glWindow1KA); + + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, true)); + + // Continuous animation .. + Animator animator = new Animator(glWindow); + animator.start(); + + Thread.sleep(durationPerTest); // manual testing + + AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic + AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input + glWindow1KA.reset(); + + testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK); + testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK); + testKeyCodeModifier(robot, glWindow1KA, KeyEvent.VK_ALT, InputEvent.ALT_MASK); + + testKeyCodeAllModifierV1(robot, glWindow1KA); + + // Remove listeners to avoid logging during dispose/destroy. + glWindow.removeKeyListener(glWindow1KA); + + // Shutdown the test. + animator.stop(); + } + + static int atoi(String a) { + int i=0; + try { + i = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = atoi(args[++i]); + } + } + /** + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println("Press enter to continue"); + System.err.println(stdin.readLine()); + */ + System.out.println("durationPerTest: "+durationPerTest); + String tstname = TestNewtKeyCodeModifiersAWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java index 37debfcc2..e786eaf74 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java @@ -60,18 +60,9 @@ import com.jogamp.opengl.test.junit.util.*; import com.jogamp.opengl.test.junit.util.NEWTKeyUtil.CodeSeg; /** - * Testing key event order incl. auto-repeat (Bug 601) - * - * <p> - * Note Event order: - * <ol> - * <li>{@link #EVENT_KEY_PRESSED}</li> - * <li>{@link #EVENT_KEY_RELEASED}</li> - * <li>{@link #EVENT_KEY_TYPED}</li> - * </ol> - * </p> + * Testing key code of key events. */ -public class TestNewtKeyCodeAWT extends UITestCase { +public class TestNewtKeyCodesAWT extends UITestCase { static int width, height; static long durationPerTest = 100; static long awtWaitTimeout = 1000; @@ -108,7 +99,7 @@ public class TestNewtKeyCodeAWT extends UITestCase { glWindow.destroy(); } - // @Test + @Test public void test02NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException { GLWindow glWindow = GLWindow.create(glCaps); @@ -145,7 +136,7 @@ public class TestNewtKeyCodeAWT extends UITestCase { new CodeSeg(0x008, 0x008, "bs"), // new CodeSeg(0x009, 0x009, "tab"), // TAB functions as focus traversal key new CodeSeg(0x00a, 0x00a, "cr"), - new CodeSeg(0x010, 0x011, "shift, ctrl"), // single alt n/a on windows + new CodeSeg(0x010, 0x012, "shift, ctrl, alt"), new CodeSeg(0x01B, 0x01B, "esc"), new CodeSeg(0x020, 0x024, "space, up, down, end, home"), new CodeSeg(0x025, 0x028, "cursor"), @@ -169,9 +160,8 @@ public class TestNewtKeyCodeAWT extends UITestCase { // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; .. }; - static void testKeyCode(Robot robot, NEWTKeyAdapter keyAdapter) { + static void testKeyCodes(Robot robot, NEWTKeyAdapter keyAdapter) { final List<List<EventObject>> cse = new ArrayList<List<EventObject>>(); - final List<EventObject> queue = keyAdapter.getQueued(); for(int i=0; i<codeSegments.length; i++) { keyAdapter.reset(); @@ -184,13 +174,13 @@ public class TestNewtKeyCodeAWT extends UITestCase { robot.waitForIdle(); } final int codeCount = codeSeg.max - codeSeg.min + 1; - for(int j=0; j < 10 && queue.size() < 3 * codeCount; j++) { // wait until events are collected + for(int j=0; j < 10 && keyAdapter.getQueueSize() < 3 * codeCount; j++) { // wait until events are collected robot.delay(100); } - final ArrayList<EventObject> events = new ArrayList<EventObject>(queue); + final ArrayList<EventObject> events = new ArrayList<EventObject>(keyAdapter.getQueued()); cse.add(events); } - Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCode(codeSegments, cse, true)); + Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCodes(codeSegments, cse, true)); } void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException { @@ -216,13 +206,10 @@ public class TestNewtKeyCodeAWT extends UITestCase { Thread.sleep(durationPerTest); // manual testing AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic - AWTRobotUtil.requestFocus(robot, glWindow); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input + AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input glWindow1KA.reset(); - // - // Test the key event order w/o auto-repeat - // - testKeyCode(robot, glWindow1KA); + testKeyCodes(robot, glWindow1KA); // Remove listeners to avoid logging during dispose/destroy. glWindow.removeKeyListener(glWindow1KA); @@ -251,7 +238,7 @@ public class TestNewtKeyCodeAWT extends UITestCase { System.err.println(stdin.readLine()); */ System.out.println("durationPerTest: "+durationPerTest); - String tstname = TestNewtKeyCodeAWT.class.getName(); + String tstname = TestNewtKeyCodesAWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java index 6816863da..7b6fe0596 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventAutoRepeatAWT.java @@ -159,7 +159,6 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { EventObject[][] last = new EventObject[loops][3]; keyAdapter.reset(); - final List<EventObject> keyEvents = keyAdapter.getQueued(); int firstIdx = 0; for(int i=0; i<loops; i++) { System.err.println("+++ KEY Event Auto-Repeat START Input Loop: "+i); @@ -169,11 +168,12 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { robot.waitForIdle(); final int minCodeCount = firstIdx + 3; final int desiredCodeCount = firstIdx + 6; - for(int j=0; j < 10 && keyEvents.size() < desiredCodeCount; j++) { // wait until events are collected + for(int j=0; j < 10 && keyAdapter.getQueueSize() < desiredCodeCount; j++) { // wait until events are collected robot.delay(100); } - Assert.assertTrue("AR Test didn't collect enough key events: required min "+minCodeCount+", received "+(keyEvents.size()-firstIdx)+", "+keyEvents, - keyEvents.size() >= minCodeCount ); + Assert.assertTrue("AR Test didn't collect enough key events: required min "+minCodeCount+", received "+(keyAdapter.getQueueSize()-firstIdx)+", "+keyAdapter.getQueued(), + keyAdapter.getQueueSize() >= minCodeCount ); + final List<EventObject> keyEvents = keyAdapter.getQueued(); first[i][0] = (KeyEvent) keyEvents.get(firstIdx+0); first[i][1] = (KeyEvent) keyEvents.get(firstIdx+1); first[i][2] = (KeyEvent) keyEvents.get(firstIdx+2); @@ -184,22 +184,27 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { System.err.println("+++ KEY Event Auto-Repeat END Input Loop: "+i); // add a pair of normal press/release in between auto-repeat! + firstIdx = keyEvents.size(); AWTRobotUtil.keyPress(0, robot, true, java.awt.event.KeyEvent.VK_B, 10); robot.waitForIdle(); AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_B, 250); robot.waitForIdle(); + for(int j=0; j < 10 && keyAdapter.getQueueSize() < firstIdx+3; j++) { // wait until events are collected + robot.delay(100); + } firstIdx = keyEvents.size(); } // dumpKeyEvents(keyEvents); - + final List<EventObject> keyEvents = keyAdapter.getQueued(); NEWTKeyUtil.validateKeyEventOrder(keyEvents); final boolean hasAR = 0 < keyAdapter.getKeyPressedCount(true) ; - Assert.assertEquals("Key event count not multiple of 3", 0, keyEvents.size()%3); - final int expTotal = keyEvents.size()/3; - final int expAR = hasAR ? expTotal - loops - loops : 0; - NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, expTotal, expAR); + { + final int expTotal = keyEvents.size(); + final int expAR = hasAR ? expTotal - 3 * 2 * loops : 0; // per loop: 3 for non AR events and 3 for non AR 'B' + NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, expTotal, expAR); + } if( !hasAR ) { System.err.println("No AUTO-REPEAT triggered by AWT Robot .. aborting test analysis"); @@ -266,7 +271,7 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { Thread.sleep(durationPerTest); // manual testing AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic - AWTRobotUtil.requestFocus(robot, glWindow); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input + AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input glWindow1KA.reset(); // diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java index 11f552ecb..cf5016173 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyEventOrderAWT.java @@ -56,7 +56,7 @@ import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; import com.jogamp.opengl.test.junit.util.*; /** - * Testing key event order incl. auto-repeat (Bug 601) + * Testing key event order excl. auto-repeat (Bug 601) * * <p> * Note Event order: @@ -167,7 +167,7 @@ public class TestNewtKeyEventOrderAWT extends UITestCase { NEWTKeyUtil.validateKeyEventOrder(keyAdapter.getQueued()); - NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 6*loops, 0); + NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, 6*3*loops, 0); } void testImpl(GLWindow glWindow) throws AWTException, InterruptedException, InvocationTargetException { @@ -191,7 +191,7 @@ public class TestNewtKeyEventOrderAWT extends UITestCase { Thread.sleep(durationPerTest); // manual testing AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic - AWTRobotUtil.requestFocus(robot, glWindow); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input + AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input glWindow1KA.reset(); // diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java index 6ebaf2707..c27513905 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyPressReleaseUnmaskRepeatAWT.java @@ -151,7 +151,7 @@ public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase { Thread.sleep(durationPerTest); // manual testing AWTRobotUtil.assertRequestFocusAndWait(null, glWindow, glWindow, null, null); // programmatic - AWTRobotUtil.requestFocus(robot, glWindow); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input + AWTRobotUtil.requestFocus(robot, glWindow, false); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input // Remove listeners to avoid logging during dispose/destroy. glWindow.removeKeyListener(simpleKeyPressRelease); diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java index a9fa373b5..837ba5da1 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java @@ -46,33 +46,37 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent reset(); } - public void setVerbose(boolean v) { verbose = false; } + public synchronized void setVerbose(boolean v) { verbose = false; } - public boolean isPressed() { + public synchronized boolean isPressed() { return pressed; } - public int getCount() { + public synchronized int getCount() { return keyTyped; } - public int getKeyPressedCount(boolean autoRepeatOnly) { + public synchronized int getKeyPressedCount(boolean autoRepeatOnly) { return keyPressed; } - public int getKeyReleasedCount(boolean autoRepeatOnly) { + public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) { return keyReleased; } - public int getKeyTypedCount(boolean autoRepeatOnly) { + public synchronized int getKeyTypedCount(boolean autoRepeatOnly) { return keyTyped; } - public List<EventObject> getQueued() { + public synchronized List<EventObject> getQueued() { return queue; } - public void reset() { + public synchronized int getQueueSize() { + return queue.size(); + } + + public synchronized void reset() { keyTyped = 0; keyPressed = 0; keyReleased = 0; @@ -80,7 +84,7 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent queue.clear(); } - public void keyPressed(KeyEvent e) { + public synchronized void keyPressed(KeyEvent e) { pressed = true; keyPressed++; queue.add(e); @@ -89,7 +93,7 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent } } - public void keyReleased(KeyEvent e) { + public synchronized void keyReleased(KeyEvent e) { pressed = false; keyReleased++; queue.add(e); @@ -98,7 +102,7 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent } } - public void keyTyped(java.awt.event.KeyEvent e) { + public synchronized void keyTyped(java.awt.event.KeyEvent e) { keyTyped++; queue.add(e); if( verbose ) { diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java index 3334f18ea..31362bfa1 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java @@ -45,27 +45,31 @@ public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements Inpu reset(); } - public void setVerbose(boolean v) { verbose = false; } + public synchronized void setVerbose(boolean v) { verbose = false; } - public boolean isPressed() { + public synchronized boolean isPressed() { return pressed; } - public int getCount() { + public synchronized int getCount() { return mouseClicked; } - public List<EventObject> getQueued() { + public synchronized List<EventObject> getQueued() { return queue; } - public void reset() { + public synchronized int getQueueSize() { + return queue.size(); + } + + public synchronized void reset() { mouseClicked = 0; pressed = false; queue.clear(); } - public void mousePressed(MouseEvent e) { + public synchronized void mousePressed(MouseEvent e) { pressed = true; queue.add(e); if( verbose ) { @@ -73,7 +77,7 @@ public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements Inpu } } - public void mouseReleased(MouseEvent e) { + public synchronized void mouseReleased(MouseEvent e) { pressed = false; queue.add(e); if( verbose ) { @@ -81,7 +85,7 @@ public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements Inpu } } - public void mouseClicked(java.awt.event.MouseEvent e) { + public synchronized void mouseClicked(java.awt.event.MouseEvent e) { mouseClicked+=e.getClickCount(); queue.add(e); if( verbose ) { diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index f48033ae0..e64b3208e 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -196,10 +196,20 @@ public class AWTRobotUtil { /** * requestFocus, if robot is valid, use mouse operation, - * otherwise programatic, ie call requestFocus + * otherwise programmatic, ie call requestFocus */ public static void requestFocus(Robot robot, Object obj) throws AWTException, InterruptedException, InvocationTargetException { + requestFocus(robot, obj, true); + } + + /** + * requestFocus, if robot is valid, use mouse operation, + * otherwise programmatic, ie call requestFocus + */ + public static void requestFocus(Robot robot, Object obj, boolean onTitleBarIfWindow) + throws AWTException, InterruptedException, InvocationTargetException { + final Component comp; final com.jogamp.newt.Window win; @@ -226,7 +236,7 @@ public class AWTRobotUtil { } } else { final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK; - centerMouse(robot, obj, true); + centerMouse(robot, obj, onTitleBarIfWindow); robot.waitForIdle(); robot.mousePress(mouseButton); diff --git a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java index ed7485951..c4078436f 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/InputEventCountAdapter.java @@ -35,6 +35,7 @@ public interface InputEventCountAdapter extends EventCountAdapter { int getCount(); boolean isPressed(); - public List<EventObject> getQueued(); + public List<EventObject> getQueued(); + public int getQueueSize(); } diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java index 42235254a..f19169b42 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java @@ -50,33 +50,37 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { reset(); } - public void setVerbose(boolean v) { verbose = false; } + public synchronized void setVerbose(boolean v) { verbose = false; } - public boolean isPressed() { + public synchronized boolean isPressed() { return pressed; } - public int getCount() { + public synchronized int getCount() { return keyTyped; } - public int getKeyPressedCount(boolean autoRepeatOnly) { + public synchronized int getKeyPressedCount(boolean autoRepeatOnly) { return autoRepeatOnly ? keyPressedAR: keyPressed; } - public int getKeyReleasedCount(boolean autoRepeatOnly) { + public synchronized int getKeyReleasedCount(boolean autoRepeatOnly) { return autoRepeatOnly ? keyReleasedAR: keyReleased; } - public int getKeyTypedCount(boolean autoRepeatOnly) { + public synchronized int getKeyTypedCount(boolean autoRepeatOnly) { return autoRepeatOnly ? keyTypedAR: keyTyped; } - public List<EventObject> getQueued() { + public synchronized List<EventObject> getQueued() { return queue; } - public void reset() { + public synchronized int getQueueSize() { + return queue.size(); + } + + public synchronized void reset() { keyTyped = 0; keyPressed = 0; keyReleased = 0; @@ -87,7 +91,7 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { queue.clear(); } - public void keyPressed(KeyEvent e) { + public synchronized void keyPressed(KeyEvent e) { pressed = true; keyPressed++; if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) { @@ -99,7 +103,7 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { } } - public void keyReleased(KeyEvent e) { + public synchronized void keyReleased(KeyEvent e) { pressed = false; keyReleased++; if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) { @@ -112,7 +116,7 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { } @Override - public void keyTyped(KeyEvent e) { + public synchronized void keyTyped(KeyEvent e) { keyTyped++; if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) { keyTypedAR++; diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java index 95818845e..e090ed4cf 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java @@ -62,14 +62,14 @@ public class NEWTKeyUtil { return "Code 0x"+Integer.toHexString(code)+" != "+event+" // "+description; } } - + public static void dumpKeyEvents(List<EventObject> keyEvents) { for(int i=0; i<keyEvents.size(); i++) { System.err.println(i+": "+keyEvents.get(i)); } } - - public static boolean validateKeyCode(CodeSeg[] codeSegments, List<List<EventObject>> keyEventsList, boolean verbose) { + + public static boolean validateKeyCodes(CodeSeg[] codeSegments, List<List<EventObject>> keyEventsList, boolean verbose) { final List<CodeEvent> missCodes = new ArrayList<CodeEvent>(); int totalCodeCount = 0; boolean res = true; @@ -77,7 +77,7 @@ public class NEWTKeyUtil { final CodeSeg codeSeg = codeSegments[i]; totalCodeCount += codeSeg.max - codeSeg.min + 1; final List<EventObject> keyEvents = keyEventsList.get(i); - res &= validateKeyCode(missCodes, codeSeg, keyEvents, verbose); + res &= validateKeyCodes(missCodes, codeSeg, keyEvents, verbose); } if(verbose) { System.err.println("*** Total KeyCode Misses "+missCodes.size()+" / "+totalCodeCount+", valid "+res); @@ -87,7 +87,7 @@ public class NEWTKeyUtil { } return res; } - public static boolean validateKeyCode(List<CodeEvent> missCodes, CodeSeg codeSeg, List<EventObject> keyEvents, boolean verbose) { + public static boolean validateKeyCodes(List<CodeEvent> missCodes, CodeSeg codeSeg, List<EventObject> keyEvents, boolean verbose) { final int codeCount = codeSeg.max - codeSeg.min + 1; int misses = 0; for(int i=0; i<codeCount; i++) { @@ -106,6 +106,18 @@ public class NEWTKeyUtil { return res; } + public static void validateKeyEvent(KeyEvent e, int eventType, int modifier, int keyCode) { + if(0 <= keyCode) { + Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode()); + } + if(0 <= eventType) { + Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType()); + } + if(0 <= modifier) { + Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifier)+", has "+e, modifier == e.getModifiers()); + } + } + public static int getNextKeyEventType(int et) { switch( et ) { case KeyEvent.EVENT_KEY_PRESSED: @@ -138,8 +150,8 @@ public class NEWTKeyUtil { /** * * @param keyAdapter - * @param expTotalCount number of physical key press/release, i.e. 1 shall result in 3 events (press, release and typed) - * @param expARCount as auto-release .. + * @param expTotalCount number of key press/release/types events + * @param expARCount number of key press/release/types Auto-Release events */ public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter, int expTotalCount, int expARCount) { final int keyPressed = keyAdapter.getKeyPressedCount(false); @@ -157,17 +169,17 @@ public class NEWTKeyUtil { final List<EventObject> keyEvents = keyAdapter.getQueued(); Assert.assertEquals("Key event count not multiple of 3", 0, keyEvents.size()%3); - Assert.assertEquals("Key event count not 3 * press_release_count", 3*expTotalCount, keyEvents.size()); - Assert.assertEquals("Key press count failure", expTotalCount, keyPressed); - Assert.assertEquals("Key press count failure (AR)", expARCount, keyPressedAR); - Assert.assertEquals("Key released count failure", expTotalCount, keyReleased); - Assert.assertEquals("Key released count failure (AR)", expARCount, keyReleasedAR); - Assert.assertEquals("Key typed count failure", expTotalCount, keyTyped); - Assert.assertEquals("Key typed count failure (AR)", expARCount, keyTypedAR); + Assert.assertEquals("Key event count not 3 * press_release_count", expTotalCount, keyEvents.size()); + Assert.assertEquals("Key press count failure", expTotalCount/3, keyPressed); + Assert.assertEquals("Key press count failure (AR)", expARCount/3, keyPressedAR); + Assert.assertEquals("Key released count failure", expTotalCount/3, keyReleased); + Assert.assertEquals("Key released count failure (AR)", expARCount/3, keyReleasedAR); + Assert.assertEquals("Key typed count failure", expTotalCount/3, keyTyped); + Assert.assertEquals("Key typed count failure (AR)", expARCount/3, keyTypedAR); // should be true - always, reaching this point - duh! - Assert.assertEquals(expTotalCount-expARCount, keyPressedNR); - Assert.assertEquals(expTotalCount-expARCount, keyReleasedNR); - Assert.assertEquals(expTotalCount-expARCount, keyTypedNR); + Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyPressedNR); + Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyReleasedNR); + Assert.assertEquals( ( expTotalCount - expARCount ) / 3, keyTypedNR); } } diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java index c77462884..644523782 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java @@ -48,27 +48,31 @@ public class NEWTMouseAdapter extends MouseAdapter implements InputEventCountAda reset(); } - public void setVerbose(boolean v) { verbose = false; } + public synchronized void setVerbose(boolean v) { verbose = false; } - public boolean isPressed() { + public synchronized boolean isPressed() { return pressed; } - public int getCount() { + public synchronized int getCount() { return mouseClicked; } - public List<EventObject> getQueued() { + public synchronized List<EventObject> getQueued() { return queue; } - public void reset() { + public synchronized int getQueueSize() { + return queue.size(); + } + + public synchronized void reset() { mouseClicked = 0; pressed = false; queue.clear(); } - public void mousePressed(MouseEvent e) { + public synchronized void mousePressed(MouseEvent e) { pressed = true; queue.add(e); if( verbose ) { @@ -76,7 +80,7 @@ public class NEWTMouseAdapter extends MouseAdapter implements InputEventCountAda } } - public void mouseReleased(MouseEvent e) { + public synchronized void mouseReleased(MouseEvent e) { pressed = false; queue.add(e); if( verbose ) { @@ -84,7 +88,7 @@ public class NEWTMouseAdapter extends MouseAdapter implements InputEventCountAda } } - public void mouseClicked(MouseEvent e) { + public synchronized void mouseClicked(MouseEvent e) { mouseClicked+=e.getClickCount(); queue.add(e); if( verbose ) { |