mirror of https://github.com/PCSX2/pcsx2.git
PAD: Process keycodes the same way on Linux and macOS
This commit is contained in:
parent
532a7addd4
commit
b90de6d89f
|
@ -1262,6 +1262,7 @@ if(NOT PCSX2_CORE)
|
|||
)
|
||||
list(APPEND pcsx2OSXSources
|
||||
Linux/LnxConsolePipe.cpp
|
||||
Darwin/DarwinKeyCodes.cpp
|
||||
)
|
||||
list(APPEND pcsx2FreeBSDSources
|
||||
Linux/LnxConsolePipe.cpp
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
int TranslateOSXtoWXK(u32 keysym)
|
||||
{
|
||||
switch (keysym)
|
||||
{
|
||||
case kVK_ANSI_A: return 'A';
|
||||
case kVK_ANSI_S: return 'S';
|
||||
case kVK_ANSI_D: return 'D';
|
||||
case kVK_ANSI_F: return 'F';
|
||||
case kVK_ANSI_H: return 'H';
|
||||
case kVK_ANSI_G: return 'G';
|
||||
case kVK_ANSI_Z: return 'Z';
|
||||
case kVK_ANSI_X: return 'X';
|
||||
case kVK_ANSI_C: return 'C';
|
||||
case kVK_ANSI_V: return 'V';
|
||||
case kVK_ANSI_B: return 'B';
|
||||
case kVK_ANSI_Q: return 'Q';
|
||||
case kVK_ANSI_W: return 'W';
|
||||
case kVK_ANSI_E: return 'E';
|
||||
case kVK_ANSI_R: return 'R';
|
||||
case kVK_ANSI_Y: return 'Y';
|
||||
case kVK_ANSI_T: return 'T';
|
||||
case kVK_ANSI_1: return '1';
|
||||
case kVK_ANSI_2: return '2';
|
||||
case kVK_ANSI_3: return '3';
|
||||
case kVK_ANSI_4: return '4';
|
||||
case kVK_ANSI_6: return '6';
|
||||
case kVK_ANSI_5: return '5';
|
||||
case kVK_ANSI_Equal: return '=';
|
||||
case kVK_ANSI_9: return '9';
|
||||
case kVK_ANSI_7: return '7';
|
||||
case kVK_ANSI_Minus: return '-';
|
||||
case kVK_ANSI_8: return '8';
|
||||
case kVK_ANSI_0: return '0';
|
||||
case kVK_ANSI_RightBracket: return ']';
|
||||
case kVK_ANSI_O: return 'O';
|
||||
case kVK_ANSI_U: return 'U';
|
||||
case kVK_ANSI_LeftBracket: return '[';
|
||||
case kVK_ANSI_I: return 'I';
|
||||
case kVK_ANSI_P: return 'P';
|
||||
case kVK_ANSI_L: return 'L';
|
||||
case kVK_ANSI_J: return 'J';
|
||||
case kVK_ANSI_Quote: return '\'';
|
||||
case kVK_ANSI_K: return 'K';
|
||||
case kVK_ANSI_Semicolon: return ';';
|
||||
case kVK_ANSI_Backslash: return '\\';
|
||||
case kVK_ANSI_Comma: return ',';
|
||||
case kVK_ANSI_Slash: return '/';
|
||||
case kVK_ANSI_N: return 'N';
|
||||
case kVK_ANSI_M: return 'M';
|
||||
case kVK_ANSI_Period: return '.';
|
||||
case kVK_ANSI_Grave: return '`';
|
||||
case kVK_ANSI_KeypadDecimal: return WXK_NUMPAD_DECIMAL;
|
||||
case kVK_ANSI_KeypadMultiply: return WXK_NUMPAD_MULTIPLY;
|
||||
case kVK_ANSI_KeypadPlus: return WXK_NUMPAD_ADD;
|
||||
case kVK_ANSI_KeypadClear: return WXK_CLEAR;
|
||||
case kVK_ANSI_KeypadDivide: return WXK_NUMPAD_DIVIDE;
|
||||
case kVK_ANSI_KeypadEnter: return WXK_NUMPAD_ENTER;
|
||||
case kVK_ANSI_KeypadMinus: return WXK_NUMPAD_SUBTRACT;
|
||||
case kVK_ANSI_KeypadEquals: return WXK_NUMPAD_EQUAL;
|
||||
case kVK_ANSI_Keypad0: return WXK_NUMPAD0;
|
||||
case kVK_ANSI_Keypad1: return WXK_NUMPAD1;
|
||||
case kVK_ANSI_Keypad2: return WXK_NUMPAD2;
|
||||
case kVK_ANSI_Keypad3: return WXK_NUMPAD3;
|
||||
case kVK_ANSI_Keypad4: return WXK_NUMPAD4;
|
||||
case kVK_ANSI_Keypad5: return WXK_NUMPAD5;
|
||||
case kVK_ANSI_Keypad6: return WXK_NUMPAD6;
|
||||
case kVK_ANSI_Keypad7: return WXK_NUMPAD7;
|
||||
case kVK_ANSI_Keypad8: return WXK_NUMPAD8;
|
||||
case kVK_ANSI_Keypad9: return WXK_NUMPAD9;
|
||||
|
||||
case kVK_Return: return WXK_RETURN;
|
||||
case kVK_Tab: return WXK_TAB;
|
||||
case kVK_Space: return WXK_SPACE;
|
||||
case kVK_Delete: return WXK_BACK;
|
||||
case kVK_Escape: return WXK_ESCAPE;
|
||||
case kVK_Command: return WXK_COMMAND;
|
||||
case kVK_Shift: return WXK_SHIFT;
|
||||
case kVK_CapsLock: return WXK_CAPITAL;
|
||||
case kVK_Option: return WXK_ALT;
|
||||
case kVK_Control: return WXK_RAW_CONTROL;
|
||||
case kVK_RightCommand: return WXK_COMMAND;
|
||||
case kVK_RightShift: return WXK_SHIFT;
|
||||
case kVK_RightOption: return WXK_ALT;
|
||||
case kVK_RightControl: return WXK_RAW_CONTROL;
|
||||
case kVK_Function: return 0;
|
||||
case kVK_F17: return WXK_F17;
|
||||
#if wxCHECK_VERSION(3, 1, 0)
|
||||
case kVK_VolumeUp: return WXK_VOLUME_UP;
|
||||
case kVK_VolumeDown: return WXK_VOLUME_DOWN;
|
||||
case kVK_Mute: return WXK_VOLUME_MUTE;
|
||||
#endif
|
||||
case kVK_F18: return WXK_F18;
|
||||
case kVK_F19: return WXK_F19;
|
||||
case kVK_F20: return WXK_F20;
|
||||
case kVK_F5: return WXK_F5;
|
||||
case kVK_F6: return WXK_F6;
|
||||
case kVK_F7: return WXK_F7;
|
||||
case kVK_F3: return WXK_F3;
|
||||
case kVK_F8: return WXK_F8;
|
||||
case kVK_F9: return WXK_F9;
|
||||
case kVK_F11: return WXK_F11;
|
||||
case kVK_F13: return WXK_F13;
|
||||
case kVK_F16: return WXK_F16;
|
||||
case kVK_F14: return WXK_F14;
|
||||
case kVK_F10: return WXK_F10;
|
||||
case kVK_F12: return WXK_F12;
|
||||
case kVK_F15: return WXK_F15;
|
||||
case kVK_Help: return WXK_HELP;
|
||||
case kVK_Home: return WXK_HOME;
|
||||
case kVK_PageUp: return WXK_PAGEUP;
|
||||
case kVK_ForwardDelete: return WXK_DELETE;
|
||||
case kVK_F4: return WXK_F4;
|
||||
case kVK_End: return WXK_END;
|
||||
case kVK_F2: return WXK_F2;
|
||||
case kVK_PageDown: return WXK_PAGEDOWN;
|
||||
case kVK_F1: return WXK_F1;
|
||||
case kVK_LeftArrow: return WXK_LEFT;
|
||||
case kVK_RightArrow: return WXK_RIGHT;
|
||||
case kVK_DownArrow: return WXK_DOWN;
|
||||
case kVK_UpArrow: return WXK_UP;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -27,6 +27,8 @@
|
|||
#include "gui/AppCoreThread.h"
|
||||
#if defined(__unix__)
|
||||
#include <X11/keysym.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
static std::string GetDumpName()
|
||||
|
@ -603,10 +605,17 @@ void GSRenderer::EndCapture()
|
|||
|
||||
void GSRenderer::KeyEvent(const HostKeyEvent& e)
|
||||
{
|
||||
#if !defined(PCSX2_CORE) && !defined(__APPLE__) // TODO: Add hotkey support on macOS
|
||||
#if !defined(PCSX2_CORE)
|
||||
#ifdef _WIN32
|
||||
m_shift_key = !!(::GetAsyncKeyState(VK_SHIFT) & 0x8000);
|
||||
m_control_key = !!(::GetAsyncKeyState(VK_CONTROL) & 0x8000);
|
||||
#elif defined(__APPLE__)
|
||||
m_shift_key = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_Shift)
|
||||
|| CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_RightShift);
|
||||
m_control_key = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_Control)
|
||||
|| CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_RightControl)
|
||||
|| CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_Command)
|
||||
|| CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_RightCommand);
|
||||
#else
|
||||
switch (e.key)
|
||||
{
|
||||
|
@ -628,12 +637,12 @@ void GSRenderer::KeyEvent(const HostKeyEvent& e)
|
|||
|
||||
#if defined(__unix__)
|
||||
#define VK_F5 XK_F5
|
||||
#define VK_F6 XK_F6
|
||||
#define VK_DELETE XK_Delete
|
||||
#define VK_INSERT XK_Insert
|
||||
#define VK_PRIOR XK_Prior
|
||||
#define VK_NEXT XK_Next
|
||||
#define VK_HOME XK_Home
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_F5 kVK_F5
|
||||
#define VK_DELETE kVK_ForwardDelete
|
||||
#define VK_NEXT kVK_PageDown
|
||||
#endif
|
||||
|
||||
// NOTE: These are all BROKEN! They mess with GS thread state from the UI thread.
|
||||
|
@ -657,7 +666,7 @@ void GSRenderer::KeyEvent(const HostKeyEvent& e)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif // __APPLE__
|
||||
#endif // PCSX2_CORE
|
||||
}
|
||||
|
||||
void GSRenderer::PurgePool()
|
||||
|
|
18
pcsx2/Host.h
18
pcsx2/Host.h
|
@ -26,14 +26,16 @@ struct HostKeyEvent
|
|||
{
|
||||
enum class Type
|
||||
{
|
||||
NoEvent = 0,
|
||||
KeyPressed = 1,
|
||||
KeyReleased = 2,
|
||||
MousePressed = 3,
|
||||
MouseReleased = 4,
|
||||
MouseWheelDown = 5,
|
||||
MouseWheelUp = 6,
|
||||
MouseMove = 7,
|
||||
NoEvent,
|
||||
KeyPressed,
|
||||
KeyReleased,
|
||||
MousePressed,
|
||||
MouseReleased,
|
||||
MouseWheelDown,
|
||||
MouseWheelUp,
|
||||
MouseMove,
|
||||
FocusGained,
|
||||
FocustLost,
|
||||
};
|
||||
|
||||
Type type;
|
||||
|
|
|
@ -31,6 +31,6 @@ void PADconfigure();
|
|||
s32 PADfreeze(FreezeAction mode, freezeData* data);
|
||||
s32 PADsetSlot(u8 port, u8 slot);
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
void PADWriteEvent(HostKeyEvent& evt);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -220,7 +220,7 @@ HostKeyEvent* PADkeyEvent()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef __unix__
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
if (g_ev_fifo.size() == 0)
|
||||
{
|
||||
//PAD_LOG("No events in queue, returning empty event");
|
||||
|
@ -234,15 +234,10 @@ HostKeyEvent* PADkeyEvent()
|
|||
AnalyzeKeyEvent(s_event);
|
||||
//PAD_LOG("Returning Event. Event Type: %d, Key: %d", s_event.type, s_event.key);
|
||||
return &s_event;
|
||||
#else // MacOS
|
||||
s_event = event;
|
||||
event.type = HostKeyEvent::Type::NoEvent;
|
||||
event.key = 0;
|
||||
return &s_event;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
void PADWriteEvent(HostKeyEvent& evt)
|
||||
{
|
||||
// if (evt.evt != 6) { // Skip mouse move events for logging
|
||||
|
@ -280,4 +275,4 @@ void PADconfigure()
|
|||
DisplayDialog();
|
||||
paused_core.AllowResume();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,29 +64,7 @@ static void PressButton(u32 pad, u32 button)
|
|||
|
||||
void UpdateKeyboardInput()
|
||||
{
|
||||
for (u32 pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||
{
|
||||
const auto& map = g_conf.keysym_map[pad];
|
||||
// If we loop over all keys press/release based on current state,
|
||||
// joystick axes (which have two bound keys) will always go to the later-polled key
|
||||
// Instead, release all keys first and then set the ones that are pressed
|
||||
for (const auto& key : map)
|
||||
g_key_status.release(pad, key.second);
|
||||
for (const auto& key : map)
|
||||
{
|
||||
bool state;
|
||||
if (key.first >> 16 == 0)
|
||||
{
|
||||
state = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, (CGMouseButton)(key.first & 0xFFFF));
|
||||
}
|
||||
if (state)
|
||||
PressButton(pad, key.second);
|
||||
}
|
||||
}
|
||||
g_ev_fifo.consume_all(AnalyzeKeyEvent);
|
||||
}
|
||||
|
||||
bool PollForNewKeyboardKeys(u32& pkey)
|
||||
|
@ -101,31 +79,103 @@ bool PollForNewKeyboardKeys(u32& pkey)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
for (auto btn : {kCGMouseButtonLeft, kCGMouseButtonCenter, kCGMouseButtonRight})
|
||||
{
|
||||
if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, btn))
|
||||
{
|
||||
pkey = btn | (1 << 16);
|
||||
return true;
|
||||
}
|
||||
#define CHECK(button, value) \
|
||||
if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, (button))) \
|
||||
{ \
|
||||
pkey = (value); \
|
||||
return true; \
|
||||
}
|
||||
CHECK(kCGMouseButtonLeft, 0x10001)
|
||||
CHECK(kCGMouseButtonCenter, 0x10002)
|
||||
CHECK(kCGMouseButtonRight, 0x10003)
|
||||
#undef CHECK
|
||||
return false;
|
||||
}
|
||||
#elif defined(__unix__)
|
||||
static bool s_grab_input = false;
|
||||
static bool s_Shift = false;
|
||||
|
||||
void UpdateKeyboardInput()
|
||||
{
|
||||
HostKeyEvent evt = {};
|
||||
XEvent E = {0};
|
||||
|
||||
// Keyboard input send by PCSX2
|
||||
g_ev_fifo.consume_all(AnalyzeKeyEvent);
|
||||
|
||||
// keyboard input
|
||||
if (!GSdsp)
|
||||
return;
|
||||
|
||||
while (XPending(GSdsp) > 0)
|
||||
{
|
||||
XNextEvent(GSdsp, &E);
|
||||
|
||||
// Change the format of the structure to be compatible with GSOpen2
|
||||
// mode (event come from pcsx2 not X)
|
||||
evt.type = static_cast<HostKeyEvent::Type>(E.type);
|
||||
switch (E.type)
|
||||
{
|
||||
case MotionNotify:
|
||||
evt.key = (E.xbutton.x & 0xFFFF) | (E.xbutton.y << 16);
|
||||
evt.type = HostKeyEvent::Type::MouseMove;
|
||||
break;
|
||||
case ButtonRelease:
|
||||
evt.key = E.xbutton.button | 0x10000;
|
||||
evt.type = HostKeyEvent::Type::MouseReleased;
|
||||
break;
|
||||
case ButtonPress:
|
||||
evt.key = E.xbutton.button | 0x10000;
|
||||
evt.type = HostKeyEvent::Type::MousePressed;
|
||||
break;
|
||||
case KeyPress:
|
||||
evt.key = (int)XLookupKeysym(&E.xkey, 0);
|
||||
evt.type = HostKeyEvent::Type::KeyPressed;
|
||||
break;
|
||||
case KeyRelease:
|
||||
evt.key = (int)XLookupKeysym(&E.xkey, 0);
|
||||
evt.type = HostKeyEvent::Type::KeyReleased;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
AnalyzeKeyEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
bool PollForNewKeyboardKeys(u32& pkey)
|
||||
{
|
||||
GdkEvent* ev = gdk_event_get();
|
||||
|
||||
if (ev != NULL)
|
||||
{
|
||||
if (ev->type == GDK_KEY_PRESS)
|
||||
{
|
||||
pkey = ev->key.keyval != GDK_KEY_Escape ? ev->key.keyval : UINT32_MAX;
|
||||
return true;
|
||||
}
|
||||
else if (ev->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
pkey = ev->button.button | 0x10000;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int s_previous_mouse_x = 0;
|
||||
static unsigned int s_previous_mouse_y = 0;
|
||||
|
||||
void AnalyzeKeyEvent(HostKeyEvent& evt)
|
||||
{
|
||||
KeySym key = (KeySym)evt.key;
|
||||
int pad = 0;
|
||||
int index = -1;
|
||||
|
||||
for (u32 cpad = 0; cpad < GAMEPAD_NUMBER; cpad++)
|
||||
{
|
||||
int tmp_index = get_keyboard_key(cpad, key);
|
||||
int tmp_index = get_keyboard_key(cpad, evt.key);
|
||||
if (tmp_index != -1)
|
||||
{
|
||||
pad = cpad;
|
||||
|
@ -133,17 +183,18 @@ void AnalyzeKeyEvent(HostKeyEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
switch (static_cast<int>(evt.type))
|
||||
switch (evt.type)
|
||||
{
|
||||
case KeyPress:
|
||||
case HostKeyEvent::Type::KeyPressed:
|
||||
// Shift F12 is not yet use by pcsx2. So keep it to grab/ungrab input
|
||||
// I found it very handy vs the automatic fullscreen detection
|
||||
// 1/ Does not need to detect full-screen
|
||||
// 2/ Can use a debugger in full-screen
|
||||
// 3/ Can grab input in window without the need of a pixelated full-screen
|
||||
if (key == XK_Shift_R || key == XK_Shift_L)
|
||||
#ifdef __unix__
|
||||
if (evt.key == XK_Shift_R || evt.key == XK_Shift_L)
|
||||
s_Shift = true;
|
||||
if (key == XK_F12 && s_Shift)
|
||||
if (evt.key == XK_F12 && s_Shift)
|
||||
{
|
||||
if (!s_grab_input)
|
||||
{
|
||||
|
@ -158,6 +209,7 @@ void AnalyzeKeyEvent(HostKeyEvent& evt)
|
|||
XUngrabKeyboard(GSdsp, CurrentTime);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (index != -1)
|
||||
PressButton(pad, index);
|
||||
|
@ -165,38 +217,42 @@ void AnalyzeKeyEvent(HostKeyEvent& evt)
|
|||
//PAD_LOG("Key pressed:%d", index);
|
||||
|
||||
event.type = HostKeyEvent::Type::KeyPressed;
|
||||
event.key = key;
|
||||
event.key = evt.key;
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
if (key == XK_Shift_R || key == XK_Shift_L)
|
||||
case HostKeyEvent::Type::KeyReleased:
|
||||
#ifdef __unix__
|
||||
if (evt.key == XK_Shift_R || evt.key == XK_Shift_L)
|
||||
s_Shift = false;
|
||||
#endif
|
||||
|
||||
if (index != -1)
|
||||
g_key_status.release(pad, index);
|
||||
|
||||
event.type = HostKeyEvent::Type::KeyReleased;
|
||||
event.key = key;
|
||||
event.key = evt.key;
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
case HostKeyEvent::Type::FocusGained:
|
||||
break;
|
||||
|
||||
case FocusOut:
|
||||
case HostKeyEvent::Type::FocustLost:
|
||||
#ifdef __unix__
|
||||
s_Shift = false;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
case HostKeyEvent::Type::MousePressed:
|
||||
if (index != -1)
|
||||
g_key_status.press(pad, index);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
case HostKeyEvent::Type::MouseReleased:
|
||||
if (index != -1)
|
||||
g_key_status.release(pad, index);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
case HostKeyEvent::Type::MouseMove:
|
||||
// FIXME: How to handle when the mouse does not move, no event generated!!!
|
||||
// 1/ small move == no move. Cons : can not do small movement
|
||||
// 2/ use a watchdog timer thread
|
||||
|
@ -253,63 +309,10 @@ void AnalyzeKeyEvent(HostKeyEvent& evt)
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
case HostKeyEvent::Type::NoEvent:
|
||||
case HostKeyEvent::Type::MouseWheelDown:
|
||||
case HostKeyEvent::Type::MouseWheelUp:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateKeyboardInput()
|
||||
{
|
||||
HostKeyEvent evt = {};
|
||||
XEvent E = {0};
|
||||
|
||||
// Keyboard input send by PCSX2
|
||||
g_ev_fifo.consume_all(AnalyzeKeyEvent);
|
||||
|
||||
// keyboard input
|
||||
if (!GSdsp)
|
||||
return;
|
||||
|
||||
while (XPending(GSdsp) > 0)
|
||||
{
|
||||
XNextEvent(GSdsp, &E);
|
||||
|
||||
// Change the format of the structure to be compatible with GSOpen2
|
||||
// mode (event come from pcsx2 not X)
|
||||
evt.type = static_cast<HostKeyEvent::Type>(E.type);
|
||||
switch (E.type)
|
||||
{
|
||||
case MotionNotify:
|
||||
evt.key = (E.xbutton.x & 0xFFFF) | (E.xbutton.y << 16);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
case ButtonPress:
|
||||
evt.key = E.xbutton.button;
|
||||
break;
|
||||
default:
|
||||
evt.key = (int)XLookupKeysym(&E.xkey, 0);
|
||||
}
|
||||
|
||||
AnalyzeKeyEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
bool PollForNewKeyboardKeys(u32& pkey)
|
||||
{
|
||||
GdkEvent* ev = gdk_event_get();
|
||||
|
||||
if (ev != NULL)
|
||||
{
|
||||
if (ev->type == GDK_KEY_PRESS)
|
||||
{
|
||||
pkey = ev->key.keyval != GDK_KEY_Escape ? ev->key.keyval : UINT32_MAX;
|
||||
return true;
|
||||
}
|
||||
else if (ev->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
pkey = ev->button.button;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,14 +25,16 @@ static std::string KeyName(int pad, int key, int keysym)
|
|||
{
|
||||
switch (keysym & 0xFFFF)
|
||||
{
|
||||
case kCGMouseButtonLeft:
|
||||
case 0:
|
||||
return "Mouse ???";
|
||||
case 1:
|
||||
return "Mouse Left";
|
||||
case kCGMouseButtonRight:
|
||||
return "Mouse Right";
|
||||
case kCGMouseButtonCenter:
|
||||
case 2:
|
||||
return "Mouse Middle";
|
||||
case 3:
|
||||
return "Mouse Right";
|
||||
default: // Use only number for extra button
|
||||
return "Mouse " + std::to_string(keysym & 0xFFFF);
|
||||
return "Mouse " + std::to_string((keysym & 0xFFFF) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,12 +169,12 @@ static std::string KeyName(int pad, int key, int keysym)
|
|||
static std::string KeyName(int pad, int key, int keysym)
|
||||
{
|
||||
// Mouse
|
||||
if (keysym < 10)
|
||||
if (keysym >> 16)
|
||||
{
|
||||
switch (keysym)
|
||||
switch (keysym & 0xFFFF)
|
||||
{
|
||||
case 0:
|
||||
return "";
|
||||
return "Mouse ???";
|
||||
case 1:
|
||||
return "Mouse Left";
|
||||
case 2:
|
||||
|
@ -180,7 +182,7 @@ static std::string KeyName(int pad, int key, int keysym)
|
|||
case 3:
|
||||
return "Mouse Right";
|
||||
default: // Use only number for extra button
|
||||
return "Mouse " + std::to_string(keysym);
|
||||
return "Mouse " + std::to_string((keysym & 0xFFFF) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,9 +153,11 @@ protected:
|
|||
wxIMPLEMENT_DYNAMIC_CLASS( Pcsx2AppMethodEvent, pxActionEvent );
|
||||
|
||||
#ifdef __WXMSW__
|
||||
extern int TranslateVKToWXK( u32 keysym );
|
||||
#elif defined( __WXGTK__ )
|
||||
extern int TranslateGDKtoWXK( u32 keysym );
|
||||
extern int TranslateVKToWXK(u32 keysym);
|
||||
#elif defined(__WXGTK__)
|
||||
extern int TranslateGDKtoWXK(u32 keysym);
|
||||
#elif defined(__APPLE__)
|
||||
extern int TranslateOSXtoWXK(u32 keysym);
|
||||
#endif
|
||||
|
||||
void Pcsx2App::PadKeyDispatch(const HostKeyEvent& ev)
|
||||
|
@ -166,9 +168,9 @@ void Pcsx2App::PadKeyDispatch(const HostKeyEvent& ev)
|
|||
#ifdef __WXMSW__
|
||||
const int vkey = TranslateVKToWXK(ev.key);
|
||||
#elif defined( __WXMAC__ )
|
||||
const int vkey = wxCharCodeWXToOSX( (wxKeyCode) ev.key );
|
||||
const int vkey = TranslateOSXtoWXK(ev.key);
|
||||
#elif defined( __WXGTK__ )
|
||||
const int vkey = TranslateGDKtoWXK( ev.key );
|
||||
const int vkey = TranslateGDKtoWXK(ev.key);
|
||||
#else
|
||||
# error Unsupported Target Platform.
|
||||
#endif
|
||||
|
|
|
@ -397,24 +397,24 @@ void GSPanel::OnMouseEvent( wxMouseEvent& evt )
|
|||
DoShowMouse();
|
||||
}
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
// HACK2: In gsopen2 there is one event buffer read by both wx/gui and pad. Wx deletes
|
||||
// the event before the pad see it. So you send key event directly to the pad.
|
||||
HostKeyEvent event;
|
||||
// FIXME how to handle double click ???
|
||||
if (evt.ButtonDown())
|
||||
{
|
||||
event.type = static_cast<HostKeyEvent::Type>(4); // X equivalent of ButtonPress
|
||||
event.key = evt.GetButton();
|
||||
event.type = HostKeyEvent::Type::MousePressed;
|
||||
event.key = evt.GetButton() | 0x10000;
|
||||
}
|
||||
else if (evt.ButtonUp())
|
||||
{
|
||||
event.type = static_cast<HostKeyEvent::Type>(5); // X equivalent of ButtonRelease
|
||||
event.key = evt.GetButton();
|
||||
event.type = HostKeyEvent::Type::MouseReleased;
|
||||
event.key = evt.GetButton() | 0x10000;
|
||||
}
|
||||
else if (evt.Moving() || evt.Dragging())
|
||||
{
|
||||
event.type = static_cast<HostKeyEvent::Type>(6); // X equivalent of MotionNotify
|
||||
event.type = HostKeyEvent::Type::MouseMove;
|
||||
long x, y;
|
||||
evt.GetPosition(&x, &y);
|
||||
|
||||
|
@ -464,15 +464,15 @@ void GSPanel::OnKeyDownOrUp( wxKeyEvent& evt )
|
|||
// to the APP level message handler, which in turn routes them right back here -- yes it's
|
||||
// silly, but oh well).
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
// HACK2: In gsopen2 there is one event buffer read by both wx/gui and pad. Wx deletes
|
||||
// the event before the pad see it. So you send key event directly to the pad.
|
||||
HostKeyEvent event;
|
||||
event.key = evt.GetRawKeyCode();
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP)
|
||||
event.type = static_cast<HostKeyEvent::Type>(3); // X equivalent of KEYRELEASE;
|
||||
event.type = HostKeyEvent::Type::KeyReleased;
|
||||
else if (evt.GetEventType() == wxEVT_KEY_DOWN)
|
||||
event.type = static_cast<HostKeyEvent::Type>(2); // X equivalent of KEYPRESS;
|
||||
event.type = HostKeyEvent::Type::KeyPressed;
|
||||
else
|
||||
event.type = HostKeyEvent::Type::NoEvent;
|
||||
|
||||
|
@ -547,10 +547,10 @@ void GSPanel::OnFocus( wxFocusEvent& evt )
|
|||
else
|
||||
DoShowMouse();
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
// HACK2: In gsopen2 there is one event buffer read by both wx/gui and pad. Wx deletes
|
||||
// the event before the pad see it. So you send key event directly to the pad.
|
||||
HostKeyEvent event = {static_cast<HostKeyEvent::Type>(9), 0}; // X equivalent of FocusIn;
|
||||
HostKeyEvent event = {HostKeyEvent::Type::FocusGained, 0};
|
||||
PADWriteEvent(event);
|
||||
#endif
|
||||
//Console.Warning("GS frame > focus set");
|
||||
|
@ -563,10 +563,10 @@ void GSPanel::OnFocusLost( wxFocusEvent& evt )
|
|||
evt.Skip();
|
||||
m_HasFocus = false;
|
||||
DoShowMouse();
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
// HACK2: In gsopen2 there is one event buffer read by both wx/gui and pad. Wx deletes
|
||||
// the event before the pad see it. So you send key event directly to the pad.
|
||||
HostKeyEvent event = {static_cast<HostKeyEvent::Type>(9), 0}; // X equivalent of FocusOut
|
||||
HostKeyEvent event = {HostKeyEvent::Type::FocustLost, 0};
|
||||
PADWriteEvent(event);
|
||||
#endif
|
||||
//Console.Warning("GS frame > focus lost");
|
||||
|
|
Loading…
Reference in New Issue