ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ResidualVMEvents.java

Go to the documentation of this file.
00001 package org.residualvm.residualvm;
00002 
00003 import android.os.Handler;
00004 import android.os.Message;
00005 import android.util.DisplayMetrics;
00006 import android.content.Context;
00007 import android.view.InputDevice;
00008 import android.view.KeyEvent;
00009 import android.view.KeyCharacterMap;
00010 import android.view.MotionEvent;
00011 import android.view.View;
00012 import android.view.ViewConfiguration;
00013 import android.view.GestureDetector;
00014 import android.view.inputmethod.InputMethodManager;
00015 
00016 import tv.ouya.console.api.OuyaController;
00017 
00018 public class ResidualVMEvents implements
00019         android.view.View.OnKeyListener,
00020         android.view.View.OnGenericMotionListener,
00021         android.view.GestureDetector.OnGestureListener,
00022         android.view.GestureDetector.OnDoubleTapListener {
00023 
00024     public static final int JE_SYS_KEY = 0;
00025     public static final int JE_KEY = 1;
00026     public static final int JE_DPAD = 2;
00027     public static final int JE_DOWN = 3;
00028     public static final int JE_SCROLL = 4;
00029     public static final int JE_TAP = 5;
00030     public static final int JE_DOUBLE_TAP = 6;
00031     public static final int JE_MULTI = 7;
00032     public static final int JE_BALL = 8;
00033     public static final int JE_LMB_DOWN = 9;
00034     public static final int JE_LMB_UP = 10;
00035     public static final int JE_RMB_DOWN = 11;
00036     public static final int JE_RMB_UP = 12;
00037     public static final int JE_MOUSE_MOVE = 13;
00038     public static final int JE_MMB_DOWN = 16;
00039     public static final int JE_MMB_UP = 17;
00040     public static final int JE_TOUCH = 18;
00041     public static final int JE_LONG = 19;
00042     public static final int JE_FLING = 20;
00043     public static final int JE_QUIT = 0x1000;
00044     
00045     private final int REL_SWIPE_MIN_DISTANCE;
00046     private final int REL_SWIPE_THRESHOLD_VELOCITY;
00047 
00048     final protected Context _context;
00049     final protected ResidualVM _residualvm;
00050     final protected GestureDetector _gd;
00051     final protected int _longPress;
00052     final protected MouseHelper _mouseHelper;
00053     final protected int _width;
00054 
00055     public ResidualVMEvents(Context context, ResidualVM residualvm, MouseHelper mouseHelper) {
00056         _context = context;
00057         _residualvm = residualvm;
00058         _mouseHelper = mouseHelper;
00059 
00060         _gd = new GestureDetector(context, this);
00061         _gd.setOnDoubleTapListener(this);
00062         //_gd.setIsLongpressEnabled(false);
00063 
00064         _longPress = ViewConfiguration.getLongPressTimeout();
00065         
00066         DisplayMetrics dm = context.getResources().getDisplayMetrics();
00067         REL_SWIPE_MIN_DISTANCE       = (int)(120 * dm.densityDpi / 160.0f);
00068         REL_SWIPE_THRESHOLD_VELOCITY = (int)(100 * dm.densityDpi / 160.0f);
00069         _width = dm.widthPixels;
00070     }
00071 
00072     final public void sendQuitEvent() {
00073         _residualvm.pushEvent(JE_QUIT, 0, 0, 0, 0, 0, 0);
00074     }
00075 
00076     public boolean onTrackballEvent(MotionEvent e) {
00077         _residualvm.pushEvent(JE_BALL, e.getAction(),
00078                             (int)(e.getX() * e.getXPrecision() * 100),
00079                             (int)(e.getY() * e.getYPrecision() * 100),
00080                             0, 0, 0);
00081         return true;
00082     }
00083 
00084     final static int MSG_MENU_LONG_PRESS = 1;
00085 
00086     final private Handler keyHandler = new Handler() {
00087         @Override
00088         public void handleMessage(Message msg) {
00089             if (msg.what == MSG_MENU_LONG_PRESS) {
00090                 InputMethodManager imm = (InputMethodManager)
00091                     _context.getSystemService(Context.INPUT_METHOD_SERVICE);
00092 
00093                 if (imm != null)
00094                     imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
00095             }
00096         }
00097     };
00098 
00099     // OnKeyListener
00100     @Override
00101     final public boolean onKey(View v, int keyCode, KeyEvent e) {
00102         final int action = e.getAction();
00103 
00104         if (keyCode == 238) {
00105             // this (undocumented) event is sent when ACTION_HOVER_ENTER or ACTION_HOVER_EXIT occurs
00106             return false;
00107         }
00108 
00109         if (keyCode == KeyEvent.KEYCODE_BACK) {
00110             if (action != KeyEvent.ACTION_UP) {
00111                 // only send event from back button on up event, since down event is sent on right mouse click and
00112                 // cannot be caught (thus rmb click would send escape key first)
00113                 return true;
00114             }
00115 
00116             if (_mouseHelper != null) {
00117                 if (_mouseHelper.getRmbGuard()) {
00118                     // right mouse button was just clicked which sends an extra back button press
00119                     return true;
00120                 }
00121             }
00122         }
00123 
00124         if (e.isSystem()) {
00125             // filter what we handle
00126             switch (keyCode) {
00127             case KeyEvent.KEYCODE_BACK:
00128             case KeyEvent.KEYCODE_MENU:
00129             case KeyEvent.KEYCODE_CAMERA:
00130             case KeyEvent.KEYCODE_SEARCH:
00131             case KeyEvent.KEYCODE_MEDIA_PLAY:
00132             case KeyEvent.KEYCODE_MEDIA_PAUSE:
00133                 break;
00134 
00135             default:
00136                 return false;
00137             }
00138 
00139             // no repeats for system keys
00140             if (e.getRepeatCount() > 0)
00141                 return false;
00142 
00143             // Have to reimplement hold-down-menu-brings-up-softkeybd
00144             // ourselves, since we are otherwise hijacking the menu key :(
00145             // See com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel()
00146             // for the usual Android implementation of this feature.
00147             if (keyCode == KeyEvent.KEYCODE_MENU) {
00148                 final boolean fired =
00149                     !keyHandler.hasMessages(MSG_MENU_LONG_PRESS);
00150 
00151                 keyHandler.removeMessages(MSG_MENU_LONG_PRESS);
00152 
00153                 if (action == KeyEvent.ACTION_DOWN) {
00154                     keyHandler.sendMessageDelayed(keyHandler.obtainMessage(
00155                                     MSG_MENU_LONG_PRESS), _longPress);
00156                     return true;
00157                 }
00158 
00159                 if (fired)
00160                     return true;
00161 
00162                 // only send up events of the menu button to the native side
00163                 if (action != KeyEvent.ACTION_UP)
00164                     return true;
00165             }
00166 
00167             _residualvm.pushEvent(JE_SYS_KEY, action, keyCode, 0, 0, 0, 0);
00168 
00169             return true;
00170         }
00171 
00172         // sequence of characters
00173         if (action == KeyEvent.ACTION_MULTIPLE &&
00174                 keyCode == KeyEvent.KEYCODE_UNKNOWN) {
00175             final KeyCharacterMap m = KeyCharacterMap.load(e.getDeviceId());
00176             final KeyEvent[] es = m.getEvents(e.getCharacters().toCharArray());
00177 
00178             if (es == null)
00179                 return true;
00180 
00181             for (KeyEvent s : es) {
00182                 _residualvm.pushEvent(JE_KEY, s.getAction(), s.getKeyCode(),
00183                     s.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
00184                     s.getMetaState(), s.getRepeatCount(), 0);
00185             }
00186 
00187             return true;
00188         }
00189 
00190         switch (keyCode) {
00191         case KeyEvent.KEYCODE_DPAD_UP:
00192         case KeyEvent.KEYCODE_DPAD_DOWN:
00193         case KeyEvent.KEYCODE_DPAD_LEFT:
00194         case KeyEvent.KEYCODE_DPAD_RIGHT:
00195         case KeyEvent.KEYCODE_DPAD_CENTER:
00196             _residualvm.pushEvent(JE_DPAD, action, keyCode,
00197                                 (int)(e.getEventTime() - e.getDownTime()),
00198                                 e.getRepeatCount(), 0, 0);
00199             return true;
00200         }
00201 
00202         _residualvm.pushEvent(JE_KEY, action, keyCode,
00203                     e.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
00204                     e.getMetaState(), e.getRepeatCount(), 0);
00205 
00206         return true;
00207     }
00208 
00209     final public boolean onTouchEvent(MotionEvent e) {
00210         if (_mouseHelper != null) {
00211             boolean isMouse = MouseHelper.isMouse(e);
00212             if (isMouse) {
00213                 // mouse button is pressed
00214                 return _mouseHelper.onMouseEvent(e, false);
00215             }
00216         }
00217 
00218         
00219         _gd.onTouchEvent(e);
00220         
00221         final int action = e.getActionMasked();
00222 
00223         // ACTION_MOVE always returns the first pointer as the "active" one.
00224         if (action == MotionEvent.ACTION_MOVE) {
00225             for (int idx = 0; idx < e.getPointerCount(); ++idx) {
00226                 final int pointer = e.getPointerId(idx);
00227                 
00228                 final int x = (int)e.getX(idx);
00229                 final int y = (int)e.getY(idx);
00230                 
00231                 _residualvm.pushEvent(JE_TOUCH, pointer, action, x, y, 0, 0);   
00232             }
00233         } else {
00234             final int idx = e.getActionIndex();
00235             final int pointer = e.getPointerId(idx);
00236             
00237             final int x = (int)e.getX(idx);
00238             final int y = (int)e.getY(idx);
00239             
00240             _residualvm.pushEvent(JE_TOUCH, pointer, action, x, y, 0, 0);   
00241         }
00242         
00243         
00244         return true;
00245     }
00246 
00247     // OnGestureListener
00248     @Override
00249     final public boolean onDown(MotionEvent e) {
00250         _residualvm.pushEvent(JE_DOWN, (int)e.getX(), (int)e.getY(), 0, 0, 0, 0);
00251         return true;
00252     }
00253 
00254     @Override
00255     final public boolean onFling(MotionEvent e1, MotionEvent e2,
00256                                     float velocityX, float velocityY) {
00257         return false;
00258 //      if (e1.getX() < 0.4 * _width
00259 //          || Math.abs(e1.getX() - e2.getX()) < REL_SWIPE_MIN_DISTANCE
00260 //          || velocityX < REL_SWIPE_THRESHOLD_VELOCITY
00261 //          || Math.abs(e1.getY() - e2.getY()) < REL_SWIPE_MIN_DISTANCE
00262 //          || velocityY < REL_SWIPE_THRESHOLD_VELOCITY)
00263 //        return false;
00264 //      
00265 //      _residualvm.pushEvent(JE_FLING, (int)e1.getX(), (int)e1.getY(),
00266 //                          (int)e2.getX(), (int)e2.getY(), 0, 0);
00267     }
00268 
00269     @Override
00270     final public void onLongPress(MotionEvent e) {
00271         _residualvm.pushEvent(JE_LONG, (int)e.getX(), (int)e.getY(),
00272                 0, 0, 0, 0);
00273     }
00274 
00275     @Override
00276     final public boolean onScroll(MotionEvent e1, MotionEvent e2,
00277                                     float distanceX, float distanceY) {
00278         _residualvm.pushEvent(JE_SCROLL, (int)e1.getX(), (int)e1.getY(),
00279                             (int)e2.getX(), (int)e2.getY(), 0, 0);
00280         return true;
00281     }
00282 
00283     @Override
00284     final public void onShowPress(MotionEvent e) {
00285     }
00286 
00287     @Override
00288     final public boolean onSingleTapUp(MotionEvent e) {
00289         return false;
00290     }
00291 
00292     // OnDoubleTapListener
00293     @Override
00294     final public boolean onDoubleTap(MotionEvent e) {
00295         return false;
00296     }
00297 
00298     @Override
00299     final public boolean onDoubleTapEvent(MotionEvent e) {
00300         _residualvm.pushEvent(JE_DOUBLE_TAP, (int)e.getX(), (int)e.getY(),
00301                             e.getAction(), 0, 0, 0);
00302 
00303         return true;
00304     }
00305 
00306     @Override
00307     final public boolean onSingleTapConfirmed(MotionEvent e) {
00308         _residualvm.pushEvent(JE_TAP, (int)e.getX(), (int)e.getY(),
00309                 (int)(e.getEventTime() - e.getDownTime()), 0, 0, 0);
00310         return true;
00311     }
00312 
00313     private static boolean rightJoystickHeld = false;
00314     private static int rightJoystickKeyCode = -1;
00315 
00316     public boolean onGenericMotion(View v, final MotionEvent event) {
00317         if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
00318             float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
00319             if (Math.abs(RS_Y) > OuyaController.STICK_DEADZONE && !rightJoystickHeld) {
00320                 rightJoystickHeld = true;
00321                 rightJoystickKeyCode = RS_Y > 0 ? KeyEvent.KEYCODE_PAGE_DOWN : KeyEvent.KEYCODE_PAGE_UP;
00322                 _residualvm.pushEvent(JE_KEY, KeyEvent.ACTION_DOWN, rightJoystickKeyCode, 0, 0, 0, 0);
00323                 return true;
00324             } else if (Math.abs(RS_Y) <= OuyaController.STICK_DEADZONE && rightJoystickHeld) {
00325                 rightJoystickHeld = false;
00326                 _residualvm.pushEvent(JE_KEY, KeyEvent.ACTION_UP, rightJoystickKeyCode, 0, 0, 0, 0);
00327                 rightJoystickKeyCode = -1;
00328                 return true;
00329             } else {
00330                 return false;
00331             }
00332         }
00333         return false;
00334     }
00335 }


Generated on Sat May 25 2019 05:00:52 for ResidualVM by doxygen 1.7.1
curved edge   curved edge