|
|
|
@ -35,11 +35,13 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
final private static int MAX_EVENTS = 1024; |
|
|
|
|
|
|
|
|
|
final private RingBuffer<TouchEvent> eventQueue = new RingBuffer<TouchEvent>(MAX_EVENTS); |
|
|
|
|
final private RingBuffer<TouchEvent> eventPoolUnConsumed = new RingBuffer<TouchEvent>(MAX_EVENTS); |
|
|
|
|
final private RingBuffer<TouchEvent> eventPool = new RingBuffer<TouchEvent>(MAX_EVENTS); |
|
|
|
|
final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>(); |
|
|
|
|
|
|
|
|
|
public boolean fireMouseEvents = true; |
|
|
|
|
public boolean fireKeyboardEvents = false; |
|
|
|
|
public boolean dontSendHistory = false; |
|
|
|
|
|
|
|
|
|
private ScaleGestureDetector scaledetector; |
|
|
|
|
private GestureDetector detector; |
|
|
|
@ -169,33 +171,67 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
return getNextFreeTouchEvent(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Fetches a touch event from the reuse pool |
|
|
|
|
* @param wait |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private TouchEvent getNextFreeTouchEvent(boolean wait) |
|
|
|
|
{ |
|
|
|
|
TouchEvent evt; |
|
|
|
|
if (eventPool.isEmpty() && wait) |
|
|
|
|
TouchEvent evt = null; |
|
|
|
|
synchronized(eventPoolUnConsumed) |
|
|
|
|
{ |
|
|
|
|
logger.warning("eventPool buffer underrun"); |
|
|
|
|
boolean isEmpty; |
|
|
|
|
do |
|
|
|
|
int size = eventPoolUnConsumed.size(); |
|
|
|
|
while (size > 0) |
|
|
|
|
{ |
|
|
|
|
synchronized(eventPool) |
|
|
|
|
evt = eventPoolUnConsumed.pop(); |
|
|
|
|
if (!evt.isConsumed()) |
|
|
|
|
{ |
|
|
|
|
isEmpty = eventPool.isEmpty(); |
|
|
|
|
eventPoolUnConsumed.push(evt); |
|
|
|
|
evt = null; |
|
|
|
|
} |
|
|
|
|
try { Thread.sleep(50); } catch (InterruptedException e) { } |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
size--; |
|
|
|
|
} |
|
|
|
|
while (isEmpty); |
|
|
|
|
evt = eventPool.pop(); |
|
|
|
|
} |
|
|
|
|
else if (eventPool.isEmpty()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (evt == null) |
|
|
|
|
{ |
|
|
|
|
evt = new TouchEvent(); |
|
|
|
|
logger.warning("eventPool buffer underrun"); |
|
|
|
|
if (eventPool.isEmpty() && wait) |
|
|
|
|
{ |
|
|
|
|
logger.warning("eventPool buffer underrun"); |
|
|
|
|
boolean isEmpty; |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
synchronized(eventPool) |
|
|
|
|
{ |
|
|
|
|
isEmpty = eventPool.isEmpty(); |
|
|
|
|
} |
|
|
|
|
try { Thread.sleep(50); } catch (InterruptedException e) { } |
|
|
|
|
} |
|
|
|
|
while (isEmpty); |
|
|
|
|
synchronized(eventPool) |
|
|
|
|
{ |
|
|
|
|
evt = eventPool.pop(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (eventPool.isEmpty()) |
|
|
|
|
{ |
|
|
|
|
evt = new TouchEvent(); |
|
|
|
|
logger.warning("eventPool buffer underrun"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
synchronized(eventPool) |
|
|
|
|
{ |
|
|
|
|
evt = eventPool.pop(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
evt = eventPool.pop(); |
|
|
|
|
} |
|
|
|
|
return evt; |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
@ -210,17 +246,37 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
// Try to detect gestures
|
|
|
|
|
this.detector.onTouchEvent(event); |
|
|
|
|
this.scaledetector.onTouchEvent(event); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final int historySize = event.getHistorySize(); |
|
|
|
|
final int pointerCount = event.getPointerCount(); |
|
|
|
|
|
|
|
|
|
switch (event.getAction()) |
|
|
|
|
{ |
|
|
|
|
case MotionEvent.ACTION_DOWN: |
|
|
|
|
|
|
|
|
|
case MotionEvent.ACTION_DOWN: |
|
|
|
|
|
|
|
|
|
if (!dontSendHistory) |
|
|
|
|
{ |
|
|
|
|
// Process history
|
|
|
|
|
for (int h = 0; h < historySize; h++) |
|
|
|
|
{ |
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < pointerCount; p++) |
|
|
|
|
{ |
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.DOWN, event.getHistoricalX(p, h), this.getHeight() - event.getHistoricalY(p, h), 0, 0); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getHistoricalEventTime(h)); |
|
|
|
|
touch.setPressure(event.getHistoricalPressure(p, h)); |
|
|
|
|
processEvent(touch); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < event.getPointerCount(); p++) |
|
|
|
|
for (int p = 0; p < pointerCount; p++) |
|
|
|
|
{ |
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.DOWN, event.getX(p), event.getY(p), 0, 0); |
|
|
|
|
touch.set(Type.DOWN, event.getX(p), this.getHeight() - event.getY(p), 0, 0); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
touch.setPressure(event.getPressure(p)); |
|
|
|
@ -232,11 +288,30 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
|
|
|
|
|
case MotionEvent.ACTION_UP: |
|
|
|
|
|
|
|
|
|
if (!dontSendHistory) |
|
|
|
|
{ |
|
|
|
|
// Process history
|
|
|
|
|
for (int h = 0; h < historySize; h++) |
|
|
|
|
{ |
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < pointerCount; p++) |
|
|
|
|
{ |
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.UP, event.getHistoricalX(p, h), this.getHeight() - event.getHistoricalY(p, h), 0, 0); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getHistoricalEventTime(h)); |
|
|
|
|
touch.setPressure(event.getHistoricalPressure(p, h)); |
|
|
|
|
processEvent(touch); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < event.getPointerCount(); p++) |
|
|
|
|
for (int p = 0; p < pointerCount; p++) |
|
|
|
|
{ |
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.UP, event.getX(p), event.getY(p), 0, 0); |
|
|
|
|
touch.set(Type.UP, event.getX(p), this.getHeight() - event.getY(p), 0, 0); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
touch.setPressure(event.getPressure(p)); |
|
|
|
@ -247,22 +322,50 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
break; |
|
|
|
|
case MotionEvent.ACTION_MOVE: |
|
|
|
|
|
|
|
|
|
if (!dontSendHistory) |
|
|
|
|
{ |
|
|
|
|
// Process history
|
|
|
|
|
for (int h = 0; h < historySize; h++) |
|
|
|
|
{ |
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < pointerCount; p++) |
|
|
|
|
{ |
|
|
|
|
Vector2f lastPos = lastPositions.get(event.getPointerId(p)); |
|
|
|
|
if (lastPos == null) |
|
|
|
|
{ |
|
|
|
|
lastPos = new Vector2f(event.getHistoricalX(p,h ), this.getHeight() - event.getHistoricalY(p, h)); |
|
|
|
|
lastPositions.put(event.getPointerId(p), lastPos); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.MOVE, event.getHistoricalX(p, h), this.getHeight() - event.getHistoricalY(p, h), |
|
|
|
|
event.getHistoricalX(p, h) - lastPos.x, this.getHeight() - event.getHistoricalY(p, h) - lastPos.y); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getHistoricalEventTime(h)); |
|
|
|
|
touch.setPressure(event.getHistoricalPressure(p, h)); |
|
|
|
|
processEvent(touch); |
|
|
|
|
lastPos.set(event.getHistoricalX(p, h), this.getHeight() - event.getHistoricalY(p, h)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Convert all pointers into events
|
|
|
|
|
for (int p = 0; p < event.getPointerCount(); p++) |
|
|
|
|
{ |
|
|
|
|
Vector2f lastPos = lastPositions.get(event.getPointerId(p)); |
|
|
|
|
if (lastPos == null) |
|
|
|
|
{ |
|
|
|
|
lastPos = new Vector2f(event.getX(p), event.getY(p)); |
|
|
|
|
lastPos = new Vector2f(event.getX(p), this.getHeight() - event.getY(p)); |
|
|
|
|
lastPositions.put(event.getPointerId(p), lastPos); |
|
|
|
|
} |
|
|
|
|
touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.MOVE, event.getX(p), event.getY(p), event.getX(p) - lastPos.x, event.getY(p) - lastPos.y); |
|
|
|
|
touch.set(Type.MOVE, event.getX(p), this.getHeight() - event.getY(p), event.getX(p) - lastPos.x, this.getHeight() - event.getY(p) - lastPos.y); |
|
|
|
|
touch.setPointerId(event.getPointerId(p)); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
touch.setPressure(event.getPressure(p)); |
|
|
|
|
processEvent(touch); |
|
|
|
|
lastPos.set(event.getX(p), event.getY(p)); |
|
|
|
|
lastPos.set(event.getX(p), this.getHeight() - event.getY(p)); |
|
|
|
|
} |
|
|
|
|
bWasHandled = true; |
|
|
|
|
break; |
|
|
|
@ -296,11 +399,8 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
// Send the event
|
|
|
|
|
processEvent(evt); |
|
|
|
|
|
|
|
|
|
// Handle all keys ourself, except the back button (4)
|
|
|
|
|
if (keyCode == 4) |
|
|
|
|
return false; |
|
|
|
|
else |
|
|
|
|
return true; |
|
|
|
|
// Handle all keys ourself
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@ -316,11 +416,8 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
// Send the event
|
|
|
|
|
processEvent(evt); |
|
|
|
|
|
|
|
|
|
// Handle all keys ourself, except the back button (4)
|
|
|
|
|
if (keyCode == 4) |
|
|
|
|
return false; |
|
|
|
|
else |
|
|
|
|
return true; |
|
|
|
|
// Handle all keys ourself
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -408,8 +505,8 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
|
|
|
|
|
if (fireMouseEvents) |
|
|
|
|
{ |
|
|
|
|
newX = getWidth() - (int) event.getX(); |
|
|
|
|
newY = (int) event.getY(); |
|
|
|
|
newX = this.getWidth() - (int) event.getX(); |
|
|
|
|
newY = this.getHeight() - (int) event.getY(); |
|
|
|
|
switch (event.getType()) |
|
|
|
|
{ |
|
|
|
|
case DOWN: |
|
|
|
@ -451,10 +548,22 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
synchronized (eventPool) |
|
|
|
|
|
|
|
|
|
if (event.isConsumed() == false) |
|
|
|
|
{ |
|
|
|
|
eventPool.push(event); |
|
|
|
|
} |
|
|
|
|
synchronized (eventPoolUnConsumed) |
|
|
|
|
{ |
|
|
|
|
eventPoolUnConsumed.push(event); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
synchronized (eventPool) |
|
|
|
|
{ |
|
|
|
|
eventPool.push(event); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
@ -470,7 +579,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public void onLongPress(MotionEvent event) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.LONGPRESSED, event.getX(), event.getY(), 0f, 0f); |
|
|
|
|
touch.set(Type.LONGPRESSED, event.getX(), this.getHeight() - event.getY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -479,7 +588,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.FLING, event.getX(), event.getY(), vx, vy); |
|
|
|
|
touch.set(Type.FLING, event.getX(), this.getHeight() - event.getY(), vx, vy); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -490,7 +599,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onSingleTapConfirmed(MotionEvent event) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f); |
|
|
|
|
touch.set(Type.TAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -501,7 +610,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onDoubleTap(MotionEvent event) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.DOUBLETAP, event.getX(), event.getY(), 0f, 0f); |
|
|
|
|
touch.set(Type.DOUBLETAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -524,7 +633,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onScale(ScaleGestureDetector scaleGestureDetector) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f); |
|
|
|
|
touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(scaleGestureDetector.getEventTime()); |
|
|
|
|
touch.setScaleSpan(scaleGestureDetector.getCurrentSpan()); |
|
|
|
@ -537,7 +646,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f); |
|
|
|
|
touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), this.getHeight() - scaleGestureDetector.getFocusY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(scaleGestureDetector.getEventTime()); |
|
|
|
|
touch.setScaleSpan(scaleGestureDetector.getCurrentSpan()); |
|
|
|
@ -548,7 +657,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.SCROLL, e1.getX(), e1.getY(), distanceX, distanceY); |
|
|
|
|
touch.set(Type.SCROLL, e1.getX(), this.getHeight() - e1.getY(), distanceX, distanceY*(-1)); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(e1.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -558,7 +667,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public void onShowPress(MotionEvent event) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.SHOWPRESS, event.getX(), event.getY(), 0f, 0f); |
|
|
|
|
touch.set(Type.SHOWPRESS, event.getX(), this.getHeight() - event.getY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -567,7 +676,7 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
public boolean onSingleTapUp(MotionEvent event) |
|
|
|
|
{ |
|
|
|
|
TouchEvent touch = getNextFreeTouchEvent(); |
|
|
|
|
touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f); |
|
|
|
|
touch.set(Type.TAP, event.getX(), this.getHeight() - event.getY(), 0f, 0f); |
|
|
|
|
touch.setPointerId(0); |
|
|
|
|
touch.setTime(event.getEventTime()); |
|
|
|
|
processEvent(touch); |
|
|
|
@ -585,5 +694,10 @@ public class AndroidInput extends GLSurfaceView implements TouchInput, |
|
|
|
|
{ |
|
|
|
|
fireKeyboardEvents = simulate; |
|
|
|
|
} |
|
|
|
|
@Override |
|
|
|
|
public void setOmitHistoricEvents(boolean dontSendHistory) |
|
|
|
|
{ |
|
|
|
|
this.dontSendHistory = dontSendHistory; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|