1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package com.jme3.input.awt;
34
35import com.jme3.input.KeyInput;
36import com.jme3.input.RawInputListener;
37import com.jme3.input.event.KeyInputEvent;
38import java.awt.Component;
39import java.awt.event.KeyEvent;
40import java.awt.event.KeyListener;
41import java.util.ArrayList;
42import java.util.logging.Logger;
43
44/**
45 * <code>AwtKeyInput</code>
46 *
47 * @author Joshua Slack
48 * @author Kirill Vainer
49 * @version $Revision: 4133 $
50 */
51public class AwtKeyInput implements KeyInput, KeyListener {
52
53    private static final Logger logger = Logger.getLogger(AwtKeyInput.class.getName());
54
55    private final ArrayList<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>();
56    private RawInputListener listener;
57    private Component component;
58
59    public AwtKeyInput(){
60    }
61
62    public void initialize() {
63    }
64
65    public void destroy() {
66    }
67
68    public void setInputSource(Component comp){
69        synchronized (eventQueue){
70            if (component != null){
71                component.removeKeyListener(this);
72                eventQueue.clear();
73            }
74            component = comp;
75            component.addKeyListener(this);
76        }
77    }
78
79    public long getInputTimeNanos() {
80        return System.nanoTime();
81    }
82
83    public int getKeyCount() {
84        return KeyEvent.KEY_LAST+1;
85    }
86
87    public void update() {
88        synchronized (eventQueue){
89            // flush events to listener
90            for (int i = 0; i < eventQueue.size(); i++){
91                listener.onKeyEvent(eventQueue.get(i));
92            }
93            eventQueue.clear();
94        }
95    }
96
97    public boolean isInitialized() {
98        return true;
99    }
100
101    public void setInputListener(RawInputListener listener) {
102        this.listener = listener;
103    }
104
105    public void keyTyped(KeyEvent evt) {
106        // key code is zero for typed events
107//        int code = 0;
108//        KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, true);
109//        keyEvent.setTime(evt.getWhen());
110//        synchronized (eventQueue){
111//            eventQueue.add(keyEvent);
112//        }
113    }
114
115    public void keyPressed(KeyEvent evt) {
116        int code = convertAwtKey(evt.getKeyCode());
117        KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, false);
118        keyEvent.setTime(evt.getWhen());
119        synchronized (eventQueue){
120            eventQueue.add(keyEvent);
121        }
122    }
123
124    public void keyReleased(KeyEvent evt) {
125        int code = convertAwtKey(evt.getKeyCode());
126        KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, false);
127        keyEvent.setTime(evt.getWhen());
128        synchronized (eventQueue){
129            eventQueue.add(keyEvent);
130        }
131    }
132
133    /**
134     * <code>convertJmeCode</code> converts KeyInput key codes to AWT key codes.
135     *
136     * @param key jme KeyInput key code
137     * @return awt KeyEvent key code
138     */
139    public static int convertJmeCode( int key ) {
140        switch ( key ) {
141            case KEY_ESCAPE:
142                return KeyEvent.VK_ESCAPE;
143            case KEY_1:
144                return KeyEvent.VK_1;
145            case KEY_2:
146                return KeyEvent.VK_2;
147            case KEY_3:
148                return KeyEvent.VK_3;
149            case KEY_4:
150                return KeyEvent.VK_4;
151            case KEY_5:
152                return KeyEvent.VK_5;
153            case KEY_6:
154                return KeyEvent.VK_6;
155            case KEY_7:
156                return KeyEvent.VK_7;
157            case KEY_8:
158                return KeyEvent.VK_8;
159            case KEY_9:
160                return KeyEvent.VK_9;
161            case KEY_0:
162                return KeyEvent.VK_0;
163            case KEY_MINUS:
164                return KeyEvent.VK_MINUS;
165            case KEY_EQUALS:
166                return KeyEvent.VK_EQUALS;
167            case KEY_BACK:
168                return KeyEvent.VK_BACK_SPACE;
169            case KEY_TAB:
170                return KeyEvent.VK_TAB;
171            case KEY_Q:
172                return KeyEvent.VK_Q;
173            case KEY_W:
174                return KeyEvent.VK_W;
175            case KEY_E:
176                return KeyEvent.VK_E;
177            case KEY_R:
178                return KeyEvent.VK_R;
179            case KEY_T:
180                return KeyEvent.VK_T;
181            case KEY_Y:
182                return KeyEvent.VK_Y;
183            case KEY_U:
184                return KeyEvent.VK_U;
185            case KEY_I:
186                return KeyEvent.VK_I;
187            case KEY_O:
188                return KeyEvent.VK_O;
189            case KEY_P:
190                return KeyEvent.VK_P;
191            case KEY_LBRACKET:
192                return KeyEvent.VK_OPEN_BRACKET;
193            case KEY_RBRACKET:
194                return KeyEvent.VK_CLOSE_BRACKET;
195            case KEY_RETURN:
196                return KeyEvent.VK_ENTER;
197            case KEY_LCONTROL:
198                return KeyEvent.VK_CONTROL;
199            case KEY_A:
200                return KeyEvent.VK_A;
201            case KEY_S:
202                return KeyEvent.VK_S;
203            case KEY_D:
204                return KeyEvent.VK_D;
205            case KEY_F:
206                return KeyEvent.VK_F;
207            case KEY_G:
208                return KeyEvent.VK_G;
209            case KEY_H:
210                return KeyEvent.VK_H;
211            case KEY_J:
212                return KeyEvent.VK_J;
213            case KEY_K:
214                return KeyEvent.VK_K;
215            case KEY_L:
216                return KeyEvent.VK_L;
217            case KEY_SEMICOLON:
218                return KeyEvent.VK_SEMICOLON;
219            case KEY_APOSTROPHE:
220                return KeyEvent.VK_QUOTE;
221            case KEY_GRAVE:
222                return KeyEvent.VK_DEAD_GRAVE;
223            case KEY_LSHIFT:
224                return KeyEvent.VK_SHIFT;
225            case KEY_BACKSLASH:
226                return KeyEvent.VK_BACK_SLASH;
227            case KEY_Z:
228                return KeyEvent.VK_Z;
229            case KEY_X:
230                return KeyEvent.VK_X;
231            case KEY_C:
232                return KeyEvent.VK_C;
233            case KEY_V:
234                return KeyEvent.VK_V;
235            case KEY_B:
236                return KeyEvent.VK_B;
237            case KEY_N:
238                return KeyEvent.VK_N;
239            case KEY_M:
240                return KeyEvent.VK_M;
241            case KEY_COMMA:
242                return KeyEvent.VK_COMMA;
243            case KEY_PERIOD:
244                return KeyEvent.VK_PERIOD;
245            case KEY_SLASH:
246                return KeyEvent.VK_SLASH;
247            case KEY_RSHIFT:
248                return KeyEvent.VK_SHIFT;
249            case KEY_MULTIPLY:
250                return KeyEvent.VK_MULTIPLY;
251            case KEY_SPACE:
252                return KeyEvent.VK_SPACE;
253            case KEY_CAPITAL:
254                return KeyEvent.VK_CAPS_LOCK;
255            case KEY_F1:
256                return KeyEvent.VK_F1;
257            case KEY_F2:
258                return KeyEvent.VK_F2;
259            case KEY_F3:
260                return KeyEvent.VK_F3;
261            case KEY_F4:
262                return KeyEvent.VK_F4;
263            case KEY_F5:
264                return KeyEvent.VK_F5;
265            case KEY_F6:
266                return KeyEvent.VK_F6;
267            case KEY_F7:
268                return KeyEvent.VK_F7;
269            case KEY_F8:
270                return KeyEvent.VK_F8;
271            case KEY_F9:
272                return KeyEvent.VK_F9;
273            case KEY_F10:
274                return KeyEvent.VK_F10;
275            case KEY_NUMLOCK:
276                return KeyEvent.VK_NUM_LOCK;
277            case KEY_SCROLL:
278                return KeyEvent.VK_SCROLL_LOCK;
279            case KEY_NUMPAD7:
280                return KeyEvent.VK_NUMPAD7;
281            case KEY_NUMPAD8:
282                return KeyEvent.VK_NUMPAD8;
283            case KEY_NUMPAD9:
284                return KeyEvent.VK_NUMPAD9;
285            case KEY_SUBTRACT:
286                return KeyEvent.VK_SUBTRACT;
287            case KEY_NUMPAD4:
288                return KeyEvent.VK_NUMPAD4;
289            case KEY_NUMPAD5:
290                return KeyEvent.VK_NUMPAD5;
291            case KEY_NUMPAD6:
292                return KeyEvent.VK_NUMPAD6;
293            case KEY_ADD:
294                return KeyEvent.VK_ADD;
295            case KEY_NUMPAD1:
296                return KeyEvent.VK_NUMPAD1;
297            case KEY_NUMPAD2:
298                return KeyEvent.VK_NUMPAD2;
299            case KEY_NUMPAD3:
300                return KeyEvent.VK_NUMPAD3;
301            case KEY_NUMPAD0:
302                return KeyEvent.VK_NUMPAD0;
303            case KEY_DECIMAL:
304                return KeyEvent.VK_DECIMAL;
305            case KEY_F11:
306                return KeyEvent.VK_F11;
307            case KEY_F12:
308                return KeyEvent.VK_F12;
309            case KEY_F13:
310                return KeyEvent.VK_F13;
311            case KEY_F14:
312                return KeyEvent.VK_F14;
313            case KEY_F15:
314                return KeyEvent.VK_F15;
315            case KEY_KANA:
316                return KeyEvent.VK_KANA;
317            case KEY_CONVERT:
318                return KeyEvent.VK_CONVERT;
319            case KEY_NOCONVERT:
320                return KeyEvent.VK_NONCONVERT;
321            case KEY_NUMPADEQUALS:
322                return KeyEvent.VK_EQUALS;
323            case KEY_CIRCUMFLEX:
324                return KeyEvent.VK_CIRCUMFLEX;
325            case KEY_AT:
326                return KeyEvent.VK_AT;
327            case KEY_COLON:
328                return KeyEvent.VK_COLON;
329            case KEY_UNDERLINE:
330                return KeyEvent.VK_UNDERSCORE;
331            case KEY_STOP:
332                return KeyEvent.VK_STOP;
333            case KEY_NUMPADENTER:
334                return KeyEvent.VK_ENTER;
335            case KEY_RCONTROL:
336                return KeyEvent.VK_CONTROL;
337            case KEY_NUMPADCOMMA:
338                return KeyEvent.VK_COMMA;
339            case KEY_DIVIDE:
340                return KeyEvent.VK_DIVIDE;
341            case KEY_PAUSE:
342                return KeyEvent.VK_PAUSE;
343            case KEY_HOME:
344                return KeyEvent.VK_HOME;
345            case KEY_UP:
346                return KeyEvent.VK_UP;
347            case KEY_PRIOR:
348                return KeyEvent.VK_PAGE_UP;
349            case KEY_LEFT:
350                return KeyEvent.VK_LEFT;
351            case KEY_RIGHT:
352                return KeyEvent.VK_RIGHT;
353            case KEY_END:
354                return KeyEvent.VK_END;
355            case KEY_DOWN:
356                return KeyEvent.VK_DOWN;
357            case KEY_NEXT:
358                return KeyEvent.VK_PAGE_DOWN;
359            case KEY_INSERT:
360                return KeyEvent.VK_INSERT;
361            case KEY_DELETE:
362                return KeyEvent.VK_DELETE;
363            case KEY_LMENU:
364                return KeyEvent.VK_ALT; //todo: location left
365            case KEY_RMENU:
366                return KeyEvent.VK_ALT; //todo: location right
367        }
368        logger.warning("unsupported key:" + key);
369        return 0x10000 + key;
370    }
371
372    /**
373     * <code>convertAwtKey</code> converts AWT key codes to KeyInput key codes.
374     *
375     * @param key awt KeyEvent key code
376     * @return jme KeyInput key code
377     */
378    public static int convertAwtKey(int key) {
379        switch ( key ) {
380            case KeyEvent.VK_ESCAPE:
381                return KEY_ESCAPE;
382            case KeyEvent.VK_1:
383                return KEY_1;
384            case KeyEvent.VK_2:
385                return KEY_2;
386            case KeyEvent.VK_3:
387                return KEY_3;
388            case KeyEvent.VK_4:
389                return KEY_4;
390            case KeyEvent.VK_5:
391                return KEY_5;
392            case KeyEvent.VK_6:
393                return KEY_6;
394            case KeyEvent.VK_7:
395                return KEY_7;
396            case KeyEvent.VK_8:
397                return KEY_8;
398            case KeyEvent.VK_9:
399                return KEY_9;
400            case KeyEvent.VK_0:
401                return KEY_0;
402            case KeyEvent.VK_MINUS:
403                return KEY_MINUS;
404            case KeyEvent.VK_EQUALS:
405                return KEY_EQUALS;
406            case KeyEvent.VK_BACK_SPACE:
407                return KEY_BACK;
408            case KeyEvent.VK_TAB:
409                return KEY_TAB;
410            case KeyEvent.VK_Q:
411                return KEY_Q;
412            case KeyEvent.VK_W:
413                return KEY_W;
414            case KeyEvent.VK_E:
415                return KEY_E;
416            case KeyEvent.VK_R:
417                return KEY_R;
418            case KeyEvent.VK_T:
419                return KEY_T;
420            case KeyEvent.VK_Y:
421                return KEY_Y;
422            case KeyEvent.VK_U:
423                return KEY_U;
424            case KeyEvent.VK_I:
425                return KEY_I;
426            case KeyEvent.VK_O:
427                return KEY_O;
428            case KeyEvent.VK_P:
429                return KEY_P;
430            case KeyEvent.VK_OPEN_BRACKET:
431                return KEY_LBRACKET;
432            case KeyEvent.VK_CLOSE_BRACKET:
433                return KEY_RBRACKET;
434            case KeyEvent.VK_ENTER:
435                return KEY_RETURN;
436            case KeyEvent.VK_CONTROL:
437                return KEY_LCONTROL;
438            case KeyEvent.VK_A:
439                return KEY_A;
440            case KeyEvent.VK_S:
441                return KEY_S;
442            case KeyEvent.VK_D:
443                return KEY_D;
444            case KeyEvent.VK_F:
445                return KEY_F;
446            case KeyEvent.VK_G:
447                return KEY_G;
448            case KeyEvent.VK_H:
449                return KEY_H;
450            case KeyEvent.VK_J:
451                return KEY_J;
452            case KeyEvent.VK_K:
453                return KEY_K;
454            case KeyEvent.VK_L:
455                return KEY_L;
456            case KeyEvent.VK_SEMICOLON:
457                return KEY_SEMICOLON;
458            case KeyEvent.VK_QUOTE:
459                return KEY_APOSTROPHE;
460            case KeyEvent.VK_DEAD_GRAVE:
461                return KEY_GRAVE;
462            case KeyEvent.VK_SHIFT:
463                return KEY_LSHIFT;
464            case KeyEvent.VK_BACK_SLASH:
465                return KEY_BACKSLASH;
466            case KeyEvent.VK_Z:
467                return KEY_Z;
468            case KeyEvent.VK_X:
469                return KEY_X;
470            case KeyEvent.VK_C:
471                return KEY_C;
472            case KeyEvent.VK_V:
473                return KEY_V;
474            case KeyEvent.VK_B:
475                return KEY_B;
476            case KeyEvent.VK_N:
477                return KEY_N;
478            case KeyEvent.VK_M:
479                return KEY_M;
480            case KeyEvent.VK_COMMA:
481                return KEY_COMMA;
482            case KeyEvent.VK_PERIOD:
483                return KEY_PERIOD;
484            case KeyEvent.VK_SLASH:
485                return KEY_SLASH;
486            case KeyEvent.VK_MULTIPLY:
487                return KEY_MULTIPLY;
488            case KeyEvent.VK_SPACE:
489                return KEY_SPACE;
490            case KeyEvent.VK_CAPS_LOCK:
491                return KEY_CAPITAL;
492            case KeyEvent.VK_F1:
493                return KEY_F1;
494            case KeyEvent.VK_F2:
495                return KEY_F2;
496            case KeyEvent.VK_F3:
497                return KEY_F3;
498            case KeyEvent.VK_F4:
499                return KEY_F4;
500            case KeyEvent.VK_F5:
501                return KEY_F5;
502            case KeyEvent.VK_F6:
503                return KEY_F6;
504            case KeyEvent.VK_F7:
505                return KEY_F7;
506            case KeyEvent.VK_F8:
507                return KEY_F8;
508            case KeyEvent.VK_F9:
509                return KEY_F9;
510            case KeyEvent.VK_F10:
511                return KEY_F10;
512            case KeyEvent.VK_NUM_LOCK:
513                return KEY_NUMLOCK;
514            case KeyEvent.VK_SCROLL_LOCK:
515                return KEY_SCROLL;
516            case KeyEvent.VK_NUMPAD7:
517                return KEY_NUMPAD7;
518            case KeyEvent.VK_NUMPAD8:
519                return KEY_NUMPAD8;
520            case KeyEvent.VK_NUMPAD9:
521                return KEY_NUMPAD9;
522            case KeyEvent.VK_SUBTRACT:
523                return KEY_SUBTRACT;
524            case KeyEvent.VK_NUMPAD4:
525                return KEY_NUMPAD4;
526            case KeyEvent.VK_NUMPAD5:
527                return KEY_NUMPAD5;
528            case KeyEvent.VK_NUMPAD6:
529                return KEY_NUMPAD6;
530            case KeyEvent.VK_ADD:
531                return KEY_ADD;
532            case KeyEvent.VK_NUMPAD1:
533                return KEY_NUMPAD1;
534            case KeyEvent.VK_NUMPAD2:
535                return KEY_NUMPAD2;
536            case KeyEvent.VK_NUMPAD3:
537                return KEY_NUMPAD3;
538            case KeyEvent.VK_NUMPAD0:
539                return KEY_NUMPAD0;
540            case KeyEvent.VK_DECIMAL:
541                return KEY_DECIMAL;
542            case KeyEvent.VK_F11:
543                return KEY_F11;
544            case KeyEvent.VK_F12:
545                return KEY_F12;
546            case KeyEvent.VK_F13:
547                return KEY_F13;
548            case KeyEvent.VK_F14:
549                return KEY_F14;
550            case KeyEvent.VK_F15:
551                return KEY_F15;
552            case KeyEvent.VK_KANA:
553                return KEY_KANA;
554            case KeyEvent.VK_CONVERT:
555                return KEY_CONVERT;
556            case KeyEvent.VK_NONCONVERT:
557                return KEY_NOCONVERT;
558            case KeyEvent.VK_CIRCUMFLEX:
559                return KEY_CIRCUMFLEX;
560            case KeyEvent.VK_AT:
561                return KEY_AT;
562            case KeyEvent.VK_COLON:
563                return KEY_COLON;
564            case KeyEvent.VK_UNDERSCORE:
565                return KEY_UNDERLINE;
566            case KeyEvent.VK_STOP:
567                return KEY_STOP;
568            case KeyEvent.VK_DIVIDE:
569                return KEY_DIVIDE;
570            case KeyEvent.VK_PAUSE:
571                return KEY_PAUSE;
572            case KeyEvent.VK_HOME:
573                return KEY_HOME;
574            case KeyEvent.VK_UP:
575                return KEY_UP;
576            case KeyEvent.VK_PAGE_UP:
577                return KEY_PRIOR;
578            case KeyEvent.VK_LEFT:
579                return KEY_LEFT;
580            case KeyEvent.VK_RIGHT:
581                return KEY_RIGHT;
582            case KeyEvent.VK_END:
583                return KEY_END;
584            case KeyEvent.VK_DOWN:
585                return KEY_DOWN;
586            case KeyEvent.VK_PAGE_DOWN:
587                return KEY_NEXT;
588            case KeyEvent.VK_INSERT:
589                return KEY_INSERT;
590            case KeyEvent.VK_DELETE:
591                return KEY_DELETE;
592            case KeyEvent.VK_ALT:
593                return KEY_LMENU; //Left vs. Right need to improve
594            case KeyEvent.VK_META:
595            	return KEY_RCONTROL;
596
597        }
598        logger.warning( "unsupported key:" + key );
599        if ( key >= 0x10000 ) {
600            return key - 0x10000;
601        }
602
603        return 0;
604    }
605
606}
607