Beispiel #1
0
static void process_input(struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        
        // HACK: Override back buttom to show / hide keyboard.
        int type = AInputEvent_getType(event);
        if(type == AINPUT_EVENT_TYPE_KEY) {
            if(AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) {
                static bool keyboard_shown = false;
                if( AKeyEvent_getKeyCode(event) == AKEYCODE_BACK ) {
                    displayKeyboard(app,!keyboard_shown);
                    keyboard_shown = !keyboard_shown;
                    AInputQueue_finishEvent(app->inputQueue, event, 1);
                    return;
                }
            }
        }    
        
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            return;
        }
        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
    } else {
        LOGE("Failure reading next input event: %s\n", strerror(errno));
    }
}
Beispiel #2
0
void StAndroidGlue::processInput() {
    for(AInputEvent* anEvent = NULL; AInputQueue_getEvent(myInputQueue, &anEvent) >= 0;) {
        if(AInputQueue_preDispatchEvent(myInputQueue, anEvent)) {
            continue;
        }

        bool isHandled = false;
        signals.onInputEvent(anEvent, isHandled);
        AInputQueue_finishEvent(myInputQueue, anEvent, isHandled ? 1 : 0);
    }
}
// Fix per Google for bug https://code.google.com/p/android/issues/detail?id=41755
static void process_input(struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            continue;
        }
        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
    }
}
Beispiel #4
0
void cxAndroid::cxAndroidInputExec(cxAndroid *app, AndroidPollSource *source)
{
    AInputEvent* event = NULL;
    while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            continue;
        }
        int32_t handled = app->HandleInput(event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
    }
}
static void process_input(struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            return;
        }
        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
    } else {
        LOGW("Failure reading next input event: %s\n", strerror(errno));
    }
}
Beispiel #6
0
// copied from new android_native_app_glue.c
static void process_input(struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    int processed = 0;
    while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            continue;
        }
        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
        processed = 1;
    }
    if (processed == 0) {
        CXBMCApp::android_printf("process_input: Failure reading next input event: %s", strerror(errno));
    }
}
Beispiel #7
0
static void process_input(struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    int processed = 0;
    while (AInputQueue_hasEvents( app->inputQueue ) && AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        LOGV("New input event: type=%d\n", AInputEvent_getType(event));
        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            continue;
        }
        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
        processed = 1;
    }
    if (processed == 0) {
        LOGE("Failure reading next input event: %s\n", strerror(errno));
    }
}
Beispiel #8
0
static void Sys_Android_ProcessInput( struct android_app *app, struct android_poll_source *source )
{
	AInputEvent *event = NULL;
	int32_t handled;

	while( AInputQueue_getEvent( app->inputQueue, &event ) >= 0 )
	{
		// Instead of calling AInputQueue_preDispatchEvent which hangs the whole engine on API 17 and lower,
		// let onInputEvent hide the IME using JNI.
		handled = 0;
		if( app->onInputEvent )
			handled = app->onInputEvent( app, event );
		if( ( AInputEvent_getType( event ) == AINPUT_EVENT_TYPE_KEY ) && ( AKeyEvent_getKeyCode( event ) == AKEYCODE_BACK ) )
			handled = 1;
		AInputQueue_finishEvent( app->inputQueue, event, handled );
	}
}
	event_result message_dispatcher::dispatch_message(app& the_app)
	{
		if (true) {
			scoped_lock lock(m_mutex);
			if (!m_iqueue || !m_looper)
				return event_result::unhandled;
		}

		int fd, events, ident;
		void *data;

		ident = ALooper_pollOnce(m_ticker.paused() ? -1 : 0, &fd, &events, &data);

		if (ident == MSG_ID_SYSTEM) {
			system_event se;
			read(fd, &se, sizeof(se));
			if (se & system_event::synchronous) {
				return fire_on_syncevent(the_app, se);
			} else {
				return fire_on_asyncevent(the_app, se);
			}
		} else if (ident == MSG_ID_INPUT) {
			scoped_lock lock(m_mutex);
			AInputEvent *ie = NULL;
			if (AInputQueue_getEvent(m_iqueue, &ie) < 0)
				return event_result::unhandled;
			if (AInputQueue_preDispatchEvent(m_iqueue, ie))
				return event_result::handled;
			event_result result = event_result::unhandled;
			if (is_key_message(ie)) {
				result = fire_on_key(the_app, ie);
			} else if (is_motion_message(ie)) {
				result = fire_on_motion(the_app, ie);
			} else if (is_dpad_message(ie)) {
				result = fire_on_dpad(the_app, ie);
			} else if (is_external_event(ie)) {
				result = fire_on_external(the_app, ie);
			}
			AInputQueue_finishEvent(m_iqueue, ie, result == event_result::handled ? 1 : 0);
			return result;
		}

		return event_result::unhandled;
	}
Beispiel #10
0
int WindowImplAndroid::processEvent(int fd, int events, void* data)
{
    ActivityStates* states = getActivity(NULL);
    Lock lock(states->mutex);

    AInputEvent* _event = NULL;

    if (AInputQueue_getEvent(states->inputQueue, &_event) >= 0)
    {
        if (AInputQueue_preDispatchEvent(states->inputQueue, _event))
            return 1;

        int handled = 0;

        int32_t type = AInputEvent_getType(_event);

        if (type == AINPUT_EVENT_TYPE_KEY)
        {
            int32_t action = AKeyEvent_getAction(_event);
            int32_t key = AKeyEvent_getKeyCode(_event);

            if ((action == AKEY_EVENT_ACTION_DOWN || action == AKEY_EVENT_ACTION_UP || action == AKEY_EVENT_ACTION_MULTIPLE) &&
                key != AKEYCODE_VOLUME_UP && key != AKEYCODE_VOLUME_DOWN)
            {
                handled = processKeyEvent(_event, states);
            }
        }
        else if (type == AINPUT_EVENT_TYPE_MOTION)
        {
            int32_t action = AMotionEvent_getAction(_event);

            switch (action & AMOTION_EVENT_ACTION_MASK)
            {
                case AMOTION_EVENT_ACTION_SCROLL:
                {
                    handled = processScrollEvent(_event, states);
                    break;
                }

                // todo: should hover_move indeed trigger the event?
                // case AMOTION_EVENT_ACTION_HOVER_MOVE:
                case AMOTION_EVENT_ACTION_MOVE:
                {
                    handled = processMotionEvent(_event, states);
                    break;
                }

                // todo: investigate AMOTION_EVENT_OUTSIDE
                case AMOTION_EVENT_ACTION_POINTER_DOWN:
                case AMOTION_EVENT_ACTION_DOWN:
                {
                    handled = processPointerEvent(true, _event, states);
                    break;
                }

                case AMOTION_EVENT_ACTION_POINTER_UP:
                case AMOTION_EVENT_ACTION_UP:
                case AMOTION_EVENT_ACTION_CANCEL:
                {
                    handled = processPointerEvent(false, _event, states);
                    break;
                }
            }

        }

        AInputQueue_finishEvent(states->inputQueue, _event, handled);
    }

    return 1;
}
Beispiel #11
0
void RenderThread::run (void)
{
	// Init state
	m_windowState	= WINDOWSTATE_NOT_CREATED;
	m_paused		= true;
	m_finish		= false;

	try
	{
		while (!m_finish)
		{
			if (m_paused || m_windowState != WINDOWSTATE_READY)
			{
				// Block until we are not paused and window is ready.
				Message msg = m_msgQueue.popBack();
				processMessage(msg);
				continue;
			}

			// Process available commands
			{
				Message msg;
				if (m_msgQueue.tryPopBack(msg))
				{
					processMessage(msg);
					continue;
				}
			}

			DE_ASSERT(m_windowState == WINDOWSTATE_READY);

			// Process input events.
			// \todo [2013-05-08 pyry] What if system fills up the input queue before we have window ready?
			while (m_inputQueue &&
				   AInputQueue_hasEvents(m_inputQueue) > 0)
			{
				AInputEvent* event;
				TCU_CHECK(AInputQueue_getEvent(m_inputQueue, &event) >= 0);
				onInputEvent(event);
				AInputQueue_finishEvent(m_inputQueue, event, 1);
			}

			// Everything set up - safe to render.
			if (!render())
			{
				DBG_PRINT(("RenderThread::run(): render\n"));
				break;
			}
		}
	}
	catch (const std::exception& e)
	{
		print("RenderThread: %s\n", e.what());
	}

	// Tell activity to finish.
	DBG_PRINT(("RenderThread::run(): done, waiting for FINISH\n"));
	m_activity.finish();

	// Thread must keep draining message queue until FINISH message is encountered.
	try
	{
		while (!m_finish)
		{
			Message msg = m_msgQueue.popBack();

			// Ignore all but SYNC and FINISH messages.
			if (msg.type == MESSAGE_SYNC || msg.type == MESSAGE_FINISH)
				processMessage(msg);
		}
	}
	catch (const std::exception& e)
	{
		die("RenderThread: %s\n", e.what());
	}

	DBG_PRINT(("RenderThread::run(): exiting...\n"));
}
Beispiel #12
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)
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
      {