From b62e1d027c289877686d6008ea8dd40e4e1541ec Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 31 Oct 2012 04:04:39 +0100 Subject: 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). --- .../opengl/test/junit/newt/TestNewtKeyCodeAWT.java | 259 ------------------- .../junit/newt/TestNewtKeyCodeModifiersAWT.java | 275 +++++++++++++++++++++ .../test/junit/newt/TestNewtKeyCodesAWT.java | 246 ++++++++++++++++++ .../junit/newt/TestNewtKeyEventAutoRepeatAWT.java | 25 +- .../test/junit/newt/TestNewtKeyEventOrderAWT.java | 6 +- .../TestNewtKeyPressReleaseUnmaskRepeatAWT.java | 2 +- .../opengl/test/junit/util/AWTKeyAdapter.java | 26 +- .../opengl/test/junit/util/AWTMouseAdapter.java | 20 +- .../opengl/test/junit/util/AWTRobotUtil.java | 14 +- .../test/junit/util/InputEventCountAdapter.java | 3 +- .../opengl/test/junit/util/NEWTKeyAdapter.java | 26 +- .../jogamp/opengl/test/junit/util/NEWTKeyUtil.java | 46 ++-- .../opengl/test/junit/util/NEWTMouseAdapter.java | 20 +- 13 files changed, 637 insertions(+), 331 deletions(-) delete mode 100644 src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeModifiersAWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodesAWT.java (limited to 'src/test') diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java deleted file mode 100644 index 37debfcc2..000000000 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestNewtKeyCodeAWT.java +++ /dev/null @@ -1,259 +0,0 @@ -/** - * 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.ArrayList; -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.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.*; -import com.jogamp.opengl.test.junit.util.NEWTKeyUtil.CodeSeg; - -/** - * Testing key event order incl. auto-repeat (Bug 601) - * - *

- * Note Event order: - *

    - *
  1. {@link #EVENT_KEY_PRESSED}
  2. - *
  3. {@link #EVENT_KEY_RELEASED}
  4. - *
  5. {@link #EVENT_KEY_TYPED}
  6. - *
- *

- */ -public class TestNewtKeyCodeAWT 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 CodeSeg[] codeSegments = new CodeSeg[] { - 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(0x01B, 0x01B, "esc"), - new CodeSeg(0x020, 0x024, "space, up, down, end, home"), - new CodeSeg(0x025, 0x028, "cursor"), - new CodeSeg(0x02C, 0x02F, ", - . /"), - new CodeSeg(0x030, 0x039, "0 - 9"), - new CodeSeg(0x03B, 0x03B, ";"), - new CodeSeg(0x03D, 0x03D, "="), - new CodeSeg(0x041, 0x05A, "a - z"), - new CodeSeg(0x05B, 0x05D, "[ \\ ]"), - // new CodeSeg(0x060, 0x06B, "numpad1"), // can be mapped to normal keycodes - // new CodeSeg(0x06D, 0x06F, "numpad2"), // can be mapped to normal keycodes - new CodeSeg(0x07F, 0x07F, "del"), - // new CodeSeg(0x090, 0x091, "num lock, scroll lock"), - // new CodeSeg(0x070, 0x07B, "F1 - F12"), - // new CodeSeg(0x09A, 0x09D, "prt ins hlp meta"), - new CodeSeg(0x0C0, 0x0C0, "back quote"), - new CodeSeg(0x0DE, 0x0DE, "quote"), - // new CodeSeg(0x0E0, 0x0E3, "cursor kp"), - // new CodeSeg(0x080, 0x08F, "dead-1"), - // new CodeSeg(0x096, 0x0A2, "& ^ \" < > { }"), - // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; .. - }; - - static void testKeyCode(Robot robot, NEWTKeyAdapter keyAdapter) { - final List> cse = new ArrayList>(); - final List queue = keyAdapter.getQueued(); - - for(int i=0; i events = new ArrayList(queue); - cse.add(events); - } - Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCode(codeSegments, cse, true)); - } - - 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); // within unit framework, prev. tests (TestFocus02SwingAWTRobot) 'confuses' Windows keyboard input - glWindow1KA.reset(); - - // - // Test the key event order w/o auto-repeat - // - testKeyCode(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 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 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 { }"), + // new CodeSeg(0x200, 0x20D, "extra-2"), // @ ; .. + }; + + static void testKeyCodes(Robot robot, NEWTKeyAdapter keyAdapter) { + final List> cse = new ArrayList>(); + + for(int i=0; i events = new ArrayList(keyAdapter.getQueued()); + cse.add(events); + } + Assert.assertEquals("KeyCode impl. incomplete", true, NEWTKeyUtil.validateKeyCodes(codeSegments, cse, true)); + } + + 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(); + + testKeyCodes(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 keyEvents = keyAdapter.getQueued(); int firstIdx = 0; for(int i=0; i= 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 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 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) * *

* 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 getQueued() { + public synchronized List 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 getQueued() { + public synchronized List 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 getQueued(); + public List 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 getQueued() { + public synchronized List 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 keyEvents) { for(int i=0; i> keyEventsList, boolean verbose) { + + public static boolean validateKeyCodes(CodeSeg[] codeSegments, List> keyEventsList, boolean verbose) { final List missCodes = new ArrayList(); 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 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 missCodes, CodeSeg codeSeg, List keyEvents, boolean verbose) { + public static boolean validateKeyCodes(List missCodes, CodeSeg codeSeg, List keyEvents, boolean verbose) { final int codeCount = codeSeg.max - codeSeg.min + 1; int misses = 0; for(int i=0; i 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 getQueued() { + public synchronized List 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 ) { -- cgit v1.2.3