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); }
/* 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; }
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); }
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; } }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }
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]); } }
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 } }
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); }
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); } } } }
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; }
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); }
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); }
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); }
/* * 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); }
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; }
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; }
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; }
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; }
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(¤t_input); input_get_state_for_port(settings, i, ¤t_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(¤t_input); for (j = 0; j < 8; j++) handle->analog_value[i][j] = 0; input_get_state_for_port(settings, i, ¤t_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; } } }
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); }
/* * 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; }