Skip to content

Instantly share code, notes, and snippets.

@Hasufel
Created January 13, 2014 18:28
Show Gist options
  • Save Hasufel/8405464 to your computer and use it in GitHub Desktop.
Save Hasufel/8405464 to your computer and use it in GitHub Desktop.
example for listener OnInputDeviceListener in mainview.java
package org.haxe.lime;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
::if (ANDROID_TARGET_SDK_VERSION > 15)::import android.hardware.input.InputManager;::end:: //addition nils
::if (ANDROID_TARGET_SDK_VERSION > 15)::import android.hardware.input.InputManager.InputDeviceListener;::end:://addition nils
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Handler; //addition nils
import android.os.SystemClock;
import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
::if (ANDROID_TARGET_SDK_VERSION > 15)::import android.view.InputDevice;::end::
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class MainView extends GLSurfaceView {
static final int etTouchBegin = 15;
static final int etTouchMove = 16;
static final int etTouchEnd = 17;
static final int etTouchTap = 18;
static final int resTerminate = -1;
Activity mActivity;
static MainView mRefreshView;
Timer mTimer = new Timer ();
int mTimerID = 0;
::if (ANDROID_TARGET_SDK_VERSION > 15)::
private InputManager mInputManager; //addition nils
private OnInputDeviceListener mOnInputDeviceListener; //addition nils
private InputDevice mInputDevice; //addition nils
::end::
public MainView (Context context, Activity inActivity) {
super (context);
int eglVersion = 1;
if (::WIN_ALLOW_SHADERS:: || ::WIN_REQUIRE_SHADERS::) {
EGL10 egl = (EGL10)EGLContext.getEGL ();
EGLDisplay display = egl.eglGetDisplay (EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
egl.eglInitialize (display, version);
EGLConfig[] v2_configs = new EGLConfig[1];
int[] num_config = new int[1];
int[] attrs = { EGL10.EGL_RENDERABLE_TYPE, ::if DEFINE_LIME_FORCE_GLES1::1::else::4::end:: /*EGL_OPENGL_ES2_BIT*/, EGL10.EGL_NONE };
egl.eglChooseConfig (display, attrs, v2_configs, 1, num_config);
if (num_config[0]==1) {
eglVersion = ::if DEFINE_LIME_FORCE_GLES1::1::else::2::end::;
setEGLContextClientVersion (::if DEFINE_LIME_FORCE_GLES1::1::else::2::end::);
}
}
final int renderType = (eglVersion == 1 ? 0x01 : 0x04);
setEGLConfigChooser (new EGLConfigChooser () {
public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display) {
int depth = ::if WIN_DEPTH_BUFFER::16::else::0::end::;
int stencil = ::if WIN_STENCIL_BUFFER::8::else::0::end::;
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
if (::WIN_ANTIALIASING:: > 1) {
int[] attrs = {
EGL10.EGL_DEPTH_SIZE, depth,
EGL10.EGL_STENCIL_SIZE, stencil,
EGL10.EGL_SAMPLE_BUFFERS, 1 /* true */,
EGL10.EGL_SAMPLES, ::WIN_ANTIALIASING::,
EGL10.EGL_RENDERABLE_TYPE, renderType,
EGL10.EGL_NONE
};
egl.eglChooseConfig (display, attrs, configs, 1, num_config);
if (num_config[0] == 1) {
return configs[0];
}
if (::WIN_ANTIALIASING:: > 2) {
int[] attrs_aa2 = {
EGL10.EGL_DEPTH_SIZE, depth,
EGL10.EGL_STENCIL_SIZE, stencil,
EGL10.EGL_SAMPLE_BUFFERS, 1 /* true */,
EGL10.EGL_SAMPLES, 2,
EGL10.EGL_RENDERABLE_TYPE, renderType,
EGL10.EGL_NONE
};
egl.eglChooseConfig (display, attrs_aa2, configs, 1, num_config);
if (num_config[0] == 1) {
return configs[0];
}
}
final int EGL_COVERAGE_BUFFERS_NV = 0x30E0;
final int EGL_COVERAGE_SAMPLES_NV = 0x30E1;
int[] attrs_aanv = {
EGL10.EGL_DEPTH_SIZE, depth,
EGL10.EGL_STENCIL_SIZE, stencil,
EGL_COVERAGE_BUFFERS_NV, 1 /* true */,
EGL_COVERAGE_SAMPLES_NV, 2, // always 5 in practice on tegra 2
EGL10.EGL_RENDERABLE_TYPE, renderType,
EGL10.EGL_NONE
};
egl.eglChooseConfig (display, attrs_aanv, configs, 1, num_config);
if (num_config[0] == 1) {
return configs[0];
}
}
int[] attrs1 = {
EGL10.EGL_DEPTH_SIZE, depth,
EGL10.EGL_STENCIL_SIZE, stencil,
EGL10.EGL_RENDERABLE_TYPE, renderType,
EGL10.EGL_NONE
};
egl.eglChooseConfig (display, attrs1, configs, 1, num_config);
if (num_config[0] == 1) {
return configs[0];
}
int[] attrs2 = {
EGL10.EGL_NONE
};
egl.eglChooseConfig (display, attrs2, configs, 1, num_config);
if (num_config[0] == 1) {
return configs[0];
}
return null;
}
});
mActivity = inActivity;
mRefreshView = this;
setFocusable (true);
setFocusableInTouchMode (true);
setRenderer (new Renderer (this));
setRenderMode (GLSurfaceView.RENDERMODE_WHEN_DIRTY);
//addition nils
::if (ANDROID_TARGET_SDK_VERSION > 15)::
mInputManager = (InputManager)context.getSystemService(Context.INPUT_SERVICE);
mInputManager.registerInputDeviceListener (mInputDeviceListener, new Handler());
::end::
}
::if (ANDROID_TARGET_SDK_VERSION > 15)::
public interface OnInputDeviceListener { //addition nils
void onInputDeviceAdded(int deviceId);
void onInputDeviceRemoved(int deviceId);
void onInputDeviceChanged(int deviceId);
}
private InputDeviceListener mInputDeviceListener = new InputDeviceListener() { //addition nils
@Override
public void onInputDeviceAdded(int deviceId) {
Log.v("VIEW", "deviceadded");
if (mOnInputDeviceListener != null) {
mOnInputDeviceListener.onInputDeviceAdded(deviceId);
}
}
@Override
public void onInputDeviceRemoved( int deviceId ) {
Log.v("VIEW", "deviceremoved");
if (mOnInputDeviceListener != null) {
mOnInputDeviceListener.onInputDeviceRemoved(deviceId);
}
}
@Override
public void onInputDeviceChanged( int deviceId ) {
Log.v("VIEW", "devicechanged");
if ( mOnInputDeviceListener != null ) {
mOnInputDeviceListener.onInputDeviceChanged(deviceId);
}
}
};
public static String getSerial() {
return android.os.Build.SERIAL;
}
public static int getControllersAmount() {
int[] devices = InputDevice.getDeviceIds();
int amount = 0;
for (int i = 0; i < devices.length; i++) {
InputDevice mDevice = InputDevice.getDevice(devices[i]);
int numAxes = 0;
for (InputDevice.MotionRange range : mDevice.getMotionRanges()) {
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
numAxes += 1;
}
}
if (numAxes>0) {
amount++;
}
}
return amount;
}
public static String getControllersList() {
int[] devices = InputDevice.getDeviceIds();
ArrayList<String> controllerDevices = new ArrayList<String>();
for (int i = 0; i < devices.length; i++) {
InputDevice mDevice = InputDevice.getDevice(devices[i]);
int numAxes = 0;
for (InputDevice.MotionRange range : mDevice.getMotionRanges()) {
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
numAxes += 1;
}
}
if (numAxes>0) {
controllerDevices.add(Integer.toString(devices[i]));
controllerDevices.add(mDevice.getName());
}
}
String c = "";
int j = 0;
for (String i : controllerDevices){
c+=i;
j++;
if (j < controllerDevices.size()) {
c+=";";
}
}
return c;
}
::end::
public void HandleResult (int inCode) {
if (inCode == resTerminate) {
mActivity.finish ();
return;
}
double wake = Lime.getNextWake ();
final MainView me = this;
if (wake <= 0) {
queueEvent (new Runnable () {
public void run () {
me.onPoll ();
}
});
} else {
final int tid = ++mTimerID;
Date end = new Date ();
end.setTime (end.getTime () + (int)(wake * 1000));
mTimer.schedule (new TimerTask () {
public void run () {
if (tid == me.mTimerID) {
me.queuePoll ();
}
}
}, end);
}
}
@Override public InputConnection onCreateInputConnection (EditorInfo outAttrs) {
BaseInputConnection inputConnection = new BaseInputConnection (this, false) {
@Override public boolean deleteSurroundingText (int beforeLength, int afterLength) {
::if (ANDROID_TARGET_SDK_VERSION > 15)::
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (beforeLength == 1 && afterLength == 0) {
final long time = SystemClock.uptimeMillis ();
super.sendKeyEvent (new KeyEvent (time, time, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
super.sendKeyEvent (new KeyEvent (SystemClock.uptimeMillis(), time, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
return true;
}
}
::end::
return super.deleteSurroundingText (beforeLength, afterLength);
}
};
return inputConnection;
}
::if (ANDROID_TARGET_SDK_VERSION > 11)::@Override public boolean onGenericMotionEvent (MotionEvent event) {
if ((event.getSource () & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 && event.getAction () == MotionEvent.ACTION_MOVE) {
final MainView me = this;
final InputDevice device = event.getDevice ();
final int deviceId = event.getDeviceId ();
int[] axisList = {
android.view.MotionEvent.AXIS_X, android.view.MotionEvent.AXIS_Y, android.view.MotionEvent.AXIS_Z,
android.view.MotionEvent.AXIS_RX, android.view.MotionEvent.AXIS_RY, android.view.MotionEvent.AXIS_RZ,
android.view.MotionEvent.AXIS_HAT_X, android.view.MotionEvent.AXIS_HAT_Y,
android.view.MotionEvent.AXIS_LTRIGGER, android.view.MotionEvent.AXIS_RTRIGGER
};
for (int i = 0; i < axisList.length; i++) {
final int axis = axisList[i];
final InputDevice.MotionRange range = device.getMotionRange (axis, event.getSource ());
if (range != null) {
final float flat = range.getFlat ();
final float value = event.getAxisValue (axis);
if (Math.abs (value) > flat) {
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onJoyMotion (deviceId, axis, ((value - range.getMin ()) / (range.getRange ())) * 65535 - 32768));
}
});
} else {
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onJoyMotion (deviceId, axis, 0));
}
});
}
}
}
return true;
}
return super.onGenericMotionEvent (event);
}::end::
@Override public boolean onKeyDown (final int inKeyCode, KeyEvent event) {
//Log.v("VIEW", "hi there lo");
final MainView me = this;
::if (ANDROID_TARGET_SDK_VERSION > 11)::if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && (event.isGamepadButton (inKeyCode) || (inKeyCode > 18 && inKeyCode < 23) || (inKeyCode == 82 || inKeyCode == 4))) {
if (event.getRepeatCount () == 0) {
final int deviceId = event.getDeviceId ();
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onJoyChange (deviceId, inKeyCode, true));
}
});
}
return true;
}::end::
final int keyCode = translateKey (inKeyCode, event);
if (keyCode != 0) {
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onKeyChange (keyCode, true));
}
});
return true;
}
return super.onKeyDown(inKeyCode, event);
}
@Override public boolean onKeyUp (final int inKeyCode, KeyEvent event) {
final MainView me = this;
::if (ANDROID_TARGET_SDK_VERSION > 11)::if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && (event.isGamepadButton (inKeyCode) || (inKeyCode > 18 && inKeyCode < 23) || (inKeyCode == 82 || inKeyCode == 4))) {
if (event.getRepeatCount () == 0) {
final int deviceId = event.getDeviceId ();
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onJoyChange (deviceId, inKeyCode, false));
}
});
}
return true;
}::end::
final int keyCode = translateKey (inKeyCode, event);
if (keyCode != 0) {
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onKeyChange (keyCode, false));
}
});
return true;
}
return super.onKeyDown(inKeyCode, event);
}
void onPoll () {
HandleResult (Lime.onPoll ());
}
@Override public boolean onTouchEvent (final MotionEvent ev) {
final MainView me = this;
final int action = ev.getAction ();
int type = -1;
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: type = etTouchBegin; break;
case MotionEvent.ACTION_POINTER_DOWN: type = etTouchBegin; break;
case MotionEvent.ACTION_MOVE: type = etTouchMove; break;
case MotionEvent.ACTION_UP: type = etTouchEnd; break;
case MotionEvent.ACTION_POINTER_UP: type = etTouchEnd; break;
case MotionEvent.ACTION_CANCEL: type = etTouchEnd; break;
}
int idx = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> (MotionEvent.ACTION_POINTER_ID_SHIFT);
final int t = type;
for (int i = 0; i < ev.getPointerCount (); i++) {
final int id = ev.getPointerId (i);
final float x = ev.getX (i);
final float y = ev.getY (i);
final float sizeX = ev.getSize (i);
final float sizeY = ev.getSize (i);
if (type == etTouchMove || i == idx) {
queueEvent (new Runnable () {
public void run () {
me.HandleResult (Lime.onTouch (t, x, y, id, sizeX, sizeY));
}
});
}
}
return true;
}
@Override public boolean onTrackballEvent (final MotionEvent ev) {
final MainView me = this;
queueEvent (new Runnable () {
public void run() {
float x = ev.getX ();
float y = ev.getY ();
me.HandleResult (Lime.onTrackball (x, y));
}
});
return false;
}
void queuePoll () {
final MainView me = this;
queueEvent (new Runnable () {
public void run () {
me.onPoll ();
}
});
}
static public void renderNow () { //Called directly from C++
mRefreshView.requestRender ();
}
void sendActivity (final int inActivity) {
queueEvent (new Runnable () {
public void run () {
Lime.onActivity (inActivity);
}
});
}
public int translateKey(int inCode, KeyEvent event) {
switch (inCode) {
case KeyEvent.KEYCODE_BACK: return 27; /* Fake Escape */
case KeyEvent.KEYCODE_MENU: return 0x01000012; /* Fake MENU */
case KeyEvent.KEYCODE_DEL: return 8;
}
int result = event.getUnicodeChar (event.getMetaState ());
if (result == KeyCharacterMap.COMBINING_ACCENT) {
//TODO
return 0;
}
return result;
}
private static class Renderer implements GLSurfaceView.Renderer {
MainView mMainView;
public Renderer (MainView inView) {
mMainView = inView;
}
public void onDrawFrame (GL10 gl) {
mMainView.HandleResult (Lime.onRender ());
Sound.checkSoundCompletion ();
}
public void onSurfaceChanged (GL10 gl, int width, int height) {
mMainView.HandleResult (Lime.onResize (width, height));
}
public void onSurfaceCreated (GL10 gl, EGLConfig config) {
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment