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;
	}
예제 #2
0
/**
 * 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;
}