aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java2
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java62
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/WindowDriver.java86
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java17
5 files changed, 146 insertions, 24 deletions
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 67bc73652..12a2e3dc2 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -137,7 +137,7 @@ public class NEWTEvent extends java.util.EventObject {
if(null == sb) {
sb = new StringBuilder();
}
- return sb.append("NEWTEvent[source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
+ return sb.append("NEWTEvent[source:").append(getSource().getClass().getName()).append("consumed ").append(isConsumed()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]");
}
public static String toHexString(short hex) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index e8dc0d7d7..e1636ffcd 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -1625,6 +1625,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowHandle = handle;
}
+ @Override
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
if( windowLock.isOwner( Thread.currentThread() ) ) {
task.run();
@@ -1650,14 +1651,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
};
+ @Override
public final boolean hasFocus() {
return hasFocus;
}
+ @Override
public void requestFocus() {
requestFocus(true);
}
+ @Override
public void requestFocus(boolean wait) {
requestFocus(wait /* wait */, false /* skipFocusAction */, brokenFocusChange /* force */);
}
@@ -1680,6 +1684,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void setFocusAction(FocusRunnable focusAction) {
this.focusAction = focusAction;
}
@@ -1704,6 +1709,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
brokenFocusChange = v;
}
+ @Override
public void setKeyboardFocusHandler(KeyListener l) {
keyboardFocusHandler = l;
}
@@ -1737,11 +1743,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void setPosition(int x, int y) {
autoPosition = false;
runOnEDTIfAvail(true, new SetPositionAction(x, y));
}
+ @Override
public void setTopLevelPosition(int x, int y) {
setPosition(x + getInsets().getLeftWidth(), y + getInsets().getTopHeight());
}
@@ -1848,6 +1856,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private final FullScreenAction fullScreenAction = new FullScreenAction();
+ @Override
public boolean setFullscreen(boolean fullscreen) {
synchronized(fullScreenAction) {
if( fullScreenAction.init(fullscreen) ) {
@@ -1921,12 +1930,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Child Window Management
//
+ @Override
public final boolean removeChild(NativeWindow win) {
synchronized(childWindowsLock) {
return childWindows.remove(win);
}
}
+ @Override
public final boolean addChild(NativeWindow win) {
if (win == null) {
return false;
@@ -1952,12 +1963,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ @Override
public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
if(isNativeValid()) {
((DisplayImpl)screen.getDisplay()).enqueueEvent(wait, event);
}
}
+ @Override
public boolean consumeEvent(NEWTEvent e) {
switch(e.getEventType()) {
// special repaint treatment
@@ -2009,18 +2022,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// SurfaceUpdatedListener Support
//
+ @Override
public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+ @Override
public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
}
+ @Override
public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
}
+ @Override
public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
}
@@ -2149,11 +2166,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
-
+ @Override
public void addMouseListener(MouseListener l) {
addMouseListener(-1, l);
}
+ @Override
public void addMouseListener(int index, MouseListener l) {
if(l == null) {
return;
@@ -2167,6 +2185,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
mouseListeners = clonedListeners;
}
+ @Override
public void removeMouseListener(MouseListener l) {
if (l == null) {
return;
@@ -2177,6 +2196,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
mouseListeners = clonedListeners;
}
+ @Override
public MouseListener getMouseListener(int index) {
@SuppressWarnings("unchecked")
ArrayList<MouseListener> clonedListeners = (ArrayList<MouseListener>) mouseListeners.clone();
@@ -2186,6 +2206,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return clonedListeners.get(index);
}
+ @Override
public MouseListener[] getMouseListeners() {
return mouseListeners.toArray(new MouseListener[mouseListeners.size()]);
}
@@ -2267,26 +2288,31 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers | mouseButtonModMask, keyCode, keySym, keyChar) );
}
- public void addKeyListener(KeyListener l) {
- addKeyListener(-1, l);
- }
-
+ @Override
public final void setKeyboardVisible(boolean visible) {
if(isNativeValid()) {
// We don't skip the impl. if it seems that there is no state change,
// since we cannot assume the impl. reliably gives us it's current state.
- final boolean n = setKeyboardVisibleImpl(visible);
+ final boolean ok = setKeyboardVisibleImpl(visible);
if(DEBUG_IMPLEMENTATION || DEBUG_KEY_EVENT) {
- System.err.println("setKeyboardVisible(native): visible "+keyboardVisible+" -> "+visible +" -> "+n);
+ System.err.println("setKeyboardVisible(native): visible "+keyboardVisible+" -- op[visible:"+visible +", ok "+ok+"] -> "+(visible && ok));
}
- keyboardVisible = n;
+ keyboardVisibilityChanged( visible && ok );
} else {
- keyboardVisible = visible; // earmark for creation
+ keyboardVisibilityChanged( visible ); // earmark for creation
}
}
+ @Override
public final boolean isKeyboardVisible() {
return keyboardVisible;
- }
+ }
+ /**
+ * Returns <code>true</code> if operation was successful, otherwise <code>false</code>.
+ * <p>
+ * We assume that a failed invisible operation is due to an already invisible keyboard,
+ * hence even if an invisible operation failed, the keyboard is considered invisible!
+ * </p>
+ */
protected boolean setKeyboardVisibleImpl(boolean visible) {
return false; // nop
}
@@ -2301,6 +2327,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
protected boolean keyboardVisible = false;
+ @Override
+ public void addKeyListener(KeyListener l) {
+ addKeyListener(-1, l);
+ }
+
+ @Override
public void addKeyListener(int index, KeyListener l) {
if(l == null) {
return;
@@ -2314,6 +2346,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
keyListeners = clonedListeners;
}
+ @Override
public void removeKeyListener(KeyListener l) {
if (l == null) {
return;
@@ -2324,6 +2357,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
keyListeners = clonedListeners;
}
+ @Override
public KeyListener getKeyListener(int index) {
@SuppressWarnings("unchecked")
ArrayList<KeyListener> clonedListeners = (ArrayList<KeyListener>) keyListeners.clone();
@@ -2333,6 +2367,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return clonedListeners.get(index);
}
+ @Override
public KeyListener[] getKeyListeners() {
return keyListeners.toArray(new KeyListener[keyListeners.size()]);
}
@@ -2404,6 +2439,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// WindowListener/Event Support
//
+ @Override
public void sendWindowEvent(int eventType) {
consumeWindowEvent( new WindowEvent((short)eventType, this, System.currentTimeMillis()) ); // FIXME
}
@@ -2412,10 +2448,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
enqueueEvent( wait, new WindowEvent((short)eventType, this, System.currentTimeMillis()) ); // FIXME
}
+ @Override
public void addWindowListener(WindowListener l) {
addWindowListener(-1, l);
}
+ @Override
public void addWindowListener(int index, WindowListener l)
throws IndexOutOfBoundsException
{
@@ -2431,6 +2469,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowListeners = clonedListeners;
}
+ @Override
public final void removeWindowListener(WindowListener l) {
if (l == null) {
return;
@@ -2441,6 +2480,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowListeners = clonedListeners;
}
+ @Override
public WindowListener getWindowListener(int index) {
@SuppressWarnings("unchecked")
ArrayList<WindowListener> clonedListeners = (ArrayList<WindowListener>) windowListeners.clone();
@@ -2450,6 +2490,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return clonedListeners.get(index);
}
+ @Override
public WindowListener[] getWindowListeners() {
return windowListeners.toArray(new WindowListener[windowListeners.size()]);
}
@@ -2676,6 +2717,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return destroyed;
}
+ @Override
public void windowRepaint(int x, int y, int width, int height) {
windowRepaint(false, x, y, width, height);
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index 6bc81a555..726793768 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -126,6 +126,9 @@ public class NewtBaseActivity extends Activity {
* @see #addContentView(android.view.Window, Window, android.view.ViewGroup.LayoutParams)
*/
public void registerNEWTWindow(Window newtWindow) {
+ newtWindow = newtWindow.getDelegatedWindow();
+ WindowDriver newtAWindow = (WindowDriver)newtWindow;
+ newtAWindow.registerActivity(getActivity());
newtWindows.add(newtWindow);
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index c5371ae9c..0a253ff9e 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -47,12 +47,15 @@ import com.jogamp.common.os.AndroidVersion;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.newt.Screen;
import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.NEWTEvent;
import jogamp.opengl.egl.EGL;
import jogamp.opengl.egl.EGLGraphicsConfiguration;
import jogamp.opengl.egl.EGLGraphicsConfigurationFactory;
+import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.IBinder;
@@ -205,6 +208,11 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
public WindowDriver() {
reset();
}
+
+ public void registerActivity(Activity activity) {
+ this.activity = activity;
+ }
+ protected Activity activity = null;
private final void reset() {
added2StaticViewGroup = false;
@@ -499,14 +507,15 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
if(null != androidView) {
final InputMethodManager imm = (InputMethodManager) getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
final IBinder winid = getAndroidView().getWindowToken();
+ final boolean result;
if(visible) {
// Show soft-keyboard:
- imm.showSoftInput(androidView, 0, keyboardVisibleReceiver);
+ result = imm.showSoftInput(androidView, 0, keyboardVisibleReceiver);
} else {
// hide keyboard :
- imm.hideSoftInputFromWindow(winid, 0, keyboardVisibleReceiver);
+ result = imm.hideSoftInputFromWindow(winid, 0, keyboardVisibleReceiver);
}
- return visible;
+ return result;
} else {
return false; // nop
}
@@ -588,25 +597,74 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
protected boolean handleKeyCodeBack(KeyEvent.DispatcherState state, android.view.KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ Log.d(MD.TAG, "handleKeyCodeBack.0 : "+event);
state.startTracking(event, this);
} else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() && state.isTracking(event)) {
- if( isKeyboardVisible() ) {
- keyboardVisibilityChanged(false);
- enqueueAKey2NKeyUpDown(event);
+ // Since we cannot trust the visibility state 'completly',
+ // assume an already invisible state if the invisible operation fails.
+ final boolean wasVisible = setKeyboardVisibleImpl(false);
+ Log.d(MD.TAG, "handleKeyCodeBack.1 : wasVisible "+wasVisible+": "+event);
+ keyboardVisibilityChanged(false);
+ if( wasVisible ) {
+ // event processed, just send invisible event, no activity.finished()
+ enqueueAKey2NKeyUpDown(event, com.jogamp.newt.event.KeyEvent.VK_KEYBOARD_INVISIBLE);
+ return true;
+ } else if( null != activity ) {
+ // process event on our own, since we have an activity to call finish()
+ // and decide in overriden consumeKeyEvent(..) whether we suppress or proceed w/ activity.finish().
+ enqueueAKey2NKeyUpDown(event, com.jogamp.newt.event.KeyEvent.VK_ESCAPE);
+ return true;
} else {
- Log.d(MD.TAG, "handleKeyCodeBack : "+event);
+ Log.d(MD.TAG, "handleKeyCodeBack.X1 : "+event);
windowDestroyNotify(true);
+ // -> default BACK action, usually activity.finish()
}
}
- return false; // cont. processing
+ return false; // continue w/ further processing
+ }
+ protected boolean handleKeyCodeHome(KeyEvent.DispatcherState state, android.view.KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ Log.d(MD.TAG, "handleKeyCodeHome.0 : "+event);
+ state.startTracking(event, this);
+ } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() && state.isTracking(event)) {
+ Log.d(MD.TAG, "handleKeyCodeHome.1 : "+event);
+ enqueueAKey2NKeyUpDown(event, com.jogamp.newt.event.KeyEvent.VK_HOME);
+ return true; // we handle further processing
+ }
+ return false; // continue w/ further processing
}
- private void enqueueAKey2NKeyUpDown(android.view.KeyEvent aEvent) {
- final com.jogamp.newt.event.KeyEvent eDown = AndroidNewtEventFactory.createKeyEvent(aEvent, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED, this, true);
- final com.jogamp.newt.event.KeyEvent eUp = AndroidNewtEventFactory.createKeyEvent(aEvent, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED, this, true);
+ private void enqueueAKey2NKeyUpDown(android.view.KeyEvent aEvent, short newtKeyCode) {
+ final com.jogamp.newt.event.KeyEvent eDown = AndroidNewtEventFactory.createKeyEvent(aEvent, newtKeyCode, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED, this);
+ final com.jogamp.newt.event.KeyEvent eUp = AndroidNewtEventFactory.createKeyEvent(aEvent, newtKeyCode, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED, this);
enqueueEvent(false, eDown);
enqueueEvent(false, eUp);
}
+ // private GLEventListenerState glels = null;
+
+ @Override
+ protected void consumeKeyEvent(com.jogamp.newt.event.KeyEvent e) {
+ super.consumeKeyEvent(e); // consume event, i.e. call all KeyListener
+ if( com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED == e.getEventType() && !e.isConsumed() ) {
+ if( com.jogamp.newt.event.KeyEvent.VK_ESCAPE == e.getKeyCode() ) {
+ Log.d(MD.TAG, "handleKeyCodeBack.X2 : "+e);
+ activity.finish();
+ } else if( com.jogamp.newt.event.KeyEvent.VK_HOME == e.getKeyCode() ) {
+ Log.d(MD.TAG, "handleKeyCodeHome.X2 : "+e);
+ triggerHome();
+ }
+ }
+ }
+ private void triggerHome() {
+ Context ctx = StaticContext.getContext();
+ if(null == ctx) {
+ throw new NativeWindowException("No static [Application] Context has been set. Call StaticContext.setContext(Context) first.");
+ }
+ Intent showOptions = new Intent(Intent.ACTION_MAIN);
+ showOptions.addCategory(Intent.CATEGORY_HOME);
+ ctx.startActivity(showOptions);
+ }
+
private boolean added2StaticViewGroup;
private MSurfaceView androidView;
private int nativeFormat; // chosen current native PixelFormat (suitable for EGL)
@@ -625,11 +683,17 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ Log.d(MD.TAG, "onKeyPreIme : "+event);
if ( event.getKeyCode() == KeyEvent.KEYCODE_BACK ) {
final KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null) {
return handleKeyCodeBack(state, event);
}
+ } else if ( event.getKeyCode() == KeyEvent.KEYCODE_HOME ) {
+ final KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ return handleKeyCodeHome(state, event);
+ }
}
return false; // cont. processing
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
index 1f78bd578..5d2333c1f 100644
--- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
+++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java
@@ -110,7 +110,7 @@ public class AndroidNewtEventFactory {
case android.view.KeyEvent.KEYCODE_TAB: return com.jogamp.newt.event.KeyEvent.VK_TAB;
case android.view.KeyEvent.KEYCODE_SPACE: return com.jogamp.newt.event.KeyEvent.VK_SPACE;
case android.view.KeyEvent.KEYCODE_ENTER: return com.jogamp.newt.event.KeyEvent.VK_ENTER;
- case android.view.KeyEvent.KEYCODE_DEL: return com.jogamp.newt.event.KeyEvent.VK_DELETE;
+ case android.view.KeyEvent.KEYCODE_DEL: return com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE;
case android.view.KeyEvent.KEYCODE_MINUS: return com.jogamp.newt.event.KeyEvent.VK_MINUS;
case android.view.KeyEvent.KEYCODE_EQUALS: return com.jogamp.newt.event.KeyEvent.VK_EQUALS;
case android.view.KeyEvent.KEYCODE_LEFT_BRACKET: return com.jogamp.newt.event.KeyEvent.VK_LEFT_PARENTHESIS;
@@ -128,11 +128,16 @@ public class AndroidNewtEventFactory {
case android.view.KeyEvent.KEYCODE_CTRL_RIGHT: return com.jogamp.newt.event.KeyEvent.VK_CONTROL; // ??
case android.view.KeyEvent.KEYCODE_BACK:
if( inclSysKeys ) {
- return com.jogamp.newt.event.KeyEvent.VK_KEYBOARD_INVISIBLE;
+ // Note that manual mapping is performed, based on the keyboard state.
+ // I.e. we map to VK_KEYBOARD_INVISIBLE if keyboard was visible and now becomes invisible!
+ // Otherwise we map to VK_ESCAPE, and if not consumed by user, the application will be terminated.
+ return com.jogamp.newt.event.KeyEvent.VK_ESCAPE;
}
break;
case android.view.KeyEvent.KEYCODE_HOME:
if( inclSysKeys ) {
+ // If not consumed by user, the application will be 'paused',
+ // i.e. resources (GLEventListener) pulled before surface gets destroyed!
return com.jogamp.newt.event.KeyEvent.VK_HOME;
}
break;
@@ -184,6 +189,14 @@ public class AndroidNewtEventFactory {
return res;
}
+ public static com.jogamp.newt.event.KeyEvent createKeyEvent(android.view.KeyEvent aEvent, short newtKeyCode, short newtType, com.jogamp.newt.Window newtSource) {
+ final com.jogamp.newt.event.KeyEvent res = createKeyEventImpl(aEvent, newtType, newtKeyCode, newtSource);
+ if(Window.DEBUG_KEY_EVENT) {
+ System.err.println("createKeyEvent2: newtType "+NEWTEvent.toHexString(newtType)+", "+aEvent+" -> "+res);
+ }
+ return res;
+ }
+
private static com.jogamp.newt.event.KeyEvent createKeyEventImpl(android.view.KeyEvent aEvent, short newtType, short newtKeyCode, com.jogamp.newt.Window newtSource) {
if( (short)0 != newtType && (short)0 != newtKeyCode ) {
final Object src = null==newtSource ? null : newtSource;