/** * 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.util; import java.util.ArrayList; import java.util.EventObject; import java.util.List; import org.junit.Assert; import com.jogamp.common.util.IntIntHashMap; import com.jogamp.newt.event.KeyEvent; public class NEWTKeyUtil { public static final int TIME_OUT = 2000; // 2s public static final int POLL_DIVIDER = 20; // TO/20 public static final int TIME_SLICE = TIME_OUT / POLL_DIVIDER ; public static class CodeSeg { public final short min; public final short max; public final String description; public CodeSeg(final int min, final int max, final String description) { this.min = (short)min; this.max = (short)max; this.description = description; } } public static class CodeEvent { public final short code; public final String description; public final KeyEvent event; public CodeEvent(final short code, final String description, final KeyEvent event) { this.code = code; this.description = description; this.event = event; } public String toString() { return "Code 0x"+Integer.toHexString( code & 0x0000FFFF )+" != "+event+" // "+description; } } public static void dumpKeyEvents(final List<EventObject> keyEvents) { for(int i=0; i<keyEvents.size(); i++) { System.err.println(i+": "+keyEvents.get(i)); } } public static boolean validateKeyCodes(final CodeSeg[] codeSegments, final List<List<EventObject>> keyEventsList, final boolean verbose) { final List<CodeEvent> missCodes = new ArrayList<CodeEvent>(); int totalCodeCount = 0; boolean res = true; for(int i=0; i<codeSegments.length; i++) { final CodeSeg codeSeg = codeSegments[i]; totalCodeCount += codeSeg.max - codeSeg.min + 1; final List<EventObject> keyEvents = keyEventsList.get(i); res &= validateKeyCodes(missCodes, codeSeg, keyEvents, verbose); } if(verbose) { System.err.println("*** Total KeyCode Misses "+missCodes.size()+" / "+totalCodeCount+", valid "+res); for(int i=0; i<missCodes.size(); i++) { System.err.println("Miss["+i+"]: "+missCodes.get(i)); } } return res; } public static boolean validateKeyCodes(final List<CodeEvent> missCodes, final CodeSeg codeSeg, final List<EventObject> keyEvents, final boolean verbose) { final int codeCount = codeSeg.max - codeSeg.min + 1; int misses = 0; int evtIdx = 0; for(int i=0; i<codeCount; i++) { // evtIdx -> KEY_PRESSED ! final short c = (short) ( codeSeg.min + i ); final KeyEvent e = (KeyEvent) ( evtIdx < keyEvents.size() ? keyEvents.get(evtIdx) : null ); if( null == e ) { missCodes.add(new CodeEvent(c, codeSeg.description, e)); misses++; evtIdx++; } else { if( c != e.getKeyCode() ) { missCodes.add(new CodeEvent(c, codeSeg.description, e)); misses++; } evtIdx += 2; } } final boolean res = evtIdx == keyEvents.size() && 0 == missCodes.size(); if(verbose) { System.err.println("+++ Code Segment "+codeSeg.description+", Misses: "+misses+" / "+codeCount+", events "+keyEvents.size()+", valid "+res); } return res; } public static void validateKeyEvent(final KeyEvent e, final short eventType, final int modifiers, final short keyCode, final char keyChar) { if(0 <= eventType) { Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType()); } if(0 <= modifiers) { Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifiers)+", has "+e, modifiers == e.getModifiers()); } if(KeyEvent.VK_UNDEFINED != keyCode) { Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode()); } if(KeyEvent.NULL_CHAR != keyChar) { Assert.assertTrue("KeyEvent char mismatch, expected 0x"+Integer.toHexString(keyChar)+", has "+e, keyChar == e.getKeyChar()); } } public static short getNextKeyEventType(final KeyEvent e) { final int et = e.getEventType(); switch( et ) { case KeyEvent.EVENT_KEY_PRESSED: return KeyEvent.EVENT_KEY_RELEASED; case KeyEvent.EVENT_KEY_RELEASED: return KeyEvent.EVENT_KEY_PRESSED; default: Assert.assertTrue("Invalid event "+e, false); return 0; } } public static void validateKeyEventOrder(final List<EventObject> keyEvents) { final IntIntHashMap keyCode2NextEvent = new IntIntHashMap(); for(int i=0; i<keyEvents.size(); i++) { final KeyEvent e = (KeyEvent) keyEvents.get(i); int eet = keyCode2NextEvent.get(e.getKeyCode()); if( 0 >= eet ) { eet = KeyEvent.EVENT_KEY_PRESSED; } final int et = e.getEventType(); Assert.assertEquals("Key event not in proper order "+i+"/"+keyEvents.size()+" - event "+e, eet, et); eet = getNextKeyEventType(e); keyCode2NextEvent.put(e.getKeyCode(), eet); } } /** * @param keyAdapter * @param expPressedCountSI number of single key press events * @param expReleasedCountSI number of single key release events * @param expPressedCountAR number of auto-repeat key press events * @param expReleasedCountAR number of auto-repeat key release events */ public static void validateKeyAdapterStats(final NEWTKeyAdapter keyAdapter, final int expPressedCountSI, final int expReleasedCountSI, final int expPressedCountAR, final int expReleasedCountAR) { final int expPressReleaseCountSI = expPressedCountSI + expReleasedCountSI; final int expPressReleaseCountAR = expPressedCountAR + expReleasedCountAR; final int expPressReleaseCountALL = expPressReleaseCountSI + expPressReleaseCountAR; final int keyPressedALL = keyAdapter.getKeyPressedCount(false); final int keyPressedAR = keyAdapter.getKeyPressedCount(true); final int keyReleasedALL = keyAdapter.getKeyReleasedCount(false); final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true); final int keyPressedSI = keyPressedALL-keyPressedAR; final int keyReleasedSI = keyReleasedALL-keyReleasedAR; final int pressReleaseCountALL = keyPressedALL + keyReleasedALL; final int pressReleaseCountSI = keyPressedSI + keyReleasedSI; final int pressReleaseCountAR = keyPressedAR + keyReleasedAR; System.err.println("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI); System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR); System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Events "+pressReleaseCountSI); System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Events "+pressReleaseCountAR); System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Events "+pressReleaseCountALL); Assert.assertEquals("Internal Error: pressReleaseSI != pressReleaseALL - pressReleaseAR", pressReleaseCountSI, pressReleaseCountALL - pressReleaseCountAR); Assert.assertEquals("Key press count failure (SI)", expPressedCountSI, keyPressedSI); Assert.assertEquals("Key released count failure (SI)", expReleasedCountSI, keyReleasedSI); Assert.assertEquals("Key press count failure (AR)", expPressedCountAR, keyPressedAR); Assert.assertEquals("Key released count failure (AR)", expReleasedCountAR, keyReleasedAR); Assert.assertEquals("Key pressRelease count failure (SI)", expPressReleaseCountSI, pressReleaseCountSI); Assert.assertEquals("Key pressRelease count failure (AR)", expPressReleaseCountAR, pressReleaseCountAR); final List<EventObject> keyEvents = keyAdapter.copyQueue(); Assert.assertEquals("Key pressRelease count failure (ALL) w/ list sum ", expPressReleaseCountALL, pressReleaseCountALL); Assert.assertEquals("Key total count failure (ALL) w/ list size ", pressReleaseCountALL, keyEvents.size()); } }