Пример #1
0
void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
{
   int i;
   unsigned state, key;
   uint16_t mod = 0;
   uint32_t chars[32] = {0};

   bool down     = event->type == KeyPress;
   int num       = 0;
   KeySym keysym = 0;

   if (down && !filter)
   {
      char keybuf[32] = {0};
#ifdef X_HAVE_UTF8_STRING
      Status status = 0;

      /* XwcLookupString doesn't seem to work. */
      num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status);

      /* libc functions need UTF-8 locale to work properly, 
       * which makes mbrtowc a bit impractical.
       *
       * Use custom UTF8 -> UTF-32 conversion. */
      num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num);
#else
      (void)ic;
      num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */
      for (i = 0; i < num; i++)
         chars[i] = keybuf[i] & 0x7f;
#endif
   }

   key   = input_keymaps_translate_keysym_to_rk(keysym);
   state = event->xkey.state;

   if (state & ShiftMask)
      mod |= RETROKMOD_SHIFT;
   if (state & LockMask)
      mod |= RETROKMOD_CAPSLOCK;
   if (state & ControlMask)
      mod |= RETROKMOD_CTRL;
   if (state & Mod1Mask)
      mod |= RETROKMOD_ALT;
   if (state & Mod4Mask)
      mod |= RETROKMOD_META;
   if (IsKeypadKey(keysym))
      mod |= RETROKMOD_NUMLOCK;

   input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD);

   for (i = 1; i < num; i++)
      input_keyboard_event(down, RETROK_UNKNOWN,
            chars[i], mod, RETRO_DEVICE_KEYBOARD);
}
Пример #2
0
/* FIXME: Don't handle composed and dead-keys properly. 
 * Waiting for support in libxkbcommon ... */
int handle_xkb(int code, int value)
{
   unsigned i;
   const xkb_keysym_t *syms = NULL;
   unsigned num_syms        = 0;
   uint16_t mod             = 0;
   /* Convert Linux evdev to X11 (xkbcommon docs say so at least ...) */
   int xk_code              = code + 8;

   if (!xkb_state)
      return -1;

   if (value == 2) /* Repeat, release first explicitly. */
      xkb_state_update_key(xkb_state, xk_code, XKB_KEY_UP);

   if (value)
      num_syms = xkb_state_key_get_syms(xkb_state, xk_code, &syms);

   if (value > 0)
      xkb_state_update_key(xkb_state, xk_code, XKB_KEY_DOWN);
   else
      xkb_state_update_key(xkb_state, xk_code, XKB_KEY_UP);

   if (!syms)
      return -1;

   /* Build mod state. */
   for (i = 0; i < MOD_MAP_SIZE; i++)
   {
      xkb_mod_index_t *map_idx = (xkb_mod_index_t*)&mod_map_idx[i];
      uint16_t        *map_bit = (uint16_t       *)&mod_map_bit[i];

      if (*map_idx != XKB_MOD_INVALID)
         mod |= xkb_state_mod_index_is_active(
               xkb_state, *map_idx,
               (enum xkb_state_component)
               ((XKB_STATE_MODS_EFFECTIVE) > 0)) ? *map_bit : 0;
   }

   input_keyboard_event(value, input_keymaps_translate_keysym_to_rk(code),
         num_syms ? xkb_keysym_to_utf32(syms[0]) : 0, mod, RETRO_DEVICE_KEYBOARD);

   for (i = 1; i < num_syms; i++)
      input_keyboard_event(value, RETROK_UNKNOWN,
            xkb_keysym_to_utf32(syms[i]), mod, RETRO_DEVICE_KEYBOARD);

   return 0;
}
Пример #3
0
static void keyboard_handle_key(void *data,
      struct wl_keyboard *keyboard,
      uint32_t serial,
      uint32_t time,
      uint32_t key,
      uint32_t state)
{
   (void)serial;
   (void)time;
   (void)keyboard;

   int value = 1;
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
   if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
   {
      BIT_SET(wl->input.key_state, key);
      value = 1;
   }
   else if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
   {
      BIT_CLEAR(wl->input.key_state, key);
      value = 0;
   }

#ifdef HAVE_XKBCOMMON
   if (handle_xkb(key, value) == 0)
      return;
#endif
   input_keyboard_event(value,
         rarch_keysym_lut[key],
         0, 0, RETRO_DEVICE_KEYBOARD);
}
Пример #4
0
void udev_handle_keyboard(void *data,
      const struct input_event *event, udev_input_device_t *dev)
{
   bool key_handled = false;

   switch (event->type)
   {
      case EV_KEY:
         if (event->value)
            BIT_SET(udev_key_state, event->code);
         else
            BIT_CLEAR(udev_key_state, event->code);

#ifdef HAVE_XKBCOMMON
         if (handle_xkb(event->code, event->value) == 0)
            return;
#endif

         input_keyboard_event(event->value,
               input_keymaps_translate_keysym_to_rk(event->code),
               0, 0, RETRO_DEVICE_KEYBOARD);
         break;

      default:
         break;
   }
}
Пример #5
0
void kb_key_callback(KBDKeyEvent *key)
{
   uint16_t mod        = 0;
   unsigned code       = 0;
   bool pressed        = false;

   if (key->state > 0)
      pressed = true;

   code                = input_keymaps_translate_keysym_to_rk(key->scancode);
   if (code < RETROK_LAST)
      keyboardState[code] = pressed;


   if (key->modifier & KBD_WIIU_SHIFT)
      mod |= RETROKMOD_SHIFT;

   if (key->modifier & KBD_WIIU_CTRL)
      mod |= RETROKMOD_CTRL;

   if (key->modifier & KBD_WIIU_ALT)
      mod |= RETROKMOD_ALT;

   if (key->modifier & KBD_WIIU_NUM_LOCK)
      mod |= RETROKMOD_NUMLOCK;

   if (key->modifier & KBD_WIIU_CAPS_LOCK)
      mod |= RETROKMOD_CAPSLOCK;

   if (key->modifier & KBD_WIIU_SCROLL_LOCK)
      mod |= RETROKMOD_SCROLLOCK;

   input_keyboard_event(pressed, code, (char)key->UTF16, mod,
         RETRO_DEVICE_KEYBOARD);
}
Пример #6
0
static void qnx_process_keyboard_event(
      qnx_input_t *qnx,
      screen_event_t event, int type)
{
    // Get key properties from screen event
    int flags = 0;
    screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);

    int cap = 0;
    screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);

    int mod = 0;
    screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);

    // Calculate state
    unsigned keycode = input_keymaps_translate_keysym_to_rk(cap);
    bool keydown = flags & KEY_DOWN;
    bool keyrepeat = flags & KEY_REPEAT;

    // Fire keyboard event
    if(!keyrepeat)
    {
        input_keyboard_event(keydown, keycode, 0, mod, RETRO_DEVICE_KEYBOARD);
    }

    // Apply keyboard state
    if(keydown && !keyrepeat)
    {
       BIT_SET(qnx->keyboard_state, cap);
    }
    else if(!keydown && !keyrepeat)
    {
       BIT_CLEAR(qnx->keyboard_state, cap);
    }
}
Пример #7
0
void apple_input_keyboard_event(bool down,
      unsigned code, uint32_t character, uint32_t mod, unsigned device)
{
#if TARGET_OS_IPHONE
   settings_t *settings = config_get_ptr();
#endif

   code = HIDKEY(code);

#if TARGET_OS_IPHONE
   if (settings->input.keyboard_gamepad_enable)
   {
      if (handle_icade_event(&code, &down))
         character = 0;
      else
         code      = 0;
   }
   else if (settings->input.small_keyboard_enable)
   {
      if (handle_small_keyboard(&code, down))
         character = 0;
   }
#endif

   if (code == 0 || code >= MAX_KEYS)
      return;

   apple_key_state[code] = down;

   input_keyboard_event(down,
         input_keymaps_translate_keysym_to_rk(code),
         character, (enum retro_mod)mod, device);
}
Пример #8
0
void apple_input_keyboard_event(bool down,
      unsigned code, uint32_t character, uint32_t mod, unsigned device)
{
   driver_t *driver = driver_get_ptr();
   apple_input_data_t *apple = (apple_input_data_t*)driver->input_data;

   if (!apple)
      return;

   code = HIDKEY(code);

   if (apple->icade_enabled)
   {
      handle_icade_event(code);
      return;
   }

   if (apple->small_keyboard_enabled && 
      handle_small_keyboard(&code, down))
      character = 0;
   
   if (code == 0 || code >= MAX_KEYS)
      return;

   apple->key_state[code] = down;
    
   input_keyboard_event(down,
         input_keymaps_translate_keysym_to_rk(code),
         character, (enum retro_mod)mod, device);
}
Пример #9
0
void apple_input_keyboard_event(bool down,
      unsigned code, uint32_t character, uint32_t mod)
{
   apple_input_data_t *apple = (apple_input_data_t*)driver.input_data;
   enum retro_mod mods = RETROKMOD_NONE;

   code = HIDKEY(code);

   if (icade_enabled)
   {
      handle_icade_event(code);
      return;
   }

   if (small_keyboard_enabled && handle_small_keyboard(&code, down))
      character = 0;
   
   if (code == 0 || code >= MAX_KEYS)
      return;

   if (apple)
      apple->key_state[code] = down;

   mods |= (mod & NSAlphaShiftKeyMask) ? RETROKMOD_CAPSLOCK : 0;
   mods |= (mod & NSShiftKeyMask)      ? RETROKMOD_SHIFT : 0;
   mods |= (mod & NSControlKeyMask)    ? RETROKMOD_CTRL : 0;
   mods |= (mod & NSAlternateKeyMask)  ? RETROKMOD_ALT : 0;
   mods |= (mod & NSCommandKeyMask)    ? RETROKMOD_META : 0;
   mods |= (mod & NSNumericPadKeyMask) ? RETROKMOD_NUMLOCK : 0;

   input_keyboard_event(down,
         input_translate_keysym_to_rk(code), character, mods);
}
Пример #10
0
void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
{
   int i;
   char keybuf[32] = {0};
   uint32_t chars[32] = {0};

   bool down    = event->type == KeyPress;
   unsigned key = input_translate_keysym_to_rk(XLookupKeysym(&event->xkey, 0));
   int num      = 0;

   if (down && !filter)
   {
      KeySym keysym = 0;

#ifdef X_HAVE_UTF8_STRING
      Status status = 0;

      // XwcLookupString doesn't seem to work.
      num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status);

      // libc functions need UTF-8 locale to work properly, which makes mbrtowc a bit impractical.
      // Use custom utf8 -> UTF-32 conversion.
      num = conv_utf8_utf32(chars, ARRAY_SIZE(chars), keybuf, num);
#else
      (void)ic;
      num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); // ASCII only.
      for (i = 0; i < num; i++)
         chars[i] = keybuf[i] & 0x7f;
#endif
   }

   unsigned state = event->xkey.state;
   uint16_t mod = 0;
   mod |= (state & ShiftMask) ? RETROKMOD_SHIFT : 0;
   mod |= (state & LockMask) ? RETROKMOD_CAPSLOCK : 0;
   mod |= (state & ControlMask) ? RETROKMOD_CTRL : 0;
   mod |= (state & Mod1Mask) ? RETROKMOD_ALT : 0;
   mod |= (state & Mod4Mask) ? RETROKMOD_META : 0;

   input_keyboard_event(down, key, chars[0], mod);
   for (i = 1; i < num; i++)
      input_keyboard_event(down, RETROK_UNKNOWN, chars[i], mod);
}
Пример #11
0
static void qnx_process_joystick_event(qnx_input_t *qnx, screen_event_t screen_event, int type)
{
    int displacement[2];
    screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_DISPLACEMENT, displacement);

    if(displacement != 0)
    {
        qnx->trackpad_acc[0] += displacement[0];
        if(abs(qnx->trackpad_acc[0]) > TRACKPAD_THRESHOLD)
        {
            if(qnx->trackpad_acc < 0)
            {
                input_keyboard_event(true, RETROK_LEFT, 0, 0, RETRO_DEVICE_KEYBOARD);
                input_keyboard_event(false, RETROK_LEFT, 0, 0, RETRO_DEVICE_KEYBOARD);
            }
            else if(qnx->trackpad_acc > 0)
            {
                input_keyboard_event(true, RETROK_RIGHT, 0, 0, RETRO_DEVICE_KEYBOARD);
                input_keyboard_event(false, RETROK_RIGHT, 0, 0, RETRO_DEVICE_KEYBOARD);
            }

            qnx->trackpad_acc[0] = 0;
        }

        qnx->trackpad_acc[1] += displacement[1];
        if(abs(qnx->trackpad_acc[1]) > TRACKPAD_THRESHOLD)
        {
            if(qnx->trackpad_acc < 0)
            {
                input_keyboard_event(true, RETROK_UP, 0, 0, RETRO_DEVICE_KEYBOARD);
                input_keyboard_event(false, RETROK_UP, 0, 0, RETRO_DEVICE_KEYBOARD);
            }
            else if(qnx->trackpad_acc > 0)
            {
                input_keyboard_event(true, RETROK_DOWN, 0, 0, RETRO_DEVICE_KEYBOARD);
                input_keyboard_event(false, RETROK_DOWN, 0, 0, RETRO_DEVICE_KEYBOARD);
            }

            qnx->trackpad_acc[1] = 0;
        }
    }

    int buttons = 0;
    screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons);
    input_keyboard_event(buttons != 0, RETROK_RETURN, 0, 0, RETRO_DEVICE_KEYBOARD);
}
Пример #12
0
void menu_event_osk_append(int ptr)
{
   if (ptr >= 0)
   {
      if (string_is_equal(osk_grid[ptr],"⇦"))
         input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
      else if (string_is_equal(osk_grid[ptr],"⏎"))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);
      else if (string_is_equal(osk_grid[ptr],"⇧"))
         osk_idx = OSK_UPPERCASE_LATIN;
      else if (string_is_equal(osk_grid[ptr],"⇩"))
         osk_idx = OSK_LOWERCASE_LATIN;
      else if (string_is_equal(osk_grid[ptr],"⊕"))
         if (osk_idx < OSK_TYPE_LAST - 1)
            osk_idx = (enum osk_type)(osk_idx + 1);
         else
            osk_idx = (enum osk_type)(OSK_TYPE_UNKNOWN + 1);
      else
         input_keyboard_line_append(osk_grid[ptr]);
   }
}
Пример #13
0
static void sdl_input_poll(void *data)
{
   sdl_input_t *sdl = (sdl_input_t*)data;
   SDL_Event event;

   SDL_PumpEvents();

   if (sdl->joypad)
      sdl->joypad->poll();
   sdl_poll_mouse(sdl);

#ifdef HAVE_SDL2
   while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_KEYDOWN, SDL_MOUSEWHEEL) > 0)
#else
   while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_KEYEVENTMASK) > 0)
#endif
   {
      if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP)
      {
         uint16_t mod = 0;
         unsigned code = input_keymaps_translate_keysym_to_rk(event.key.keysym.sym);

         if (event.key.keysym.mod & KMOD_SHIFT)
            mod |= RETROKMOD_SHIFT;

         if (event.key.keysym.mod & KMOD_CTRL)
            mod |= RETROKMOD_CTRL;

         if (event.key.keysym.mod & KMOD_ALT)
            mod |= RETROKMOD_ALT;

         if (event.key.keysym.mod & KMOD_NUM)
            mod |= RETROKMOD_NUMLOCK;

         if (event.key.keysym.mod & KMOD_CAPS)
            mod |= RETROKMOD_CAPSLOCK;

         input_keyboard_event(event.type == SDL_KEYDOWN, code, code, mod,
               RETRO_DEVICE_KEYBOARD);
      }
#ifdef HAVE_SDL2
      else if (event.type == SDL_MOUSEWHEEL)
      {
         sdl->mouse_wu = event.wheel.y < 0;
         sdl->mouse_wd = event.wheel.y > 0;
         sdl->mouse_wl = event.wheel.x < 0;
         sdl->mouse_wr = event.wheel.x > 0;
         break;
      }
#endif
   }
}
Пример #14
0
void apple_input_keyboard_event(bool down, unsigned code, uint32_t character, uint32_t mod)
{
   code = HIDKEY(code);

   if (icade_enabled)
   {
      handle_icade_event(code);
      return;
   }

   if (small_keyboard_enabled && handle_small_keyboard(&code, down))
      character = 0;
   
   if (code == 0 || code >= MAX_KEYS)
      return;

   g_current_input_data.keys[code] = down;
   
   /* This is copied here as it isn't defined in any standard iOS header */
   enum
   {
      NSAlphaShiftKeyMask = 1 << 16,
      NSShiftKeyMask      = 1 << 17,
      NSControlKeyMask    = 1 << 18,
      NSAlternateKeyMask  = 1 << 19,
      NSCommandKeyMask    = 1 << 20,
      NSNumericPadKeyMask = 1 << 21,
      NSHelpKeyMask       = 1 << 22,
      NSFunctionKeyMask   = 1 << 23,
      NSDeviceIndependentModifierFlagsMask = 0xffff0000U
   };

   enum retro_mod mods = RETROKMOD_NONE;
   mods |= (mod & NSAlphaShiftKeyMask) ? RETROKMOD_CAPSLOCK : 0;
   mods |= (mod & NSShiftKeyMask)      ? RETROKMOD_SHIFT : 0;
   mods |= (mod & NSControlKeyMask)    ? RETROKMOD_CTRL : 0;
   mods |= (mod & NSAlternateKeyMask)  ? RETROKMOD_ALT : 0;
   mods |= (mod & NSCommandKeyMask)    ? RETROKMOD_META : 0;
   mods |= (mod & NSNumericPadKeyMask) ? RETROKMOD_NUMLOCK : 0;

   input_keyboard_event(down, input_translate_keysym_to_rk(code), character, mods);
}
Пример #15
0
static void rwebinput_input_poll(void *data)
{
   rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;

   rwebinput_state_t *state = RWebInputPoll(rwebinput->context);

   // get new keys
   for (unsigned i = 0; i < 32; i++)
   {
      if (state->keys[i] != rwebinput->state.keys[i])
      {
         uint8_t diff = state->keys[i] ^ rwebinput->state.keys[i];
         for (unsigned k = 0; diff; diff >>= 1, k++)
         {
            if (diff & 1)
            {
               input_keyboard_event((state->keys[i] & (1 << k)) != 0, input_translate_keysym_to_rk(i * 8 + k), 0, 0);
            }
         }
      }
   }
Пример #16
0
unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_input)
{
   unsigned ret                            = MENU_ACTION_NOOP;
   static bool initial_held                = true;
   static bool first_held                  = false;
   static const retro_input_t input_repeat =
        (1UL << RETRO_DEVICE_ID_JOYPAD_UP)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_DOWN)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_LEFT)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_RIGHT)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_L)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_R);
   menu_navigation_t *nav      = menu_navigation_get_ptr();
   menu_handle_t *menu         = menu_driver_get_ptr();
   menu_display_t *disp        = menu_display_get_ptr();
   menu_input_t *menu_input    = menu_input_get_ptr();
   driver_t *driver            = driver_get_ptr();
   settings_t *settings        = config_get_ptr();

   if (!menu || !driver || !nav || !menu_input)
      return 0;

   driver->retro_ctx.poll_cb();

   /* don't run anything first frame, only capture held inputs
    * for old_input_state. */

   if (input & input_repeat)
   {
      if (!first_held)
      {
         first_held = true;
         menu_input->delay.timer = initial_held ? 12 : 6;
         menu_input->delay.count = 0;
      }

      if (menu_input->delay.count >= menu_input->delay.timer)
      {
         first_held = false;
         trigger_input |= input & input_repeat;
         nav->scroll.acceleration =
            min(nav->scroll.acceleration + 1, 64);
      }

      initial_held = false;
   }
   else
   {
      first_held = false;
      initial_held = true;
      nav->scroll.acceleration = 0;
   }

   menu_input->delay.count += menu_animation_get_delta_time(disp->animation) / IDEAL_DT;

   if (menu_input->keyboard.display)
   {
      /* send return key to close keyboard input window */
      if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      trigger_input = 0;
   }

   if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      ret = MENU_ACTION_UP;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      ret = MENU_ACTION_DOWN;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      ret = MENU_ACTION_LEFT;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      ret = MENU_ACTION_RIGHT;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_up_btn))
      ret = MENU_ACTION_SCROLL_UP;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_down_btn))
      ret = MENU_ACTION_SCROLL_DOWN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
      ret = MENU_ACTION_CANCEL;
   else if (trigger_input & (UINT64_C(1) << settings->menu_ok_btn))
      ret = MENU_ACTION_OK;
   else if (trigger_input & (UINT64_C(1) << settings->menu_search_btn))
      ret = MENU_ACTION_SEARCH;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
      ret = MENU_ACTION_SCAN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_default_btn))
      ret = MENU_ACTION_START;
   else if (trigger_input & (UINT64_C(1) << settings->menu_info_btn))
      ret = MENU_ACTION_INFO;
   else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE))
      ret = MENU_ACTION_TOGGLE;

   if (settings->menu.mouse.enable)
      menu_input_mouse(&ret);

   if (settings->menu.pointer.enable)
      menu_input_pointer(&ret);

   return ret;
}
Пример #17
0
LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message,
		WPARAM wparam, LPARAM lparam)
{
   unsigned scancode = (lparam >> 16) & 0xff;
   unsigned keycode = input_keymaps_translate_keysym_to_rk(scancode);
   uint16_t mod     = 0;
   bool keydown     = true;

   if (GetKeyState(VK_SHIFT)   & 0x80)
      mod |= RETROKMOD_SHIFT;
   if (GetKeyState(VK_CONTROL) & 0x80)
      mod |=  RETROKMOD_CTRL;
   if (GetKeyState(VK_MENU)    & 0x80)
      mod |=  RETROKMOD_ALT;
   if (GetKeyState(VK_CAPITAL) & 0x81)
      mod |= RETROKMOD_CAPSLOCK;
   if (GetKeyState(VK_SCROLL)  & 0x81)
      mod |= RETROKMOD_SCROLLOCK;
   if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
      mod |= RETROKMOD_META;

   switch (message)
   {
      /* Seems to be hard to synchronize 
       * WM_CHAR and WM_KEYDOWN properly.
       */
      case WM_CHAR:
         input_keyboard_event(keydown, RETROK_UNKNOWN, wparam, mod,
               RETRO_DEVICE_KEYBOARD);
         return TRUE;

      case WM_KEYUP:
      case WM_SYSKEYUP:
      case WM_KEYDOWN:
      case WM_SYSKEYDOWN:
         /* Key released? */
         if (message == WM_KEYUP || message == WM_SYSKEYUP)
            keydown = false;

         /* DirectInput uses scancodes directly. */
         input_keyboard_event(keydown, keycode, 0, mod,
               RETRO_DEVICE_KEYBOARD);

         if (message == WM_SYSKEYDOWN)
         {
            switch (wparam)
            {
               case VK_F10:
               case VK_MENU:
               case VK_RSHIFT:
                  return 0;
               default:
                  break;
            }
         }
         else
            return 0;

         break;
   }

   return DefWindowProc(hwnd, message, wparam, lparam);
}
Пример #18
0
static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
{
   int i;
   Status status;
   uint32_t chars[32];
   unsigned key   = 0;
   uint16_t mod   = 0;
   unsigned state = event->xkey.state;
   bool down      = event->type == KeyPress;
   int num        = 0;
   KeySym keysym  = 0;

   chars[0]       = '\0';

   if (!filter)
   {
      if (down)
      {
         char keybuf[32];

         keybuf[0] = '\0';
#ifdef X_HAVE_UTF8_STRING
         status = 0;

         /* XwcLookupString doesn't seem to work. */
         num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status);

         /* libc functions need UTF-8 locale to work properly,
          * which makes mbrtowc a bit impractical.
          *
          * Use custom UTF8 -> UTF-32 conversion. */
         num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num);
#else
         (void)ic;
         num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */
         for (i = 0; i < num; i++)
            chars[i] = keybuf[i] & 0x7f;
#endif
      }
      else
         keysym = XLookupKeysym(&event->xkey, (state & ShiftMask) || (state & LockMask));
   }

   /* We can't feed uppercase letters to the keycode translator. Seems like a bad idea
    * to feed it keysyms anyway, so here is a little hack... */
   if (keysym >= XK_A && keysym <= XK_Z)
       keysym += XK_z - XK_Z;

   key   = input_keymaps_translate_keysym_to_rk(keysym);

   if (state & ShiftMask)
      mod |= RETROKMOD_SHIFT;
   if (state & LockMask)
      mod |= RETROKMOD_CAPSLOCK;
   if (state & ControlMask)
      mod |= RETROKMOD_CTRL;
   if (state & Mod1Mask)
      mod |= RETROKMOD_ALT;
   if (state & Mod4Mask)
      mod |= RETROKMOD_META;
   if (IsKeypadKey(keysym))
      mod |= RETROKMOD_NUMLOCK;

   input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD);

   for (i = 1; i < num; i++)
      input_keyboard_event(down, RETROK_UNKNOWN,
            chars[i], mod, RETRO_DEVICE_KEYBOARD);
}
Пример #19
0
unsigned menu_input_frame_retropad(retro_input_t input,
      retro_input_t trigger_input)
{
   menu_animation_ctx_delta_t delta;
   float delta_time;
   static bool initial_held                = true;
   static bool first_held                  = false;
   bool set_scroll                         = false;
   size_t new_scroll_accel                 = 0;
   menu_input_t *menu_input                = menu_input_get_ptr();

   if (!menu_input)
      return 0;

   core_poll();

   /* don't run anything first frame, only capture held inputs
    * for old_input_state. */

   if (input)
   {
      if (!first_held)
      {
         first_held = true;
         menu_input->delay.timer = initial_held ? 12 : 6;
         menu_input->delay.count = 0;
      }

      if (menu_input->delay.count >= menu_input->delay.timer)
      {
         retro_input_t input_repeat = 0;
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_B);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_A);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R);

         set_scroll     = true;
         first_held     = false;
         trigger_input |= input & input_repeat;

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
               &new_scroll_accel);

         new_scroll_accel = MIN(new_scroll_accel + 1, 64);
      }

      initial_held  = false;
   }
   else
   {
      set_scroll   = true;
      first_held   = false;
      initial_held = true;
   }

   if (set_scroll)
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
            &new_scroll_accel);

   menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

   delta.current = delta_time;

   if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta))
      menu_input->delay.count += delta.ideal;

   if (menu_input->keyboard.display)
   {
      settings_t *settings = config_get_ptr();

      /* send return key to close keyboard input window */
      if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      trigger_input = 0;
   }

   return menu_input_frame_build(trigger_input);
}
Пример #20
0
/*
 * input_poll_overlay:
 * @overlay_device : pointer to overlay 
 *
 * Poll pressed buttons/keys on currently active overlay.
 **/
static INLINE void input_poll_overlay(input_overlay_t *overlay_device, float opacity)
{
   input_overlay_state_t old_key_state;
   unsigned i, j, device;
   uint16_t key_mod               = 0;
   bool polled                    = false;
   driver_t *driver               = driver_get_ptr();
   settings_t *settings           = config_get_ptr();

   if (overlay_device->state != OVERLAY_STATUS_ALIVE)
      return;

   memcpy(old_key_state.keys, driver->overlay_state.keys,
         sizeof(driver->overlay_state.keys));
   memset(&driver->overlay_state, 0, sizeof(driver->overlay_state));

   device = input_overlay_full_screen(overlay_device) ?
      RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER;

   for (i = 0;
         input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_PRESSED);
         i++)
   {
      input_overlay_state_t polled_data;
      int16_t x = input_driver_state(NULL, 0,
            device, i, RETRO_DEVICE_ID_POINTER_X);
      int16_t y = input_driver_state(NULL, 0,
            device, i, RETRO_DEVICE_ID_POINTER_Y);

      input_overlay_poll(overlay_device, &polled_data, x, y);

      driver->overlay_state.buttons |= polled_data.buttons;

      for (j = 0; j < ARRAY_SIZE(driver->overlay_state.keys); j++)
         driver->overlay_state.keys[j] |= polled_data.keys[j];

      /* Fingers pressed later take prio and matched up
       * with overlay poll priorities. */
      for (j = 0; j < 4; j++)
         if (polled_data.analog[j])
            driver->overlay_state.analog[j] = polled_data.analog[j];

      polled = true;
   }

   if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LSHIFT) ||
         OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RSHIFT))
      key_mod |= RETROKMOD_SHIFT;

   if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LCTRL) ||
    OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RCTRL))
      key_mod |= RETROKMOD_CTRL;

   if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LALT) ||
         OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RALT))
      key_mod |= RETROKMOD_ALT;

   if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LMETA) ||
         OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RMETA))
      key_mod |= RETROKMOD_META;

   /* CAPSLOCK SCROLLOCK NUMLOCK */
   for (i = 0; i < ARRAY_SIZE(driver->overlay_state.keys); i++)
   {
      if (driver->overlay_state.keys[i] != old_key_state.keys[i])
      {
         uint32_t orig_bits = old_key_state.keys[i];
         uint32_t new_bits  = driver->overlay_state.keys[i];

         for (j = 0; j < 32; j++)
            if ((orig_bits & (1 << j)) != (new_bits & (1 << j)))
               input_keyboard_event(new_bits & (1 << j),
                     i * 32 + j, 0, key_mod, RETRO_DEVICE_POINTER);
      }
   }

   /* Map "analog" buttons to analog axes like regular input drivers do. */
   for (j = 0; j < 4; j++)
   {
      unsigned bind_plus  = RARCH_ANALOG_LEFT_X_PLUS + 2 * j;
      unsigned bind_minus = bind_plus + 1;

      if (driver->overlay_state.analog[j])
         continue;

      if (driver->overlay_state.buttons & (1ULL << bind_plus))
         driver->overlay_state.analog[j] += 0x7fff;
      if (driver->overlay_state.buttons & (1ULL << bind_minus))
         driver->overlay_state.analog[j] -= 0x7fff;
   }

   /* Check for analog_dpad_mode.
    * Map analogs to d-pad buttons when configured. */
   switch (settings->input.analog_dpad_mode[0])
   {
      case ANALOG_DPAD_LSTICK:
      case ANALOG_DPAD_RSTICK:
      {
         float analog_x, analog_y;
         unsigned analog_base = 2;

         if (settings->input.analog_dpad_mode[0] == ANALOG_DPAD_LSTICK)
            analog_base = 0;

         analog_x = (float)driver->overlay_state.analog[analog_base + 0] / 0x7fff;
         analog_y = (float)driver->overlay_state.analog[analog_base + 1] / 0x7fff;

         if (analog_x <= -settings->input.axis_threshold)
            driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT);
         if (analog_x >=  settings->input.axis_threshold)
            driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT);
         if (analog_y <= -settings->input.axis_threshold)
            driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_UP);
         if (analog_y >=  settings->input.axis_threshold)
            driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN);
         break;
      }

      default:
         break;
   }

   if (polled)
      input_overlay_post_poll(overlay_device, opacity);
   else
      input_overlay_poll_clear(overlay_device, opacity);
}
Пример #21
0
unsigned menu_event(retro_input_t input,
                    retro_input_t trigger_input)
{
    menu_animation_ctx_delta_t delta;
    float delta_time;
    /* Used for key repeat */
    static float delay_timer                = 0.0f;
    static float delay_count                = 0.0f;
    unsigned ret                            = MENU_ACTION_NOOP;
    static bool initial_held                = true;
    static bool first_held                  = false;
    bool set_scroll                         = false;
    bool mouse_enabled                      = false;
    size_t new_scroll_accel                 = 0;
    menu_input_t *menu_input                = NULL;
    settings_t *settings                    = config_get_ptr();

    if (input.state)
    {
        if (!first_held)
        {
            /* don't run anything first frame, only capture held inputs
             * for old_input_state. */

            first_held  = true;
            delay_timer = initial_held ? 12 : 6;
            delay_count = 0;
        }

        if (delay_count >= delay_timer)
        {
            retro_input_t input_repeat = {0};
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_UP);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_DOWN);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_LEFT);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_RIGHT);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_B);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_A);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_L);
            BIT32_SET(input_repeat.state, RETRO_DEVICE_ID_JOYPAD_R);

            set_scroll           = true;
            first_held           = false;
            trigger_input.state |= input.state & input_repeat.state;

            menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
                                &new_scroll_accel);

            new_scroll_accel = MIN(new_scroll_accel + 1, 64);
        }

        initial_held  = false;
    }
    else
    {
        set_scroll   = true;
        first_held   = false;
        initial_held = true;
    }

    if (set_scroll)
        menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
                            &new_scroll_accel);

    menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

    delta.current = delta_time;

    if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta))
        delay_count += delta.ideal;

    if (menu_input_dialog_get_display_kb())
    {
        static unsigned ti_char = 64;
        static bool ti_next     = false;

        if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
        {
            if (ti_char > 32)
                ti_char--;
            if (! ti_next)
                input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
            input_keyboard_event(true, ti_char, ti_char, 0, RETRO_DEVICE_KEYBOARD);
            ti_next = false;
        }

        if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
        {
            if (ti_char < 125)
                ti_char++;
            if (! ti_next)
                input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
            input_keyboard_event(true, ti_char, ti_char, 0, RETRO_DEVICE_KEYBOARD);
            ti_next = false;
        }

        if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A))
        {
            ti_char = 64;
            ti_next = true;
        }

        if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B))
        {
            input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
            ti_char = 64;
            ti_next = false;
        }

        /* send return key to close keyboard input window */
        if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
            input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

        trigger_input.state = 0;
    }

    if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
        ret = MENU_ACTION_UP;
    else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
        ret = MENU_ACTION_DOWN;
    else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
        ret = MENU_ACTION_LEFT;
    else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
        ret = MENU_ACTION_RIGHT;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_scroll_up_btn))
        ret = MENU_ACTION_SCROLL_UP;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_scroll_down_btn))
        ret = MENU_ACTION_SCROLL_DOWN;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_cancel_btn))
        ret = MENU_ACTION_CANCEL;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_ok_btn))
        ret = MENU_ACTION_OK;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_search_btn))
        ret = MENU_ACTION_SEARCH;
    else if (trigger_input.state & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
        ret = MENU_ACTION_SCAN;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_default_btn))
        ret = MENU_ACTION_START;
    else if (trigger_input.state & (UINT64_C(1) << settings->menu_info_btn))
        ret = MENU_ACTION_INFO;
    else if (trigger_input.state & (UINT64_C(1) << RARCH_MENU_TOGGLE))
        ret = MENU_ACTION_TOGGLE;

    mouse_enabled                      = settings->menu.mouse.enable;
#ifdef HAVE_OVERLAY
    if (!mouse_enabled)
        mouse_enabled = !(settings->input.overlay_enable
                          && input_overlay_is_alive(NULL));
#endif

    if (!(menu_input = menu_input_get_ptr()))
        return 0;

    if (!mouse_enabled)
        menu_input->mouse.ptr = 0;

    if (settings->menu.pointer.enable)
        menu_event_pointer(&ret);
    else
        memset(&menu_input->pointer, 0, sizeof(menu_input->pointer));

    return ret;
}
Пример #22
0
unsigned menu_event(uint64_t input, uint64_t trigger_input)
{
   menu_animation_ctx_delta_t delta;
   float delta_time;
   /* Used for key repeat */
   static float delay_timer                = 0.0f;
   static float delay_count                = 0.0f;
   unsigned ret                            = MENU_ACTION_NOOP;
   static bool initial_held                = true;
   static bool first_held                  = false;
   bool set_scroll                         = false;
   bool mouse_enabled                      = false;
   size_t new_scroll_accel                 = 0;
   menu_input_t *menu_input                = NULL;
   settings_t *settings                    = config_get_ptr();
   static unsigned ok_old                  = 0;
   unsigned menu_ok_btn                    = settings->input.menu_swap_ok_cancel_buttons ?
      RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A;
   unsigned menu_cancel_btn                = settings->input.menu_swap_ok_cancel_buttons ?
      RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B;
   unsigned ok_current                     = input & UINT64_C(1) << menu_ok_btn;
   unsigned ok_trigger                     = ok_current & ~ok_old;

   ok_old     = ok_current;

   if (input)
   {
      if (!first_held)
      {
         /* don't run anything first frame, only capture held inputs
          * for old_input_state. */

         first_held  = true;
         delay_timer = initial_held ? 12 : 6;
         delay_count = 0;
      }

      if (delay_count >= delay_timer)
      {
         uint64_t input_repeat = 0;
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R);

         set_scroll           = true;
         first_held           = false;
         trigger_input |= input & input_repeat;

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
               &new_scroll_accel);

         new_scroll_accel = MIN(new_scroll_accel + 1, 64);
      }

      initial_held  = false;
   }
   else
   {
      set_scroll   = true;
      first_held   = false;
      initial_held = true;
   }

   if (set_scroll)
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
            &new_scroll_accel);

   menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

   delta.current = delta_time;

   if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta))
      delay_count += delta.ideal;

   if (menu_input_dialog_get_display_kb())
   {
      switch (osk_idx)
      {
         case OSK_HIRAGANA_PAGE1:
         {
            memcpy(osk_grid, hiragana_page1_grid, sizeof(hiragana_page1_grid));
            break;
         }
         case OSK_HIRAGANA_PAGE2:
         {
            memcpy(osk_grid, hiragana_page2_grid, sizeof(hiragana_page2_grid));
            break;
         }
         case OSK_KATAKANA_PAGE1:
         {
            memcpy(osk_grid, katakana_page1_grid, sizeof(katakana_page1_grid));
            break;
         }
         case OSK_KATAKANA_PAGE2:
         {
            memcpy(osk_grid, katakana_page2_grid, sizeof(katakana_page2_grid));
            break;
         }
         case OSK_UPPERCASE_LATIN:
         {
            memcpy(osk_grid, uppercase_grid, sizeof(uppercase_grid));
            break;
         }
         case OSK_LOWERCASE_LATIN:
         default:
         {
            memcpy(osk_grid, lowercase_grid, sizeof(lowercase_grid));
            break;
         }
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      {
         if (osk_ptr < 33)
            osk_ptr = osk_ptr + OSK_CHARS_PER_LINE;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      {
         if (osk_ptr >= OSK_CHARS_PER_LINE)
            osk_ptr = osk_ptr - OSK_CHARS_PER_LINE;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      {
         if (osk_ptr < 43)
            osk_ptr = osk_ptr + 1;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      {
         if (osk_ptr >= 1)
            osk_ptr = osk_ptr - 1;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L))
      {
         if (osk_idx > OSK_TYPE_UNKNOWN + 1)
            osk_idx = (enum osk_type)(osk_idx - 1);
         else
            osk_idx = (enum osk_type)(OSK_TYPE_LAST - 1);
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R))
      {
         if (osk_idx < OSK_TYPE_LAST - 1)
            osk_idx = (enum osk_type)(osk_idx + 1);
         else
            osk_idx = (enum osk_type)(OSK_TYPE_UNKNOWN + 1);
      }

      if (trigger_input & (UINT64_C(1) << menu_ok_btn))
      {
         if (osk_ptr >= 0)
         {
            menu_event_osk_append(osk_ptr);
         }
      }

      if (trigger_input & (UINT64_C(1) << menu_cancel_btn))
      {
         input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
      }

      /* send return key to close keyboard input window */
      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      trigger_input = 0;
      ok_trigger = 0;
   }

   if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      ret = MENU_ACTION_UP;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      ret = MENU_ACTION_DOWN;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      ret = MENU_ACTION_LEFT;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      ret = MENU_ACTION_RIGHT;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L))
      ret = MENU_ACTION_SCROLL_UP;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R))
      ret = MENU_ACTION_SCROLL_DOWN;
   else if (ok_trigger)
      ret = MENU_ACTION_OK;
   else if (trigger_input & (UINT64_C(1) << menu_cancel_btn))
      ret = MENU_ACTION_CANCEL;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X))
      ret = MENU_ACTION_SEARCH;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
      ret = MENU_ACTION_SCAN;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
      ret = MENU_ACTION_START;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT))
      ret = MENU_ACTION_INFO;
   else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE))
      ret = MENU_ACTION_TOGGLE;

   if (menu_keyboard_key_state[RETROK_F11])
   {
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);
      menu_keyboard_key_state[RETROK_F11] = false;
   }

   if (runloop_cmd_press(trigger_input, RARCH_QUIT_KEY))
      return MENU_ACTION_QUIT;

   mouse_enabled                      = settings->menu.mouse.enable;
#ifdef HAVE_OVERLAY
   if (!mouse_enabled)
      mouse_enabled = !(settings->input.overlay_enable
            && input_overlay_is_alive(overlay_ptr));
#endif

   if (!(menu_input = menu_input_get_ptr()))
      return 0;

   if (!mouse_enabled)
      menu_input->mouse.ptr = 0;

   if (settings->menu.pointer.enable)
      menu_event_pointer(&ret);
   else
   {
      menu_input->pointer.x          = 0;
      menu_input->pointer.y          = 0;
      menu_input->pointer.dx         = 0;
      menu_input->pointer.dy         = 0;
      menu_input->pointer.accel      = 0;
      menu_input->pointer.pressed[0] = false;
      menu_input->pointer.pressed[1] = false;
      menu_input->pointer.back       = false;
      menu_input->pointer.ptr        = 0;
   }

   return ret;
}
Пример #23
0
static void qnx_handle_navigator_event(
      qnx_input_t *qnx, bps_event_t *event)
{
   navigator_window_state_t state;
   bps_event_t *event_pause = NULL;

   switch (bps_event_get_code(event))
   {
      case NAVIGATOR_SYSKEY_PRESS:
         switch(navigator_event_get_syskey_key(event))
         {
            case NAVIGATOR_SYSKEY_BACK:
               input_keyboard_event(true, RETROK_BACKSPACE, 0, 0, RETRO_DEVICE_KEYBOARD);
               input_keyboard_event(false, RETROK_BACKSPACE, 0, 0, RETRO_DEVICE_KEYBOARD);
               break;
            case NAVIGATOR_SYSKEY_SEND:
            case NAVIGATOR_SYSKEY_END:
               break;
            default:
               break;
         }
         break;
      case NAVIGATOR_SWIPE_DOWN:
         command_event(CMD_EVENT_MENU_TOGGLE, NULL);
         break;
      case NAVIGATOR_WINDOW_STATE:
         switch(navigator_event_get_window_state(event))
         {
            case NAVIGATOR_WINDOW_THUMBNAIL:
            case NAVIGATOR_WINDOW_INVISIBLE:
               while(true)
               {
                  unsigned event_code;

                  /* Block until we get a resume or exit event. */
                  bps_get_event(&event_pause, -1);
                  event_code = bps_event_get_code(event_pause);

                  if(event_code == NAVIGATOR_WINDOW_STATE)
                  {
                     if(navigator_event_get_window_state(event_pause) == NAVIGATOR_WINDOW_FULLSCREEN)
                        break;
                  }
                  else if(event_code == NAVIGATOR_EXIT)
                     goto shutdown;
               }
               break;
            case NAVIGATOR_WINDOW_FULLSCREEN:
               break;
         }
         break;
     case NAVIGATOR_EXIT:
        goto shutdown;
      default:
         break;
   }

   return;

   togglemenu:
       command_event(CMD_EVENT_MENU_TOGGLE, NULL);
       return;
   shutdown:
       rarch_ctl(RARCH_CTL_SET_SHUTDOWN, NULL);
       return;
}
Пример #24
0
unsigned menu_event(uint64_t input, uint64_t trigger_input)
{
   menu_animation_ctx_delta_t delta;
   float delta_time;
   /* Used for key repeat */
   static float delay_timer                = 0.0f;
   static float delay_count                = 0.0f;
   unsigned ret                            = MENU_ACTION_NOOP;
   static bool initial_held                = true;
   static bool first_held                  = false;
   bool set_scroll                         = false;
   bool mouse_enabled                      = false;
   size_t new_scroll_accel                 = 0;
   menu_input_t *menu_input                = NULL;
   settings_t *settings                    = config_get_ptr();

   if (input)
   {
      if (!first_held)
      {
         /* don't run anything first frame, only capture held inputs
          * for old_input_state. */

         first_held  = true;
         delay_timer = initial_held ? 12 : 6;
         delay_count = 0;
      }

      if (delay_count >= delay_timer)
      {
         uint64_t input_repeat = 0;
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R);

         set_scroll           = true;
         first_held           = false;
         trigger_input |= input & input_repeat;

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
               &new_scroll_accel);

         new_scroll_accel = MIN(new_scroll_accel + 1, 64);
      }

      initial_held  = false;
   }
   else
   {
      set_scroll   = true;
      first_held   = false;
      initial_held = true;
   }

   if (set_scroll)
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
            &new_scroll_accel);

   menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

   delta.current = delta_time;

   if (menu_animation_ctl(MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET, &delta))
      delay_count += delta.ideal;

   if (menu_input_dialog_get_display_kb())
   {
      if (kbd_upper)
         strlcpy(kbd_grid, "!@#$%^&*()QWERTYUIOPASDFGHJKL:ZXCVBNM <>?", sizeof(kbd_grid));
      else
         strlcpy(kbd_grid, "1234567890qwertyuiopasdfghjkl:zxcvbnm ,./", sizeof(kbd_grid));

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      {
         if (kbd_index < 30)
            kbd_index = kbd_index + 10;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      {
         if (kbd_index >= 10)
            kbd_index = kbd_index - 10;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      {
         if (kbd_index < 39)
            kbd_index = kbd_index + 1;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      {
         if (kbd_index >= 1)
            kbd_index = kbd_index - 1;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
      {
         kbd_upper = ! kbd_upper;
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A))
      {
         input_keyboard_event(true, kbd_grid[kbd_index], kbd_grid[kbd_index],
               0, RETRO_DEVICE_KEYBOARD);
      }

      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B))
      {
         input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
      }

      /* send return key to close keyboard input window */
      if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      trigger_input = 0;
   }

   if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      ret = MENU_ACTION_UP;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      ret = MENU_ACTION_DOWN;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      ret = MENU_ACTION_LEFT;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      ret = MENU_ACTION_RIGHT;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_up_btn))
      ret = MENU_ACTION_SCROLL_UP;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_down_btn))
      ret = MENU_ACTION_SCROLL_DOWN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
      ret = MENU_ACTION_CANCEL;
   else if (trigger_input & (UINT64_C(1) << settings->menu_ok_btn))
      ret = MENU_ACTION_OK;
   else if (trigger_input & (UINT64_C(1) << settings->menu_search_btn))
      ret = MENU_ACTION_SEARCH;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
      ret = MENU_ACTION_SCAN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_default_btn))
      ret = MENU_ACTION_START;
   else if (trigger_input & (UINT64_C(1) << settings->menu_info_btn))
      ret = MENU_ACTION_INFO;
   else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE))
      ret = MENU_ACTION_TOGGLE;

   mouse_enabled                      = settings->menu.mouse.enable;
#ifdef HAVE_OVERLAY
   if (!mouse_enabled)
      mouse_enabled = !(settings->input.overlay_enable
            && input_overlay_is_alive(NULL));
#endif

   if (!(menu_input = menu_input_get_ptr()))
      return 0;

   if (!mouse_enabled)
      menu_input->mouse.ptr = 0;

   if (settings->menu.pointer.enable)
      menu_event_pointer(&ret);
   else
   {
      menu_input->pointer.x          = 0;
      menu_input->pointer.y          = 0;
      menu_input->pointer.dx         = 0;
      menu_input->pointer.dy         = 0;
      menu_input->pointer.accel      = 0;
      menu_input->pointer.pressed[0] = false;
      menu_input->pointer.pressed[1] = false;
      menu_input->pointer.back       = false;
      menu_input->pointer.ptr        = 0;
   }

   return ret;
}
Пример #25
0
void input_mapper_poll(input_mapper_t *handle)
{
   unsigned i, j;
   input_bits_t current_input;
   settings_t *settings                       = config_get_ptr();
   unsigned max_users                         =
      *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
   bool key_event[RARCH_CUSTOM_BIND_LIST_END] = { false };
#ifdef HAVE_OVERLAY
   bool poll_overlay = input_overlay_is_alive(overlay_ptr) ? true : false;
#endif

#ifdef HAVE_MENU
   if (menu_driver_is_alive())
      return;
#endif

   memset(handle->keys, 0, sizeof(handle->keys));

   for (i = 0; i < max_users; i++)
   {
      unsigned device  = settings->uints.input_libretro_device[i];
      device          &= RETRO_DEVICE_MASK;

      switch (device)
      {
            /* keyboard to gamepad remapping */
         case RETRO_DEVICE_KEYBOARD:
            BIT256_CLEAR_ALL_PTR(&current_input);
            input_get_state_for_port(settings, i, &current_input);
            for (j = 0; j < RARCH_CUSTOM_BIND_LIST_END; j++)
            {
               unsigned remap_button         = 
                  settings->uints.input_keymapper_ids[i][j];
               bool remap_valid              = remap_button != RETROK_UNKNOWN;

               if (remap_valid)
               {
                  unsigned current_button_value = BIT256_GET(current_input, j);

                  if ((current_button_value == 1) && (j != remap_button))
                  {
                     MAPPER_SET_KEY (handle,
                           remap_button);
                     input_keyboard_event(true,
                           remap_button,
                           0, 0, RETRO_DEVICE_KEYBOARD);
                     key_event[j] = true;
                  }
                  /* key_event tracks if a key is pressed for ANY PLAYER, so we must check 
                     if the key was used by any player before releasing */
                  else if (!key_event[j])
                  {
                     input_keyboard_event(false,
                           remap_button,
                           0, 0, RETRO_DEVICE_KEYBOARD);
                  }
               }
            }
            break;

            /* gamepad remapping */
         case RETRO_DEVICE_JOYPAD:
         case RETRO_DEVICE_ANALOG:
            /* this loop iterates on all users and all buttons, 
             * and checks if a pressed button is assigned to any 
             * other button than the default one, then it sets 
             * the bit on the mapper input bitmap, later on the 
             * original input is cleared in input_state */
            BIT256_CLEAR_ALL(handle->buttons[i]);
            BIT256_CLEAR_ALL_PTR(&current_input);

            for (j = 0; j < 8; j++)
               handle->analog_value[i][j] = 0;

            input_get_state_for_port(settings, i, &current_input);

            for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
            {
               bool remap_valid;
               unsigned remap_button;
               unsigned current_button_value = BIT256_GET(current_input, j);
#ifdef HAVE_OVERLAY
               if (poll_overlay && i == 0)
                  current_button_value |= input_overlay_key_pressed(overlay_ptr, j);
#endif

               remap_button                  =
                  settings->uints.input_remap_ids[i][j];
               remap_valid                   = (current_button_value == 1) &&
                  (j != remap_button) && (remap_button != RARCH_UNMAPPED);

               if (remap_valid)
               {
                  if (remap_button < RARCH_FIRST_CUSTOM_BIND)
                  {
                     BIT256_SET(handle->buttons[i], remap_button);
                  }
                  else if (remap_button >= RARCH_FIRST_CUSTOM_BIND)
                  {
                     int invert = 1;

                     if (remap_button % 2 != 0)
                        invert = -1;

                     handle->analog_value[i][
                        remap_button - RARCH_FIRST_CUSTOM_BIND] = 
                           32767 * invert;
                  }
               }
            }

            for (j = 0; j < 8; j++)
            {
               unsigned k                 = j + RARCH_FIRST_CUSTOM_BIND;
               int16_t current_axis_value = current_input.analogs[j];
               unsigned remap_axis        = 
                  settings->uints.input_remap_ids[i][k];

               if (
                     (abs(current_axis_value) > 
                     *input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD) * 32767) && 
                     (k != remap_axis)         &&
                     (remap_axis != RARCH_UNMAPPED)
                  )
               {
                  if (remap_axis < RARCH_FIRST_CUSTOM_BIND)
                  {
                     BIT256_SET(handle->buttons[i], remap_axis);
                  }
                  else
                  {
                     int invert = 1;

                     if (  (k % 2 == 0 && remap_axis % 2 != 0) || 
                           (k % 2 != 0 && remap_axis % 2 == 0)
                        )
                        invert = -1;

                     handle->analog_value[i][
                        remap_axis - RARCH_FIRST_CUSTOM_BIND] = 
                           current_axis_value * invert;
#if 0
                     RARCH_LOG("axis %d(%d) remapped to axis %d val %d\n",
                           j, k, 
                           remap_axis - RARCH_FIRST_CUSTOM_BIND,
                           current_axis_value);
#endif
                  }
               }

            }
            break;
         default:
            break;
      }
   }
}
Пример #26
0
unsigned menu_input_frame_retropad(retro_input_t input, retro_input_t trigger_input)
{
   float delta_time;
   unsigned         ret                    = MENU_ACTION_NOOP;
   static bool initial_held                = true;
   static bool first_held                  = false;
   static const retro_input_t input_repeat =
        (1UL << RETRO_DEVICE_ID_JOYPAD_UP)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_DOWN)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_LEFT)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_RIGHT)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_L)
      | (1UL << RETRO_DEVICE_ID_JOYPAD_R);
   bool set_scroll                         = false;
   size_t new_scroll_accel                 = 0;
   menu_input_t *menu_input                = menu_input_get_ptr();
   driver_t *driver                        = driver_get_ptr();
   settings_t *settings                    = config_get_ptr();

   if (!driver || !menu_input)
      return 0;

   driver->retro_ctx.poll_cb();

   /* don't run anything first frame, only capture held inputs
    * for old_input_state. */

   if (input & input_repeat)
   {
      if (!first_held)
      {
         first_held = true;
         menu_input->delay.timer = initial_held ? 12 : 6;
         menu_input->delay.count = 0;
      }

      if (menu_input->delay.count >= menu_input->delay.timer)
      {
         set_scroll     = true;
         first_held     = false;
         trigger_input |= input & input_repeat;

         menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
               &new_scroll_accel);

         new_scroll_accel = min(new_scroll_accel + 1, 64);
      }

      initial_held  = false;
   }
   else
   {
      set_scroll   = true;
      first_held   = false;
      initial_held = true;
   }

   if (set_scroll)
      menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
            &new_scroll_accel);

   menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time);

   menu_input->delay.count += delta_time / IDEAL_DT;

   if (menu_input->keyboard.display)
   {
      /* send return key to close keyboard input window */
      if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      trigger_input = 0;
   }

   if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
      ret = MENU_ACTION_UP;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
      ret = MENU_ACTION_DOWN;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
      ret = MENU_ACTION_LEFT;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      ret = MENU_ACTION_RIGHT;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_up_btn))
      ret = MENU_ACTION_SCROLL_UP;
   else if (trigger_input & (UINT64_C(1) << settings->menu_scroll_down_btn))
      ret = MENU_ACTION_SCROLL_DOWN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_cancel_btn))
      ret = MENU_ACTION_CANCEL;
   else if (trigger_input & (UINT64_C(1) << settings->menu_ok_btn))
      ret = MENU_ACTION_OK;
   else if (trigger_input & (UINT64_C(1) << settings->menu_search_btn))
      ret = MENU_ACTION_SEARCH;
   else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
      ret = MENU_ACTION_SCAN;
   else if (trigger_input & (UINT64_C(1) << settings->menu_default_btn))
      ret = MENU_ACTION_START;
   else if (trigger_input & (UINT64_C(1) << settings->menu_info_btn))
      ret = MENU_ACTION_INFO;
   else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE))
      ret = MENU_ACTION_TOGGLE;

   return menu_input_frame_pointer(&ret);
}
Пример #27
0
/*
 * This function gets called in order to process all input events
 * for the current frame.
 *
 * Sends input code to menu for one frame.
 *
 * It uses as input the local variables' input' and 'trigger_input'.
 *
 * Mouse and touch input events get processed inside this function.
 *
 * NOTE: 'input' and 'trigger_input' is sourced from the keyboard and/or
 * the gamepad. It does not contain input state derived from the mouse
 * and/or touch - this gets dealt with separately within this function.
 *
 * TODO/FIXME - maybe needs to be overhauled so we can send multiple
 * events per frame if we want to, and we shouldn't send the
 * entire button state either but do a separate event per button
 * state.
 */
unsigned menu_event(input_bits_t *p_input, input_bits_t *p_trigger_input)
{
   /* Used for key repeat */
   static float delay_timer                = 0.0f;
   static float delay_count                = 0.0f;
   static unsigned ok_old                  = 0;
   unsigned ret                            = MENU_ACTION_NOOP;
   static bool initial_held                = true;
   static bool first_held                  = false;
   bool set_scroll                         = false;
   bool mouse_enabled                      = false;
   size_t new_scroll_accel                 = 0;
   menu_input_t *menu_input                = NULL;
   settings_t *settings                    = config_get_ptr();
   bool swap_ok_cancel_btns                = settings->bools.input_menu_swap_ok_cancel_buttons;
   bool input_swap_override                =
      input_autoconfigure_get_swap_override();
   unsigned menu_ok_btn                    = (!input_swap_override &&
      swap_ok_cancel_btns) ?
      RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A;
   unsigned menu_cancel_btn                = (!input_swap_override &&
      swap_ok_cancel_btns) ?
      RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B;
   unsigned ok_current                     = BIT256_GET_PTR(p_input,
         menu_ok_btn );
   unsigned ok_trigger                     = ok_current & ~ok_old;

   ok_old                                  = ok_current;

   if (bits_any_set(p_input->data, ARRAY_SIZE(p_input->data)))
   {
      if (!first_held)
      {
         /* don't run anything first frame, only capture held inputs
          * for old_input_state. */

         first_held  = true;
         delay_timer = initial_held ? 200 : 100;
         delay_count = 0;
      }

      if (delay_count >= delay_timer)
      {
         uint32_t input_repeat = 0;
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_RIGHT);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_L);
         BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_R);

         set_scroll           = true;
         first_held           = false;
         p_trigger_input->data[0] |= p_input->data[0] & input_repeat;

         menu_driver_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
               &new_scroll_accel);

         new_scroll_accel = MIN(new_scroll_accel + 1, 64);
      }

      initial_held  = false;
   }
   else
   {
      set_scroll   = true;
      first_held   = false;
      initial_held = true;
   }

   if (set_scroll)
      menu_driver_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL,
            &new_scroll_accel);

   delay_count += menu_animation_get_delta_time();

   if (menu_input_dialog_get_display_kb())
   {
      menu_event_osk_iterate();

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
      {
         if (menu_event_get_osk_ptr() < 33)
            menu_event_set_osk_ptr(menu_event_get_osk_ptr()
                  + OSK_CHARS_PER_LINE);
      }

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP))
      {
         if (menu_event_get_osk_ptr() >= OSK_CHARS_PER_LINE)
            menu_event_set_osk_ptr(menu_event_get_osk_ptr()
                  - OSK_CHARS_PER_LINE);
      }

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT))
      {
         if (menu_event_get_osk_ptr() < 43)
            menu_event_set_osk_ptr(menu_event_get_osk_ptr() + 1);
      }

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT))
      {
         if (menu_event_get_osk_ptr() >= 1)
            menu_event_set_osk_ptr(menu_event_get_osk_ptr() - 1);
      }

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L))
      {
         if (menu_event_get_osk_idx() > OSK_TYPE_UNKNOWN + 1)
            menu_event_set_osk_idx((enum osk_type)(
                     menu_event_get_osk_idx() - 1));
         else
            menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_LAST - 1));
      }

      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R))
      {
         if (menu_event_get_osk_idx() < OSK_TYPE_LAST - 1)
            menu_event_set_osk_idx((enum osk_type)(
                     menu_event_get_osk_idx() + 1));
         else
            menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1));
      }

      if (BIT256_GET_PTR(p_trigger_input, menu_ok_btn))
      {
         if (menu_event_get_osk_ptr() >= 0)
            menu_event_osk_append(menu_event_get_osk_ptr());
      }

      if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn))
         input_keyboard_event(true, '\x7f', '\x7f',
               0, RETRO_DEVICE_KEYBOARD);

      /* send return key to close keyboard input window */
      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START))
         input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);

      BIT256_CLEAR_ALL_PTR(p_trigger_input);
   }
   else
   {
      if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP))
         ret = MENU_ACTION_UP;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
         ret = MENU_ACTION_DOWN;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT))
         ret = MENU_ACTION_LEFT;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT))
         ret = MENU_ACTION_RIGHT;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L))
         ret = MENU_ACTION_SCROLL_UP;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R))
         ret = MENU_ACTION_SCROLL_DOWN;
      else if (ok_trigger)
         ret = MENU_ACTION_OK;
      else if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn))
         ret = MENU_ACTION_CANCEL;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X))
         ret = MENU_ACTION_SEARCH;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y))
         ret = MENU_ACTION_SCAN;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START))
         ret = MENU_ACTION_START;
      else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
         ret = MENU_ACTION_INFO;
      else if (BIT256_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE))
         ret = MENU_ACTION_TOGGLE;
   }

   if (menu_event_kb_is_set(RETROK_F11))
   {
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);
      menu_event_kb_set_internal(RETROK_F11, 0);
   }

   mouse_enabled                      = settings->bools.menu_mouse_enable;
#ifdef HAVE_OVERLAY
   if (!mouse_enabled)
      mouse_enabled = !(settings->bools.input_overlay_enable
            && input_overlay_is_alive(overlay_ptr));
#endif

   menu_input = &menu_input_state;

   if (!mouse_enabled)
      menu_input->mouse.ptr = 0;

   if (settings->bools.menu_pointer_enable)
      menu_event_pointer(&ret);
   else
   {
      menu_input->pointer.x          = 0;
      menu_input->pointer.y          = 0;
      menu_input->pointer.dx         = 0;
      menu_input->pointer.dy         = 0;
      menu_input->pointer.accel      = 0;
      menu_input->pointer.pressed[0] = false;
      menu_input->pointer.pressed[1] = false;
      menu_input->pointer.back       = false;
      menu_input->pointer.ptr        = 0;
   }

   return ret;
}