/********************************************************************
 * Process the next input event.
 *******************************************************************/
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
{
    if(app==NULL)
        return 0;
    struct engine* engine = (struct engine*)app->userData;

    if(engine == NULL || event == NULL)
        return 0;

    if (AInputEvent_getType(event) != AINPUT_EVENT_TYPE_MOTION)
        return 0;

    switch(AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK)
    {

    case AMOTION_EVENT_ACTION_DOWN:
    {
        engine->state.x = (((int)AMotionEvent_getX(event, 1))<<16) | (int)AMotionEvent_getX(event, 0);
        engine->state.y = (((int)AMotionEvent_getY(event, 1))<<16) | (int)AMotionEvent_getY(event, 0);
        opengl_touch(engine->state.x, engine->state.y, 0);

        int32_t idx = (AMotionEvent_getAction(event)& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        LOGI("AMOTION_EVENT_ACTION_DOWN,idx=%d",idx>>8);
    }
    return 1;

    case AMOTION_EVENT_ACTION_UP:
    {
        engine->state.x = (((int)AMotionEvent_getX(event, 1))<<16) | (int)AMotionEvent_getX(event, 0);
        engine->state.y = (((int)AMotionEvent_getY(event, 1))<<16) | (int)AMotionEvent_getY(event, 0);
        opengl_touch(engine->state.x, engine->state.y, 2);

        int32_t idx = (AMotionEvent_getAction(event)& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        LOGI("AMOTION_EVENT_ACTION_UP,idx=%d",idx>>8);
    }
    return 1;

    case AMOTION_EVENT_ACTION_MOVE:
        engine->state.x = (((int)AMotionEvent_getX(event, 1))<<16) | (int)AMotionEvent_getX(event, 0);
        engine->state.y = (((int)AMotionEvent_getY(event, 1))<<16) | (int)AMotionEvent_getY(event, 0);
        opengl_touch(engine->state.x, engine->state.y, 1);
        return 1;

    case AMOTION_EVENT_ACTION_POINTER_DOWN:
    {
        engine->state.x = (((int)AMotionEvent_getX(event, 1))<<16) | (int)AMotionEvent_getX(event, 0);
        engine->state.y = (((int)AMotionEvent_getY(event, 1))<<16) | (int)AMotionEvent_getY(event, 0);
        int32_t idx = (AMotionEvent_getAction(event)& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        opengl_touch(engine->state.x, engine->state.y, 3);
        LOGI("AMOTION_EVENT_ACTION_POINTER_DOWN,idx=%d",idx>>8);
    }
    return 1;

    case AMOTION_EVENT_ACTION_POINTER_UP:
    {
        engine->state.x = (((int)AMotionEvent_getX(event, 1))<<16) | (int)AMotionEvent_getX(event, 0);
        engine->state.y = (((int)AMotionEvent_getY(event, 1))<<16) | (int)AMotionEvent_getY(event, 0);
        int32_t idx = (AMotionEvent_getAction(event)& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        opengl_touch(engine->state.x, engine->state.y, 4);
        LOGI("AMOTION_EVENT_ACTION_POINTER_UP,idx=%d",idx>>8);
    }
    return 1;

    default:
        break;
    }
    /*
    	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
    	{
    		engine->state.x = AMotionEvent_getX(event, 0);
    		engine->state.y = AMotionEvent_getY(event, 0);
    		opengl_touch(engine->state.x, engine->state.y, 0);
    		return 1;
    	}*/
    return 0;
}
Exemple #2
0
int WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates* states)
{
    // Prepare the Java virtual machine
    jint lResult;
    jint lFlags = 0;

    JavaVM* lJavaVM = states->activity->vm;
    JNIEnv* lJNIEnv = states->activity->env;

    JavaVMAttachArgs lJavaVMAttachArgs;
    lJavaVMAttachArgs.version = JNI_VERSION_1_6;
    lJavaVMAttachArgs.name = "NativeThread";
    lJavaVMAttachArgs.group = NULL;

    lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);

    if (lResult == JNI_ERR) {
        err() << "Failed to initialize JNI, couldn't get the Unicode value" << std::endl;
        return 0;
    }

    // Retrieve everything we need to create this MotionEvent in Java
    jlong downTime = AMotionEvent_getDownTime(_event);
    jlong eventTime = AMotionEvent_getEventTime(_event);
    jint action = AMotionEvent_getAction(_event);
    jfloat x = AMotionEvent_getX(_event, 0);
    jfloat y = AMotionEvent_getY(_event, 0);
    jfloat pressure = AMotionEvent_getPressure(_event, 0);
    jfloat size = AMotionEvent_getSize(_event, 0);
    jint metaState = AMotionEvent_getMetaState(_event);
    jfloat xPrecision = AMotionEvent_getXPrecision(_event);
    jfloat yPrecision = AMotionEvent_getYPrecision(_event);
    jint deviceId = AInputEvent_getDeviceId(_event);
    jint edgeFlags = AMotionEvent_getEdgeFlags(_event);

    // Create the MotionEvent object in Java trough its static constructor obtain()
    jclass ClassMotionEvent = lJNIEnv->FindClass("android/view/MotionEvent");
    jmethodID StaticMethodObtain = lJNIEnv->GetStaticMethodID(ClassMotionEvent, "obtain", "(JJIFFFFIFFII)Landroid/view/MotionEvent;");
    jobject ObjectMotionEvent = lJNIEnv->CallStaticObjectMethod(ClassMotionEvent, StaticMethodObtain, downTime, eventTime, action, x, y, pressure, size, metaState, xPrecision, yPrecision, deviceId, edgeFlags);

    // Call its getAxisValue() method to get the delta value of our wheel move event
    jmethodID MethodGetAxisValue = lJNIEnv->GetMethodID(ClassMotionEvent, "getAxisValue", "(I)F");
    jfloat delta = lJNIEnv->CallFloatMethod(ObjectMotionEvent, MethodGetAxisValue, 0x00000001);

    lJNIEnv->DeleteLocalRef(ClassMotionEvent);
    lJNIEnv->DeleteLocalRef(ObjectMotionEvent);

    // Create and send our mouse wheel event
    Event event;
    event.type = Event::MouseWheelMoved;
    event.mouseWheel.delta = static_cast<double>(delta);
    event.mouseWheel.x = AMotionEvent_getX(_event, 0);
    event.mouseWheel.y = AMotionEvent_getY(_event, 0);

    forwardEvent(event);

    // Detach this thread from the JVM
    lJavaVM->DetachCurrentThread();

    return 1;
}
Exemple #3
0
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
	engine* e = (engine*)app->userData;

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {

		int32_t key = AKeyEvent_getKeyCode(event);
		int32_t key_action = AKeyEvent_getAction(event);

		if (key == AKEYCODE_BACK) {

			LOGD( "engine_handle_input", "AKEYCODE_BACK");

			if (key_action == AKEY_EVENT_ACTION_UP) {
				LOGD("engine_handle_input", "AKEY_EVENT_ACTION_UP");
			}

	        return 1; // <-- prevent default handler
		}

		if (key == AKEYCODE_MENU) {

			LOGD( "engine_handle_input", "AKEYCODE_MENU");

			if (key_action == AKEY_EVENT_ACTION_UP) {
				LOGD("engine_handle_input", "AKEY_EVENT_ACTION_UP");
			}

	        return 1; // <-- prevent default handler
		}

/*		if (key == AKEYCODE_HOME) {
			LOGD( "engine_handle_input", "AKEYCODE_HOME");
			if (key_action == AKEY_EVENT_ACTION_UP) {
				LOGD("engine_handle_input", "AKEY_EVENT_ACTION_UP");
			}
	        return 1; // <-- prevent default handler
		}

		if (key == AKEYCODE_VOLUME_UP) {
			LOGD( "engine_handle_input", "AKEYCODE_VOLUME_UP");
			if (key_action == AKEY_EVENT_ACTION_UP) {
				LOGD("engine_handle_input", "AKEY_EVENT_ACTION_UP");
			}
	        return 1; // <-- prevent default handler
		}

		if (key == AKEYCODE_VOLUME_DOWN) {
			LOGD( "engine_handle_input", "AKEYCODE_VOLUME_DOWN");
			if (key_action == AKEY_EVENT_ACTION_UP) {
				LOGD("engine_handle_input", "AKEY_EVENT_ACTION_UP");
			}
	        return 1; // <-- prevent default handler
		}*/
	}

    int index = 0;
    int touch_max = 5;
	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {

		if (touch_enabled) {

			int p;
			int action = AKeyEvent_getAction(event);
			switch (action & AMOTION_EVENT_ACTION_MASK) {
			case AMOTION_EVENT_ACTION_DOWN:
				LOGDw("engine_handle_input", "AMOTION_EVENT_ACTION_DOWN");
				touch_branching(AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0));
				e->animating = 1;
				break;

			case AMOTION_EVENT_ACTION_POINTER_DOWN:
				LOGDw(
						"engine_handle_input", "AMOTION_EVENT_ACTION_POINTER_DOWN");

				/* Bits in the action code that represent a pointer index, used with
				 * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP.  Shifting
				 * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
				 * index where the data for the pointer going up or down can be found.
				 */
				//  AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,
				// マルチタッチバグを解決するため、こうやれば一番いい。
				size_t pointer_index_mask = (action
						& AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
						>> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

				trigger_note(AMotionEvent_getX(event, pointer_index_mask),
						AMotionEvent_getY(event, pointer_index_mask));
				set_parts_active();
				LOGD("engine_handle_input", "pointer_index_mask: %d", pointer_index_mask);
				break;
			}
			return 1;
		}
	}
	return 0;
}
Exemple #4
0
/**
 * Process the next input event.
 */
int32_t handle_input(struct android_app* app, AInputEvent* event) {
  SFG_Window* window = fgStructure.CurrentWindow;

  /* FIXME: in Android, when key is repeated, down and up events
     happen most often at the exact same time.  This makes it
     impossible to animate based on key press time. */
  /* e.g. down/up/wait/down/up rather than down/wait/down/wait/up */
  
  if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
    /* LOGI("action: %d", AKeyEvent_getAction(event)); */
    /* LOGI("keycode: %d", code); */
    int32_t code = AKeyEvent_getKeyCode(event);

    if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) {
      int32_t keypress = 0;
      unsigned char ascii = 0;
      if ((keypress = key_a2fg[code]) && FETCH_WCB(*window, Special)) {
	INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY));
	return EVENT_HANDLED;
      } else if ((ascii = key_ascii(app, event)) && FETCH_WCB(*window, Keyboard)) {
	INVOKE_WCB(*window, Keyboard, (ascii, window->State.MouseX, window->State.MouseY));
	return EVENT_HANDLED;
      }
    }
    else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) {
      int32_t keypress = 0;
      unsigned char ascii = 0;
      if ((keypress = key_a2fg[code]) && FETCH_WCB(*window, Special)) {
	INVOKE_WCB(*window, SpecialUp, (keypress, window->State.MouseX, window->State.MouseY));
	return EVENT_HANDLED;
      } else if ((ascii = key_ascii(app, event)) && FETCH_WCB(*window, Keyboard)) {
	INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY));
	return EVENT_HANDLED;
      }
    }
  }

  if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
    int32_t action = AMotionEvent_getAction(event);
    float x = AMotionEvent_getX(event, 0);
    float y = AMotionEvent_getY(event, 0);
    LOGI("motion %.01f,%.01f action=%d", x, y, AMotionEvent_getAction(event));
    
    /* Virtual arrows PAD */
    // Don't interfere with existing mouse move event
    if (!touchscreen.in_mmotion) {
      struct vpad_state prev_vpad = touchscreen.vpad;
      touchscreen.vpad.left = touchscreen.vpad.right
	= touchscreen.vpad.up = touchscreen.vpad.down = false;

      int32_t width = ANativeWindow_getWidth(window->Window.Handle);
      int32_t height = ANativeWindow_getHeight(window->Window.Handle);
      if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_MOVE) {
	if ((x > 0 && x < 100) && (y > (height - 100) && y < height))
	  touchscreen.vpad.left = true;
	if ((x > 200 && x < 300) && (y > (height - 100) && y < height))
	  touchscreen.vpad.right = true;
	if ((x > 100 && x < 200) && (y > (height - 100) && y < height))
	  touchscreen.vpad.down = true;
	if ((x > 100 && x < 200) && (y > (height - 200) && y < (height - 100)))
	  touchscreen.vpad.up = true;
      }
      if (action == AMOTION_EVENT_ACTION_DOWN && 
	  (touchscreen.vpad.left || touchscreen.vpad.right || touchscreen.vpad.down || touchscreen.vpad.up))
	touchscreen.vpad.on = true;
      if (action == AMOTION_EVENT_ACTION_UP)
	touchscreen.vpad.on = false;
      if (prev_vpad.left != touchscreen.vpad.left
	  || prev_vpad.right != touchscreen.vpad.right
	  || prev_vpad.up != touchscreen.vpad.up
	  || prev_vpad.down != touchscreen.vpad.down
	  || prev_vpad.on != touchscreen.vpad.on) {
	if (FETCH_WCB(*window, Special)) {
	  if (prev_vpad.left == false && touchscreen.vpad.left == true)
	    INVOKE_WCB(*window, Special, (GLUT_KEY_LEFT, x, y));
	  else if (prev_vpad.right == false && touchscreen.vpad.right == true)
	    INVOKE_WCB(*window, Special, (GLUT_KEY_RIGHT, x, y));
	  else if (prev_vpad.up == false && touchscreen.vpad.up == true)
	    INVOKE_WCB(*window, Special, (GLUT_KEY_UP, x, y));
	  else if (prev_vpad.down == false && touchscreen.vpad.down == true)
	    INVOKE_WCB(*window, Special, (GLUT_KEY_DOWN, x, y));
	}
	if (FETCH_WCB(*window, SpecialUp)) {
	  if (prev_vpad.left == true && touchscreen.vpad.left == false)
	    INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_LEFT, x, y));
	  if (prev_vpad.right == true && touchscreen.vpad.right == false)
	    INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_RIGHT, x, y));
	  if (prev_vpad.up == true && touchscreen.vpad.up == false)
	    INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_UP, x, y));
	  if (prev_vpad.down == true && touchscreen.vpad.down == false)
	    INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_DOWN, x, y));
	}
	return EVENT_HANDLED;
      }
    }
    
    /* Normal mouse events */
    if (!touchscreen.vpad.on) {
      window->State.MouseX = x;
      window->State.MouseY = y;
      LOGI("Changed mouse position: %d,%d", x, y);
      if (action == AMOTION_EVENT_ACTION_DOWN && FETCH_WCB(*window, Mouse)) {
	touchscreen.in_mmotion = true;
	INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, GLUT_DOWN, x, y));
      } else if (action == AMOTION_EVENT_ACTION_UP && FETCH_WCB(*window, Mouse)) {
	touchscreen.in_mmotion = false;
	INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, GLUT_UP, x, y));
      } else if (action == AMOTION_EVENT_ACTION_MOVE && FETCH_WCB(*window, Motion)) {
	INVOKE_WCB(*window, Motion, (x, y));
      }
    }
    
    return EVENT_HANDLED;
  }

  /* Let Android handle other events (e.g. Back and Menu buttons) */
  return EVENT_NOT_HANDLED;
}
Exemple #5
0
	int32_t processInput(struct android_app* androidApp, AInputEvent* event)
	{
		if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
		{
			const int32_t action = AMotionEvent_getAction(event);
			const int32_t pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
			const int32_t pointerCount = AMotionEvent_getPointerCount(event);

			const int32_t pointerId = AMotionEvent_getPointerId(event, pointerIndex);
			const float x = AMotionEvent_getX(event, pointerIndex);
			const float y = AMotionEvent_getY(event, pointerIndex);

			const int32_t actionMasked = (action & AMOTION_EVENT_ACTION_MASK);

			switch (actionMasked)
			{
				case AMOTION_EVENT_ACTION_DOWN:
				case AMOTION_EVENT_ACTION_POINTER_DOWN:
				{
					deviceEventQueue.pushButtonEvent(InputDeviceType::TOUCHSCREEN
						, 0
						, pointerId
						, true
						);
				}
				break;
				case AMOTION_EVENT_ACTION_UP:
				case AMOTION_EVENT_ACTION_POINTER_UP:
				{
					deviceEventQueue.pushButtonEvent(InputDeviceType::TOUCHSCREEN
						, 0
						, pointerId
						, false
						);
				}
				break;
				case AMOTION_EVENT_ACTION_OUTSIDE:
				case AMOTION_EVENT_ACTION_CANCEL:
				{
					deviceEventQueue.pushButtonEvent(InputDeviceType::TOUCHSCREEN
						, 0
						, pointerId
						, false
						);
				}
				break;
				case AMOTION_EVENT_ACTION_MOVE:
				{
					for (int index = 0; index < pointerCount; index++)
					{
						const float xx = AMotionEvent_getX(event, index);
						const float yy = AMotionEvent_getY(event, index);
						const int32_t pointerId = AMotionEvent_getPointerId(event, index);
						deviceEventQueue.pushAxisEvent(InputDeviceType::TOUCHSCREEN
							, 0
							, pointerId
							, xx
							, yy
							, 0.0f
							);
					}
				}
				break;
			}

			return 1;
		}
		else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
Exemple #6
0
void StWindowImpl::onAndroidInput(const AInputEvent* theEvent,
                                  bool&              theIsProcessed) {
    const int anEventType = AInputEvent_getType(theEvent);
    switch(anEventType) {
        case AINPUT_EVENT_TYPE_KEY: {
            StVirtKey aVKeySt = ST_VK_NULL;
            int32_t   aKeySym = AKeyEvent_getKeyCode(theEvent);
            if(aKeySym < ST_ANDROID2ST_VK_SIZE) {
                aVKeySt = (StVirtKey )ST_ANDROID2ST_VK[aKeySym];
            }
            if(aVKeySt == ST_VK_NULL) {
                return;
            }

            myStEvent.Key.Time = getEventTime(); //AKeyEvent_getEventTime(theEvent);
            myStEvent.Key.VKey = aVKeySt;
            myStEvent.Key.Char = 0;

            const int32_t aKeyAction = AKeyEvent_getAction(theEvent);
            if(aKeyAction == AKEY_EVENT_ACTION_DOWN) {
                postKeyDown(myStEvent);
            } else if(aKeyAction == AKEY_EVENT_ACTION_UP) {
                postKeyUp(myStEvent);
            }// else if(aKeyAction == AKEY_EVENT_ACTION_MULTIPLE) {}
            return;
        }
        case AINPUT_EVENT_TYPE_MOTION: {
            theIsProcessed = true;

            const int32_t aSource          = AInputEvent_getSource(theEvent);
            const int32_t anActionPak      = AMotionEvent_getAction(theEvent);
            const int32_t anAction         = anActionPak & AMOTION_EVENT_ACTION_MASK;
            const size_t  anActionPntIndex = anActionPak & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK;

            //const StRectI_t& aWinRect = attribs.IsFullScreen ? myRectFull : myRectNorm;
            const StRectI_t& aWinRect  = myRectNorm;
            const float      aWinSizeX = aWinRect.width();
            const float      aWinSizeY = aWinRect.height();

            // at least single point is defined
            StPointD_t aPos0(double(AMotionEvent_getX(theEvent, 0)) / double(aWinSizeX),
                             double(AMotionEvent_getY(theEvent, 0)) / double(aWinSizeY));

            myStEvent.Type      = stEvent_None;
            myStEvent.Base.Time = getEventTime(); /// int64_t AMotionEvent_getEventTime(theEvent);
            switch(aSource) {
                case AINPUT_SOURCE_TOUCHSCREEN:
                case AINPUT_SOURCE_TOUCHPAD: {
                    const size_t aNbTouches = AMotionEvent_getPointerCount(theEvent);
                    myStEvent.Touch.NbTouches = std::min(aNbTouches, (size_t )ST_MAX_TOUCHES);
                    bool isUp = anAction == AMOTION_EVENT_ACTION_UP
                             || anAction == AMOTION_EVENT_ACTION_POINTER_UP;
                    if(isUp) {
                        myStEvent.Touch.NbTouches = std::max(myStEvent.Touch.NbTouches - 1, 0);
                    }
                    for(size_t aTouchIter = 0; aTouchIter < ST_MAX_TOUCHES; ++aTouchIter) {
                        StTouch& aTouch = myStEvent.Touch.Touches[aTouchIter];
                        aTouch = StTouch::Empty();
                        if(aTouchIter == anActionPntIndex
                        && isUp) {
                            continue;
                        }
                        if(aTouchIter >= aNbTouches) {
                            continue;
                        }

                        aTouch.Id       = AMotionEvent_getPointerId(theEvent, aTouchIter);
                        aTouch.DeviceId = AInputEvent_getDeviceId(theEvent);
                        aTouch.OnScreen = aSource == AINPUT_SOURCE_TOUCHSCREEN;

                        const float aPosX = AMotionEvent_getX(theEvent, aTouchIter);
                        const float aPosY = AMotionEvent_getY(theEvent, aTouchIter);
                        aTouch.PointX = (aPosX - float(aWinRect.left())) / aWinSizeX;
                        aTouch.PointY = (aPosY - float(aWinRect.top()))  / aWinSizeY;
                    }

                    switch(anAction) {
                        case AMOTION_EVENT_ACTION_DOWN:
                        case AMOTION_EVENT_ACTION_POINTER_DOWN: {
                            myStEvent.Type = stEvent_TouchDown;
                            doTouch(myStEvent.Touch);
                            if(aNbTouches == 1) {
                                // simulate mouse click
                                myMousePt = aPos0;
                                myIsPreciseCursor = false;
                                myStEvent.Type = stEvent_MouseDown;
                                myStEvent.Button.Button  = ST_MOUSE_LEFT;
                                myStEvent.Button.Buttons = 0;
                                myStEvent.Button.PointX  = myMousePt.x();
                                myStEvent.Button.PointY  = myMousePt.y();
                                signals.onMouseDown->emit(myStEvent.Button);
                            } else if(aNbTouches == 2) {
                                // emit special event to cancel previously simulated click
                                myStEvent.Type = stEvent_MouseCancel;
                                myStEvent.Button.Button  = ST_MOUSE_LEFT;
                                myStEvent.Button.Buttons = 0;
                                myStEvent.Button.PointX  = myMousePt.x();
                                myStEvent.Button.PointY  = myMousePt.y();
                                signals.onMouseUp->emit(myStEvent.Button);
                            }
                            break;
                        }
                        case AMOTION_EVENT_ACTION_MOVE: {
                            myStEvent.Type = stEvent_TouchMove;
                            if(aNbTouches == 1) {
                                // simulate mouse move
                                myMousePt = aPos0;
                                myIsPreciseCursor = false;
                            }
                            doTouch(myStEvent.Touch);
                            break;
                        }
                        case AMOTION_EVENT_ACTION_UP:
                        case AMOTION_EVENT_ACTION_POINTER_UP: {
                            myStEvent.Type = stEvent_TouchUp;
                            doTouch(myStEvent.Touch);
                            if(aNbTouches == 1) {
                                // simulate mouse unclick
                                myMousePt = aPos0;
                                myIsPreciseCursor = false;
                                myStEvent.Type = stEvent_MouseUp;
                                myStEvent.Button.Button  = ST_MOUSE_LEFT;
                                myStEvent.Button.Buttons = 0;
                                myStEvent.Button.PointX  = myMousePt.x();
                                myStEvent.Button.PointY  = myMousePt.y();
                                signals.onMouseUp->emit(myStEvent.Button);
                            }
                            break;
                        }
                        case AMOTION_EVENT_ACTION_CANCEL: {
                            myStEvent.Type = stEvent_TouchCancel;
                            doTouch(myStEvent.Touch);
                            break;
                        }
                    }
                    return;
                }
            }

            myMousePt = aPos0;
            myIsPreciseCursor = aSource == AINPUT_SOURCE_MOUSE; // || AINPUT_SOURCE_STYLUS

            StVirtButton aMouseBtn = ST_MOUSE_LEFT;
            myStEvent.Button.Button  = aMouseBtn;
            myStEvent.Button.Buttons = 0;
            myStEvent.Button.PointX  = myMousePt.x();
            myStEvent.Button.PointY  = myMousePt.y();

            if(anAction == AMOTION_EVENT_ACTION_DOWN) {
                myStEvent.Type = stEvent_MouseDown;
                signals.onMouseDown->emit(myStEvent.Button);
            } else if(anAction == AMOTION_EVENT_ACTION_UP) {
                myStEvent.Type = stEvent_MouseUp;
                signals.onMouseUp->emit(myStEvent.Button);
            }
            return;
        }
    }
}
    bool InputService::onTrackballEvent(AInputEvent* pEvent) {
#ifdef INPUTSERVICE_LOG_EVENTS
         packt_Log_debug("AMotionEvent_getAction=%d", AMotionEvent_getAction(pEvent));
         packt_Log_debug("AMotionEvent_getFlags=%d", AMotionEvent_getFlags(pEvent));
         packt_Log_debug("AMotionEvent_getMetaState=%d", AMotionEvent_getMetaState(pEvent));
         packt_Log_debug("AMotionEvent_getEdgeFlags=%d", AMotionEvent_getEdgeFlags(pEvent));
         packt_Log_debug("AMotionEvent_getDownTime=%lld", AMotionEvent_getDownTime(pEvent));
         packt_Log_debug("AMotionEvent_getEventTime=%lld", AMotionEvent_getEventTime(pEvent));
         packt_Log_debug("AMotionEvent_getXOffset=%f", AMotionEvent_getXOffset(pEvent));
         packt_Log_debug("AMotionEvent_getYOffset=%f", AMotionEvent_getYOffset(pEvent));
         packt_Log_debug("AMotionEvent_getXPrecision=%f", AMotionEvent_getXPrecision(pEvent));
         packt_Log_debug("AMotionEvent_getYPrecision=%f", AMotionEvent_getYPrecision(pEvent));
         packt_Log_debug("AMotionEvent_getPointerCount=%d", AMotionEvent_getPointerCount(pEvent));
         packt_Log_debug("AMotionEvent_getRawX=%f", AMotionEvent_getRawX(pEvent, 0));
         packt_Log_debug("AMotionEvent_getRawY=%f", AMotionEvent_getRawY(pEvent, 0));
         packt_Log_debug("AMotionEvent_getX=%f", AMotionEvent_getX(pEvent, 0));
         packt_Log_debug("AMotionEvent_getY=%f", AMotionEvent_getY(pEvent, 0));
         packt_Log_debug("AMotionEvent_getPressure=%f", AMotionEvent_getPressure(pEvent, 0));
         packt_Log_debug("AMotionEvent_getSize=%f", AMotionEvent_getSize(pEvent, 0));
         packt_Log_debug("AMotionEvent_getOrientation=%f", AMotionEvent_getOrientation(pEvent, 0));
         packt_Log_debug("AMotionEvent_getTouchMajor=%f", AMotionEvent_getTouchMajor(pEvent, 0));
         packt_Log_debug("AMotionEvent_getTouchMinor=%f", AMotionEvent_getTouchMinor(pEvent, 0));
#endif
        const float ORTHOGONAL_MOVE = 1.0f;
        const float DIAGONAL_MOVE   = 0.707f;
        const float THRESHOLD       = (1/100.0f);

         if (AMotionEvent_getAction(pEvent) == AMOTION_EVENT_ACTION_MOVE) {
            float lDirectionX = AMotionEvent_getX(pEvent, 0);
            float lDirectionY = AMotionEvent_getY(pEvent, 0);
            float lHorizontal, lVertical;

            if (lDirectionX < -THRESHOLD) {
                if (lDirectionY < -THRESHOLD) {
                    lHorizontal = -DIAGONAL_MOVE;
                    lVertical   = DIAGONAL_MOVE;
                } else if (lDirectionY > THRESHOLD) {
                    lHorizontal = -DIAGONAL_MOVE;
                    lVertical   = -DIAGONAL_MOVE;
                } else {
                    lHorizontal = -ORTHOGONAL_MOVE;
                    lVertical   = 0.0f;
                }
            } else if (lDirectionX > THRESHOLD) {
                if (lDirectionY < -THRESHOLD) {
                    lHorizontal = DIAGONAL_MOVE;
                    lVertical   = DIAGONAL_MOVE;
                } else if (lDirectionY > THRESHOLD) {
                    lHorizontal = DIAGONAL_MOVE;
                    lVertical   = -DIAGONAL_MOVE;
                } else {
                    lHorizontal = ORTHOGONAL_MOVE;
                    lVertical   = 0.0f;
                }
            } else if (lDirectionY < -THRESHOLD) {
                lHorizontal = 0.0f;
                lVertical   = ORTHOGONAL_MOVE;
            } else if (lDirectionY > THRESHOLD) {
                lHorizontal = 0.0f;
                lVertical   = -ORTHOGONAL_MOVE;
            }

            // Ends movement if there is a counter movement.
            if ((lHorizontal < 0.0f) && (mHorizontal > 0.0f)) {
                mHorizontal = 0.0f;
            } else if ((lHorizontal > 0.0f) && (mHorizontal < 0.0f)) {
                mHorizontal = 0.0f;
            } else {
                mHorizontal = lHorizontal;
            }

            if ((lVertical < 0.0f) && (mVertical > 0.0f)) {
                mVertical = 0.0f;
            } else if ((lVertical > 0.0f) && (mVertical < 0.0f)) {
                mVertical = 0.0f;
            } else {
                mVertical = lVertical;
            }
        } else {
            mHorizontal = 0.0f; mVertical = 0.0f;
        }
        return true;
    }
/**
 * Process the next input event.
 */
int32_t Engine::handleInput(AInputEvent* event) {
    if (mCallbacks && mGamepad->pollGamepads(event, mPadChangedMask))
        return true;
    else if (NULL==mCallbacks)
        return false;

    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
        bool handled = false;
        int32_t pointerCount = AMotionEvent_getPointerCount(event);
        int32_t action = amotion_getActionMasked(event);
        int32_t pointerIndex = amotion_getActionIndex(event);

        float x=0, y=0;
        NvPointerEvent p[20]; // !!!!!TBD  should use linkedlist or app-member struct or something?  TODO
        NvInputDeviceType::Enum dev = NvInputDeviceType::TOUCH;
        // loop over pointercount and copy data
        // !!!!TBD TODO, might need to ensure that p[0] is always the data from the first-finger-touched ID...
        for (int i=0; i<pointerCount; i++) {
            x = AMotionEvent_getX(event, i);
            y = AMotionEvent_getY(event, i);
            p[i].m_x = x;
            p[i].m_y = y;
            p[i].m_id = AMotionEvent_getPointerId(event, i);
            // then figure out tool/device enum...
            int32_t tool = AMotionEvent_getToolType(event, i);
            if (tool==AMOTION_EVENT_TOOL_TYPE_STYLUS ||
                tool==AMOTION_EVENT_TOOL_TYPE_ERASER)//!!!!TBD TODO
                dev = NvInputDeviceType::STYLUS;
            else if (tool==AMOTION_EVENT_TOOL_TYPE_MOUSE)
                dev = NvInputDeviceType::MOUSE;
            else
                dev = NvInputDeviceType::TOUCH;
            // else we assume == FINGER... if unknown, treat as FINGER. TODO.
            p[i].m_device = dev;
        }

        mState.x = x;
        mState.y = y;
    
        NvPointerActionType::Enum pact;

        switch(action)
        {
        case AMOTION_EVENT_ACTION_DOWN:
            pact = NvPointerActionType::DOWN;
            break;
        case AMOTION_EVENT_ACTION_POINTER_DOWN:
            pact = NvPointerActionType::EXTRA_DOWN;
            break;
        case AMOTION_EVENT_ACTION_UP:
            pact = NvPointerActionType::UP;
            break;
        case AMOTION_EVENT_ACTION_POINTER_UP:
            pact = NvPointerActionType::EXTRA_UP;
            break;
        case AMOTION_EVENT_ACTION_MOVE:
            pact = NvPointerActionType::MOTION;
            break;
        case AMOTION_EVENT_ACTION_CANCEL:
            pact = NvPointerActionType::UP;
            pointerCount = 0; // clear.
            break;
        }

        const int64_t timestamp = AMotionEvent_getEventTime((const AInputEvent*)event);
        handled = mCallbacks->pointerInput(dev, pact, 0, pointerCount, p, timestamp);
        // return code handling...
        if (pact==NvPointerActionType::UP)
            return 1;
        return handled ? 1 : 0;
    } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
        bool handled = false;
        int32_t source = AInputEvent_getSource(event);
        int32_t code = AKeyEvent_getKeyCode((const AInputEvent*)event);
        int32_t action = AKeyEvent_getAction((const AInputEvent*)event);

        bool down = (action != AKEY_EVENT_ACTION_UP) ? true : false;

        if (mCallbacks) {
            handled = mCallbacks->keyInput(code, 
                down ? NvKeyActionType::DOWN : NvKeyActionType::UP);

            if (!handled && down) {
                uint8_t c = mapAndroidCodeToChar(code);
                if (c)
                    handled = mCallbacks->characterInput(c);
            }
        }

        return handled ? 1 : 0;
    }

    return 0;
}
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) 
{

	struct engine* engine = (struct engine*)app->userData;

	int pointers = AMotionEvent_getPointerCount(event);

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {

		int pointers = AMotionEvent_getPointerCount(event);

		switch(pointers) {

		case 1:
			//rotation
			if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN ) 
			{

						X1 = AMotionEvent_getX(event, 0);
						Y1 = AMotionEvent_getY(event, 0);

						return 1;
					}
					else if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_UP) 
					{
						// Do nothing
					}
					else if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_MOVE )
					{

						float dx = AMotionEvent_getX(event, 0) - X1;
						float dy = AMotionEvent_getY(event, 0) - Y1;

						touchRotate(-dx,-dy);

						X1 = AMotionEvent_getX(event, 0);
						Y1 = AMotionEvent_getY(event, 0);
					}

			break;
		case 2:
			//pinch/zoom (multitouch)

			if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN )
			{

				X1 = AMotionEvent_getX(event, 0);
				Y1 = AMotionEvent_getY(event, 0);
				X2 = AMotionEvent_getX(event, 1);
				Y2 = AMotionEvent_getY(event, 1);


				double dx = abs((double) (X2 - X1));
				double dy = abs((double) (Y2 - Y1));
				S = (float) sqrt((dx * dx) + (dy * dy));
			}

			else if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_MOVE )
			{
				float x1 = 0.0F;
				float y1 = 0.0F;
				float x2 = 0.0F;
				float y2 = 0.0F;

				// some unknown device throws an exception here
				x1 = AMotionEvent_getX(event, 0);
				y1 = AMotionEvent_getY(event, 0);
				x2 = AMotionEvent_getX(event, 1);
				y2 = AMotionEvent_getY(event, 1);

				double dx = abs((double) (x2 - x1));
				double dy = abs((double) (y2 - y1));
				float s = (float) sqrt((dx * dx) + (dy * dy));

				touchScale(4.0f * (S - s));

				//LOGI("S-s: %f",S-s);
				X1 = x1;
				Y1 = y1;
				X2 = x2;
				Y2 = y2;
				S = s;
			}
			break;

		case 3:
			//3 finger tap to switch shaders
			//LOGI("action: %i%",AKeyEvent_getAction(event));

			if(AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_UP || AKeyEvent_getAction(event) == AMOTION_EVENT_ACTION_POINTER_UP ) 
			{
				LOGI("3 finger tap UP");
				ShaderToUse ++;
				if(ShaderToUse>2)
					ShaderToUse=0;
			}

		}
	}

    return 0;
}
/*****************************************************************************
 Global code
*****************************************************************************/
static int32_t handle_input(struct android_app* app, AInputEvent* event)
{
	PVRShellInit* init = (PVRShellInit*) app->userData;

	if(init)
	{
		switch(AInputEvent_getType(event))
		{
			case AINPUT_EVENT_TYPE_KEY: // Handle keyboard events
			{
				switch(AKeyEvent_getAction(event))
				{
					case AKEY_EVENT_ACTION_DOWN:
					{
						switch(AKeyEvent_getKeyCode(event))
						{
							case AKEYCODE_Q:			init->KeyPressed(PVRShellKeyNameQUIT);		break;
							case AKEYCODE_BACK:			init->KeyPressed(PVRShellKeyNameQUIT);		break;
							case AKEYCODE_DPAD_CENTER:	init->KeyPressed(PVRShellKeyNameSELECT);	break;
							case AKEYCODE_SPACE: 		init->KeyPressed(PVRShellKeyNameACTION1); 	break;
							case AKEYCODE_SHIFT_LEFT: 	init->KeyPressed(PVRShellKeyNameACTION2); 	break;
							case AKEYCODE_DPAD_UP: 		init->KeyPressed(init->m_eKeyMapUP); 		break;
							case AKEYCODE_DPAD_DOWN: 	init->KeyPressed(init->m_eKeyMapDOWN); 		break;
							case AKEYCODE_DPAD_LEFT: 	init->KeyPressed(init->m_eKeyMapLEFT);  	break;
							case AKEYCODE_DPAD_RIGHT: 	init->KeyPressed(init->m_eKeyMapRIGHT); 	break;
							case AKEYCODE_S: 			init->KeyPressed(PVRShellKeyNameScreenshot);break;
							default:
								break;
						}
					}
					return 1;

					default:
						break;
				}
				return 1;
			}
			case AINPUT_EVENT_TYPE_MOTION: // Handle touch events
			{
				switch(AMotionEvent_getAction(event))
				{
					case AMOTION_EVENT_ACTION_DOWN:
					{
						PVRShell *pShell = init->m_pShell;
						if(pShell)
						{
							float vec2TouchPosition[2] = { AMotionEvent_getX(event, 0) / pShell->PVRShellGet(prefWidth), AMotionEvent_getY(event, 0) / pShell->PVRShellGet(prefHeight) };
							init->TouchBegan(vec2TouchPosition);
						}
						break;
					}
					case AMOTION_EVENT_ACTION_MOVE:
					{
						PVRShell *pShell = init->m_pShell;

						if(pShell)
						{
							float vec2TouchPosition[2] = { AMotionEvent_getX(event, 0) / pShell->PVRShellGet(prefWidth), AMotionEvent_getY(event, 0) / pShell->PVRShellGet(prefHeight) };
							init->TouchMoved(vec2TouchPosition);
						}
						break;
					}
					case AMOTION_EVENT_ACTION_UP:
					{
						PVRShell *pShell = init->m_pShell;
						if(pShell)
						{
							float vec2TouchPosition[2] = { AMotionEvent_getX(event, 0) / pShell->PVRShellGet(prefWidth), AMotionEvent_getY(event, 0) / pShell->PVRShellGet(prefHeight) };
							init->TouchEnded(vec2TouchPosition);
						}
						break;
					}
				}
				return 1;
			}
		}
	}

    return 1;
}
Exemple #11
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
	struct engine* androidEngine = (struct engine*)app->userData;

	int touchCount = 0;
	static int previousTouchCount;
	int numButton;
	touch_t* touch;
	touch_t* currentTouchSet;

	struct TOUCHSTATE *touchstate = 0;
	struct TOUCHSTATE *prev_touchstate = 0;

	int nSourceId = AInputEvent_getSource( event );

	if (nSourceId == AINPUT_SOURCE_TOUCHPAD)
   		touchstate = engine.touchstate_pad; // GJT: For Xperia Play...and other devices?
	else if (nSourceId == AINPUT_SOURCE_TOUCHSCREEN)
    	touchstate = engine.touchstate_screen;
    else
    	return 0; // GJT: Volume? Keyboard? Let the system handle it...

	if (engine.menuVisible)
	{
		numButton = MENU_GetNumButtonsTouches();
		currentTouchSet = MENU_GetCurrentButtonTouches();		
	}
	else 
	{
		numButton = NUM_BUTTONS;
		currentTouchSet = touches;
	}

	if (engine.menuVisible || engine.controlMode == CONTROL_MODE_VIRT_PAD)
	{
		size_t pointerCount =  AMotionEvent_getPointerCount(event);
		size_t i;
		for (i = 0; i < pointerCount; i++) 
		{
            size_t pointerId = AMotionEvent_getPointerId(event, i);
	        size_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
		
			touchstate[pointerId].x = AMotionEvent_getX( event, i );
			touchstate[pointerId].y = AMotionEvent_getY( event, i );
			
			LOGI("DEBUG BEFORE x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);

			// Transforming from whatever screen resolution we have to the original iPhone 320*480
			touchstate[pointerId].x = ( touchstate[pointerId].x - renderer.viewPortDimensions[VP_X] ) * commScale[X] ;
			touchstate[pointerId].y = ( touchstate[pointerId].y - renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;

			LOGI("DEBUG AFTER  x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);

			touchCount++;

			// find which one it is closest to
			int		minDist = INT_MAX; // allow up to 64 unit moves to be drags
			int		minIndex = -1;
			int dist;
			touch_t	*t2 = currentTouchSet;
			int i;

			for ( i = 0 ; i < numButton ; i++ ) 
			{
				dist = SQUARE( t2->iphone_coo_SysPos[X] - touchstate[pointerId].x )  + SQUARE( t2->iphone_coo_SysPos[Y] - touchstate[pointerId].y ) ;

				LOGI("DEBUG dist %i minDist %i", dist, minDist);
				if ( dist < minDist ) {
					minDist = dist;
					minIndex = i;
					touch = t2;
				}
				t2++;
			}

			if ( minIndex != -1 ) 
			{
				if (action == AMOTION_EVENT_ACTION_UP) 
				{
					touch->down = 0;
				}
				else 
				{
					if (action == AMOTION_EVENT_ACTION_DOWN) 
					{
					}
					touch->down = 1;
					touch->dist[X] = MIN(1,(touchstate[pointerId].x - touches[minIndex].iphone_coo_SysPos[X])/touches[minIndex].iphone_size);
					touch->dist[Y] = MIN(1,(touches[minIndex].iphone_coo_SysPos[Y] - touchstate[pointerId].y)/touches[minIndex].iphone_size);
					LOGI("DEBUG minIndexIphone %i", touches[minIndex].iphone_size);
				}
			}
		}

		LOGI("DEBUG touchcount %i previous %i", touchCount, previousTouchCount);
		if ( touchCount == 5 && previousTouchCount != 5 ) 
		{
			MENU_Set(MENU_HOME);
			engine.requiredSceneId = 0;
		}
	
		previousTouchCount = touchCount;

		return 1;
	}

	else
	{
		size_t pointerCount =  AMotionEvent_getPointerCount(event);
		size_t i;

		for (i = 0; i < pointerCount; i++) 
		{
			size_t pointerCount =  AMotionEvent_getPointerCount(event);
			size_t pointerId = AMotionEvent_getPointerId(event, i);
	        size_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
	        size_t pointerIndex = i;
		
			int historySize = AMotionEvent_getHistorySize(event);

			touchstate[pointerId].x = AMotionEvent_getX( event, pointerIndex );
			touchstate[pointerId].y = AMotionEvent_getY( event, pointerIndex );

			LOGI("DEBUG history %i", historySize);

			LOGI("DEBUG nomenu x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);
			if (historySize > 0)
			{
				//prev_touchstate[pointerId].x = AMotionEvent_getX( event, pointerIndex );
				//prev_touchstate[pointerId].y = AMotionEvent_getY( event, pointerIndex );

				LOGI("DEBUG nomenu prevx %f prevy %f", prev_touchstate[pointerId].x, prev_touchstate[pointerId].y);
			}
			//Transforming from whatever screen resolution we have to the original iPHone 320*480
			/*touchstate[pointerId].x = ( touchstate[pointerId].x- renderer.viewPortDimensions[VP_X] ) * commScale[X] ;//* renderer.resolution ;
			touchstate[pointerId].y = ( touchstate[pointerId].y- renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;//* renderer.resolution;
			
			prev_touchstate[pointerId].x = ( prev_touchstate[pointerId].x- renderer.viewPortDimensions[VP_X] ) * commScale[X] ;//* renderer.resolution ;
			prev_touchstate[pointerId].y = ( prev_touchstate[pointerId].y- renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;//* renderer.resolution;*/
			
			
			touchCount++;					

			if (action == AMOTION_EVENT_ACTION_UP) 
			{
				if (touchCount == 1) //Last finger ended
					touches[BUTTON_FIRE].down = 0;
			}
			else 
			{
				if (action == AMOTION_EVENT_ACTION_MOVE) 
				{
					//printf("m\n");
								LOGI("DEBUG MOVE x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);
			//LOGI("DEBUG MOVE prevx %f prevy %f", prev_touchstate[pointerId].x, prev_touchstate[pointerId].y);

					touches[BUTTON_MOVE].down = 1;
					//touches[BUTTON_MOVE].dist[X] = (touchstate[pointerId].x - prev_touchstate[pointerId].x)*40/(float)320;
					//touches[BUTTON_MOVE].dist[Y] = (touchstate[pointerId].y - prev_touchstate[pointerId].y)*-40/(float)480;
					
				}
				if (action == AMOTION_EVENT_ACTION_DOWN)
				{
					int currTime = E_Sys_Milliseconds();
					if (currTime-lastTouchBegan < 200)
						touches[BUTTON_GHOST].down = 1;
					
					lastTouchBegan = currTime ;
					
					touches[BUTTON_FIRE].down = 1;
				}
				
				
			}
		}

		if ( touchCount == 5 && previousTouchCount != 5 ) 
		{
			MENU_Set(MENU_HOME);
			engine.requiredSceneId=0;
		}
	
		previousTouchCount = touchCount;

		return 1;
	}
	return 0;
}
Exemple #12
0
int32_t on_motion_event(android_app *app, AInputEvent *event)
{
    /*
    AMotionEvent_getAction();
    AMotionEvent_getEventTime();
    AMotionEvent_getPointerCount();
    AMotionEvent_getPointerId();
    AMotionEvent_getX();
    AMotionEvent_getY();

    AMOTION_EVENT_ACTION_DOWN
    AMOTION_EVENT_ACTION_UP
    AMOTION_EVENT_ACTION_MOVE
    AMOTION_EVENT_ACTION_CANCEL
    AMOTION_EVENT_ACTION_POINTER_DOWN
    AMOTION_EVENT_ACTION_POINTER_UP
    */
    user_data *p = (user_data *)app->userData;
    pan_state *pan = &p->motion.pan;

    pan->stick = {};

    uint action = AMotionEvent_getAction(event);
    uint num_pointers = AMotionEvent_getPointerCount(event);
    if (num_pointers != 2 || action == AMOTION_EVENT_ACTION_UP || action == AMOTION_EVENT_ACTION_CANCEL)
    {
        if (pan->in_pan)
        {
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "ending pan");
        }
        pan->in_pan = 0;
    }
    else
    {
        uint pointer_id_0 = AMotionEvent_getPointerId(event, 0);
        uint pointer_id_1 = AMotionEvent_getPointerId(event, 1);
        v2 pointer_pos_0 = {AMotionEvent_getX(event, pointer_id_0), AMotionEvent_getY(event, pointer_id_0)};
        v2 pointer_pos_1 = {AMotionEvent_getX(event, pointer_id_1), AMotionEvent_getY(event, pointer_id_1)};
        v2 center_pos = (pointer_pos_0 + pointer_pos_1) * 0.5f;

        if (!pan->in_pan)
        {
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "starting pan");
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pointer_pos_0: %0.2f, %0.2f", pointer_pos_0.X, pointer_pos_0.Y);
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pointer_pos_1: %0.2f, %0.2f", pointer_pos_1.X, pointer_pos_1.Y);
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "center_pos: %0.2f, %0.2f", center_pos.X, center_pos.Y);
            pan->in_pan = 1;
            pan->start_pos = center_pos;
        }

        if (pan->in_pan)
        {
            v2 distance = center_pos - pan->start_pos;
            if ((abs(distance.X) > 100) || (abs(distance.Y) > 100))
            {
                if (abs(distance.X) > 100)
                {
                    pan->stick.X = distance.X > 0 ? 1.0 : -1.0;
                }
                if (abs(distance.Y) > 100)
                {
                    pan->stick.Y = distance.Y < 0 ? 1.0 : -1.0;
                }
            }
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pan->stick: %0.2f, %0.2f", pan->stick.X, pan->stick.Y);
        }
    }
    return 1;
}
//Called from the event process thread
static int32_t HandleInputCB(struct android_app* app, AInputEvent* event)
{
//	FPlatformMisc::LowLevelOutputDebugStringf(L"INPUT - type: %x, action: %x, source: %x, keycode: %x, buttons: %x", AInputEvent_getType(event), 
//		AMotionEvent_getAction(event), AInputEvent_getSource(event), AKeyEvent_getKeyCode(event), AMotionEvent_getButtonState(event));

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
	{
		int action = AMotionEvent_getAction(event);
		int actionType = action & AMOTION_EVENT_ACTION_MASK;
		size_t actionPointer = (size_t)((action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
		bool isActionTargeted = (actionType == AMOTION_EVENT_ACTION_POINTER_DOWN || actionType == AMOTION_EVENT_ACTION_POINTER_UP);

		// trap Joystick events first, with fallthrough if there is no joystick support
		if (((AInputEvent_getSource(event) & AINPUT_SOURCE_CLASS_JOYSTICK) != 0) &&
				(GetAxes != NULL) &&
				(actionType == AMOTION_EVENT_ACTION_MOVE))
		{
			const int axisCount = sizeof(AxisList)/sizeof(int32_t);
			int device = AInputEvent_getDeviceId(event);

			for (int axis = 0; axis < axisCount; axis++)
			{
				float val = GetAxes( event, AxisList[axis], 0);
				FAndroidInputInterface::JoystickAxisEvent( device, AxisList[axis], val);
			}
		}
		else
		{
			TArray<TouchInput> TouchesArray;
			
			TouchType type = TouchEnded;

			switch (actionType)
			{
			case AMOTION_EVENT_ACTION_DOWN:
			case AMOTION_EVENT_ACTION_POINTER_DOWN:
				type = TouchBegan;
				break;
			case AMOTION_EVENT_ACTION_MOVE:
				type = TouchMoved;
				break;
			case AMOTION_EVENT_ACTION_UP:
			case AMOTION_EVENT_ACTION_POINTER_UP:
			case AMOTION_EVENT_ACTION_CANCEL:
			case AMOTION_EVENT_ACTION_OUTSIDE:
				type = TouchEnded;
				break;
			}

			size_t pointerCount = AMotionEvent_getPointerCount(event);

			if (pointerCount == 0)
			{
				return 1;
			}

			ANativeWindow* Window = (ANativeWindow*)FPlatformMisc::GetHardwareWindow();
			if (!Window)
			{
				return 0;
			}

			int32_t Width = 0 ;
			int32_t Height = 0 ;

			if(Window)
			{
				FAndroidWindow::CalculateSurfaceSize(Window, Width, Height);
			}

			// make sure OpenGL context created before accepting touch events.. FAndroidWindow::GetScreenRect() may try to create it early from wrong thread if this is the first call
			if (!GAndroidGPUInfoReady)
			{
				return 1;
			}
			FPlatformRect ScreenRect = FAndroidWindow::GetScreenRect();

			if(isActionTargeted)
			{
				if(actionPointer < 0 || pointerCount < (int)actionPointer)
				{
					return 1;
				}

				int pointerId = AMotionEvent_getPointerId(event, actionPointer);
				float x = FMath::Min<float>(AMotionEvent_getX(event, actionPointer) / Width, 1.f);
				x *= (ScreenRect.Right - 1);
				float y = FMath::Min<float>(AMotionEvent_getY(event, actionPointer) / Height, 1.f);
				y *= (ScreenRect.Bottom - 1);

				UE_LOG(LogAndroid, Verbose, TEXT("Received targeted motion event from pointer %u (id %d) action %d: (%.2f, %.2f)"), actionPointer, pointerId, action, x, y);

				TouchInput TouchMessage;
				TouchMessage.Handle = pointerId;
				TouchMessage.Type = type;
				TouchMessage.Position = FVector2D(x, y);
				TouchMessage.LastPosition = FVector2D(x, y);		//@todo android: AMotionEvent_getHistoricalRawX
				TouchesArray.Add(TouchMessage);
			}
			else
			{
				for (size_t i = 0; i < pointerCount; ++i)
				{
					int pointerId = AMotionEvent_getPointerId(event, i);

					float x = FMath::Min<float>(AMotionEvent_getX(event, i) / Width, 1.f);
					x *= (ScreenRect.Right - 1);
					float y = FMath::Min<float>(AMotionEvent_getY(event, i) / Height, 1.f);
					y *= (ScreenRect.Bottom - 1);

					UE_LOG(LogAndroid, Verbose, TEXT("Received motion event from pointer %u (id %d) action %d: (%.2f, %.2f)"), i, action, AMotionEvent_getPointerId(event,i), x, y);

					TouchInput TouchMessage;
					TouchMessage.Handle = AMotionEvent_getPointerId(event, i);
					TouchMessage.Type = type;
					TouchMessage.Position = FVector2D(x, y);
					TouchMessage.LastPosition = FVector2D(x, y);		//@todo android: AMotionEvent_getHistoricalRawX
					TouchesArray.Add(TouchMessage);
				}
			}

			FAndroidInputInterface::QueueTouchInput(TouchesArray);

#if !UE_BUILD_SHIPPING
			if ((pointerCount >= 4) && (type == TouchBegan))
			{
				bool bShowConsole = true;
				GConfig->GetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bShowConsoleOnFourFingerTap"), bShowConsole, GInputIni);

				if (bShowConsole)
				{
					GShowConsoleWindowNextTick = true;
				}
			}
#endif
		}

		return 1;
	}
Exemple #14
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
    struct engine* engine = (struct engine*)app->userData;

    const int32_t input_type = AInputEvent_getType(event);
    
    if (input_type == AINPUT_EVENT_TYPE_MOTION) {
        engine->has_focus = 1;        
        
        const float x = AMotionEvent_getX(event, 0);
        const float y = AMotionEvent_getY(event, 0);
        const int32_t actionAndPtr = AMotionEvent_getAction(event);
        const int32_t action = AMOTION_EVENT_ACTION_MASK & actionAndPtr;
//        const int32_t ptrindex = (AMOTION_EVENT_ACTION_POINTER_INDEX_MASK & actionAndPtr) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
                
        const size_t num_ptrs = AMotionEvent_getPointerCount(event);
        
        switch(action)
        {
        case AMOTION_EVENT_ACTION_UP:
        case AMOTION_EVENT_ACTION_POINTER_UP:
            UnpressAll();
            break;
        case AMOTION_EVENT_ACTION_DOWN:
        case AMOTION_EVENT_ACTION_POINTER_DOWN:
            UnpressAll();
            if(num_ptrs <=2) {
                const int button = (num_ptrs==1) ? 0 : 2;
                pangolin::process::Mouse(button, 0, x, y);
            }
            break;
        case AMOTION_EVENT_ACTION_MOVE:
            if(num_ptrs == 3) {
                const double dx = x - process::last_x;
                const double dy = y - process::last_y;
                process::last_x = x;
                process::last_y = y;
                pangolin::process::Scroll(dx,dy);
            }else{
                pangolin::process::MouseMotion(x,y);
            }
            break;
        default:
            break;
        }
        
        return 1;
    }else if(AINPUT_EVENT_TYPE_KEY) {
        static bool shift = false;
        
        const int32_t action = AKeyEvent_getAction(event);
        const int32_t keycode  = AKeyEvent_getKeyCode(event);
        
        if(keycode == AKEYCODE_SHIFT_LEFT) {
            shift = (action == AKEY_EVENT_ACTION_DOWN);
            return 1;
        }
        
        unsigned char key = PangolinKeyFromAndroidKeycode(keycode, shift);
        
        if(action == AKEY_EVENT_ACTION_DOWN) {
            pangolin::process::Keyboard(key, pangolin::process::last_x,pangolin::process::last_y);
        }else{
            pangolin::process::KeyboardUp(key, pangolin::process::last_x,pangolin::process::last_y);
        }
    }
    return 1;
}
Exemple #15
0
static bool android_input_set_sensor_state(void *data, unsigned port,
      enum retro_sensor_action action, unsigned event_rate);

extern float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
      int32_t axis, size_t pointer_idx);

static typeof(AMotionEvent_getAxisValue) *p_AMotionEvent_getAxisValue;

#define AMotionEvent_getAxisValue (*p_AMotionEvent_getAxisValue)

static void engine_handle_dpad_default(android_input_t *android,
      AInputEvent *event, int port, int source)
{
   size_t motion_pointer = AMotionEvent_getAction(event) >>
      AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
   float x = AMotionEvent_getX(event, motion_pointer);
   float y = AMotionEvent_getY(event, motion_pointer);

   android->analog_state[port][0] = (int16_t)(x * 32767.0f);
   android->analog_state[port][1] = (int16_t)(y * 32767.0f);
}

static void engine_handle_dpad_getaxisvalue(android_input_t *android,
      AInputEvent *event, int port, int source)
{
   size_t motion_pointer = AMotionEvent_getAction(event) >>
      AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
   float x = AMotionEvent_getAxisValue(event, AXIS_X, motion_pointer);
   float y = AMotionEvent_getAxisValue(event, AXIS_Y, motion_pointer);
   float z = AMotionEvent_getAxisValue(event, AXIS_Z, motion_pointer);
   float rz = AMotionEvent_getAxisValue(event, AXIS_RZ, motion_pointer);
Exemple #16
0
//callback
extern int32_t __android_handle_input(struct android_app* app, AInputEvent* event){

		/*
		Input source
		*/
		int nSourceId = AInputEvent_getSource( event );
		//not supported device?
		if (!(nSourceId == AINPUT_SOURCE_TOUCHPAD  || 
			  nSourceId == AINPUT_SOURCE_KEYBOARD || 
			  nSourceId == AINPUT_SOURCE_TOUCHSCREEN))
	    	return 0;  
	    //keyboard
	    if(nSourceId == AINPUT_SOURCE_KEYBOARD)
	    {
		    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) 
		    { //keybord down
				 //get key code
				 unsigned int keyAction =  AKeyEvent_getAction(event);
				 //
				 if( keyDown && keyAction == AKEY_EVENT_ACTION_DOWN )
				 {
				 	keyDown(app->userData,AKeyEvent_getKeyCode(event));
				 }
				 else if( keyUp && keyAction == AKEY_EVENT_ACTION_UP )
				 {
				 	keyUp(app->userData,AKeyEvent_getKeyCode(event));
				 }
				 else 
				 {
				 	return 0;
				 }
				 return 1;
			}
			return 0;
		}
	    //action
	    unsigned int unmaskAction = AMotionEvent_getAction(event);
	    //base action
		unsigned int action = unmaskAction & AMOTION_EVENT_ACTION_MASK; 
		//pointer action
        unsigned int actionPointerIndex = (unmaskAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        			 actionPointerIndex >>= AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        
		if (action == AMOTION_EVENT_ACTION_DOWN) { //all down
			if(fingerDown){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
						unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
						fingerDown(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_POINTER_DOWN ) { //one down
			if(fingerDown){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					if( pointerFingerId==actionPointerIndex ) {
						fingerDown(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
					}
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_UP) { //up all			
			if(fingerUp){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					fingerUp(app->userData,pointerFingerId,
									       AMotionEvent_getX(event, i),
										   AMotionEvent_getY(event, i),
										   AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_POINTER_UP) { //up one			
			if(fingerUp){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					if( pointerFingerId==actionPointerIndex ) {
						fingerUp(app->userData,pointerFingerId,
										       AMotionEvent_getX(event, i),
											   AMotionEvent_getY(event, i),
											   AMotionEvent_getPressure(event, i));
					}
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_MOVE) { //move
			if(fingerMove){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
						unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
						fingerMove(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_CANCEL) {                                  
		} else {
			return 0;
		}
	return 1;
}
Exemple #17
0
static void android_input_poll(void *data)
{
   (void)data;

   RARCH_PERFORMANCE_INIT(input_poll);
   RARCH_PERFORMANCE_START(input_poll);

   bool debug_enable = g_settings.input.debug_enable;
   struct android_app* android_app = (struct android_app*)g_android;
   uint64_t *lifecycle_state = &g_extern.lifecycle_state;

   *lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS));

   // Read all pending events.
   while (AInputQueue_hasEvents(android_app->inputQueue) > 0)
   {
      AInputEvent* event = NULL;
      if (AInputQueue_getEvent(android_app->inputQueue, &event) < 0)
         break;

      bool long_msg_enable = false;
      int32_t handled = 1;
      int action = 0;
      char msg[128];
      msg[0] = 0;

      int source = AInputEvent_getSource(event);
      int id = AInputEvent_getDeviceId(event);
      if (id == zeus_second_id)
         id = zeus_id;
      int keycode = AKeyEvent_getKeyCode(event);

      int type_event = AInputEvent_getType(event);
      int state_id = -1;

      if (source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD))
         state_id = 0; // touch overlay is always player 1
      else
      {
         for (unsigned i = 0; i < pads_connected; i++)
            if (state_device_ids[i] == id)
               state_id = i;
      }

      if (state_id < 0)
      {
         state_id = pads_connected;
         state_device_ids[pads_connected++] = id;

         input_autodetect_setup(android_app, msg, sizeof(msg), state_id, id, source);
         long_msg_enable = true;
      }

      if (keycode == AKEYCODE_BACK )
      {
         int meta = AKeyEvent_getMetaState(event);
         if (!(meta & AMETA_ALT_ON))
         {
            *lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
            AInputQueue_finishEvent(android_app->inputQueue, event, handled);
            break;
         }
      }

      if (type_event == AINPUT_EVENT_TYPE_MOTION)
      {
         float x = 0.0f;
         float y = 0.0f;
         action = AMotionEvent_getAction(event);
         size_t motion_pointer = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
         action &= AMOTION_EVENT_ACTION_MASK;

         if (source & ~(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))
         {
            if (g_settings.input.dpad_emulation[state_id] != DPAD_EMULATION_NONE)
            {
               uint64_t *state_cur = &state[state_id];
               x = AMotionEvent_getX(event, motion_pointer);
               y = AMotionEvent_getY(event, motion_pointer);
               *state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) |
                     (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
               *state_cur |= PRESSED_LEFT(x, y)  ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)  : 0;
               *state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
               *state_cur |= PRESSED_UP(x, y)    ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP)    : 0;
               *state_cur |= PRESSED_DOWN(x, y)  ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)  : 0;
            }
         }
         else
         {
            bool keyup = (action == AMOTION_EVENT_ACTION_UP ||
                  action == AMOTION_EVENT_ACTION_CANCEL || action == AMOTION_EVENT_ACTION_POINTER_UP) ||
               (source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN);

            if (keyup && motion_pointer < MAX_TOUCH)
            {
               memmove(pointer + motion_pointer, pointer + motion_pointer + 1, (MAX_TOUCH - motion_pointer - 1) * sizeof(struct input_pointer));
               if (pointer_count > 0)
                  pointer_count--;
            }
            else
            {
               int pointer_max = min(AMotionEvent_getPointerCount(event), MAX_TOUCH);
               for (motion_pointer = 0; motion_pointer < pointer_max; motion_pointer++)
               {
                  x = AMotionEvent_getX(event, motion_pointer);
                  y = AMotionEvent_getY(event, motion_pointer);

                  input_translate_coord_viewport(x, y,
                        &pointer[motion_pointer].x, &pointer[motion_pointer].y,
                        &pointer[motion_pointer].full_x, &pointer[motion_pointer].full_y);

                  pointer_count = max(pointer_count, motion_pointer + 1);
               }
            }
         }

         if (debug_enable)
            snprintf(msg, sizeof(msg), "Pad %d : x = %.2f, y = %.2f, src %d.\n", state_id, x, y, source);
      }
      else if (type_event == AINPUT_EVENT_TYPE_KEY)
s32 CIrrDeviceAndroid::handleInput(android_app* app, AInputEvent* androidEvent)
{
	CIrrDeviceAndroid* device = (CIrrDeviceAndroid*)app->userData;
	s32 status = 0;

	switch ( AInputEvent_getType(androidEvent) )
	{
		case AINPUT_EVENT_TYPE_MOTION:
		{
			SEvent event;
			event.EventType = EET_TOUCH_INPUT_EVENT;

			s32 eventAction = AMotionEvent_getAction(androidEvent);
			s32 eventType =  eventAction & AMOTION_EVENT_ACTION_MASK;

			bool touchReceived = true;

			switch (eventType)
			{
			case AMOTION_EVENT_ACTION_DOWN:
			case AMOTION_EVENT_ACTION_POINTER_DOWN:
				event.TouchInput.Event = ETIE_PRESSED_DOWN;
				break;
			case AMOTION_EVENT_ACTION_MOVE:
				event.TouchInput.Event = ETIE_MOVED;
				break;
			case AMOTION_EVENT_ACTION_UP:
			case AMOTION_EVENT_ACTION_POINTER_UP:
			case AMOTION_EVENT_ACTION_CANCEL:
				event.TouchInput.Event = ETIE_LEFT_UP;
				break;
			default:
				touchReceived = false;
				break;
			}

			if (touchReceived)
			{
				// Process all touches for move action.
				if (event.TouchInput.Event == ETIE_MOVED)
				{
					s32 pointerCount = AMotionEvent_getPointerCount(androidEvent);

					for (s32 i = 0; i < pointerCount; ++i)
					{
						event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i);
						event.TouchInput.X = AMotionEvent_getX(androidEvent, i);
						event.TouchInput.Y = AMotionEvent_getY(androidEvent, i);

						device->postEventFromUser(event);
					}
				}
				else // Process one touch for other actions.
				{
					s32 pointerIndex = (eventAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

					event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex);
					event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex);
					event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex);

					device->postEventFromUser(event);
				}

				status = 1;
			}
		}
		break;
		case AINPUT_EVENT_TYPE_KEY:
		{
			SEvent event;
			event.EventType = EET_KEY_INPUT_EVENT;

			int32_t keyCode = AKeyEvent_getKeyCode(androidEvent);
			int32_t keyAction = AKeyEvent_getAction(androidEvent);
			int32_t keyMetaState = AKeyEvent_getMetaState(androidEvent);

			if ( keyCode >= 0 && (u32)keyCode < device->KeyMap.size() )
				event.KeyInput.Key = device->KeyMap[keyCode];
			else
				event.KeyInput.Key = KEY_UNKNOWN;
			event.KeyInput.SystemKeyCode = (u32)keyCode;
			if ( keyAction == AKEY_EVENT_ACTION_DOWN )
				event.KeyInput.PressedDown = true;
			else if ( keyAction == AKEY_EVENT_ACTION_UP )
				event.KeyInput.PressedDown = false;
			else if ( keyAction == AKEY_EVENT_ACTION_MULTIPLE )
			{
				// TODO: Multiple duplicate key events have occurred in a row,
				// or a complex string is being delivered. The repeat_count
				// property of the key event contains the number of times the
				// given key code should be executed.
				// I guess this might necessary for more complicated i18n key input,
				// but don't see yet how to handle this correctly.
			}

			/* no use for meta keys so far.
			if (   keyMetaState & AMETA_ALT_ON
				|| keyMetaState & AMETA_ALT_LEFT_ON
				|| keyMetaState & AMETA_ALT_RIGHT_ON )
				;
			// what is a sym?
			if (   keyMetaState & AMETA_SYM_ON )
				;
			*/
			if (   keyMetaState & AMETA_SHIFT_ON
				|| keyMetaState & AMETA_SHIFT_LEFT_ON
				|| keyMetaState & AMETA_SHIFT_RIGHT_ON )
				event.KeyInput.Shift = true;
			else
				event.KeyInput.Shift = false;
			event.KeyInput.Control = false;

			// Having memory allocations + going through JNI for each key-press is pretty bad (slow). 
			// So we do it only for those keys which are likely text-characters and avoid it for all other keys.
			// So it's fast for keys like game controller input and special keys. And text keys are typically 
			// only used or entering text and not for gaming on Android, so speed likely doesn't matter there too much.
			if ( event.KeyInput.Key > 0 )
			{
				// TODO:
				// Not sure why we have to attach a JNIEnv here, but it won't work when doing that in the constructor or 
				// trying to use the activity->env. My best guess is that the event-handling happens in an own thread.
				// It means JNIEnvAttachedToVM will never get detached as I don't know a safe way where to do that 
				// (we could attach & detach each time, but that would probably be slow)
				// Also - it has to be each time as it get's invalid when the application mode changes.
				if ( device->Initialized && device->Android && device->Android->activity && device->Android->activity->vm )
				{
					JavaVMAttachArgs attachArgs;
					attachArgs.version = JNI_VERSION_1_6;
					attachArgs.name = 0;
					attachArgs.group = NULL;

					// Not a big problem calling it each time - it's a no-op when the thread already is attached.
					// And we have to do that as someone else can have detached the thread in the meantime.
					jint result = device->Android->activity->vm->AttachCurrentThread(&device->JNIEnvAttachedToVM, &attachArgs);
					if(result == JNI_ERR)
					{
						os::Printer::log("AttachCurrentThread for the JNI environment failed.", ELL_WARNING);
						device->JNIEnvAttachedToVM = 0;
					}
				
					if ( device->JNIEnvAttachedToVM )
					{
						jni::CKeyEventWrapper * keyEventWrapper = new jni::CKeyEventWrapper(device->JNIEnvAttachedToVM, keyAction, keyCode);
						event.KeyInput.Char = keyEventWrapper->getUnicodeChar(keyMetaState);
						delete keyEventWrapper;
					}
				}
			}
			else
			{
				// os::Printer::log("keyCode: ", core::stringc(keyCode).c_str(), ELL_DEBUG);
				event.KeyInput.Char = 0;
			}
		
			device->postEventFromUser(event);
		}
		break;
		default:
		break;
	}

	return status;
}
Exemple #19
0
/*
 * Handle Touch Inputs
 */
static int32_t handle_touch_input(AInputEvent *event) {

    pthread_t thisthread = pthread_self();
    LOG_EVENTS_DEBUG("handle_touch_input(%X), pthread_self() = %X", event, thisthread);

    switch(AMotionEvent_getAction(event) &
           AMOTION_EVENT_ACTION_MASK) {

    case AMOTION_EVENT_ACTION_DOWN:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_DOWN");
            int pointerId = AMotionEvent_getPointerId(event, 0);
            float xP = AMotionEvent_getX(event,0);
            float yP = AMotionEvent_getY(event,0);

            LOG_EVENTS_DEBUG("Event: Action DOWN x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pointerId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_POINTER_DOWN:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_DOWN");
            int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
            int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
            float xP = AMotionEvent_getX(event,pointerIndex);
            float yP = AMotionEvent_getY(event,pointerIndex);

            LOG_EVENTS_DEBUG("Event: Action POINTER DOWN x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pointerId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_MOVE:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_MOVE");
            int pointerCount = AMotionEvent_getPointerCount(event);
            int ids[pointerCount];
            float xs[pointerCount], ys[pointerCount];
            getTouchPos(event, ids, xs, ys);
            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(pointerCount, ids, xs, ys);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_UP:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_UP");
            int pointerId = AMotionEvent_getPointerId(event, 0);
            float xP = AMotionEvent_getX(event,0);
            float yP = AMotionEvent_getY(event,0);
            LOG_EVENTS_DEBUG("Event: Action UP x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pointerId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_POINTER_UP:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_UP");
            int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
            int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
            float xP = AMotionEvent_getX(event,pointerIndex);
            float yP = AMotionEvent_getY(event,pointerIndex);
            LOG_EVENTS_DEBUG("Event: Action POINTER UP x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerIndex);
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pointerId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_CANCEL:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_CANCEL");
            int pointerCount = AMotionEvent_getPointerCount(event);
            int ids[pointerCount];
            float xs[pointerCount], ys[pointerCount];
            getTouchPos(event, ids, xs, ys);
            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(pointerCount, ids, xs, ys);
            return 1;
        }
        break;

    default:
        LOG_EVENTS_DEBUG("handle_touch_input() default case.... NOT HANDLE");
        return 0;
        break;
    }
}
	bool OuyaInputView::dispatchGenericMotionEvent(AInputEvent* motionEvent)
	{
		int64_t downTime = AMotionEvent_getDownTime(motionEvent);
		int64_t eventTime = AMotionEvent_getEventTime(motionEvent);
		int32_t action = AMotionEvent_getAction(motionEvent);
		int32_t metaState = AMotionEvent_getMetaState(motionEvent);
		int32_t pointerCount = AMotionEvent_getPointerCount(motionEvent);
		int32_t buttonState = AMotionEvent_getButtonState(motionEvent);
		float xPrecision = AMotionEvent_getXPrecision(motionEvent);
		float yPrecision = AMotionEvent_getYPrecision(motionEvent);
		int32_t deviceId = AInputEvent_getDeviceId(motionEvent);
		int32_t edgeFlags = AMotionEvent_getEdgeFlags(motionEvent);
		int32_t flags = AMotionEvent_getFlags(motionEvent);
		int32_t source = AInputEvent_getSource(motionEvent);

		int* pointerPropertiesId = new int[pointerCount];
		int* pointerPropertiesToolType = new int[pointerCount];
		float* pointerCoordsOrientation = new float[pointerCount];
		float* pointerCoordsPressure = new float[pointerCount];
		float* pointerCoordsSize = new float[pointerCount];
		float* pointerCoordsToolMajor = new float[pointerCount];
		float* pointerCoordsToolMinor = new float[pointerCount];
		float* pointerCoordsTouchMajor = new float[pointerCount];
		float* pointerCoordsTouchMinor = new float[pointerCount];
		float* pointerCoordsX = new float[pointerCount];
		float* pointerCoordsY = new float[pointerCount];

		std::vector<int> listAxisIndices;
		std::vector<float> listAxisValues;

		if (pointerCount > 0)
		{
#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "pointerCount=%d deviceId=%d source=%d",
				pointerCount, deviceId, source);
#endif

			// MotionEvent.PointerProperties
			long long pointerId = AMotionEvent_getPointerId(motionEvent, 0);
			int32_t toolType = AMotionEvent_getToolType(motionEvent, 0);

#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerProperties pointerId=%lld toolType-%d",
				pointerId, toolType);
#endif

			pointerPropertiesId[0] = pointerId;
			pointerPropertiesToolType[0] = toolType;

			// MotionEvent.PointerCoords
			float orientation = AMotionEvent_getOrientation(motionEvent, pointerId);
			float pressure = AMotionEvent_getPressure(motionEvent, pointerId);
			float size = AMotionEvent_getSize(motionEvent, pointerId);
			float toolMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId);
			float toolMinor = AMotionEvent_getToolMinor(motionEvent, pointerId);
			float touchMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId);
			float touchMinor = AMotionEvent_getTouchMinor(motionEvent, pointerId);
			float x = AMotionEvent_getX(motionEvent, pointerId);
			float y = AMotionEvent_getY(motionEvent, pointerId);

#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerCoords orientation=%f pressure=%f size=%f toolMajor=%f toolMinor=%f touchMajor=%f touchMinor=%f x=%f y=%f",
				orientation, pressure, size,
				toolMajor, toolMinor, touchMajor, touchMinor,
				x, y);
#endif

			pointerCoordsOrientation[0] = orientation;
			pointerCoordsPressure[0] = pressure;
			pointerCoordsSize[0] = size;
			pointerCoordsToolMajor[0] = toolMajor;
			pointerCoordsToolMinor[0] = toolMinor;
			pointerCoordsTouchMajor[0] = touchMajor;
			pointerCoordsTouchMinor[0] = touchMinor;
			pointerCoordsX[0] = x;
			pointerCoordsY[0] = y;

			for (int32_t axis = 0; axis < 50; ++axis) // 50 is based on the AXIS_value range I saw in the documentation
			{
				float val = AMotionEvent_getAxisValue(motionEvent, axis, pointerId);
				if (val != 0.0f)
				{
#if ENABLE_VERBOSE_LOGGING
					__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "axis=%d val=%f", axis, val);
#endif
					listAxisIndices.push_back(axis);
					listAxisValues.push_back(val);
				}
			}
		}

		int axisCount = listAxisIndices.size();
		int* axisIndexes = new int[axisCount];
		float* axisValues = new float[axisCount];
		for (int index = 0; index < axisCount; ++index)
		{
			axisIndexes[index] = listAxisIndices[index];
			axisValues[index] = listAxisValues[index];
		}
		listAxisIndices.clear();
		listAxisValues.clear();

		bool handled = javaDispatchGenericMotionEvent(
			downTime,
			eventTime,
			action,
			pointerCount,
			metaState,
			buttonState,
			xPrecision,
			yPrecision,
			deviceId,
			edgeFlags,
			source,
			flags,
			pointerPropertiesId,
			pointerPropertiesToolType,
			pointerCoordsOrientation,
			pointerCoordsPressure,
			pointerCoordsSize,
			pointerCoordsToolMajor,
			pointerCoordsToolMinor,
			pointerCoordsTouchMajor,
			pointerCoordsTouchMinor,
			pointerCoordsX,
			pointerCoordsY,
			axisCount,
			axisIndexes,
			axisValues);

		delete pointerPropertiesId;
		delete pointerPropertiesToolType;
		delete pointerCoordsOrientation;
		delete pointerCoordsPressure;
		delete pointerCoordsSize;
		delete pointerCoordsToolMajor;
		delete pointerCoordsToolMinor;
		delete pointerCoordsTouchMajor;
		delete pointerCoordsTouchMinor;
		delete pointerCoordsX;
		delete pointerCoordsY;
		delete axisIndexes;
		delete axisValues;
		return handled;
	}
Exemple #21
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
{
	struct engine* engine = (struct engine*)app->userData;
	switch(AInputEvent_getType(event))
	{
	case AINPUT_EVENT_TYPE_MOTION:
		{
		int32_t action = AMotionEvent_getAction(event );
		int pointer = ( action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK ) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
		int p = AMotionEvent_getPointerCount( event );
#ifdef DEBUG_TOUCH_INPUT
		LOGI( "pointer (full action)%04x (pointer)%d (number points)%d", action, pointer, p );
#endif
		{
			int n;
			for( n = 0; n < engine->nPoints; n++ )
			{
				engine->points[n].flags.new_event = 0;
				if( engine->points[n].flags.end_event )
				{
					int m;
					for( m = n; m < (engine->nPoints-1); m++ )
					{
						if( engine->input_point_map[m+1] == m+1 )
							engine->input_point_map[m] = m;
						else
						{
							if( engine->input_point_map[m+1] < n )
								engine->input_point_map[m] = engine->input_point_map[m+1];
							else
								engine->input_point_map[m] = engine->input_point_map[m+1] - 1;

						}
						engine->points[m] = engine->points[m+1];
					}
					engine->nPoints--;
					n--;
				}
			}
		}

		switch( action & AMOTION_EVENT_ACTION_MASK )
		{
		case AMOTION_EVENT_ACTION_DOWN:
			// primary pointer down.
			//if( engine->nPoints )
			//{
			//	LOGI( "Pointer Event Down (pointer0) and there's already pointers..." );
			//}
			engine->points[0].x = AMotionEvent_getX( event, pointer );
			engine->points[0].y = AMotionEvent_getY( event, pointer );
			engine->points[0].flags.new_event = 1;
			engine->points[0].flags.end_event = 0;
			engine->nPoints++;
			engine->input_point_map[0] = 0;
			break;
		case AMOTION_EVENT_ACTION_UP:
			// primary pointer up.
			engine->points[0].flags.new_event = 0;
			engine->points[0].flags.end_event = 1;
			break;
		case AMOTION_EVENT_ACTION_MOVE:
			{
				int n;
				for( n = 0; n < p; n++ )
				{
					// points may have come in as 'new' in the wrong order,
					// reference the input point map to fill in the correct point location
					int actual = engine->input_point_map[n];
					engine->points[actual].x = AMotionEvent_getX( event, n );
					engine->points[actual].y = AMotionEvent_getY( event, n );
					engine->points[actual].flags.new_event = 0;
					engine->points[actual].flags.end_event = 0;
				}
			}
			break;
		case AMOTION_EVENT_ACTION_POINTER_DOWN:
			// the new pointer might not be the last one, so we insert it.
			// at the end, before dispatch, new points are moved to the end
			// and mapping begins.  this code should not reference the map
			if( pointer < engine->nPoints )
			{
				int c;
#ifdef DEBUG_TOUCH_INPUT
				LOGI( "insert point new. %d", engine->nPoints-1 );
#endif
				for( c = engine->nPoints; c >= pointer; c-- )
				{
#ifdef DEBUG_TOUCH_INPUT
					LOGI( "Set %d to %d", c, engine->input_point_map[c-1] );
#endif
					engine->input_point_map[c] = engine->input_point_map[c-1]; // save still in the same target...
				}
#ifdef DEBUG_TOUCH_INPUT
				LOGI( "Set %d to %d", pointer, engine->nPoints );
#endif
				engine->input_point_map[pointer] = engine->nPoints; // and the new one maps to the last.
				// now just save in last and don't swap twice.
				engine->points[engine->nPoints].x = AMotionEvent_getX( event, pointer );
				engine->points[engine->nPoints].y = AMotionEvent_getY( event, pointer );
				pointer = engine->nPoints;
			}
			else
			{
				engine->points[pointer].x = AMotionEvent_getX( event, pointer );
				engine->points[pointer].y = AMotionEvent_getY( event, pointer );
				engine->input_point_map[pointer] = pointer;
			}
			// primary pointer down.
			engine->points[pointer].flags.new_event = 1;
			engine->points[pointer].flags.end_event = 0;
			// always initialize the
			engine->nPoints++;
			break;
		case AMOTION_EVENT_ACTION_POINTER_UP:
			{
				// a up pointer may be remapped already, set the actual entry for the point
				int actual = engine->input_point_map[pointer];
				int n;
				engine->points[actual].flags.new_event = 0;
				engine->points[actual].flags.end_event = 1;

#ifdef DEBUG_TOUCH_INPUT
				LOGI( "Set point %d (map %d) to ended", pointer, actual );
#endif
				// any release event will reset the other input points appropriately(?)
				for( n = 0; n < engine->nPoints; n++ )
				{
					int other;
					if( engine->input_point_map[n] != n )
					{
						int m;
#ifdef DEBUG_TOUCH_INPUT
						LOGI( "reorder to natural input order" );
#endif
						memcpy( engine->tmp_points, engine->points, engine->nPoints * sizeof( struct input_point ) );
						// m is the point currently mapped to this position.
						// data from engine[n] and engine[m] need to swap
						for( m = 0; m < engine->nPoints; m++ )
						{
							engine->points[m] = engine->tmp_points[other = engine->input_point_map[m]];
							engine->input_point_map[m] = m;
#ifdef DEBUG_TOUCH_INPUT
							LOGI( "move point %d to %d", other, m );
#endif
						}
						break;
					}
				}
			}
			break;
		default:
#ifdef DEBUG_TOUCH_INPUT
			LOGI( "Motion Event ignored..." );
#endif
			break;
		}

		{
			int n;
#ifdef DEBUG_TOUCH_INPUT
			for( n = 0; n < engine->nPoints; n++ )
			{
				LOGI( "Point : %d %d %g %g %d %d", n, engine->input_point_map[n], engine->points[n].x , engine->points[n].y, engine->points[n].flags.new_event, engine->points[n].flags.end_event );
			}
#endif
		}

		BagVidlibPureglSendTouchEvents( engine->nPoints, engine->points );
		//engine->state.animating = 1;
		//engine->state.x = AMotionEvent_getX(event, 0);
		//engine->state.y = AMotionEvent_getY(event, 0);
		return 1;
		}
	case AINPUT_EVENT_TYPE_KEY:
		{
			int32_t key_val = AKeyEvent_getKeyCode(event);
			//int32_t key_char = AKeyEvent_getKeyChar(event);
			int32_t key_mods = AKeyEvent_getMetaState( event );
			int32_t key_pressed = AKeyEvent_getAction( event );
			int realmod = 0;
         //lprintf( "key char is %d (%c)", key_char, key_char );
			if( ( key_mods & 0x3000 ) == 0x3000 )
				realmod |= KEY_MOD_CTRL;
			if( ( key_mods & 0x12 ) == 0x12 )
				realmod |= KEY_MOD_ALT;
			if( ( key_mods & 0x41 ) == 0x41 )
				realmod |= KEY_MOD_SHIFT;
			key_mods = realmod;
#ifdef DEBUG_KEY_INPUT
			LOGI("Received key event: %d %d %d\n", key_pressed, key_val, key_mods );
#endif
			{
				engine->key_text = AndroidGetKeyText( event );
            lprintf( "Event translates to %d(%04x)%c", engine->key_text, engine->key_text ,engine->key_text );
			}

			if( key_val )
			{
				int used;
				if( key_pressed == AKEY_EVENT_ACTION_MULTIPLE )
				{
					int count = AKeyEvent_getRepeatCount( event );
					int n;
					for( n = 0; n < count; n++ )
					{
						used = BagVidlibPureglSendKeyEvents( 1, key_val, key_mods );
						used = BagVidlibPureglSendKeyEvents( 0, key_val, key_mods );
					}
				}
				else
					used = BagVidlibPureglSendKeyEvents( (key_pressed==AKEY_EVENT_ACTION_DOWN)?1:0, key_val, key_mods );
				return used;
			}
			break;
		}
	default:
		LOGI( "Unhandled Motion Event ignored..." );
		break;
	}
	return 0;
}
Exemple #22
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
	struct engine* engine = (struct engine*)app->userData;

	if (!engine->os)
		return 0;

	switch(AInputEvent_getType(event)) {

		case AINPUT_EVENT_TYPE_KEY: {

			int ac = AKeyEvent_getAction(event);
			switch(ac) {

				case AKEY_EVENT_ACTION_DOWN: {

					int32_t code = AKeyEvent_getKeyCode(event);
					if (code==AKEYCODE_BACK) {

						//AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
						if (engine->os)
							engine->os->main_loop_request_quit();
						return 1;

					}


				} break;
				case AKEY_EVENT_ACTION_UP: {


				} break;
			}


		} break;
		case AINPUT_EVENT_TYPE_MOTION: {


			Vector<OS_Android::TouchPos> touchvec;

			int pc = AMotionEvent_getPointerCount(event);

			touchvec.resize(pc);

			for(int i=0;i<pc;i++) {

				touchvec[i].pos.x=AMotionEvent_getX(event,i);
				touchvec[i].pos.y=AMotionEvent_getY(event,i);
				touchvec[i].id=AMotionEvent_getPointerId(event,i);
			}


			//System.out.printf("gaction: %d\n",event.getAction());
			int pidx=(AMotionEvent_getAction(event)&AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)>>8;
			switch(AMotionEvent_getAction(event)&AMOTION_EVENT_ACTION_MASK) {

				case AMOTION_EVENT_ACTION_DOWN: {
					engine->os->process_touch(0,0,touchvec);

				    //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
				} break;
				case AMOTION_EVENT_ACTION_MOVE: {
					engine->os->process_touch(1,0,touchvec);
				    //for(int i=0;i<event.getPointerCount();i++) {
				    //	System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
				    //}
				} break;
				case AMOTION_EVENT_ACTION_POINTER_UP: {

					engine->os->process_touch(4,pidx,touchvec);
				    //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
				} break;
				case AMOTION_EVENT_ACTION_POINTER_DOWN: {
					engine->os->process_touch(3,pidx,touchvec);
				    //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
				} break;
				case AMOTION_EVENT_ACTION_CANCEL:
				case AMOTION_EVENT_ACTION_UP: {
					engine->os->process_touch(2,0,touchvec);
				    //for(int i=0;i<event.getPointerCount();i++) {
				    //	System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
				    //}
				} break;
			}

			return 1;
		} break;

	}

    return 0;
}
Exemple #23
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
    struct engine* engine = (struct engine*)app->userData;
    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {


        if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN) {
            engine->state.x0 = AMotionEvent_getX(event, 0);
            engine->state.y0 = AMotionEvent_getY(event, 0);
            return 1;
        }

        if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_UP
            && (AMotionEvent_getPointerCount(event) == 1)) {
            engine->kiwiApp->handleSingleTouchUp();
            return 1;
        }

        // When transitioning from one touch to two touches, we record the position
        // of of the new touch and return.  When transitioning from two touches to
        // one touch, we record the position of the single remaining touch and return.
        if (AMotionEvent_getPointerCount(event) > 1) {
            if (!engine->state.isTwoTouches) {
              engine->state.x1 = AMotionEvent_getX(event, 1);
              engine->state.y1 = AMotionEvent_getY(event, 1);
              engine->state.isTwoTouches = true;
              return 1;
            }
        }
        else if (engine->state.isTwoTouches) {
          engine->state.isTwoTouches = false;
          engine->state.x0 = AMotionEvent_getX(event, 0);
          engine->state.y0 = AMotionEvent_getY(event, 0);
          return 1;
        }

        if (AMotionEvent_getPointerCount(event) > 1 && !engine->state.isTwoTouches) {
            return 1;
        }

        engine->animating = 1;
        float px0 = engine->state.x0;
        float py0 = engine->state.y0;
        float px1 = engine->state.x1;
        float py1 = engine->state.y1;
        float x0 = AMotionEvent_getX(event, 0);
        float y0 = AMotionEvent_getY(event, 0);
        float x1 = x0;
        float y1 = y0;
        if (AMotionEvent_getPointerCount(event) > 1) {
            x1 = AMotionEvent_getX(event, 1);
            y1 = AMotionEvent_getY(event, 1);
        }


        if (AMotionEvent_getPointerCount(event) == 1) {
            float dx0 = x0 - px0;
            float dy0 = y0 - py0;
            engine->kiwiApp->handleSingleTouchPanGesture(dx0, dy0);
        } else {

          int viewHeight = engine->kiwiApp->viewHeight();

          // Average positions of current and previous two touches.
          // Invert y since vesCamera expects y to go in opposite direction.
          float pcx = (px0 + px1)/2.0;
          float pcy = viewHeight - (py0 + py1)/2.0;
          float cx = (x0 + x1)/2.0;
          float cy = viewHeight - (y0 + y1)/2.0;


          engine->kiwiApp->handleTwoTouchPanGesture(pcx, pcy, cx, cy);


            // zoom and rotate too

          double previousDist = sqrt((px0 - px1) *
                                     (px0 - px1) +
                                     (py0 - py1) *
                                     (py0 - py1));
          double currentDist = sqrt((x0 - x1) *
                                    (x0 - x1) +
                                    (y0 - y1) *
                                    (y0 - y1));
          double dy = currentDist - previousDist;
          double dyf = 10.0 * dy / (viewHeight/2.0);
          double factor = pow(1.1, dyf);

          engine->kiwiApp->handleTwoTouchPinchGesture(factor);

          double pi = 3.14159265358979;
          double newAngle = atan2(y0 - y1,
                                  x0 - x1);

          double oldAngle = atan2(py0 - py1,
                                  px0 - px1);

          double rotation = newAngle - oldAngle;

          engine->kiwiApp->handleTwoTouchRotationGesture(rotation);


        }

        engine->state.x0 = x0;
        engine->state.y0 = y0;
        if (AMotionEvent_getPointerCount(event) > 1) {
            engine->state.x1 = x1;
            engine->state.y1 = y1;
        }

        return 1;
    }
    return 0;
}
Exemple #24
0
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) 
{
	struct engineState* engine = (struct engineState*)app->userData;

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) 
	{

		int source = AInputEvent_getSource(event);

		if (source == AINPUT_SOURCE_TOUCHSCREEN)
		{
			float x = AMotionEvent_getX(event, 0);
			float y = AMotionEvent_getY(event, 0);

			engine->instance->getAndroidInputSystem()->handleTouchInput(x, y);

			return 1;
		}

		if (source == AINPUT_SOURCE_JOYSTICK)
		{
			float x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0);
			float y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0);

			int devId = AInputEvent_getDeviceId(event);

			LOG_INFO("dev: " << devId << " pos: " << x << ":" << y);
		}

		return 0;
	}

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) 
	{
		int32_t source = AInputEvent_getSource(event);
		int32_t code = AKeyEvent_getKeyCode(event);
		int32_t action = AKeyEvent_getAction(event);

		LOG_INFO("Code: " << code << " Action: " << action);

		engine::input::KeyCode keycode = engine::input::KEY_VOID;

		switch (code)
		{
			case 96:
				keycode = engine::input::BUTTON_A;
				break;
			case 99:
				keycode = engine::input::BUTTON_X;
				break;
			case 100:
				keycode = engine::input::BUTTON_Y;
				break;
			case 97:
				keycode = engine::input::BUTTON_B;
				break;
		}

		if (action == 1)
			engine->instance->getInputSystem()->keyUp(keycode);
		else
			engine->instance->getInputSystem()->keyDown(keycode);

		return 1;
	}

	return 0;
}
Exemple #25
0
static bool android_input_set_sensor_state(void *data, unsigned port,
      enum retro_sensor_action action, unsigned event_rate);

extern float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
      int32_t axis, size_t pointer_idx);

static typeof(AMotionEvent_getAxisValue) *p_AMotionEvent_getAxisValue;

#define AMotionEvent_getAxisValue (*p_AMotionEvent_getAxisValue)

static void engine_handle_dpad_default(android_input_t *android,
      AInputEvent *event, int port, int source)
{
   size_t motion_ptr = AMotionEvent_getAction(event) >>
      AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
   float x           = AMotionEvent_getX(event, motion_ptr);
   float y           = AMotionEvent_getY(event, motion_ptr);

   android->analog_state[port][0] = (int16_t)(x * 32767.0f);
   android->analog_state[port][1] = (int16_t)(y * 32767.0f);
}

static void engine_handle_dpad_getaxisvalue(android_input_t *android,
      AInputEvent *event, int port, int source)
{
   size_t motion_ptr = AMotionEvent_getAction(event) >>
      AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
   float x           = AMotionEvent_getAxisValue(event, AXIS_X, motion_ptr);
   float y           = AMotionEvent_getAxisValue(event, AXIS_Y, motion_ptr);
   float z           = AMotionEvent_getAxisValue(event, AXIS_Z, motion_ptr);
   float rz          = AMotionEvent_getAxisValue(event, AXIS_RZ, motion_ptr);
static void android_input_poll(void *data)
{
   (void)data;

   RARCH_PERFORMANCE_INIT(input_poll);
   RARCH_PERFORMANCE_START(input_poll);

   struct android_app* android_app = g_android.app;

   g_extern.lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS));


   // Read all pending events.
   while(AInputQueue_hasEvents(android_app->inputQueue))
   {
      AInputEvent* event = NULL;
      AInputQueue_getEvent(android_app->inputQueue, &event);

      if (AInputQueue_preDispatchEvent(android_app->inputQueue, event))
         continue;

      int32_t handled = 1;

      int source = AInputEvent_getSource(event);
      int id = AInputEvent_getDeviceId(event);

      int type_event = AInputEvent_getType(event);
      int state_id = state_device_ids[id];

      if(state_id == -1)
         state_id = state_device_ids[id] = pads_connected++;

      int action = 0;
#ifdef RARCH_INPUT_DEBUG
      char msg[128];
#endif

      if(type_event == AINPUT_EVENT_TYPE_MOTION)
      {
         action = AMotionEvent_getAction(event);
         int8_t motion_action = action & AMOTION_EVENT_ACTION_MASK;
         size_t motion_pointer = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

         float x = AMotionEvent_getX(event, motion_pointer);
         float y = AMotionEvent_getY(event, motion_pointer);

         if(source & ~(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))
         {
            state[state_id] &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) |
                  (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
            state[state_id] |= PRESSED_LEFT(x, y)  ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)  : 0;
            state[state_id] |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
            state[state_id] |= PRESSED_UP(x, y)    ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP)    : 0;
            state[state_id] |= PRESSED_DOWN(x, y)  ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)  : 0;
         }
         else
         {
            bool mouse_is_not_dirty = (source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN);
            bool pointer_is_not_dirty = (action == AMOTION_EVENT_ACTION_UP ||
                  action == AMOTION_EVENT_ACTION_CANCEL || action == AMOTION_EVENT_ACTION_POINTER_UP);

            pointer_dirty = !(mouse_is_not_dirty || pointer_is_not_dirty);

            if (pointer_dirty)
               input_translate_coord_viewport(x, y, &pointer_x, &pointer_y);
         }
#ifdef RARCH_INPUT_DEBUG
         snprintf(msg, sizeof(msg), "Pad %d : x = %.2f, y = %.2f, src %d.\n", state_id, x, y, source);
#endif
      }
      else
      {
Exemple #27
0
int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, ActivityStates* states)
{
    int32_t device = AInputEvent_getSource(_event);
    int32_t action = AMotionEvent_getAction(_event);

    int index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
    int id = AMotionEvent_getPointerId(_event, index);

    float x = AMotionEvent_getX(_event, index);
    float y = AMotionEvent_getY(_event, index);

    Event event;

    if (isDown)
    {
        if (device == AINPUT_SOURCE_MOUSE)
        {
            event.type = Event::MouseButtonPressed;
            event.mouseButton.button = static_cast<Mouse::Button>(id);
            event.mouseButton.x = x;
            event.mouseButton.y = y;

            if (id >= 0 && id < Mouse::ButtonCount)
                states->isButtonPressed[id] = true;
        }
        else if (device & AINPUT_SOURCE_TOUCHSCREEN)
        {
            event.type = Event::TouchBegan;
            event.touch.finger = id;
            event.touch.x = x;
            event.touch.y = y;

            states->touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
        }
    }
    else
    {
        if (device == AINPUT_SOURCE_MOUSE)
        {
            event.type = Event::MouseButtonReleased;
            event.mouseButton.button = static_cast<Mouse::Button>(id);
            event.mouseButton.x = x;
            event.mouseButton.y = y;

            if (id >= 0 && id < Mouse::ButtonCount)
                states->isButtonPressed[id] = false;
        }
        else if (device & AINPUT_SOURCE_TOUCHSCREEN)
        {
            event.type = Event::TouchEnded;
            event.touch.finger = id;
            event.touch.x = x;
            event.touch.y = y;

            states->touchEvents.erase(id);
        }
    }

    forwardEvent(event);
    return 1;
}
Exemple #28
0
int Engine::handleInput(AInputEvent* event)
{
    //We only handle motion events (touchscreen) and key (button/key) events
	int32_t eventType = AInputEvent_getType(event);

	if (eventType == AINPUT_EVENT_TYPE_MOTION)
	{
		int32_t edgeFlags = AMotionEvent_getEdgeFlags(event);

		if(edgeFlags == AMOTION_EVENT_EDGE_FLAG_NONE)
		{
    		//The current motion event (touch) is within screen bounds
			int32_t action = AMOTION_EVENT_ACTION_MASK &
        					 AMotionEvent_getAction((const AInputEvent*)event);
    		int32_t iX = AMotionEvent_getX(event, 0);
    		int32_t iY = AMotionEvent_getY(event, 0);

			if (checkUIHandledMotion(iX, iY, action))
				return 0;

			if (AMOTION_EVENT_ACTION_UP == action)
			{
        		mGlobeApp->pauseAnim(false);
        		mLastX = mEgl.getWidth() / 2;
        		mLastY = mEgl.getHeight() / 2;
			}
			else if (AMOTION_EVENT_ACTION_DOWN == action)
			{
				mGlobeApp->pauseAnim(true);
				mLastX = iX;
				mLastY = iY;
			}
			else if (AMOTION_EVENT_ACTION_MOVE == action)
			{
				// Empirical value (how many degrees to rotate when dragging finger on screen so
				// it looks like finger is "anchored"
				const static float DEGS_PER_PIXEL_DRAG = 0.25f;

        		float fRotX = (float)(iY - mLastY) *
        						DEGS_PER_PIXEL_DRAG;
				float fRotY = (float)(iX - mLastX) *
        						DEGS_PER_PIXEL_DRAG;
				mGlobeApp->addRotation(fRotX, fRotY);
				mGlobeApp->positionCamera();
				mLastX = iX;
				mLastY = iY;
			}

			return 1;
		}
		else // if(edgeFlags == AMOTION_EVENT_EDGE_FLAG_NONE)
		{
    		//The current motion event (touch) has reached an edge.
    		//We process it the same way as if we were touching and we had lifted
    		//the finger off the screen
			mGlobeApp->pauseAnim(false);
			mLastX = mEgl.getWidth() / 2;
			mLastY = mEgl.getHeight() / 2;

    		return 1;
		}
	} else if (eventType == AINPUT_EVENT_TYPE_KEY) {
		int32_t action = AKeyEvent_getAction((const AInputEvent*)event);
		int32_t code = AKeyEvent_getKeyCode((const AInputEvent*)event);

		int returnCode = 1;
		// pass to the on-screen UI, which will return what our "handled" code should be
		// or will return false to us, which indicates that the UI is allowing default
		// behavior for the key
		if (checkUIHandledKey(code, action, returnCode))
			return returnCode;
	}

    return 0;
}
static int32_t _onInputEvent(struct android_app* app, AInputEvent* event)
{
    if (!event || !::g_defaultWindow.get())
    {
        return 1;
    }

    int32_t source = AInputEvent_getSource(event);

    if (source == AINPUT_SOURCE_MOUSE)
    {
        int32_t x = (int32_t)AMotionEvent_getX(event, 0);
        int32_t y = (int32_t)AMotionEvent_getY(event, 0);

        g_defaultWindow->getMouseInput().setLocation(glm::ivec2(x, y));


        int32_t buttonState = AMotionEvent_getButtonState(event);

        g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_LEFT, buttonState & AMOTION_EVENT_BUTTON_PRIMARY);
        g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_RIGHT, buttonState & AMOTION_EVENT_BUTTON_SECONDARY);
        g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_MIDDLE, buttonState & AMOTION_EVENT_BUTTON_TERTIARY);


        int32_t vscroll = (int32_t)AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_VSCROLL, 0);

        g_defaultWindow->getMouseInput().setMouseWheel(vscroll);

        return 1;
    }
    else if (source == AINPUT_SOURCE_KEYBOARD)
    {
        VkBool32 pressed = (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN);

        int32_t scanCode = AKeyEvent_getScanCode(event);

        int32_t key = vkts::_visualTranslateKey(scanCode);

        if (pressed && key == VKTS_KEY_ESCAPE)
        {
            g_app->destroyRequested = 1;
        }
        else if (key != VKTS_KEY_UNKNOWN)
        {
            g_defaultWindow->getKeyInput().setKey(key, pressed);
        }

        return 1;
    }
    else if (source == AINPUT_SOURCE_JOYSTICK)
    {
        int32_t pointerIndex = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

        if (pointerIndex >= 0 && pointerIndex < VKTS_MAX_GAMEPADS)
        {
            for (int32_t axis = AMOTION_EVENT_AXIS_X; axis <= AMOTION_EVENT_AXIS_RTRIGGER; axis++)
            {
                int32_t axisIndex = -1;

                float axisValue = AMotionEvent_getAxisValue(event, axis, pointerIndex);

                switch (axis)
                {
                    case AMOTION_EVENT_AXIS_X:
                        axisIndex = VKTS_GAMEPAD_LEFT_STICK_X;
                        break;
                    case AMOTION_EVENT_AXIS_Y:
                        axisIndex = VKTS_GAMEPAD_LEFT_STICK_Y;
                        axisValue = -axisValue;
                        break;
                    case AMOTION_EVENT_AXIS_Z:
                        axisIndex = VKTS_GAMEPAD_RIGHT_STICK_X;
                        break;
                    case AMOTION_EVENT_AXIS_RZ:
                        axisIndex = VKTS_GAMEPAD_RIGHT_STICK_Y;
                        axisValue = -axisValue;
                        break;
                    case AMOTION_EVENT_AXIS_LTRIGGER:
                        axisIndex = VKTS_GAMEPAD_LEFT_TRIGGER;
                        break;
                    case AMOTION_EVENT_AXIS_RTRIGGER:
                        axisIndex = VKTS_GAMEPAD_RIGHT_TRIGGER;
                        break;
                    case AMOTION_EVENT_AXIS_HAT_X:
                    {
                        VkBool32 buttonPressed = axisValue < 0.0f ? VK_TRUE : VK_FALSE;

                        g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_LEFT, buttonPressed);

                        buttonPressed = axisValue > 0.0f ? VK_TRUE : VK_FALSE;

                        g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_RIGHT, buttonPressed);
                    }
                    break;
                    case AMOTION_EVENT_AXIS_HAT_Y:
                    {
                        VkBool32 buttonPressed = axisValue > 0.0f ? VK_TRUE : VK_FALSE;

                        g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_DOWN, buttonPressed);

                        buttonPressed = axisValue < 0.0f ? VK_TRUE : VK_FALSE;

                        g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_UP, buttonPressed);
                    }
                    break;
                }

                if (axisIndex == -1)
                {
                    continue;
                }

                g_defaultWindow->getGamepadInput(pointerIndex).setAxis(axisIndex, axisValue);
            }
        }

        return 1;
    }
Exemple #30
0
int Engine::handleInput(AInputEvent* event)
{
	if( !event )
		return 0;
    //We only handle motion events (touchscreen) and key (button/key) events
	int32_t eventType = AInputEvent_getType(event);
	if (eventType == AINPUT_EVENT_TYPE_MOTION)
	{
		int32_t actionUnmasked = AMotionEvent_getAction(event);
		int32_t action = (actionUnmasked & AMOTION_EVENT_ACTION_MASK);	
		static int	l_siIgnoreTime = 0;
		bool	l_bTouch = false;
		if(AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN || AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_MULTIPLE )
		{
			l_bTouch = true;
		}
		if( cGameApp::m_sbGamePause )
			l_siIgnoreTime = 1;
		if( g_pAndroidTestApp && !cGameApp::m_sbGamePause && l_siIgnoreTime == 0 )
		{
			if(g_pAndroidTestApp->m_sbDoMultiTouch)
			{
				int numEvents = AMotionEvent_getPointerCount(event);
				for (int index=0; index<numEvents; index++)
				{
					int		id = AMotionEvent_getPointerId(event, index);
					float	l_fPosX = AMotionEvent_getX(event, index);
					float	l_fPosY = AMotionEvent_getY(event, index);
					float	l_fpressure = AMotionEvent_getPressure(event, index);
					float	l_fSize =AMotionEvent_getSize(event, index);
					g_pAndroidTestApp->m_spMultiTouchPoints->Touch(l_bTouch,(int)l_fPosX,(int)l_fPosY,id);
					g_pAndroidTestApp->TouchSignalProcess(l_fPosX,l_fPosY,l_bTouch);
				}
				g_pAndroidTestApp->m_spMultiTouchPoints->Update(0);
			}
			else
			{
				int32_t iX = AMotionEvent_getX(event, 0);
				int32_t iY = AMotionEvent_getY(event, 0);
				g_pAndroidTestApp->TouchSignalProcess(iX,iY,l_bTouch);
			}
		}
		if( l_siIgnoreTime > 0 )
		{
			if( l_bTouch == false )
				l_siIgnoreTime = 0;
		}

		//int32_t action = AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction((const AInputEvent*)event);
		// A tap on the screen takes us out of autopause into gameplay mode if
		// we were paused.  No other touch processing is done.
		if (action == AMOTION_EVENT_ACTION_DOWN)
		{
			setGameplayMode(true);
			g_pAndroidTestApp->m_spMultiTouchPoints->Init();
		}
		//,
		return 1;
	} 
	else
	if (eventType == AINPUT_EVENT_TYPE_KEY) 
	{
		int32_t code = AKeyEvent_getKeyCode((const AInputEvent*)event);
		int32_t action = AKeyEvent_getAction((const AInputEvent*)event);

		// if we are in gameplay mode, we eat the back button and move into
		// pause mode.  If we are already in pause mode, we allow the back
		// button to be handled by the OS, which means we'll be shut down
		if ((code == AKEYCODE_BACK) && mGameplayMode)
		{
			setGameplayMode(false);
			return 1;
		}

		std::string	l_strDebugInfo = "Code:";
		l_strDebugInfo += ValueToString(code);
		l_strDebugInfo += "___Action";
		l_strDebugInfo += ValueToString(action);
		cGameApp::OutputDebugInfoString(l_strDebugInfo);

		bool	l_bVaildKey = false;
		bool	l_bKeyDown = action==0?true:false;
		if((code >= AKEYCODE_A && code <= AKEYCODE_Z))
		{//windows 65-90
			code -= AKEYCODE_A;
			code += 65;
			l_bVaildKey = true;
		}
		else
		if((code >= AKEYCODE_0 && code <= AKEYCODE_9))
		{//windows 45-97
			code -= AKEYCODE_0;
			code += 45;
			l_bVaildKey = true;
		}
		if( l_bVaildKey )
		{
			if( l_bKeyDown )
			{
				g_pAndroidTestApp->KeyDown((char)code);
			}
			else
			{
				g_pAndroidTestApp->KeyUp((char)code);
			}
		}
	}

    return 0;
}