JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
NEWTKeyUtil.java
Go to the documentation of this file.
1/**
2 * Copyright 2012 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 */
28package com.jogamp.opengl.test.junit.util;
29
30import java.util.ArrayList;
31import java.util.EventObject;
32import java.util.List;
33
34import org.junit.Assert;
35
36import com.jogamp.common.util.IntIntHashMap;
37import com.jogamp.newt.event.KeyEvent;
38
39public class NEWTKeyUtil {
40 public static final int TIME_OUT = 2000; // 2s
41 public static final int POLL_DIVIDER = 20; // TO/20
42 public static final int TIME_SLICE = TIME_OUT / POLL_DIVIDER ;
43
44 public static class CodeSeg {
45 public final short min;
46 public final short max;
47 public final String description;
48
49 public CodeSeg(final int min, final int max, final String description) {
50 this.min = (short)min;
51 this.max = (short)max;
52 this.description = description;
53 }
54 }
55 public static class CodeEvent {
56 public final short code;
57 public final String description;
58 public final KeyEvent event;
59
60 public CodeEvent(final short code, final String description, final KeyEvent event) {
61 this.code = code;
62 this.description = description;
63 this.event = event;
64 }
65 public String toString() {
66 return "Code 0x"+Integer.toHexString( code & 0x0000FFFF )+" != "+event+" // "+description;
67 }
68 }
69
70 public static void dumpKeyEvents(final List<EventObject> keyEvents) {
71 for(int i=0; i<keyEvents.size(); i++) {
72 System.err.println(i+": "+keyEvents.get(i));
73 }
74 }
75
76 public static boolean validateKeyCodes(final CodeSeg[] codeSegments, final List<List<EventObject>> keyEventsList, final boolean verbose) {
77 final List<CodeEvent> missCodes = new ArrayList<CodeEvent>();
78 int totalCodeCount = 0;
79 boolean res = true;
80 for(int i=0; i<codeSegments.length; i++) {
81 final CodeSeg codeSeg = codeSegments[i];
82 totalCodeCount += codeSeg.max - codeSeg.min + 1;
83 final List<EventObject> keyEvents = keyEventsList.get(i);
84 res &= validateKeyCodes(missCodes, codeSeg, keyEvents, verbose);
85 }
86 if(verbose) {
87 System.err.println("*** Total KeyCode Misses "+missCodes.size()+" / "+totalCodeCount+", valid "+res);
88 for(int i=0; i<missCodes.size(); i++) {
89 System.err.println("Miss["+i+"]: "+missCodes.get(i));
90 }
91 }
92 return res;
93 }
94 public static boolean validateKeyCodes(final List<CodeEvent> missCodes, final CodeSeg codeSeg, final List<EventObject> keyEvents, final boolean verbose) {
95 final int codeCount = codeSeg.max - codeSeg.min + 1;
96 int misses = 0;
97 int evtIdx = 0;
98 for(int i=0; i<codeCount; i++) {
99 // evtIdx -> KEY_PRESSED !
100 final short c = (short) ( codeSeg.min + i );
101 final KeyEvent e = (KeyEvent) ( evtIdx < keyEvents.size() ? keyEvents.get(evtIdx) : null );
102 if( null == e ) {
103 missCodes.add(new CodeEvent(c, codeSeg.description, e));
104 misses++;
105 evtIdx++;
106 } else {
107 if( c != e.getKeyCode() ) {
108 missCodes.add(new CodeEvent(c, codeSeg.description, e));
109 misses++;
110 }
111 evtIdx += 2;
112 }
113 }
114 final boolean res = evtIdx == keyEvents.size() && 0 == missCodes.size();
115 if(verbose) {
116 System.err.println("+++ Code Segment "+codeSeg.description+", Misses: "+misses+" / "+codeCount+", events "+keyEvents.size()+", valid "+res);
117 }
118 return res;
119 }
120
121 public static void validateKeyEvent(final KeyEvent e, final short eventType, final int modifiers, final short keyCode, final char keyChar) {
122 if(0 <= eventType) {
123 Assert.assertTrue("KeyEvent type mismatch, expected 0x"+Integer.toHexString(eventType)+", has "+e, eventType == e.getEventType());
124 }
125 if(0 <= modifiers) {
126 Assert.assertTrue("KeyEvent modifier mismatch, expected 0x"+Integer.toHexString(modifiers)+", has "+e, modifiers == e.getModifiers());
127 }
128 if(KeyEvent.VK_UNDEFINED != keyCode) {
129 Assert.assertTrue("KeyEvent code mismatch, expected 0x"+Integer.toHexString(keyCode)+", has "+e, keyCode == e.getKeyCode());
130 }
131 if(KeyEvent.NULL_CHAR != keyChar) {
132 Assert.assertTrue("KeyEvent char mismatch, expected 0x"+Integer.toHexString(keyChar)+", has "+e, keyChar == e.getKeyChar());
133 }
134 }
135
136 public static short getNextKeyEventType(final KeyEvent e) {
137 final int et = e.getEventType();
138 switch( et ) {
143 default:
144 Assert.assertTrue("Invalid event "+e, false);
145 return 0;
146 }
147 }
148
149 public static void validateKeyEventOrder(final List<EventObject> keyEvents) {
150 final IntIntHashMap keyCode2NextEvent = new IntIntHashMap();
151 for(int i=0; i<keyEvents.size(); i++) {
152 final KeyEvent e = (KeyEvent) keyEvents.get(i);
153 int eet = keyCode2NextEvent.get(e.getKeyCode());
154 if( 0 >= eet ) {
156 }
157 final int et = e.getEventType();
158 Assert.assertEquals("Key event not in proper order "+i+"/"+keyEvents.size()+" - event "+e, eet, et);
159 eet = getNextKeyEventType(e);
160 keyCode2NextEvent.put(e.getKeyCode(), eet);
161 }
162 }
163
164 /**
165 * @param keyAdapter
166 * @param expPressedCountSI number of single key press events
167 * @param expReleasedCountSI number of single key release events
168 * @param expPressedCountAR number of auto-repeat key press events
169 * @param expReleasedCountAR number of auto-repeat key release events
170 */
171 public static void validateKeyAdapterStats(final NEWTKeyAdapter keyAdapter,
172 final int expPressedCountSI, final int expReleasedCountSI,
173 final int expPressedCountAR, final int expReleasedCountAR) {
174 final int expPressReleaseCountSI = expPressedCountSI + expReleasedCountSI;
175 final int expPressReleaseCountAR = expPressedCountAR + expReleasedCountAR;
176 final int expPressReleaseCountALL = expPressReleaseCountSI + expPressReleaseCountAR;
177
178 final int keyPressedALL = keyAdapter.getKeyPressedCount(false);
179 final int keyPressedAR = keyAdapter.getKeyPressedCount(true);
180 final int keyReleasedALL = keyAdapter.getKeyReleasedCount(false);
181 final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true);
182
183 final int keyPressedSI = keyPressedALL-keyPressedAR;
184 final int keyReleasedSI = keyReleasedALL-keyReleasedAR;
185
186 final int pressReleaseCountALL = keyPressedALL + keyReleasedALL;
187 final int pressReleaseCountSI = keyPressedSI + keyReleasedSI;
188 final int pressReleaseCountAR = keyPressedAR + keyReleasedAR;
189
190 System.err.println("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI);
191 System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR);
192
193 System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Events "+pressReleaseCountSI);
194 System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Events "+pressReleaseCountAR);
195 System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Events "+pressReleaseCountALL);
196
197 Assert.assertEquals("Internal Error: pressReleaseSI != pressReleaseALL - pressReleaseAR", pressReleaseCountSI, pressReleaseCountALL - pressReleaseCountAR);
198
199 Assert.assertEquals("Key press count failure (SI)", expPressedCountSI, keyPressedSI);
200 Assert.assertEquals("Key released count failure (SI)", expReleasedCountSI, keyReleasedSI);
201
202 Assert.assertEquals("Key press count failure (AR)", expPressedCountAR, keyPressedAR);
203 Assert.assertEquals("Key released count failure (AR)", expReleasedCountAR, keyReleasedAR);
204
205 Assert.assertEquals("Key pressRelease count failure (SI)", expPressReleaseCountSI, pressReleaseCountSI);
206 Assert.assertEquals("Key pressRelease count failure (AR)", expPressReleaseCountAR, pressReleaseCountAR);
207
208 final List<EventObject> keyEvents = keyAdapter.copyQueue();
209
210 Assert.assertEquals("Key pressRelease count failure (ALL) w/ list sum ", expPressReleaseCountALL, pressReleaseCountALL);
211 Assert.assertEquals("Key total count failure (ALL) w/ list size ", pressReleaseCountALL, keyEvents.size());
212 }
213}
final int getModifiers()
Return the modifier bits of this event, e.g.
static final char NULL_CHAR
This value, '\0', is used to indicate that the keyChar is unknown or not printable.
Definition: KeyEvent.java:369
final char getKeyChar()
Returns the UTF-16 character reflecting the key symbol incl.
Definition: KeyEvent.java:161
static final short EVENT_KEY_PRESSED
A key has been pressed, excluding auto-repeat-modifier keys.
Definition: KeyEvent.java:362
final short getKeyCode()
Returns the virtual key code using a fixed mapping to the US keyboard layout.
Definition: KeyEvent.java:195
static final short EVENT_KEY_RELEASED
A key has been released, excluding auto-repeat-modifier keys.
Definition: KeyEvent.java:364
static final short VK_UNDEFINED
This value, {@value}, is used to indicate that the keyCode is unknown.
Definition: KeyEvent.java:411
final short getEventType()
Returns the event type of this event.
Definition: NEWTEvent.java:72
synchronized int getKeyReleasedCount(final boolean autoRepeatOnly)
synchronized List< EventObject > copyQueue()
synchronized int getKeyPressedCount(final boolean autoRepeatOnly)
CodeEvent(final short code, final String description, final KeyEvent event)
CodeSeg(final int min, final int max, final String description)
static boolean validateKeyCodes(final List< CodeEvent > missCodes, final CodeSeg codeSeg, final List< EventObject > keyEvents, final boolean verbose)
static boolean validateKeyCodes(final CodeSeg[] codeSegments, final List< List< EventObject > > keyEventsList, final boolean verbose)
static void dumpKeyEvents(final List< EventObject > keyEvents)
static void validateKeyEventOrder(final List< EventObject > keyEvents)
static void validateKeyEvent(final KeyEvent e, final short eventType, final int modifiers, final short keyCode, final char keyChar)
static void validateKeyAdapterStats(final NEWTKeyAdapter keyAdapter, final int expPressedCountSI, final int expReleasedCountSI, final int expPressedCountAR, final int expReleasedCountAR)
static short getNextKeyEventType(final KeyEvent e)