/* * The MIT License (MIT) * * Copyright (c) 2014-2017 Sri Harsha Chilakapati * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.shc.silenceengine.backend.android; import android.opengl.GLSurfaceView; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import com.shc.silenceengine.input.InputDevice; import java.util.HashMap; import java.util.Map; import static android.view.KeyEvent.*; import static com.shc.silenceengine.input.Keyboard.*; import static com.shc.silenceengine.input.Touch.*; /** * @author Sri Harsha Chilakapati */ class AndroidInputDevice extends InputDevice { private static Map<Integer, Integer> keyMap; private GLSurfaceView surfaceView; AndroidInputDevice() { surfaceView = AndroidLauncher.instance.surfaceView; surfaceView.setOnKeyListener(this::onKey); surfaceView.setOnTouchListener(this::onTouch); prepareKeyMap(); } private void prepareKeyMap() { keyMap = new HashMap<>(); // Escape key keyMap.put(KEYCODE_ESCAPE, KEY_ESCAPE); // Function keys keyMap.put(KEYCODE_F1, KEY_F1); keyMap.put(KEYCODE_F2, KEY_F2); keyMap.put(KEYCODE_F3, KEY_F3); keyMap.put(KEYCODE_F4, KEY_F4); keyMap.put(KEYCODE_F5, KEY_F5); keyMap.put(KEYCODE_F6, KEY_F6); keyMap.put(KEYCODE_F7, KEY_F7); keyMap.put(KEYCODE_F8, KEY_F8); keyMap.put(KEYCODE_F9, KEY_F9); keyMap.put(KEYCODE_F10, KEY_F10); keyMap.put(KEYCODE_F11, KEY_F11); keyMap.put(KEYCODE_F12, KEY_F12); // Number keys keyMap.put(KEYCODE_0, KEY_0); keyMap.put(KEYCODE_1, KEY_1); keyMap.put(KEYCODE_2, KEY_2); keyMap.put(KEYCODE_3, KEY_3); keyMap.put(KEYCODE_4, KEY_4); keyMap.put(KEYCODE_5, KEY_5); keyMap.put(KEYCODE_6, KEY_6); keyMap.put(KEYCODE_7, KEY_7); keyMap.put(KEYCODE_8, KEY_8); keyMap.put(KEYCODE_9, KEY_9); // Symbol keys keyMap.put(KEYCODE_MINUS, KEY_UNDERSCORE); keyMap.put(KEYCODE_EQUALS, KEY_EQUALS); keyMap.put(KEYCODE_LEFT_BRACKET, KEY_LEFT_BRACE); keyMap.put(KEYCODE_RIGHT_BRACKET, KEY_RIGHT_BRACE); keyMap.put(KEYCODE_BACKSLASH, KEY_BACKWARD_SLASH); keyMap.put(KEYCODE_SEMICOLON, KEY_SEMICOLON); keyMap.put(KEYCODE_APOSTROPHE, KEY_DOUBLE_QUOTE); keyMap.put(KEYCODE_COMMA, KEY_COMMA); keyMap.put(KEYCODE_PERIOD, KEY_PERIOD); keyMap.put(KEYCODE_SLASH, KEY_FORWARD_SLASH); // Lock keys keyMap.put(KEYCODE_NUM_LOCK, KEY_NUM_LOCK); keyMap.put(KEYCODE_CAPS_LOCK, KEY_CAPS_LOCK); keyMap.put(KEYCODE_SCROLL_LOCK, KEY_SCROLL_LOCK); // Special keys keyMap.put(KEYCODE_TAB, KEY_TAB); keyMap.put(KEYCODE_BACK, KEY_BACKSPACE); keyMap.put(KEYCODE_ENTER, KEY_ENTER); keyMap.put(KEYCODE_SHIFT_LEFT, KEY_LEFT_SHIFT); keyMap.put(KEYCODE_SHIFT_RIGHT, KEY_RIGHT_SHIFT); keyMap.put(KEYCODE_CTRL_LEFT, KEY_LEFT_CTRL); keyMap.put(KEYCODE_CTRL_RIGHT, KEY_RIGHT_CTRL); keyMap.put(KEYCODE_ALT_LEFT, KEY_LEFT_ALT); keyMap.put(KEYCODE_ALT_RIGHT, KEY_RIGHT_ALT); keyMap.put(KEYCODE_INSERT, KEY_INSERT); keyMap.put(KEYCODE_DEL, KEY_DELETE); keyMap.put(KEYCODE_HOME, KEY_HOME); keyMap.put(KEYCODE_PAGE_DOWN, KEY_PAGEDOWN); keyMap.put(KEYCODE_PAGE_UP, KEY_PAGEUP); // Keypad keys keyMap.put(KEYCODE_NUMPAD_0, KEY_KP_0); keyMap.put(KEYCODE_NUMPAD_1, KEY_KP_1); keyMap.put(KEYCODE_NUMPAD_2, KEY_KP_2); keyMap.put(KEYCODE_NUMPAD_3, KEY_KP_3); keyMap.put(KEYCODE_NUMPAD_4, KEY_KP_4); keyMap.put(KEYCODE_NUMPAD_5, KEY_KP_5); keyMap.put(KEYCODE_NUMPAD_6, KEY_KP_6); keyMap.put(KEYCODE_NUMPAD_7, KEY_KP_7); keyMap.put(KEYCODE_NUMPAD_8, KEY_KP_8); keyMap.put(KEYCODE_NUMPAD_9, KEY_KP_9); keyMap.put(KEYCODE_NUMPAD_DIVIDE, KEY_KP_SLASH); keyMap.put(KEYCODE_NUMPAD_MULTIPLY, KEY_KP_ASTERISK); keyMap.put(KEYCODE_NUMPAD_SUBTRACT, KEY_KP_MINUS); keyMap.put(KEYCODE_NUMPAD_ADD, KEY_KP_PLUS); keyMap.put(KEYCODE_NUMPAD_ENTER, KEY_KP_ENTER); keyMap.put(KEYCODE_NUMPAD_DOT, KEY_KP_PERIOD); // Arrow keys keyMap.put(KEYCODE_DPAD_UP, KEY_UP); keyMap.put(KEYCODE_DPAD_DOWN, KEY_DOWN); keyMap.put(KEYCODE_DPAD_LEFT, KEY_LEFT); keyMap.put(KEYCODE_DPAD_RIGHT, KEY_RIGHT); // Alphabet keys keyMap.put(KEYCODE_A, KEY_A); keyMap.put(KEYCODE_B, KEY_B); keyMap.put(KEYCODE_C, KEY_C); keyMap.put(KEYCODE_D, KEY_D); keyMap.put(KEYCODE_E, KEY_E); keyMap.put(KEYCODE_F, KEY_F); keyMap.put(KEYCODE_G, KEY_G); keyMap.put(KEYCODE_H, KEY_H); keyMap.put(KEYCODE_I, KEY_I); keyMap.put(KEYCODE_J, KEY_J); keyMap.put(KEYCODE_K, KEY_K); keyMap.put(KEYCODE_L, KEY_L); keyMap.put(KEYCODE_M, KEY_M); keyMap.put(KEYCODE_N, KEY_N); keyMap.put(KEYCODE_O, KEY_O); keyMap.put(KEYCODE_P, KEY_P); keyMap.put(KEYCODE_Q, KEY_Q); keyMap.put(KEYCODE_R, KEY_R); keyMap.put(KEYCODE_S, KEY_S); keyMap.put(KEYCODE_T, KEY_T); keyMap.put(KEYCODE_U, KEY_U); keyMap.put(KEYCODE_V, KEY_V); keyMap.put(KEYCODE_W, KEY_W); keyMap.put(KEYCODE_X, KEY_X); keyMap.put(KEYCODE_Y, KEY_Y); keyMap.put(KEYCODE_Z, KEY_Z); keyMap.put(KEYCODE_SPACE, KEY_SPACE); } private int translateKeyCode(int nativeCode) { Integer code = keyMap.get(nativeCode); return (code == null) ? 0 : code; } private boolean onKey(View v, int keyCode, KeyEvent event) { surfaceView.queueEvent(() -> postKeyEvent(translateKeyCode(keyCode), event.getAction() == ACTION_DOWN)); return true; } private boolean onTouch(View v, MotionEvent e) { final int action = e.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: { final boolean down = action == ACTION_DOWN; final float x = e.getX(); final float y = e.getY(); surfaceView.queueEvent(() -> postTouchEvent(FINGER_0, down, x, y)); break; } case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: { final int index = e.getActionIndex(); final int finger = index + 1; if (finger < FINGER_1 || finger > FINGER_9) break; final float x = e.getX(); final float y = e.getY(); final boolean isDown = action == MotionEvent.ACTION_POINTER_DOWN; surfaceView.queueEvent(() -> postTouchEvent(finger, isDown, x, y)); break; } case MotionEvent.ACTION_MOVE: { for (int i = 0; i < e.getPointerCount(); i++) { final int finger = i + 1; if (finger < FINGER_0 || finger > FINGER_9) break; final float x = e.getX(i); final float y = e.getY(i); surfaceView.queueEvent(() -> postTouchEvent(finger, true, x, y)); } for (int i = e.getPointerCount(); i < FINGER_9; i++) { final int finger = i + 1; surfaceView.queueEvent(() -> postTouchEvent(finger, false, 0, 0)); } break; } } return true; } }