Merge branch '2.6.x' into master
This commit is contained in:
commit
d9f8df9ca0
@ -61,6 +61,7 @@ public:
|
||||
struct KeyEvent
|
||||
{
|
||||
Keyboard::Key code; //!< Code of the key that has been pressed
|
||||
Keyboard::Scancode scancode; //!< Physical code of the key that has been pressed
|
||||
bool alt; //!< Is the Alt key pressed?
|
||||
bool control; //!< Is the Control key pressed?
|
||||
bool shift; //!< Is the Shift key pressed?
|
||||
|
@ -30,15 +30,23 @@
|
||||
#include <SFML/Window/Export.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
class String;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Give access to the real-time state of the keyboard
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace sf::Keyboard
|
||||
namespace Keyboard
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Key codes
|
||||
///
|
||||
/// The enumerators refer to the "localized" key; i.e. depending
|
||||
/// on the layout set by the operating system, a key can be mapped
|
||||
/// to `Y` or `Z`.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
enum Key
|
||||
{
|
||||
@ -83,21 +91,21 @@ enum Key
|
||||
LControl, //!< The left Control key
|
||||
LShift, //!< The left Shift key
|
||||
LAlt, //!< The left Alt key
|
||||
LSystem, //!< The left OS specific key: window (Windows and Linux), apple (MacOS X), ...
|
||||
LSystem, //!< The left OS specific key: window (Windows and Linux), apple (macOS), ...
|
||||
RControl, //!< The right Control key
|
||||
RShift, //!< The right Shift key
|
||||
RAlt, //!< The right Alt key
|
||||
RSystem, //!< The right OS specific key: window (Windows and Linux), apple (MacOS X), ...
|
||||
RSystem, //!< The right OS specific key: window (Windows and Linux), apple (macOS), ...
|
||||
Menu, //!< The Menu key
|
||||
LBracket, //!< The [ key
|
||||
RBracket, //!< The ] key
|
||||
Semicolon, //!< The ; key
|
||||
Comma, //!< The , key
|
||||
Period, //!< The . key
|
||||
Quote, //!< The ' key
|
||||
Apostrophe, //!< The ' key
|
||||
Slash, //!< The / key
|
||||
Backslash, //!< The \ key
|
||||
Tilde, //!< The ~ key
|
||||
Grave, //!< The ` key
|
||||
Equal, //!< The = key
|
||||
Hyphen, //!< The - key (hyphen)
|
||||
Space, //!< The Space key
|
||||
@ -145,9 +153,205 @@ enum Key
|
||||
F15, //!< The F15 key
|
||||
Pause, //!< The Pause key
|
||||
|
||||
KeyCount //!< Keep last -- the total number of keyboard keys
|
||||
KeyCount, //!< Keep last -- the total number of keyboard keys
|
||||
|
||||
// Deprecated values:
|
||||
|
||||
Tilde = Grave, //!< \deprecated Use Grave instead
|
||||
Dash = Hyphen, //!< \deprecated Use Hyphen instead
|
||||
BackSpace = Backspace, //!< \deprecated Use Backspace instead
|
||||
BackSlash = Backslash, //!< \deprecated Use Backslash instead
|
||||
SemiColon = Semicolon, //!< \deprecated Use Semicolon instead
|
||||
Return = Enter, //!< \deprecated Use Enter instead
|
||||
Quote = Apostrophe //!< \deprecated Use Apostrophe instead
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Scancodes
|
||||
///
|
||||
/// The enumerators are bound to a physical key and do not depend on
|
||||
/// the keyboard layout used by the operating system. Usually, the AT-101
|
||||
/// keyboard can be used as reference for the physical position of the keys.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
struct Scan
|
||||
{
|
||||
// TODO: replace with enum class in SFML 3.
|
||||
// Clang warns us rightfully that Scancode names shadow Key names.
|
||||
// A safer solution would be to use a C++11 scoped enumeration (enum class),
|
||||
// but it is not possible in SFML 2 which uses C++03.
|
||||
// For now, we just ignore those warnings.
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
|
||||
enum Scancode
|
||||
{
|
||||
Unknown = -1, //!< Represents any scancode not present in this enum
|
||||
A = 0, //!< Keyboard a and A key
|
||||
B, //!< Keyboard b and B key
|
||||
C, //!< Keyboard c and C key
|
||||
D, //!< Keyboard d and D key
|
||||
E, //!< Keyboard e and E key
|
||||
F, //!< Keyboard f and F key
|
||||
G, //!< Keyboard g and G key
|
||||
H, //!< Keyboard h and H key
|
||||
I, //!< Keyboard i and I key
|
||||
J, //!< Keyboard j and J key
|
||||
K, //!< Keyboard k and K key
|
||||
L, //!< Keyboard l and L key
|
||||
M, //!< Keyboard m and M key
|
||||
N, //!< Keyboard n and N key
|
||||
O, //!< Keyboard o and O key
|
||||
P, //!< Keyboard p and P key
|
||||
Q, //!< Keyboard q and Q key
|
||||
R, //!< Keyboard r and R key
|
||||
S, //!< Keyboard s and S key
|
||||
T, //!< Keyboard t and T key
|
||||
U, //!< Keyboard u and U key
|
||||
V, //!< Keyboard v and V key
|
||||
W, //!< Keyboard w and W key
|
||||
X, //!< Keyboard x and X key
|
||||
Y, //!< Keyboard y and Y key
|
||||
Z, //!< Keyboard z and Z key
|
||||
Num1, //!< Keyboard 1 and ! key
|
||||
Num2, //!< Keyboard 2 and @ key
|
||||
Num3, //!< Keyboard 3 and # key
|
||||
Num4, //!< Keyboard 4 and $ key
|
||||
Num5, //!< Keyboard 5 and % key
|
||||
Num6, //!< Keyboard 6 and ^ key
|
||||
Num7, //!< Keyboard 7 and & key
|
||||
Num8, //!< Keyboard 8 and * key
|
||||
Num9, //!< Keyboard 9 and ) key
|
||||
Num0, //!< Keyboard 0 and ) key
|
||||
Enter, //!< Keyboard Enter/Return key
|
||||
Escape, //!< Keyboard Escape key
|
||||
Backspace, //!< Keyboard Backspace key
|
||||
Tab, //!< Keyboard Tab key
|
||||
Space, //!< Keyboard Space key
|
||||
Hyphen, //!< Keyboard - and _ key
|
||||
Equal, //!< Keyboard = and +
|
||||
LBracket, //!< Keyboard [ and { key
|
||||
RBracket, //!< Keyboard ] and } key
|
||||
// For US keyboards mapped to key 29 (Microsoft Keyboard Scan Code Specification)
|
||||
// For Non-US keyboards mapped to key 42 (Microsoft Keyboard Scan Code Specification)
|
||||
// Typical language mappings: Belg:£µ` FrCa:<>} Dan:*' Dutch:`´ Fren:µ* Ger:'# Ital:§ù LatAm:[}` Nor:*@ Span:ç} Swed:*' Swiss:$£} UK:~# Brazil:}]
|
||||
Backslash, //!< Keyboard \ and | key OR various keys for Non-US keyboards
|
||||
Semicolon, //!< Keyboard ; and : key
|
||||
Apostrophe, //!< Keyboard ' and " key
|
||||
Grave, //!< Keyboard ` and ~ key
|
||||
Comma, //!< Keyboard , and < key
|
||||
Period, //!< Keyboard . and > key
|
||||
Slash, //!< Keyboard / and ? key
|
||||
F1, //!< Keyboard F1 key
|
||||
F2, //!< Keyboard F2 key
|
||||
F3, //!< Keyboard F3 key
|
||||
F4, //!< Keyboard F4 key
|
||||
F5, //!< Keyboard F5 key
|
||||
F6, //!< Keyboard F6 key
|
||||
F7, //!< Keyboard F7 key
|
||||
F8, //!< Keyboard F8 key
|
||||
F9, //!< Keyboard F9 key
|
||||
F10, //!< Keyboard F10 key
|
||||
F11, //!< Keyboard F11 key
|
||||
F12, //!< Keyboard F12 key
|
||||
F13, //!< Keyboard F13 key
|
||||
F14, //!< Keyboard F14 key
|
||||
F15, //!< Keyboard F15 key
|
||||
F16, //!< Keyboard F16 key
|
||||
F17, //!< Keyboard F17 key
|
||||
F18, //!< Keyboard F18 key
|
||||
F19, //!< Keyboard F19 key
|
||||
F20, //!< Keyboard F20 key
|
||||
F21, //!< Keyboard F21 key
|
||||
F22, //!< Keyboard F22 key
|
||||
F23, //!< Keyboard F23 key
|
||||
F24, //!< Keyboard F24 key
|
||||
CapsLock, //!< Keyboard Caps %Lock key
|
||||
PrintScreen, //!< Keyboard Print Screen key
|
||||
ScrollLock, //!< Keyboard Scroll %Lock key
|
||||
Pause, //!< Keyboard Pause key
|
||||
Insert, //!< Keyboard Insert key
|
||||
Home, //!< Keyboard Home key
|
||||
PageUp, //!< Keyboard Page Up key
|
||||
Delete, //!< Keyboard Delete Forward key
|
||||
End, //!< Keyboard End key
|
||||
PageDown, //!< Keyboard Page Down key
|
||||
Right, //!< Keyboard Right Arrow key
|
||||
Left, //!< Keyboard Left Arrow key
|
||||
Down, //!< Keyboard Down Arrow key
|
||||
Up, //!< Keyboard Up Arrow key
|
||||
NumLock, //!< Keypad Num %Lock and Clear key
|
||||
NumpadDivide, //!< Keypad / key
|
||||
NumpadMultiply, //!< Keypad * key
|
||||
NumpadMinus, //!< Keypad - key
|
||||
NumpadPlus, //!< Keypad + key
|
||||
NumpadEqual, //!< keypad = key
|
||||
NumpadEnter, //!< Keypad Enter/Return key
|
||||
NumpadDecimal, //!< Keypad . and Delete key
|
||||
Numpad1, //!< Keypad 1 and End key
|
||||
Numpad2, //!< Keypad 2 and Down Arrow key
|
||||
Numpad3, //!< Keypad 3 and Page Down key
|
||||
Numpad4, //!< Keypad 4 and Left Arrow key
|
||||
Numpad5, //!< Keypad 5 key
|
||||
Numpad6, //!< Keypad 6 and Right Arrow key
|
||||
Numpad7, //!< Keypad 7 and Home key
|
||||
Numpad8, //!< Keypad 8 and Up Arrow key
|
||||
Numpad9, //!< Keypad 9 and Page Up key
|
||||
Numpad0, //!< Keypad 0 and Insert key
|
||||
// For US keyboards doesn't exist
|
||||
// For Non-US keyboards mapped to key 45 (Microsoft Keyboard Scan Code Specification)
|
||||
// Typical language mappings: Belg:<\> FrCa:«°» Dan:<\> Dutch:]|[ Fren:<> Ger:<|> Ital:<> LatAm:<> Nor:<> Span:<> Swed:<|> Swiss:<\> UK:\| Brazil: \|.
|
||||
NonUsBackslash, //!< Keyboard Non-US \ and | key
|
||||
Application, //!< Keyboard Application key
|
||||
Execute, //!< Keyboard Execute key
|
||||
ModeChange, //!< Keyboard Mode Change key
|
||||
Help, //!< Keyboard Help key
|
||||
Menu, //!< Keyboard Menu key
|
||||
Select, //!< Keyboard Select key
|
||||
Redo, //!< Keyboard Redo key
|
||||
Undo, //!< Keyboard Undo key
|
||||
Cut, //!< Keyboard Cut key
|
||||
Copy, //!< Keyboard Copy key
|
||||
Paste, //!< Keyboard Paste key
|
||||
VolumeMute, //!< Keyboard Volume Mute key
|
||||
VolumeUp, //!< Keyboard Volume Up key
|
||||
VolumeDown, //!< Keyboard Volume Down key
|
||||
MediaPlayPause, //!< Keyboard Media Play Pause key
|
||||
MediaStop, //!< Keyboard Media Stop key
|
||||
MediaNextTrack, //!< Keyboard Media Next Track key
|
||||
MediaPreviousTrack, //!< Keyboard Media Previous Track key
|
||||
LControl, //!< Keyboard Left Control key
|
||||
LShift, //!< Keyboard Left Shift key
|
||||
LAlt, //!< Keyboard Left Alt key
|
||||
LSystem, //!< Keyboard Left System key
|
||||
RControl, //!< Keyboard Right Control key
|
||||
RShift, //!< Keyboard Right Shift key
|
||||
RAlt, //!< Keyboard Right Alt key
|
||||
RSystem, //!< Keyboard Right System key
|
||||
Back, //!< Keyboard Back key
|
||||
Forward, //!< Keyboard Forward key
|
||||
Refresh, //!< Keyboard Refresh key
|
||||
Stop, //!< Keyboard Stop key
|
||||
Search, //!< Keyboard Search key
|
||||
Favorites, //!< Keyboard Favorites key
|
||||
HomePage, //!< Keyboard Home Page key
|
||||
LaunchApplication1, //!< Keyboard Launch Application 1 key
|
||||
LaunchApplication2, //!< Keyboard Launch Application 2 key
|
||||
LaunchMail, //!< Keyboard Launch Mail key
|
||||
LaunchMediaSelect, //!< Keyboard Launch Media Select key
|
||||
|
||||
ScancodeCount //!< Keep last -- the total number of scancodes
|
||||
};
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
};
|
||||
|
||||
using Scancode = Scan::Scancode;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
@ -158,10 +362,71 @@ enum Key
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API bool isKeyPressed(Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param code Scancode to check
|
||||
///
|
||||
/// \return True if the physical key is pressed, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API bool isKeyPressed(Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Localize a physical key to a logical one
|
||||
///
|
||||
/// \param code Scancode to localize
|
||||
///
|
||||
/// \return The key corresponding to the scancode under the current
|
||||
/// keyboard layout used by the operating system, or
|
||||
/// sf::Keyboard::Unknown when the scancode cannot be mapped
|
||||
/// to a Key.
|
||||
///
|
||||
/// \see delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API Key localize(Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Identify the physical key corresponding to a logical one
|
||||
///
|
||||
/// \param key Key to "delocalize"
|
||||
///
|
||||
/// \return The scancode corresponding to the key under the current
|
||||
/// keyboard layout used by the operating system, or
|
||||
/// sf::Keyboard::Scan::Unknown when the key cannot be mapped
|
||||
/// to a sf::Keyboard::Scancode.
|
||||
///
|
||||
/// \see localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API Scancode delocalize(Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Provide a string representation for a given scancode
|
||||
///
|
||||
/// The returned string is a short, non-technical description of
|
||||
/// the key represented with the given scancode. Most effectively
|
||||
/// used in user interfaces, as the description for the key takes
|
||||
/// the users keyboard layout into consideration.
|
||||
///
|
||||
/// \warning The result is OS-dependent: for example, sf::Keyboard::Scan::LSystem
|
||||
/// is "Left Meta" on Linux, "Left Windows" on Windows and
|
||||
/// "Left Command" on macOS.
|
||||
///
|
||||
/// The current keyboard layout set by the operating system is used to
|
||||
/// interpret the scancode: for example, sf::Keyboard::Semicolon is
|
||||
/// mapped to ";" for layout and to "é" for others.
|
||||
///
|
||||
/// \return The localized description of the code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API String getDescription(Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
///
|
||||
/// Warning: the virtual keyboard is not supported on all
|
||||
/// \warning The virtual keyboard is not supported on all
|
||||
/// systems. It will typically be implemented on mobile OSes
|
||||
/// (Android, iOS) but not on desktop OSes (Windows, Linux, ...).
|
||||
///
|
||||
@ -172,7 +437,9 @@ SFML_WINDOW_API bool isKeyPressed(Key key);
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFML_WINDOW_API void setVirtualKeyboardVisible(bool visible);
|
||||
} // namespace sf::Keyboard
|
||||
} // namespace Keyboard
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -206,6 +473,10 @@ SFML_WINDOW_API void setVirtualKeyboardVisible(bool visible);
|
||||
/// {
|
||||
/// // quit...
|
||||
/// }
|
||||
/// else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Grave))
|
||||
/// {
|
||||
/// // open in-game command line (if it's not already open)
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Joystick, sf::Mouse, sf::Touch
|
||||
|
@ -44,6 +44,30 @@ bool InputImpl::isKeyPressed(Keyboard::Key /* key */)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode /* codes */)
|
||||
{
|
||||
// Not applicable
|
||||
return false;
|
||||
}
|
||||
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// Not applicable
|
||||
return Keyboard::Unknown;
|
||||
}
|
||||
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key /* key */)
|
||||
{
|
||||
// Not applicable
|
||||
return Keyboard::Scan::Unknown;
|
||||
}
|
||||
|
||||
String InputImpl::getDescription(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// Not applicable
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setVirtualKeyboardVisible(bool visible)
|
||||
{
|
||||
|
@ -41,19 +41,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
|
@ -640,7 +640,7 @@ Keyboard::Key WindowImplAndroid::androidKeyToSF(std::int32_t key)
|
||||
case AKEYCODE_ENTER: return Keyboard::Enter;
|
||||
case AKEYCODE_DEL: return Keyboard::Backspace;
|
||||
case AKEYCODE_FORWARD_DEL: return Keyboard::Delete;
|
||||
case AKEYCODE_GRAVE: return Keyboard::Tilde;
|
||||
case AKEYCODE_GRAVE: return Keyboard::Grave;
|
||||
case AKEYCODE_MINUS: return Keyboard::Subtract;
|
||||
case AKEYCODE_EQUALS: return Keyboard::Equal;
|
||||
case AKEYCODE_LEFT_BRACKET: return Keyboard::LBracket;
|
||||
|
@ -116,6 +116,12 @@ elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_OPENBSD OR SFML_OS_NETBSD)
|
||||
${SRCROOT}/Unix/ClipboardImpl.cpp
|
||||
${SRCROOT}/Unix/InputImpl.cpp
|
||||
${SRCROOT}/Unix/InputImpl.hpp
|
||||
${SRCROOT}/Unix/KeyboardImpl.hpp
|
||||
${SRCROOT}/Unix/KeyboardImpl.cpp
|
||||
${SRCROOT}/Unix/KeySymToKeyMapping.hpp
|
||||
${SRCROOT}/Unix/KeySymToKeyMapping.cpp
|
||||
${SRCROOT}/Unix/KeySymToUnicodeMapping.hpp
|
||||
${SRCROOT}/Unix/KeySymToUnicodeMapping.cpp
|
||||
${SRCROOT}/Unix/SensorImpl.cpp
|
||||
${SRCROOT}/Unix/SensorImpl.hpp
|
||||
${SRCROOT}/Unix/Display.cpp
|
||||
|
@ -227,7 +227,7 @@ sf::Keyboard::Key toKey(int code)
|
||||
case KEY_L: return sf::Keyboard::L;
|
||||
case KEY_SEMICOLON: return sf::Keyboard::Semicolon;
|
||||
case KEY_APOSTROPHE: return sf::Keyboard::Quote;
|
||||
case KEY_GRAVE: return sf::Keyboard::Tilde;
|
||||
case KEY_GRAVE: return sf::Keyboard::Grave;
|
||||
case KEY_LEFTSHIFT: return sf::Keyboard::LShift;
|
||||
case KEY_BACKSLASH: return sf::Keyboard::Backslash;
|
||||
case KEY_Z: return sf::Keyboard::Z;
|
||||
@ -416,6 +416,7 @@ bool eventProcess(sf::Event& event)
|
||||
//
|
||||
event.type = inputEvent.value ? sf::Event::KeyPressed : sf::Event::KeyReleased;
|
||||
event.key.code = kb;
|
||||
event.key.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented
|
||||
event.key.alt = altDown();
|
||||
event.key.control = controlDown();
|
||||
event.key.shift = shiftDown();
|
||||
@ -575,6 +576,41 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
return keyMap[static_cast<std::size_t>(key)];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// TODO: not implemented
|
||||
err() << "sf::Keyboard::isKeyPressed(Keyboard::Scancode) is not implemented for DRM." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// TODO: not implemented
|
||||
err() << "sf::Keyboard::localize is not implemented for DRM." << std::endl;
|
||||
return Keyboard::Unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key /* key */)
|
||||
{
|
||||
// TODO: not implemented
|
||||
err() << "sf::Keyboard::delocalize is not implemented for DRM." << std::endl;
|
||||
return Keyboard::Scan::Unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String InputImpl::getDescription(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// TODO: not implemented
|
||||
err() << "sf::Keyboard::getDescription is not implemented for DRM." << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
|
@ -42,19 +42,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
|
@ -25,6 +25,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <SFML/Window/InputImpl.hpp>
|
||||
#include <SFML/Window/Keyboard.hpp>
|
||||
|
||||
@ -37,6 +38,29 @@ bool Keyboard::isKeyPressed(Key key)
|
||||
return priv::InputImpl::isKeyPressed(key);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Keyboard::isKeyPressed(Scancode code)
|
||||
{
|
||||
return priv::InputImpl::isKeyPressed(code);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key Keyboard::localize(Scancode code)
|
||||
{
|
||||
return priv::InputImpl::localize(code);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode Keyboard::delocalize(Key key)
|
||||
{
|
||||
return priv::InputImpl::delocalize(key);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String Keyboard::getDescription(Scancode code)
|
||||
{
|
||||
return priv::InputImpl::getDescription(code);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Keyboard::setVirtualKeyboardVisible(bool visible)
|
||||
|
@ -73,16 +73,6 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
static HIDInputManager& getInstance();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the usb location ID of a given device
|
||||
///
|
||||
@ -102,28 +92,69 @@ public:
|
||||
/// \return a retained CFDictionaryRef
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static CFDictionaryRef copyDevicesMask(UInt32 page, UInt32 usage);
|
||||
static CFDictionaryRef copyDevicesMask(std::uint32_t page, std::uint32_t usage);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Try to convert a character into a SFML key code.
|
||||
/// \brief Try to convert a character into a SFML key code
|
||||
///
|
||||
/// Return sf::Keyboard::Unknown if it doesn't match any 'localized' keys.
|
||||
///
|
||||
/// By 'localized' I mean keys that depend on the keyboard layout
|
||||
/// and might not be the same as the US keycode in some country
|
||||
/// (e.g. the keys 'Y' and 'Z' are switched on QWERTZ keyboard and
|
||||
/// By 'localized' we mean keys that depend on the keyboard layout
|
||||
/// and might not be the same as the US keycode for some countries
|
||||
/// (e.g. the keys 'Y' and 'Z' are swapped on QWERTZ keyboard and
|
||||
/// US keyboard layouts.)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localizedKeys(UniChar ch);
|
||||
static Keyboard::Key localizedKey(UniChar ch);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Try to convert a virtual keycode into a SFML key code.
|
||||
/// \brief Opposite transformation as localizedKeys
|
||||
///
|
||||
/// Return sf::Keyboard::Unknown if the keycode is unknown.
|
||||
/// Return 0x00 (NULL) for non-convertible keys/numpad numbers.
|
||||
/// For letters, uppercase codes are returned.
|
||||
/// Some returned value are specific to macOS.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key nonLocalizedKeys(UniChar virtualKeycode);
|
||||
static UniChar toUnicode(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Try to convert a virtual keycode (HID level) into a
|
||||
/// SFML scancode.
|
||||
///
|
||||
/// Return sf::Keyboard::Scan::Unknown if the keycode is unknown.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode nonLocalizedKey(UniChar virtualKeycode);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
String getDescription(Keyboard::Scancode code);
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -141,7 +172,13 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Initialize the keyboard part of this class
|
||||
///
|
||||
/// If something went wrong freeUp is called
|
||||
/// If something went wrong freeUp is called.
|
||||
///
|
||||
/// In a nutshell, this function does this:
|
||||
///
|
||||
/// for each connected keyboard kb:
|
||||
/// for each key k of kb:
|
||||
/// memorize k -> scancode mapping
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void initializeKeyboard();
|
||||
@ -150,28 +187,50 @@ private:
|
||||
/// \brief Load the given keyboard into m_keys
|
||||
///
|
||||
/// If the given keyboard has no key this function simply
|
||||
/// returns. freeUp is _not_ called because this is not fatal.
|
||||
/// returns without calling freeUp because this is not fatal.
|
||||
///
|
||||
/// \param keyboard Keyboard to load
|
||||
///
|
||||
/// \see initializeKeyboard
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void loadKeyboard(IOHIDDeviceRef keyboard);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the given key into m_keys
|
||||
///
|
||||
/// freeUp is _not_ called by this function.
|
||||
/// On error, freeUp is _not_ called by this function.
|
||||
///
|
||||
/// \param key Key to load
|
||||
///
|
||||
/// \see initializeKeyboard
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void loadKey(IOHIDElementRef key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Regenerate the mappings from/to Key and Scancode
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void buildMappings();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Callback to regenerate mappings from/to Key and
|
||||
/// Scancode when there's a keyboard layout change
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void keyboardChanged(CFNotificationCenterRef /* center */,
|
||||
void* observer,
|
||||
CFStringRef /* name */,
|
||||
const void* /* object */,
|
||||
CFDictionaryRef /* userInfo */);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Release all resources
|
||||
///
|
||||
/// Close all connections to any devices, if required
|
||||
/// Set m_isValid to false
|
||||
/// Close all connections to any devices.
|
||||
///
|
||||
/// \see initializeKeyboard
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void freeUp();
|
||||
@ -179,14 +238,14 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Filter the devices and return them
|
||||
///
|
||||
/// freeUp is _not_ called by this function.
|
||||
/// On error, freeUp is _not_ called by this function.
|
||||
///
|
||||
/// \param page HID page like kHIDPage_GenericDesktop
|
||||
/// \param usage HID usage page like kHIDUsage_GD_Keyboard or kHIDUsage_GD_Mouse
|
||||
/// \return a retained CFSetRef of IOHIDDeviceRef or a null pointer
|
||||
/// \return a retained, non-empty CFSetRef of IOHIDDeviceRef or a null pointer
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CFSetRef copyDevices(UInt32 page, UInt32 usage);
|
||||
CFSetRef copyDevices(std::uint32_t page, std::uint32_t usage);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
@ -201,34 +260,46 @@ private:
|
||||
bool isPressed(IOHIDElements& elements);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert a HID key usage to its corresponding virtual code
|
||||
///
|
||||
/// See IOHIDUsageTables.h
|
||||
/// \brief Convert a HID key usage to its corresponding scancode
|
||||
///
|
||||
/// \param usage Any kHIDUsage_Keyboard* usage
|
||||
/// \return the virtual code associate with the given HID key usage
|
||||
/// or 0xff if it is associate with no virtual code
|
||||
/// \return the scancode associated with the given HID key usage
|
||||
/// or Scan::Unknown if it is associated with no scancode.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static UInt8 usageToVirtualCode(UInt32 usage);
|
||||
static Keyboard::Scancode usageToScancode(std::uint32_t usage);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Convert the scancode to the expected virtual code.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static std::uint8_t scanToVirtualCode(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Fallback convertion for keys which aren't expected to be impacted
|
||||
/// by the layout. Can return Unknown.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localizedKeyFallback(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
bool m_isValid{true}; ///< If any error occurs this variable is false
|
||||
CFDataRef m_layoutData{}; ///< CFData containing the layout
|
||||
UCKeyboardLayout* m_layout{}; ///< Current Keyboard Layout
|
||||
IOHIDManagerRef m_manager{}; ///< HID Manager
|
||||
|
||||
IOHIDElements m_keys[Keyboard::KeyCount]; ///< All the keys on any connected keyboard
|
||||
IOHIDManagerRef m_manager{}; ///< Underlying HID Manager
|
||||
IOHIDElements m_keys[Keyboard::Scan::ScancodeCount]; ///< All the keys on any connected keyboard
|
||||
Keyboard::Scancode m_keyToScancodeMapping[Keyboard::KeyCount]; ///< Mapping from Key to Scancode
|
||||
Keyboard::Key m_scancodeToKeyMapping[Keyboard::Scan::ScancodeCount]; ///< Mapping from Scancode to Key
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// m_keys' index corresponds to sf::Keyboard::Key enum.
|
||||
/// if no key is assigned with key XYZ then m_keys[XYZ].size() == 0.
|
||||
/// if there are several keyboards connected and several HID keys associate
|
||||
/// m_keys' index corresponds to sf::Keyboard::Scancode enum.
|
||||
/// If no key is assigned with key XYZ then m_keys[XYZ].size() == 0.
|
||||
/// If there are several keyboards connected and several HID keys associated
|
||||
/// with the same sf::Keyboard::Key then m_keys[XYZ] contains all these
|
||||
/// HID keys.
|
||||
///
|
||||
/// The mappings (both directions) get invalidated when the
|
||||
/// keyboard layout changes. They both default to (Scan::)Unknown.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,19 +42,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
|
@ -41,9 +41,6 @@
|
||||
/// In order to keep track of the keyboard's state and mouse buttons' state
|
||||
/// we use the HID manager. Mouse position is handled differently.
|
||||
///
|
||||
/// NB: we probably could use
|
||||
/// NSEvent +addGlobalMonitorForEventsMatchingMask:handler: for mouse only.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
namespace sf::priv
|
||||
@ -118,6 +115,7 @@ SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const WindowBase& window)
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
@ -126,6 +124,34 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode code)
|
||||
{
|
||||
return HIDInputManager::getInstance().isKeyPressed(code);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode code)
|
||||
{
|
||||
return HIDInputManager::getInstance().localize(code);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key key)
|
||||
{
|
||||
return HIDInputManager::getInstance().delocalize(key);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String InputImpl::getDescription(Keyboard::Scancode code)
|
||||
{
|
||||
return HIDInputManager::getInstance().getDescription(code);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ void initialiseKeyboardHelper();
|
||||
/// \brief Set up a SFML key event based on the given modifiers flags and key code
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key);
|
||||
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -62,6 +62,7 @@ struct ModifiersState
|
||||
BOOL leftAlternateWasDown;
|
||||
BOOL leftControlWasDown;
|
||||
BOOL rightControlWasDown;
|
||||
BOOL capsLockWasOn;
|
||||
};
|
||||
|
||||
|
||||
@ -95,6 +96,7 @@ void processOneModifier(NSUInteger modifiers,
|
||||
NSUInteger mask,
|
||||
BOOL& wasDown,
|
||||
sf::Keyboard::Key key,
|
||||
sf::Keyboard::Scancode code,
|
||||
sf::priv::WindowImplCocoa& requester);
|
||||
|
||||
|
||||
@ -112,6 +114,8 @@ void processLeftRightModifiers(
|
||||
BOOL& rightWasDown,
|
||||
sf::Keyboard::Key leftKey,
|
||||
sf::Keyboard::Key rightKey,
|
||||
sf::Keyboard::Scancode leftCode,
|
||||
sf::Keyboard::Scancode rightCode,
|
||||
sf::priv::WindowImplCocoa& requester);
|
||||
|
||||
|
||||
@ -137,16 +141,18 @@ void initialiseKeyboardHelper()
|
||||
state.rightAlternateWasDown = isKeyMaskActive(modifiers, NSRightAlternateKeyMask);
|
||||
state.leftControlWasDown = isKeyMaskActive(modifiers, NSLeftControlKeyMask);
|
||||
state.rightControlWasDown = isKeyMaskActive(modifiers, NSRightControlKeyMask);
|
||||
state.capsLockWasOn = isKeyMaskActive(modifiers, NSEventModifierFlagCapsLock);
|
||||
|
||||
isStateInitialized = YES;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key)
|
||||
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code)
|
||||
{
|
||||
sf::Event::KeyEvent event;
|
||||
event.code = key;
|
||||
event.scancode = code;
|
||||
event.alt = modifiers & NSAlternateKeyMask;
|
||||
event.control = modifiers & NSControlKeyMask;
|
||||
event.shift = modifiers & NSShiftKeyMask;
|
||||
@ -167,6 +173,8 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req
|
||||
state.rightShiftWasDown,
|
||||
sf::Keyboard::LShift,
|
||||
sf::Keyboard::RShift,
|
||||
sf::Keyboard::Scan::LShift,
|
||||
sf::Keyboard::Scan::RShift,
|
||||
requester);
|
||||
|
||||
// Handle command
|
||||
@ -177,6 +185,8 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req
|
||||
state.rightCommandWasDown,
|
||||
sf::Keyboard::LSystem,
|
||||
sf::Keyboard::RSystem,
|
||||
sf::Keyboard::Scan::LSystem,
|
||||
sf::Keyboard::Scan::RSystem,
|
||||
requester);
|
||||
|
||||
// Handle option (alt)
|
||||
@ -187,6 +197,8 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req
|
||||
state.rightAlternateWasDown,
|
||||
sf::Keyboard::LAlt,
|
||||
sf::Keyboard::RAlt,
|
||||
sf::Keyboard::Scan::LAlt,
|
||||
sf::Keyboard::Scan::RAlt,
|
||||
requester);
|
||||
|
||||
// Handle control
|
||||
@ -197,6 +209,16 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req
|
||||
state.rightControlWasDown,
|
||||
sf::Keyboard::LControl,
|
||||
sf::Keyboard::RControl,
|
||||
sf::Keyboard::Scan::LControl,
|
||||
sf::Keyboard::Scan::RControl,
|
||||
requester);
|
||||
|
||||
// Handle caps lock
|
||||
processOneModifier(modifiers,
|
||||
NSEventModifierFlagCapsLock,
|
||||
state.capsLockWasOn,
|
||||
sf::Keyboard::Unknown,
|
||||
sf::Keyboard::Scan::CapsLock,
|
||||
requester);
|
||||
}
|
||||
|
||||
@ -212,10 +234,15 @@ BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
void processOneModifier(NSUInteger modifiers, NSUInteger mask, BOOL& wasDown, sf::Keyboard::Key key, sf::priv::WindowImplCocoa& requester)
|
||||
void processOneModifier(NSUInteger modifiers,
|
||||
NSUInteger mask,
|
||||
BOOL& wasDown,
|
||||
sf::Keyboard::Key key,
|
||||
sf::Keyboard::Scancode code,
|
||||
sf::priv::WindowImplCocoa& requester)
|
||||
{
|
||||
// Setup a potential event key.
|
||||
sf::Event::KeyEvent event = keyEventWithModifiers(modifiers, key);
|
||||
sf::Event::KeyEvent event = keyEventWithModifiers(modifiers, key, code);
|
||||
|
||||
// State
|
||||
BOOL isDown = isKeyMaskActive(modifiers, mask);
|
||||
@ -244,8 +271,10 @@ void processLeftRightModifiers(
|
||||
BOOL& rightWasDown,
|
||||
sf::Keyboard::Key leftKey,
|
||||
sf::Keyboard::Key rightKey,
|
||||
sf::Keyboard::Scancode leftCode,
|
||||
sf::Keyboard::Scancode rightCode,
|
||||
sf::priv::WindowImplCocoa& requester)
|
||||
{
|
||||
processOneModifier(modifiers, leftMask, leftWasDown, leftKey, requester);
|
||||
processOneModifier(modifiers, rightMask, rightWasDown, rightKey, requester);
|
||||
processOneModifier(modifiers, leftMask, leftWasDown, leftKey, leftCode, requester);
|
||||
processOneModifier(modifiers, rightMask, rightWasDown, rightKey, rightCode, requester);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@
|
||||
{
|
||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||
|
||||
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
||||
if ((key.code != sf::Keyboard::Unknown) || (key.scancode != sf::Keyboard::Scan::Unknown))
|
||||
m_requester->keyDown(key);
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@
|
||||
|
||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||
|
||||
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
||||
if ((key.code != sf::Keyboard::Unknown) || (key.scancode != sf::Keyboard::Scan::Unknown))
|
||||
m_requester->keyUp(key);
|
||||
}
|
||||
|
||||
@ -180,21 +180,13 @@
|
||||
////////////////////////////////////////////////////////
|
||||
+ (sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
|
||||
{
|
||||
// Key code
|
||||
sf::Keyboard::Key key = sf::Keyboard::Unknown;
|
||||
// The scancode always depends on the hardware keyboard, not some OS setting.
|
||||
sf::Keyboard::Scancode code = sf::priv::HIDInputManager::nonLocalizedKey([event keyCode]);
|
||||
|
||||
// First we look if the key down is from a list of characters
|
||||
// that depend on keyboard localization.
|
||||
NSString* string = [event charactersIgnoringModifiers];
|
||||
if ([string length] > 0)
|
||||
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
|
||||
// Get the corresponding key under the current keyboard layout.
|
||||
sf::Keyboard::Key key = sf::Keyboard::localize(code);
|
||||
|
||||
// If the key is not a localized one, we try to find a corresponding code
|
||||
// through virtual key code.
|
||||
if (key == sf::Keyboard::Unknown)
|
||||
key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
|
||||
|
||||
return keyEventWithModifiers([event modifierFlags], key);
|
||||
return keyEventWithModifiers([event modifierFlags], key, code);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,9 +25,12 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <SFML/Window/Unix/Display.hpp>
|
||||
#include <SFML/Window/Unix/InputImpl.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <SFML/Window/Unix/KeyboardImpl.hpp>
|
||||
#include <SFML/Window/WindowBase.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
@ -38,145 +41,35 @@ namespace sf::priv
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
// Get the corresponding X11 keysym
|
||||
KeySym keysym = 0;
|
||||
|
||||
// clang-format off
|
||||
switch (key)
|
||||
{
|
||||
case Keyboard::LShift: keysym = XK_Shift_L; break;
|
||||
case Keyboard::RShift: keysym = XK_Shift_R; break;
|
||||
case Keyboard::LControl: keysym = XK_Control_L; break;
|
||||
case Keyboard::RControl: keysym = XK_Control_R; break;
|
||||
case Keyboard::LAlt: keysym = XK_Alt_L; break;
|
||||
case Keyboard::RAlt: keysym = XK_Alt_R; break;
|
||||
case Keyboard::LSystem: keysym = XK_Super_L; break;
|
||||
case Keyboard::RSystem: keysym = XK_Super_R; break;
|
||||
case Keyboard::Menu: keysym = XK_Menu; break;
|
||||
case Keyboard::Escape: keysym = XK_Escape; break;
|
||||
case Keyboard::Semicolon: keysym = XK_semicolon; break;
|
||||
case Keyboard::Slash: keysym = XK_slash; break;
|
||||
case Keyboard::Equal: keysym = XK_equal; break;
|
||||
case Keyboard::Hyphen: keysym = XK_minus; break;
|
||||
case Keyboard::LBracket: keysym = XK_bracketleft; break;
|
||||
case Keyboard::RBracket: keysym = XK_bracketright; break;
|
||||
case Keyboard::Comma: keysym = XK_comma; break;
|
||||
case Keyboard::Period: keysym = XK_period; break;
|
||||
case Keyboard::Quote: keysym = XK_apostrophe; break;
|
||||
case Keyboard::Backslash: keysym = XK_backslash; break;
|
||||
case Keyboard::Tilde: keysym = XK_grave; break;
|
||||
case Keyboard::Space: keysym = XK_space; break;
|
||||
case Keyboard::Enter: keysym = XK_Return; break;
|
||||
case Keyboard::Backspace: keysym = XK_BackSpace; break;
|
||||
case Keyboard::Tab: keysym = XK_Tab; break;
|
||||
case Keyboard::PageUp: keysym = XK_Prior; break;
|
||||
case Keyboard::PageDown: keysym = XK_Next; break;
|
||||
case Keyboard::End: keysym = XK_End; break;
|
||||
case Keyboard::Home: keysym = XK_Home; break;
|
||||
case Keyboard::Insert: keysym = XK_Insert; break;
|
||||
case Keyboard::Delete: keysym = XK_Delete; break;
|
||||
case Keyboard::Add: keysym = XK_KP_Add; break;
|
||||
case Keyboard::Subtract: keysym = XK_KP_Subtract; break;
|
||||
case Keyboard::Multiply: keysym = XK_KP_Multiply; break;
|
||||
case Keyboard::Divide: keysym = XK_KP_Divide; break;
|
||||
case Keyboard::Pause: keysym = XK_Pause; break;
|
||||
case Keyboard::F1: keysym = XK_F1; break;
|
||||
case Keyboard::F2: keysym = XK_F2; break;
|
||||
case Keyboard::F3: keysym = XK_F3; break;
|
||||
case Keyboard::F4: keysym = XK_F4; break;
|
||||
case Keyboard::F5: keysym = XK_F5; break;
|
||||
case Keyboard::F6: keysym = XK_F6; break;
|
||||
case Keyboard::F7: keysym = XK_F7; break;
|
||||
case Keyboard::F8: keysym = XK_F8; break;
|
||||
case Keyboard::F9: keysym = XK_F9; break;
|
||||
case Keyboard::F10: keysym = XK_F10; break;
|
||||
case Keyboard::F11: keysym = XK_F11; break;
|
||||
case Keyboard::F12: keysym = XK_F12; break;
|
||||
case Keyboard::F13: keysym = XK_F13; break;
|
||||
case Keyboard::F14: keysym = XK_F14; break;
|
||||
case Keyboard::F15: keysym = XK_F15; break;
|
||||
case Keyboard::Left: keysym = XK_Left; break;
|
||||
case Keyboard::Right: keysym = XK_Right; break;
|
||||
case Keyboard::Up: keysym = XK_Up; break;
|
||||
case Keyboard::Down: keysym = XK_Down; break;
|
||||
case Keyboard::Numpad0: keysym = XK_KP_Insert; break;
|
||||
case Keyboard::Numpad1: keysym = XK_KP_End; break;
|
||||
case Keyboard::Numpad2: keysym = XK_KP_Down; break;
|
||||
case Keyboard::Numpad3: keysym = XK_KP_Page_Down; break;
|
||||
case Keyboard::Numpad4: keysym = XK_KP_Left; break;
|
||||
case Keyboard::Numpad5: keysym = XK_KP_Begin; break;
|
||||
case Keyboard::Numpad6: keysym = XK_KP_Right; break;
|
||||
case Keyboard::Numpad7: keysym = XK_KP_Home; break;
|
||||
case Keyboard::Numpad8: keysym = XK_KP_Up; break;
|
||||
case Keyboard::Numpad9: keysym = XK_KP_Page_Up; break;
|
||||
case Keyboard::A: keysym = XK_a; break;
|
||||
case Keyboard::B: keysym = XK_b; break;
|
||||
case Keyboard::C: keysym = XK_c; break;
|
||||
case Keyboard::D: keysym = XK_d; break;
|
||||
case Keyboard::E: keysym = XK_e; break;
|
||||
case Keyboard::F: keysym = XK_f; break;
|
||||
case Keyboard::G: keysym = XK_g; break;
|
||||
case Keyboard::H: keysym = XK_h; break;
|
||||
case Keyboard::I: keysym = XK_i; break;
|
||||
case Keyboard::J: keysym = XK_j; break;
|
||||
case Keyboard::K: keysym = XK_k; break;
|
||||
case Keyboard::L: keysym = XK_l; break;
|
||||
case Keyboard::M: keysym = XK_m; break;
|
||||
case Keyboard::N: keysym = XK_n; break;
|
||||
case Keyboard::O: keysym = XK_o; break;
|
||||
case Keyboard::P: keysym = XK_p; break;
|
||||
case Keyboard::Q: keysym = XK_q; break;
|
||||
case Keyboard::R: keysym = XK_r; break;
|
||||
case Keyboard::S: keysym = XK_s; break;
|
||||
case Keyboard::T: keysym = XK_t; break;
|
||||
case Keyboard::U: keysym = XK_u; break;
|
||||
case Keyboard::V: keysym = XK_v; break;
|
||||
case Keyboard::W: keysym = XK_w; break;
|
||||
case Keyboard::X: keysym = XK_x; break;
|
||||
case Keyboard::Y: keysym = XK_y; break;
|
||||
case Keyboard::Z: keysym = XK_z; break;
|
||||
case Keyboard::Num0: keysym = XK_0; break;
|
||||
case Keyboard::Num1: keysym = XK_1; break;
|
||||
case Keyboard::Num2: keysym = XK_2; break;
|
||||
case Keyboard::Num3: keysym = XK_3; break;
|
||||
case Keyboard::Num4: keysym = XK_4; break;
|
||||
case Keyboard::Num5: keysym = XK_5; break;
|
||||
case Keyboard::Num6: keysym = XK_6; break;
|
||||
case Keyboard::Num7: keysym = XK_7; break;
|
||||
case Keyboard::Num8: keysym = XK_8; break;
|
||||
case Keyboard::Num9: keysym = XK_9; break;
|
||||
default: keysym = 0; break;
|
||||
return KeyboardImpl::isKeyPressed(key);
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
// Sanity checks
|
||||
if (key < 0 || key >= sf::Keyboard::KeyCount)
|
||||
return false;
|
||||
|
||||
// Open a connection with the X server
|
||||
Display* display = openDisplay();
|
||||
|
||||
// Convert to keycode
|
||||
KeyCode keycode = XKeysymToKeycode(display, keysym);
|
||||
if (keycode != 0)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode code)
|
||||
{
|
||||
// Get the whole keyboard state
|
||||
char keys[32];
|
||||
XQueryKeymap(display, keys);
|
||||
|
||||
// Close the connection with the X server
|
||||
closeDisplay(display);
|
||||
|
||||
// Check our keycode
|
||||
return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
|
||||
return KeyboardImpl::isKeyPressed(code);
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode code)
|
||||
{
|
||||
// Close the connection with the X server
|
||||
closeDisplay(display);
|
||||
|
||||
return false;
|
||||
return KeyboardImpl::localize(code);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key key)
|
||||
{
|
||||
return KeyboardImpl::delocalize(key);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String InputImpl::getDescription(Keyboard::Scancode code)
|
||||
{
|
||||
return KeyboardImpl::getDescription(code);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,19 +41,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
|
262
src/SFML/Window/Unix/KeySymToKeyMapping.cpp
Normal file
262
src/SFML/Window/Unix/KeySymToKeyMapping.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Unix/KeySymToKeyMapping.hpp>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key keySymToKey(KeySym symbol)
|
||||
{
|
||||
// clang-format off
|
||||
switch (symbol)
|
||||
{
|
||||
case XK_Shift_L: return Keyboard::LShift;
|
||||
case XK_Shift_R: return Keyboard::RShift;
|
||||
case XK_Control_L: return Keyboard::LControl;
|
||||
case XK_Control_R: return Keyboard::RControl;
|
||||
case XK_Alt_L: return Keyboard::LAlt;
|
||||
case XK_ISO_Level3_Shift:
|
||||
case XK_Alt_R: return Keyboard::RAlt;
|
||||
case XK_Super_L: return Keyboard::LSystem;
|
||||
case XK_Super_R: return Keyboard::RSystem;
|
||||
case XK_Menu: return Keyboard::Menu;
|
||||
case XK_Escape: return Keyboard::Escape;
|
||||
case XK_semicolon: return Keyboard::SemiColon;
|
||||
case XK_slash: return Keyboard::Slash;
|
||||
case XK_equal: return Keyboard::Equal;
|
||||
case XK_minus: return Keyboard::Dash;
|
||||
case XK_bracketleft: return Keyboard::LBracket;
|
||||
case XK_bracketright: return Keyboard::RBracket;
|
||||
case XK_comma: return Keyboard::Comma;
|
||||
case XK_period: return Keyboard::Period;
|
||||
case XK_apostrophe: return Keyboard::Quote;
|
||||
case XK_backslash: return Keyboard::BackSlash;
|
||||
case XK_grave: return Keyboard::Grave;
|
||||
case XK_space: return Keyboard::Space;
|
||||
case XK_Return: return Keyboard::Return;
|
||||
case XK_KP_Enter: return Keyboard::Return;
|
||||
case XK_BackSpace: return Keyboard::BackSpace;
|
||||
case XK_Tab: return Keyboard::Tab;
|
||||
case XK_Prior: return Keyboard::PageUp;
|
||||
case XK_Next: return Keyboard::PageDown;
|
||||
case XK_End: return Keyboard::End;
|
||||
case XK_Home: return Keyboard::Home;
|
||||
case XK_Insert: return Keyboard::Insert;
|
||||
case XK_Delete: return Keyboard::Delete;
|
||||
case XK_KP_Add: return Keyboard::Add;
|
||||
case XK_KP_Subtract: return Keyboard::Subtract;
|
||||
case XK_KP_Multiply: return Keyboard::Multiply;
|
||||
case XK_KP_Divide: return Keyboard::Divide;
|
||||
case XK_KP_Delete: return Keyboard::Period;
|
||||
case XK_Pause: return Keyboard::Pause;
|
||||
case XK_F1: return Keyboard::F1;
|
||||
case XK_F2: return Keyboard::F2;
|
||||
case XK_F3: return Keyboard::F3;
|
||||
case XK_F4: return Keyboard::F4;
|
||||
case XK_F5: return Keyboard::F5;
|
||||
case XK_F6: return Keyboard::F6;
|
||||
case XK_F7: return Keyboard::F7;
|
||||
case XK_F8: return Keyboard::F8;
|
||||
case XK_F9: return Keyboard::F9;
|
||||
case XK_F10: return Keyboard::F10;
|
||||
case XK_F11: return Keyboard::F11;
|
||||
case XK_F12: return Keyboard::F12;
|
||||
case XK_F13: return Keyboard::F13;
|
||||
case XK_F14: return Keyboard::F14;
|
||||
case XK_F15: return Keyboard::F15;
|
||||
case XK_Left: return Keyboard::Left;
|
||||
case XK_Right: return Keyboard::Right;
|
||||
case XK_Up: return Keyboard::Up;
|
||||
case XK_Down: return Keyboard::Down;
|
||||
case XK_KP_Insert: return Keyboard::Numpad0;
|
||||
case XK_KP_End: return Keyboard::Numpad1;
|
||||
case XK_KP_Down: return Keyboard::Numpad2;
|
||||
case XK_KP_Page_Down: return Keyboard::Numpad3;
|
||||
case XK_KP_Left: return Keyboard::Numpad4;
|
||||
case XK_KP_Begin: return Keyboard::Numpad5;
|
||||
case XK_KP_Right: return Keyboard::Numpad6;
|
||||
case XK_KP_Home: return Keyboard::Numpad7;
|
||||
case XK_KP_Up: return Keyboard::Numpad8;
|
||||
case XK_KP_Page_Up: return Keyboard::Numpad9;
|
||||
case XK_a: return Keyboard::A;
|
||||
case XK_b: return Keyboard::B;
|
||||
case XK_c: return Keyboard::C;
|
||||
case XK_d: return Keyboard::D;
|
||||
case XK_e: return Keyboard::E;
|
||||
case XK_f: return Keyboard::F;
|
||||
case XK_g: return Keyboard::G;
|
||||
case XK_h: return Keyboard::H;
|
||||
case XK_i: return Keyboard::I;
|
||||
case XK_j: return Keyboard::J;
|
||||
case XK_k: return Keyboard::K;
|
||||
case XK_l: return Keyboard::L;
|
||||
case XK_m: return Keyboard::M;
|
||||
case XK_n: return Keyboard::N;
|
||||
case XK_o: return Keyboard::O;
|
||||
case XK_p: return Keyboard::P;
|
||||
case XK_q: return Keyboard::Q;
|
||||
case XK_r: return Keyboard::R;
|
||||
case XK_s: return Keyboard::S;
|
||||
case XK_t: return Keyboard::T;
|
||||
case XK_u: return Keyboard::U;
|
||||
case XK_v: return Keyboard::V;
|
||||
case XK_w: return Keyboard::W;
|
||||
case XK_x: return Keyboard::X;
|
||||
case XK_y: return Keyboard::Y;
|
||||
case XK_z: return Keyboard::Z;
|
||||
case XK_0: return Keyboard::Num0;
|
||||
case XK_1: return Keyboard::Num1;
|
||||
case XK_2: return Keyboard::Num2;
|
||||
case XK_3: return Keyboard::Num3;
|
||||
case XK_4: return Keyboard::Num4;
|
||||
case XK_5: return Keyboard::Num5;
|
||||
case XK_6: return Keyboard::Num6;
|
||||
case XK_7: return Keyboard::Num7;
|
||||
case XK_8: return Keyboard::Num8;
|
||||
case XK_9: return Keyboard::Num9;
|
||||
default: return Keyboard::Unknown;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
KeySym keyToKeySym(Keyboard::Key key)
|
||||
{
|
||||
// clang-format off
|
||||
switch (key)
|
||||
{
|
||||
case Keyboard::LShift: return XK_Shift_L;
|
||||
case Keyboard::RShift: return XK_Shift_R;
|
||||
case Keyboard::LControl: return XK_Control_L;
|
||||
case Keyboard::RControl: return XK_Control_R;
|
||||
case Keyboard::LAlt: return XK_Alt_L;
|
||||
case Keyboard::RAlt: return XK_Alt_R;
|
||||
case Keyboard::LSystem: return XK_Super_L;
|
||||
case Keyboard::RSystem: return XK_Super_R;
|
||||
case Keyboard::Menu: return XK_Menu;
|
||||
case Keyboard::Escape: return XK_Escape;
|
||||
case Keyboard::SemiColon: return XK_semicolon;
|
||||
case Keyboard::Slash: return XK_slash;
|
||||
case Keyboard::Equal: return XK_equal;
|
||||
case Keyboard::Dash: return XK_minus;
|
||||
case Keyboard::LBracket: return XK_bracketleft;
|
||||
case Keyboard::RBracket: return XK_bracketright;
|
||||
case Keyboard::Comma: return XK_comma;
|
||||
case Keyboard::Period: return XK_period;
|
||||
case Keyboard::Quote: return XK_apostrophe;
|
||||
case Keyboard::BackSlash: return XK_backslash;
|
||||
case Keyboard::Grave: return XK_grave;
|
||||
case Keyboard::Space: return XK_space;
|
||||
case Keyboard::Return: return XK_Return;
|
||||
case Keyboard::BackSpace: return XK_BackSpace;
|
||||
case Keyboard::Tab: return XK_Tab;
|
||||
case Keyboard::PageUp: return XK_Prior;
|
||||
case Keyboard::PageDown: return XK_Next;
|
||||
case Keyboard::End: return XK_End;
|
||||
case Keyboard::Home: return XK_Home;
|
||||
case Keyboard::Insert: return XK_Insert;
|
||||
case Keyboard::Delete: return XK_Delete;
|
||||
case Keyboard::Add: return XK_KP_Add;
|
||||
case Keyboard::Subtract: return XK_KP_Subtract;
|
||||
case Keyboard::Multiply: return XK_KP_Multiply;
|
||||
case Keyboard::Divide: return XK_KP_Divide;
|
||||
case Keyboard::Pause: return XK_Pause;
|
||||
case Keyboard::F1: return XK_F1;
|
||||
case Keyboard::F2: return XK_F2;
|
||||
case Keyboard::F3: return XK_F3;
|
||||
case Keyboard::F4: return XK_F4;
|
||||
case Keyboard::F5: return XK_F5;
|
||||
case Keyboard::F6: return XK_F6;
|
||||
case Keyboard::F7: return XK_F7;
|
||||
case Keyboard::F8: return XK_F8;
|
||||
case Keyboard::F9: return XK_F9;
|
||||
case Keyboard::F10: return XK_F10;
|
||||
case Keyboard::F11: return XK_F11;
|
||||
case Keyboard::F12: return XK_F12;
|
||||
case Keyboard::F13: return XK_F13;
|
||||
case Keyboard::F14: return XK_F14;
|
||||
case Keyboard::F15: return XK_F15;
|
||||
case Keyboard::Left: return XK_Left;
|
||||
case Keyboard::Right: return XK_Right;
|
||||
case Keyboard::Up: return XK_Up;
|
||||
case Keyboard::Down: return XK_Down;
|
||||
case Keyboard::Numpad0: return XK_KP_Insert;
|
||||
case Keyboard::Numpad1: return XK_KP_End;
|
||||
case Keyboard::Numpad2: return XK_KP_Down;
|
||||
case Keyboard::Numpad3: return XK_KP_Page_Down;
|
||||
case Keyboard::Numpad4: return XK_KP_Left;
|
||||
case Keyboard::Numpad5: return XK_KP_Begin;
|
||||
case Keyboard::Numpad6: return XK_KP_Right;
|
||||
case Keyboard::Numpad7: return XK_KP_Home;
|
||||
case Keyboard::Numpad8: return XK_KP_Up;
|
||||
case Keyboard::Numpad9: return XK_KP_Page_Up;
|
||||
case Keyboard::A: return XK_a;
|
||||
case Keyboard::B: return XK_b;
|
||||
case Keyboard::C: return XK_c;
|
||||
case Keyboard::D: return XK_d;
|
||||
case Keyboard::E: return XK_e;
|
||||
case Keyboard::F: return XK_f;
|
||||
case Keyboard::G: return XK_g;
|
||||
case Keyboard::H: return XK_h;
|
||||
case Keyboard::I: return XK_i;
|
||||
case Keyboard::J: return XK_j;
|
||||
case Keyboard::K: return XK_k;
|
||||
case Keyboard::L: return XK_l;
|
||||
case Keyboard::M: return XK_m;
|
||||
case Keyboard::N: return XK_n;
|
||||
case Keyboard::O: return XK_o;
|
||||
case Keyboard::P: return XK_p;
|
||||
case Keyboard::Q: return XK_q;
|
||||
case Keyboard::R: return XK_r;
|
||||
case Keyboard::S: return XK_s;
|
||||
case Keyboard::T: return XK_t;
|
||||
case Keyboard::U: return XK_u;
|
||||
case Keyboard::V: return XK_v;
|
||||
case Keyboard::W: return XK_w;
|
||||
case Keyboard::X: return XK_x;
|
||||
case Keyboard::Y: return XK_y;
|
||||
case Keyboard::Z: return XK_z;
|
||||
case Keyboard::Num0: return XK_0;
|
||||
case Keyboard::Num1: return XK_1;
|
||||
case Keyboard::Num2: return XK_2;
|
||||
case Keyboard::Num3: return XK_3;
|
||||
case Keyboard::Num4: return XK_4;
|
||||
case Keyboard::Num5: return XK_5;
|
||||
case Keyboard::Num6: return XK_6;
|
||||
case Keyboard::Num7: return XK_7;
|
||||
case Keyboard::Num8: return XK_8;
|
||||
case Keyboard::Num9: return XK_9;
|
||||
default: return NoSymbol;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
} // namespace sf::priv
|
57
src/SFML/Window/Unix/KeySymToKeyMapping.hpp
Normal file
57
src/SFML/Window/Unix/KeySymToKeyMapping.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Keyboard.hpp> // sf::Keyboard::Key
|
||||
|
||||
#include <X11/X.h> // KeySym
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert X11 KeySym to sf::Keyboard::Key
|
||||
///
|
||||
/// \param symbol X11 KeySym
|
||||
///
|
||||
/// \return The corresponding sf::Keyboard::Key
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key keySymToKey(KeySym symbol);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert sf::Keyboard::Key to X11 KeySym
|
||||
///
|
||||
/// \param key X11 sf::Keyboard::Key
|
||||
///
|
||||
/// \return The corresponding X11 KeySym
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
KeySym keyToKeySym(Keyboard::Key key);
|
||||
|
||||
} // namespace sf::priv
|
1400
src/SFML/Window/Unix/KeySymToUnicodeMapping.cpp
Normal file
1400
src/SFML/Window/Unix/KeySymToUnicodeMapping.cpp
Normal file
File diff suppressed because it is too large
Load Diff
54
src/SFML/Window/Unix/KeySymToUnicodeMapping.hpp
Normal file
54
src/SFML/Window/Unix/KeySymToUnicodeMapping.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <X11/X.h> // KeySym
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Converts a KeySym to UTF-32
|
||||
///
|
||||
/// This code was autogenerated from the following table:
|
||||
/// https://www.cl.cam.ac.uk/~mgk25/ucs/keysyms.txt
|
||||
///
|
||||
/// The generated table was edited so that dead keys are mapped to
|
||||
/// non-combining characters instead of combining diacritical marks
|
||||
/// because is it more suitable to describe those keys in user interfaces.
|
||||
///
|
||||
/// \param keysym keysym to be converted
|
||||
///
|
||||
/// \return corresponding UTF-32
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::uint32_t keysymToUnicode(KeySym keysym);
|
||||
|
||||
} // namespace sf::priv
|
810
src/SFML/Window/Unix/KeyboardImpl.cpp
Normal file
810
src/SFML/Window/Unix/KeyboardImpl.cpp
Normal file
@ -0,0 +1,810 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <SFML/System/Utf.hpp>
|
||||
#include <SFML/Window/Unix/Display.hpp>
|
||||
#include <SFML/Window/Unix/KeySymToKeyMapping.hpp>
|
||||
#include <SFML/Window/Unix/KeySymToUnicodeMapping.hpp>
|
||||
#include <SFML/Window/Unix/KeyboardImpl.hpp>
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const KeyCode nullKeyCode = 0;
|
||||
const int maxKeyCode = 256;
|
||||
KeyCode scancodeToKeycode[sf::Keyboard::Scan::ScancodeCount]; ///< Mapping of SFML scancode to X11 KeyCode
|
||||
sf::Keyboard::Scancode keycodeToScancode[maxKeyCode]; ///< Mapping of X11 KeyCode to SFML scancode
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isValidKeycode(KeyCode keycode)
|
||||
{
|
||||
// Valid key code range is [8,255], according to the Xlib manual
|
||||
return keycode >= 8;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::Keyboard::Scancode translateKeyCode(Display* display, KeyCode keycode)
|
||||
{
|
||||
if (!isValidKeycode(keycode))
|
||||
return sf::Keyboard::Scan::Unknown;
|
||||
|
||||
// Try secondary keysym, for numeric keypad keys
|
||||
// Note: This way we always force "NumLock = ON", which is intentional
|
||||
// since the returned key code should correspond to a physical location.
|
||||
KeySym keySym = XkbKeycodeToKeysym(display, keycode, 0, 1);
|
||||
|
||||
// clang-format off
|
||||
switch (keySym)
|
||||
{
|
||||
case XK_KP_0: return sf::Keyboard::Scan::Numpad0;
|
||||
case XK_KP_1: return sf::Keyboard::Scan::Numpad1;
|
||||
case XK_KP_2: return sf::Keyboard::Scan::Numpad2;
|
||||
case XK_KP_3: return sf::Keyboard::Scan::Numpad3;
|
||||
case XK_KP_4: return sf::Keyboard::Scan::Numpad4;
|
||||
case XK_KP_5: return sf::Keyboard::Scan::Numpad5;
|
||||
case XK_KP_6: return sf::Keyboard::Scan::Numpad6;
|
||||
case XK_KP_7: return sf::Keyboard::Scan::Numpad7;
|
||||
case XK_KP_8: return sf::Keyboard::Scan::Numpad8;
|
||||
case XK_KP_9: return sf::Keyboard::Scan::Numpad9;
|
||||
case XK_KP_Separator: return sf::Keyboard::Scan::NumpadDecimal;
|
||||
case XK_KP_Decimal: return sf::Keyboard::Scan::NumpadDecimal;
|
||||
case XK_KP_Equal: return sf::Keyboard::Scan::NumpadEqual;
|
||||
case XK_KP_Enter: return sf::Keyboard::Scan::NumpadEnter;
|
||||
default: break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
// Now try primary keysym for function keys (non-printable keys)
|
||||
// These should not depend on the current keyboard layout
|
||||
keySym = XkbKeycodeToKeysym(display, keycode, 0, 0);
|
||||
|
||||
// clang-format off
|
||||
switch (keySym)
|
||||
{
|
||||
case XK_Return: return sf::Keyboard::Scan::Enter;
|
||||
case XK_Escape: return sf::Keyboard::Scan::Escape;
|
||||
case XK_BackSpace: return sf::Keyboard::Scan::Backspace;
|
||||
case XK_Tab: return sf::Keyboard::Scan::Tab;
|
||||
case XK_Shift_L: return sf::Keyboard::Scan::LShift;
|
||||
case XK_Shift_R: return sf::Keyboard::Scan::RShift;
|
||||
case XK_Control_L: return sf::Keyboard::Scan::LControl;
|
||||
case XK_Control_R: return sf::Keyboard::Scan::RControl;
|
||||
case XK_Alt_L: return sf::Keyboard::Scan::LAlt;
|
||||
case XK_ISO_Level3_Shift: // AltGr on at least some machines
|
||||
case XK_Alt_R: return sf::Keyboard::Scan::RAlt;
|
||||
case XK_Meta_L:
|
||||
case XK_Super_L: return sf::Keyboard::Scan::LSystem;
|
||||
case XK_Meta_R:
|
||||
case XK_Super_R: return sf::Keyboard::Scan::RSystem;
|
||||
case XK_Menu: return sf::Keyboard::Scan::Menu;
|
||||
|
||||
case XK_Num_Lock: return sf::Keyboard::Scan::NumLock;
|
||||
case XK_Caps_Lock: return sf::Keyboard::Scan::CapsLock;
|
||||
case XK_Execute: return sf::Keyboard::Scan::Execute;
|
||||
case XK_Hyper_R: return sf::Keyboard::Scan::Application;
|
||||
case XK_Select: return sf::Keyboard::Scan::Select;
|
||||
case XK_Cancel: return sf::Keyboard::Scan::Stop;
|
||||
case XK_Redo: return sf::Keyboard::Scan::Redo;
|
||||
case XK_Undo: return sf::Keyboard::Scan::Undo;
|
||||
case XK_Find: return sf::Keyboard::Scan::Search;
|
||||
case XK_Mode_switch: return sf::Keyboard::Scan::ModeChange;
|
||||
|
||||
case XK_Print: return sf::Keyboard::Scan::PrintScreen;
|
||||
case XK_Scroll_Lock: return sf::Keyboard::Scan::ScrollLock;
|
||||
case XK_Pause:
|
||||
case XK_Break: return sf::Keyboard::Scan::Pause;
|
||||
|
||||
case XK_Delete:
|
||||
case XK_Clear: return sf::Keyboard::Scan::Delete;
|
||||
case XK_Home: return sf::Keyboard::Scan::Home;
|
||||
case XK_End: return sf::Keyboard::Scan::End;
|
||||
case XK_Page_Up: return sf::Keyboard::Scan::PageUp;
|
||||
case XK_Page_Down: return sf::Keyboard::Scan::PageDown;
|
||||
case XK_Insert: return sf::Keyboard::Scan::Insert;
|
||||
|
||||
case XK_Left: return sf::Keyboard::Scan::Left;
|
||||
case XK_Right: return sf::Keyboard::Scan::Right;
|
||||
case XK_Down: return sf::Keyboard::Scan::Down;
|
||||
case XK_Up: return sf::Keyboard::Scan::Up;
|
||||
|
||||
case XK_F1: return sf::Keyboard::Scan::F1;
|
||||
case XK_F2: return sf::Keyboard::Scan::F2;
|
||||
case XK_F3: return sf::Keyboard::Scan::F3;
|
||||
case XK_F4: return sf::Keyboard::Scan::F4;
|
||||
case XK_F5: return sf::Keyboard::Scan::F5;
|
||||
case XK_F6: return sf::Keyboard::Scan::F6;
|
||||
case XK_F7: return sf::Keyboard::Scan::F7;
|
||||
case XK_F8: return sf::Keyboard::Scan::F8;
|
||||
case XK_F9: return sf::Keyboard::Scan::F9;
|
||||
case XK_F10: return sf::Keyboard::Scan::F10;
|
||||
case XK_F11: return sf::Keyboard::Scan::F11;
|
||||
case XK_F12: return sf::Keyboard::Scan::F12;
|
||||
case XK_F13: return sf::Keyboard::Scan::F13;
|
||||
case XK_F14: return sf::Keyboard::Scan::F14;
|
||||
case XK_F15: return sf::Keyboard::Scan::F15;
|
||||
case XK_F16: return sf::Keyboard::Scan::F16;
|
||||
case XK_F17: return sf::Keyboard::Scan::F17;
|
||||
case XK_F18: return sf::Keyboard::Scan::F18;
|
||||
case XK_F19: return sf::Keyboard::Scan::F19;
|
||||
case XK_F20: return sf::Keyboard::Scan::F20;
|
||||
case XK_F21: return sf::Keyboard::Scan::F21;
|
||||
case XK_F22: return sf::Keyboard::Scan::F22;
|
||||
case XK_F23: return sf::Keyboard::Scan::F23;
|
||||
case XK_F24: return sf::Keyboard::Scan::F24;
|
||||
|
||||
// Numeric keypad
|
||||
case XK_KP_Divide: return sf::Keyboard::Scan::NumpadDivide;
|
||||
case XK_KP_Multiply: return sf::Keyboard::Scan::NumpadMultiply;
|
||||
case XK_KP_Subtract: return sf::Keyboard::Scan::NumpadMinus;
|
||||
case XK_KP_Add: return sf::Keyboard::Scan::NumpadPlus;
|
||||
|
||||
// These should have been detected in secondary keysym test above!
|
||||
case XK_KP_Insert: return sf::Keyboard::Scan::Numpad0;
|
||||
case XK_KP_End: return sf::Keyboard::Scan::Numpad1;
|
||||
case XK_KP_Down: return sf::Keyboard::Scan::Numpad2;
|
||||
case XK_KP_Page_Down: return sf::Keyboard::Scan::Numpad3;
|
||||
case XK_KP_Left: return sf::Keyboard::Scan::Numpad4;
|
||||
case XK_KP_Right: return sf::Keyboard::Scan::Numpad6;
|
||||
case XK_KP_Home: return sf::Keyboard::Scan::Numpad7;
|
||||
case XK_KP_Up: return sf::Keyboard::Scan::Numpad8;
|
||||
case XK_KP_Page_Up: return sf::Keyboard::Scan::Numpad9;
|
||||
case XK_KP_Delete: return sf::Keyboard::Scan::NumpadDecimal;
|
||||
case XK_KP_Equal: return sf::Keyboard::Scan::NumpadEqual;
|
||||
case XK_KP_Enter: return sf::Keyboard::Scan::NumpadEnter;
|
||||
|
||||
// Last resort: Check for printable keys (should not happen if the XKB
|
||||
// extension is available). This will give a layout dependent mapping
|
||||
// (which is wrong, and we may miss some keys, especially on non-US
|
||||
// keyboards), but it's better than nothing...
|
||||
case XK_a:
|
||||
case XK_A: return sf::Keyboard::Scan::A;
|
||||
case XK_b:
|
||||
case XK_B: return sf::Keyboard::Scan::B;
|
||||
case XK_c:
|
||||
case XK_C: return sf::Keyboard::Scan::C;
|
||||
case XK_d:
|
||||
case XK_D: return sf::Keyboard::Scan::D;
|
||||
case XK_e:
|
||||
case XK_E: return sf::Keyboard::Scan::E;
|
||||
case XK_f:
|
||||
case XK_F: return sf::Keyboard::Scan::F;
|
||||
case XK_g:
|
||||
case XK_G: return sf::Keyboard::Scan::G;
|
||||
case XK_h:
|
||||
case XK_H: return sf::Keyboard::Scan::H;
|
||||
case XK_i:
|
||||
case XK_I: return sf::Keyboard::Scan::I;
|
||||
case XK_j:
|
||||
case XK_J: return sf::Keyboard::Scan::J;
|
||||
case XK_k:
|
||||
case XK_K: return sf::Keyboard::Scan::K;
|
||||
case XK_l:
|
||||
case XK_L: return sf::Keyboard::Scan::L;
|
||||
case XK_m:
|
||||
case XK_M: return sf::Keyboard::Scan::M;
|
||||
case XK_n:
|
||||
case XK_N: return sf::Keyboard::Scan::N;
|
||||
case XK_o:
|
||||
case XK_O: return sf::Keyboard::Scan::O;
|
||||
case XK_p:
|
||||
case XK_P: return sf::Keyboard::Scan::P;
|
||||
case XK_q:
|
||||
case XK_Q: return sf::Keyboard::Scan::Q;
|
||||
case XK_r:
|
||||
case XK_R: return sf::Keyboard::Scan::R;
|
||||
case XK_s:
|
||||
case XK_S: return sf::Keyboard::Scan::S;
|
||||
case XK_t:
|
||||
case XK_T: return sf::Keyboard::Scan::T;
|
||||
case XK_u:
|
||||
case XK_U: return sf::Keyboard::Scan::U;
|
||||
case XK_v:
|
||||
case XK_V: return sf::Keyboard::Scan::V;
|
||||
case XK_w:
|
||||
case XK_W: return sf::Keyboard::Scan::W;
|
||||
case XK_x:
|
||||
case XK_X: return sf::Keyboard::Scan::X;
|
||||
case XK_y:
|
||||
case XK_Y: return sf::Keyboard::Scan::Y;
|
||||
case XK_z:
|
||||
case XK_Z: return sf::Keyboard::Scan::Z;
|
||||
|
||||
case XK_1: return sf::Keyboard::Scan::Num1;
|
||||
case XK_2: return sf::Keyboard::Scan::Num2;
|
||||
case XK_3: return sf::Keyboard::Scan::Num3;
|
||||
case XK_4: return sf::Keyboard::Scan::Num4;
|
||||
case XK_5: return sf::Keyboard::Scan::Num5;
|
||||
case XK_6: return sf::Keyboard::Scan::Num6;
|
||||
case XK_7: return sf::Keyboard::Scan::Num7;
|
||||
case XK_8: return sf::Keyboard::Scan::Num8;
|
||||
case XK_9: return sf::Keyboard::Scan::Num9;
|
||||
case XK_0: return sf::Keyboard::Scan::Num0;
|
||||
|
||||
case XK_space: return sf::Keyboard::Scan::Space;
|
||||
case XK_minus: return sf::Keyboard::Scan::Hyphen;
|
||||
case XK_equal: return sf::Keyboard::Scan::Equal;
|
||||
case XK_bracketleft: return sf::Keyboard::Scan::LBracket;
|
||||
case XK_bracketright: return sf::Keyboard::Scan::RBracket;
|
||||
case XK_backslash: return sf::Keyboard::Scan::Backslash;
|
||||
case XK_semicolon: return sf::Keyboard::Scan::Semicolon;
|
||||
case XK_apostrophe: return sf::Keyboard::Scan::Apostrophe;
|
||||
case XK_grave: return sf::Keyboard::Scan::Grave;
|
||||
case XK_comma: return sf::Keyboard::Scan::Comma;
|
||||
case XK_period: return sf::Keyboard::Scan::Period;
|
||||
case XK_slash: return sf::Keyboard::Scan::Slash;
|
||||
case XK_less: return sf::Keyboard::Scan::NonUsBackslash;
|
||||
|
||||
default: return sf::Keyboard::Scan::Unknown;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::map<std::string, sf::Keyboard::Scancode> getNameScancodeMap()
|
||||
{
|
||||
std::map<std::string, sf::Keyboard::Scancode> mapping;
|
||||
|
||||
mapping.insert(std::make_pair("LSGT", sf::Keyboard::Scan::NonUsBackslash));
|
||||
|
||||
mapping.insert(std::make_pair("TLDE", sf::Keyboard::Scan::Grave));
|
||||
mapping.insert(std::make_pair("AE01", sf::Keyboard::Scan::Num1));
|
||||
mapping.insert(std::make_pair("AE02", sf::Keyboard::Scan::Num2));
|
||||
mapping.insert(std::make_pair("AE03", sf::Keyboard::Scan::Num3));
|
||||
mapping.insert(std::make_pair("AE04", sf::Keyboard::Scan::Num4));
|
||||
mapping.insert(std::make_pair("AE05", sf::Keyboard::Scan::Num5));
|
||||
mapping.insert(std::make_pair("AE06", sf::Keyboard::Scan::Num6));
|
||||
mapping.insert(std::make_pair("AE07", sf::Keyboard::Scan::Num7));
|
||||
mapping.insert(std::make_pair("AE08", sf::Keyboard::Scan::Num8));
|
||||
mapping.insert(std::make_pair("AE09", sf::Keyboard::Scan::Num9));
|
||||
mapping.insert(std::make_pair("AE10", sf::Keyboard::Scan::Num0));
|
||||
mapping.insert(std::make_pair("AE11", sf::Keyboard::Scan::Hyphen));
|
||||
mapping.insert(std::make_pair("AE12", sf::Keyboard::Scan::Equal));
|
||||
mapping.insert(std::make_pair("BKSP", sf::Keyboard::Scan::Backspace));
|
||||
mapping.insert(std::make_pair("TAB", sf::Keyboard::Scan::Tab));
|
||||
mapping.insert(std::make_pair("AD01", sf::Keyboard::Scan::Q));
|
||||
mapping.insert(std::make_pair("AD02", sf::Keyboard::Scan::W));
|
||||
mapping.insert(std::make_pair("AD03", sf::Keyboard::Scan::E));
|
||||
mapping.insert(std::make_pair("AD04", sf::Keyboard::Scan::R));
|
||||
mapping.insert(std::make_pair("AD05", sf::Keyboard::Scan::T));
|
||||
mapping.insert(std::make_pair("AD06", sf::Keyboard::Scan::Y));
|
||||
mapping.insert(std::make_pair("AD07", sf::Keyboard::Scan::U));
|
||||
mapping.insert(std::make_pair("AD08", sf::Keyboard::Scan::I));
|
||||
mapping.insert(std::make_pair("AD09", sf::Keyboard::Scan::O));
|
||||
mapping.insert(std::make_pair("AD10", sf::Keyboard::Scan::P));
|
||||
mapping.insert(std::make_pair("AD11", sf::Keyboard::Scan::LBracket));
|
||||
mapping.insert(std::make_pair("AD12", sf::Keyboard::Scan::RBracket));
|
||||
mapping.insert(std::make_pair("BKSL", sf::Keyboard::Scan::Backslash));
|
||||
mapping.insert(std::make_pair("RTRN", sf::Keyboard::Scan::Enter));
|
||||
|
||||
mapping.insert(std::make_pair("CAPS", sf::Keyboard::Scan::CapsLock));
|
||||
mapping.insert(std::make_pair("AC01", sf::Keyboard::Scan::A));
|
||||
mapping.insert(std::make_pair("AC02", sf::Keyboard::Scan::S));
|
||||
mapping.insert(std::make_pair("AC03", sf::Keyboard::Scan::D));
|
||||
mapping.insert(std::make_pair("AC04", sf::Keyboard::Scan::F));
|
||||
mapping.insert(std::make_pair("AC05", sf::Keyboard::Scan::G));
|
||||
mapping.insert(std::make_pair("AC06", sf::Keyboard::Scan::H));
|
||||
mapping.insert(std::make_pair("AC07", sf::Keyboard::Scan::J));
|
||||
mapping.insert(std::make_pair("AC08", sf::Keyboard::Scan::K));
|
||||
mapping.insert(std::make_pair("AC09", sf::Keyboard::Scan::L));
|
||||
mapping.insert(std::make_pair("AC10", sf::Keyboard::Scan::Semicolon));
|
||||
mapping.insert(std::make_pair("AC11", sf::Keyboard::Scan::Apostrophe));
|
||||
mapping.insert(std::make_pair("AC12", sf::Keyboard::Scan::Backslash));
|
||||
|
||||
mapping.insert(std::make_pair("LFSH", sf::Keyboard::Scan::LShift));
|
||||
mapping.insert(std::make_pair("AB01", sf::Keyboard::Scan::Z));
|
||||
mapping.insert(std::make_pair("AB02", sf::Keyboard::Scan::X));
|
||||
mapping.insert(std::make_pair("AB03", sf::Keyboard::Scan::C));
|
||||
mapping.insert(std::make_pair("AB04", sf::Keyboard::Scan::V));
|
||||
mapping.insert(std::make_pair("AB05", sf::Keyboard::Scan::B));
|
||||
mapping.insert(std::make_pair("AB06", sf::Keyboard::Scan::N));
|
||||
mapping.insert(std::make_pair("AB07", sf::Keyboard::Scan::M));
|
||||
mapping.insert(std::make_pair("AB08", sf::Keyboard::Scan::Comma));
|
||||
mapping.insert(std::make_pair("AB09", sf::Keyboard::Scan::Period));
|
||||
mapping.insert(std::make_pair("AB10", sf::Keyboard::Scan::Slash));
|
||||
mapping.insert(std::make_pair("RTSH", sf::Keyboard::Scan::RShift));
|
||||
|
||||
mapping.insert(std::make_pair("LCTL", sf::Keyboard::Scan::LControl));
|
||||
mapping.insert(std::make_pair("LALT", sf::Keyboard::Scan::LAlt));
|
||||
mapping.insert(std::make_pair("SPCE", sf::Keyboard::Scan::Space));
|
||||
mapping.insert(std::make_pair("RCTL", sf::Keyboard::Scan::RControl));
|
||||
mapping.insert(std::make_pair("RALT", sf::Keyboard::Scan::RAlt));
|
||||
mapping.insert(std::make_pair("LVL3", sf::Keyboard::Scan::RAlt));
|
||||
mapping.insert(std::make_pair("ALGR", sf::Keyboard::Scan::RAlt));
|
||||
mapping.insert(std::make_pair("LWIN", sf::Keyboard::Scan::LSystem));
|
||||
mapping.insert(std::make_pair("RWIN", sf::Keyboard::Scan::RSystem));
|
||||
|
||||
mapping.insert(std::make_pair("HYPR", sf::Keyboard::Scan::Application));
|
||||
mapping.insert(std::make_pair("EXEC", sf::Keyboard::Scan::Execute));
|
||||
mapping.insert(std::make_pair("MDSW", sf::Keyboard::Scan::ModeChange));
|
||||
mapping.insert(std::make_pair("MENU", sf::Keyboard::Scan::Menu));
|
||||
mapping.insert(std::make_pair("COMP", sf::Keyboard::Scan::Menu));
|
||||
mapping.insert(std::make_pair("SELE", sf::Keyboard::Scan::Select));
|
||||
|
||||
mapping.insert(std::make_pair("ESC", sf::Keyboard::Scan::Escape));
|
||||
mapping.insert(std::make_pair("FK01", sf::Keyboard::Scan::F1));
|
||||
mapping.insert(std::make_pair("FK02", sf::Keyboard::Scan::F2));
|
||||
mapping.insert(std::make_pair("FK03", sf::Keyboard::Scan::F3));
|
||||
mapping.insert(std::make_pair("FK04", sf::Keyboard::Scan::F4));
|
||||
mapping.insert(std::make_pair("FK05", sf::Keyboard::Scan::F5));
|
||||
mapping.insert(std::make_pair("FK06", sf::Keyboard::Scan::F6));
|
||||
mapping.insert(std::make_pair("FK07", sf::Keyboard::Scan::F7));
|
||||
mapping.insert(std::make_pair("FK08", sf::Keyboard::Scan::F8));
|
||||
mapping.insert(std::make_pair("FK09", sf::Keyboard::Scan::F9));
|
||||
mapping.insert(std::make_pair("FK10", sf::Keyboard::Scan::F10));
|
||||
mapping.insert(std::make_pair("FK11", sf::Keyboard::Scan::F11));
|
||||
mapping.insert(std::make_pair("FK12", sf::Keyboard::Scan::F12));
|
||||
|
||||
mapping.insert(std::make_pair("PRSC", sf::Keyboard::Scan::PrintScreen));
|
||||
mapping.insert(std::make_pair("SCLK", sf::Keyboard::Scan::ScrollLock));
|
||||
mapping.insert(std::make_pair("PAUS", sf::Keyboard::Scan::Pause));
|
||||
|
||||
mapping.insert(std::make_pair("INS", sf::Keyboard::Scan::Insert));
|
||||
mapping.insert(std::make_pair("HOME", sf::Keyboard::Scan::Home));
|
||||
mapping.insert(std::make_pair("PGUP", sf::Keyboard::Scan::PageUp));
|
||||
mapping.insert(std::make_pair("DELE", sf::Keyboard::Scan::Delete));
|
||||
mapping.insert(std::make_pair("END", sf::Keyboard::Scan::End));
|
||||
mapping.insert(std::make_pair("PGDN", sf::Keyboard::Scan::PageDown));
|
||||
|
||||
mapping.insert(std::make_pair("UP", sf::Keyboard::Scan::Up));
|
||||
mapping.insert(std::make_pair("RGHT", sf::Keyboard::Scan::Right));
|
||||
mapping.insert(std::make_pair("DOWN", sf::Keyboard::Scan::Down));
|
||||
mapping.insert(std::make_pair("LEFT", sf::Keyboard::Scan::Left));
|
||||
|
||||
mapping.insert(std::make_pair("NMLK", sf::Keyboard::Scan::NumLock));
|
||||
mapping.insert(std::make_pair("KPDV", sf::Keyboard::Scan::NumpadDivide));
|
||||
mapping.insert(std::make_pair("KPMU", sf::Keyboard::Scan::NumpadMultiply));
|
||||
mapping.insert(std::make_pair("KPSU", sf::Keyboard::Scan::NumpadMinus));
|
||||
|
||||
mapping.insert(std::make_pair("KP7", sf::Keyboard::Scan::Numpad7));
|
||||
mapping.insert(std::make_pair("KP8", sf::Keyboard::Scan::Numpad8));
|
||||
mapping.insert(std::make_pair("KP9", sf::Keyboard::Scan::Numpad9));
|
||||
mapping.insert(std::make_pair("KPAD", sf::Keyboard::Scan::NumpadPlus));
|
||||
mapping.insert(std::make_pair("KP4", sf::Keyboard::Scan::Numpad4));
|
||||
mapping.insert(std::make_pair("KP5", sf::Keyboard::Scan::Numpad5));
|
||||
mapping.insert(std::make_pair("KP6", sf::Keyboard::Scan::Numpad6));
|
||||
mapping.insert(std::make_pair("KP1", sf::Keyboard::Scan::Numpad1));
|
||||
mapping.insert(std::make_pair("KP2", sf::Keyboard::Scan::Numpad2));
|
||||
mapping.insert(std::make_pair("KP3", sf::Keyboard::Scan::Numpad3));
|
||||
mapping.insert(std::make_pair("KPEN", sf::Keyboard::Scan::NumpadEnter));
|
||||
mapping.insert(std::make_pair("KP0", sf::Keyboard::Scan::Numpad0));
|
||||
mapping.insert(std::make_pair("KPDL", sf::Keyboard::Scan::NumpadDecimal));
|
||||
mapping.insert(std::make_pair("KPEQ", sf::Keyboard::Scan::NumpadEqual));
|
||||
|
||||
mapping.insert(std::make_pair("FK13", sf::Keyboard::Scan::F13));
|
||||
mapping.insert(std::make_pair("FK14", sf::Keyboard::Scan::F14));
|
||||
mapping.insert(std::make_pair("FK15", sf::Keyboard::Scan::F15));
|
||||
mapping.insert(std::make_pair("FK16", sf::Keyboard::Scan::F16));
|
||||
mapping.insert(std::make_pair("FK17", sf::Keyboard::Scan::F17));
|
||||
mapping.insert(std::make_pair("FK18", sf::Keyboard::Scan::F18));
|
||||
mapping.insert(std::make_pair("FK19", sf::Keyboard::Scan::F19));
|
||||
mapping.insert(std::make_pair("FK20", sf::Keyboard::Scan::F20));
|
||||
mapping.insert(std::make_pair("FK21", sf::Keyboard::Scan::F21));
|
||||
mapping.insert(std::make_pair("FK22", sf::Keyboard::Scan::F22));
|
||||
mapping.insert(std::make_pair("FK23", sf::Keyboard::Scan::F23));
|
||||
mapping.insert(std::make_pair("FK24", sf::Keyboard::Scan::F24));
|
||||
mapping.insert(std::make_pair("LMTA", sf::Keyboard::Scan::LSystem));
|
||||
mapping.insert(std::make_pair("RMTA", sf::Keyboard::Scan::RSystem));
|
||||
mapping.insert(std::make_pair("MUTE", sf::Keyboard::Scan::VolumeMute));
|
||||
mapping.insert(std::make_pair("VOL-", sf::Keyboard::Scan::VolumeDown));
|
||||
mapping.insert(std::make_pair("VOL+", sf::Keyboard::Scan::VolumeUp));
|
||||
mapping.insert(std::make_pair("STOP", sf::Keyboard::Scan::Stop));
|
||||
mapping.insert(std::make_pair("REDO", sf::Keyboard::Scan::Redo));
|
||||
mapping.insert(std::make_pair("AGAI", sf::Keyboard::Scan::Redo));
|
||||
mapping.insert(std::make_pair("UNDO", sf::Keyboard::Scan::Undo));
|
||||
mapping.insert(std::make_pair("COPY", sf::Keyboard::Scan::Copy));
|
||||
mapping.insert(std::make_pair("PAST", sf::Keyboard::Scan::Paste));
|
||||
mapping.insert(std::make_pair("FIND", sf::Keyboard::Scan::Search));
|
||||
mapping.insert(std::make_pair("CUT", sf::Keyboard::Scan::Cut));
|
||||
mapping.insert(std::make_pair("HELP", sf::Keyboard::Scan::Help));
|
||||
|
||||
mapping.insert(std::make_pair("I156", sf::Keyboard::Scan::LaunchApplication1));
|
||||
mapping.insert(std::make_pair("I157", sf::Keyboard::Scan::LaunchApplication2));
|
||||
mapping.insert(std::make_pair("I164", sf::Keyboard::Scan::Favorites));
|
||||
mapping.insert(std::make_pair("I166", sf::Keyboard::Scan::Back));
|
||||
mapping.insert(std::make_pair("I167", sf::Keyboard::Scan::Forward));
|
||||
mapping.insert(std::make_pair("I171", sf::Keyboard::Scan::MediaNextTrack));
|
||||
mapping.insert(std::make_pair("I172", sf::Keyboard::Scan::MediaPlayPause));
|
||||
mapping.insert(std::make_pair("I173", sf::Keyboard::Scan::MediaPreviousTrack));
|
||||
mapping.insert(std::make_pair("I174", sf::Keyboard::Scan::MediaStop));
|
||||
mapping.insert(std::make_pair("I180", sf::Keyboard::Scan::HomePage));
|
||||
mapping.insert(std::make_pair("I181", sf::Keyboard::Scan::Refresh));
|
||||
mapping.insert(std::make_pair("I223", sf::Keyboard::Scan::LaunchMail));
|
||||
mapping.insert(std::make_pair("I234", sf::Keyboard::Scan::LaunchMediaSelect));
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void ensureMapping()
|
||||
{
|
||||
static bool isMappingInitialized = false;
|
||||
|
||||
if (isMappingInitialized)
|
||||
return;
|
||||
|
||||
// Phase 1: Initialize mappings with default values
|
||||
for (auto& keycode : scancodeToKeycode)
|
||||
keycode = nullKeyCode;
|
||||
|
||||
for (auto& scancode : keycodeToScancode)
|
||||
scancode = sf::Keyboard::Scan::Unknown;
|
||||
|
||||
// Phase 2: Get XKB names with key code
|
||||
Display* display = sf::priv::openDisplay();
|
||||
|
||||
char name[XkbKeyNameLength + 1];
|
||||
XkbDescPtr descriptor = XkbGetMap(display, 0, XkbUseCoreKbd);
|
||||
XkbGetNames(display, XkbKeyNamesMask, descriptor);
|
||||
|
||||
std::map<std::string, sf::Keyboard::Scancode> nameScancodeMap = getNameScancodeMap();
|
||||
sf::Keyboard::Scancode scancode = sf::Keyboard::Scan::Unknown;
|
||||
|
||||
for (int keycode = descriptor->min_key_code; keycode <= descriptor->max_key_code; ++keycode)
|
||||
{
|
||||
if (!isValidKeycode(static_cast<KeyCode>(keycode)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::memcpy(name, descriptor->names->keys[keycode].name, XkbKeyNameLength);
|
||||
name[XkbKeyNameLength] = '\0';
|
||||
|
||||
std::map<std::string, sf::Keyboard::Scancode>::iterator mappedScancode = nameScancodeMap.find(std::string(name));
|
||||
scancode = sf::Keyboard::Scan::Unknown;
|
||||
|
||||
if (mappedScancode != nameScancodeMap.end())
|
||||
scancode = mappedScancode->second;
|
||||
|
||||
if (scancode != sf::Keyboard::Scan::Unknown)
|
||||
scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode);
|
||||
|
||||
keycodeToScancode[keycode] = scancode;
|
||||
}
|
||||
|
||||
XkbFreeNames(descriptor, XkbKeyNamesMask, True);
|
||||
XkbFreeKeyboard(descriptor, 0, True);
|
||||
|
||||
// Phase 3: Translate un-translated keycodes using traditional X11 KeySym lookups
|
||||
for (int keycode = 8; keycode < maxKeyCode; ++keycode)
|
||||
{
|
||||
if (keycodeToScancode[static_cast<KeyCode>(keycode)] == sf::Keyboard::Scan::Unknown)
|
||||
{
|
||||
scancode = translateKeyCode(display, static_cast<KeyCode>(keycode));
|
||||
|
||||
if (scancode != sf::Keyboard::Scan::Unknown && scancodeToKeycode[scancode] == nullKeyCode)
|
||||
scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode);
|
||||
|
||||
keycodeToScancode[keycode] = scancode;
|
||||
}
|
||||
}
|
||||
|
||||
sf::priv::closeDisplay(display);
|
||||
|
||||
isMappingInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
KeyCode scancodeToKeyCode(sf::Keyboard::Scancode code)
|
||||
{
|
||||
ensureMapping();
|
||||
|
||||
if (code != sf::Keyboard::Scan::Unknown)
|
||||
return scancodeToKeycode[code];
|
||||
|
||||
return nullKeyCode;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sf::Keyboard::Scancode keyCodeToScancode(KeyCode code)
|
||||
{
|
||||
ensureMapping();
|
||||
|
||||
if (isValidKeycode(code))
|
||||
return keycodeToScancode[code];
|
||||
|
||||
return sf::Keyboard::Scan::Unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
KeyCode keyToKeyCode(sf::Keyboard::Key key)
|
||||
{
|
||||
KeySym keysym = sf::priv::keyToKeySym(key);
|
||||
|
||||
if (keysym != NoSymbol)
|
||||
{
|
||||
Display* display = sf::priv::openDisplay();
|
||||
KeyCode keycode = XKeysymToKeycode(display, keysym);
|
||||
sf::priv::closeDisplay(display);
|
||||
|
||||
if (keycode != nullKeyCode)
|
||||
return keycode;
|
||||
}
|
||||
|
||||
// Fallback for when XKeysymToKeycode cannot tell the KeyCode for XK_Alt_R
|
||||
if (key == sf::Keyboard::RAlt)
|
||||
return scancodeToKeycode[sf::Keyboard::Scan::RAlt];
|
||||
|
||||
return nullKeyCode;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
KeySym scancodeToKeySym(sf::Keyboard::Scancode code)
|
||||
{
|
||||
Display* display = sf::priv::openDisplay();
|
||||
|
||||
KeySym keysym = NoSymbol;
|
||||
KeyCode keycode = scancodeToKeyCode(code);
|
||||
|
||||
if (keycode != nullKeyCode) // ensure that this Scancode is mapped to keycode
|
||||
keysym = XkbKeycodeToKeysym(display, keycode, 0, 0);
|
||||
|
||||
sf::priv::closeDisplay(display);
|
||||
|
||||
return keysym;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isKeyPressedImpl(KeyCode keycode)
|
||||
{
|
||||
if (keycode != nullKeyCode)
|
||||
{
|
||||
Display* display = sf::priv::openDisplay();
|
||||
|
||||
// Get the whole keyboard state
|
||||
char keys[32];
|
||||
XQueryKeymap(display, keys);
|
||||
|
||||
sf::priv::closeDisplay(display);
|
||||
|
||||
// Check our keycode
|
||||
return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool KeyboardImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
KeyCode keycode = keyToKeyCode(key);
|
||||
return isKeyPressedImpl(keycode);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool KeyboardImpl::isKeyPressed(Keyboard::Scancode code)
|
||||
{
|
||||
KeyCode keycode = scancodeToKeyCode(code);
|
||||
return isKeyPressedImpl(keycode);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode KeyboardImpl::delocalize(Keyboard::Key key)
|
||||
{
|
||||
KeyCode keycode = keyToKeyCode(key);
|
||||
return keyCodeToScancode(keycode);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key KeyboardImpl::localize(Keyboard::Scancode code)
|
||||
{
|
||||
KeySym keysym = scancodeToKeySym(code);
|
||||
return keySymToKey(keysym);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String KeyboardImpl::getDescription(Keyboard::Scancode code)
|
||||
{
|
||||
bool checkInput = true;
|
||||
|
||||
// these scancodes actually correspond to keys with input
|
||||
// but we want to return their description, not their behaviour
|
||||
if (code == Keyboard::Scan::Enter || code == Keyboard::Scan::Escape || code == Keyboard::Scan::Backspace ||
|
||||
code == Keyboard::Scan::Tab || code == Keyboard::Scan::Space || code == Keyboard::Scan::ScrollLock ||
|
||||
code == Keyboard::Scan::Pause || code == Keyboard::Scan::Delete || code == Keyboard::Scan::NumpadDivide ||
|
||||
code == Keyboard::Scan::NumpadMultiply || code == Keyboard::Scan::NumpadMinus ||
|
||||
code == Keyboard::Scan::NumpadPlus || code == Keyboard::Scan::NumpadEqual ||
|
||||
code == Keyboard::Scan::NumpadEnter || code == Keyboard::Scan::NumpadDecimal)
|
||||
{
|
||||
checkInput = false;
|
||||
}
|
||||
|
||||
if (checkInput)
|
||||
{
|
||||
KeySym keysym = scancodeToKeySym(code);
|
||||
std::uint32_t unicode = keysymToUnicode(keysym);
|
||||
|
||||
if (unicode != 0)
|
||||
return String(unicode);
|
||||
}
|
||||
|
||||
// Fallback to our best guess for the keys that are known to be independent of the layout.
|
||||
// clang-format off
|
||||
switch (code)
|
||||
{
|
||||
case Keyboard::Scan::Enter: return "Enter";
|
||||
case Keyboard::Scan::Escape: return "Escape";
|
||||
case Keyboard::Scan::Backspace: return "Backspace";
|
||||
case Keyboard::Scan::Tab: return "Tab";
|
||||
case Keyboard::Scan::Space: return "Space";
|
||||
|
||||
case Keyboard::Scan::F1: return "F1";
|
||||
case Keyboard::Scan::F2: return "F2";
|
||||
case Keyboard::Scan::F3: return "F3";
|
||||
case Keyboard::Scan::F4: return "F4";
|
||||
case Keyboard::Scan::F5: return "F5";
|
||||
case Keyboard::Scan::F6: return "F6";
|
||||
case Keyboard::Scan::F7: return "F7";
|
||||
case Keyboard::Scan::F8: return "F8";
|
||||
case Keyboard::Scan::F9: return "F9";
|
||||
case Keyboard::Scan::F10: return "F10";
|
||||
case Keyboard::Scan::F11: return "F11";
|
||||
case Keyboard::Scan::F12: return "F12";
|
||||
case Keyboard::Scan::F13: return "F13";
|
||||
case Keyboard::Scan::F14: return "F14";
|
||||
case Keyboard::Scan::F15: return "F15";
|
||||
case Keyboard::Scan::F16: return "F16";
|
||||
case Keyboard::Scan::F17: return "F17";
|
||||
case Keyboard::Scan::F18: return "F18";
|
||||
case Keyboard::Scan::F19: return "F19";
|
||||
case Keyboard::Scan::F20: return "F20";
|
||||
case Keyboard::Scan::F21: return "F21";
|
||||
case Keyboard::Scan::F22: return "F22";
|
||||
case Keyboard::Scan::F23: return "F23";
|
||||
case Keyboard::Scan::F24: return "F24";
|
||||
|
||||
case Keyboard::Scan::CapsLock: return "Caps Lock";
|
||||
case Keyboard::Scan::PrintScreen: return "Print Screen";
|
||||
case Keyboard::Scan::ScrollLock: return "Scroll Lock";
|
||||
|
||||
case Keyboard::Scan::Pause: return "Pause";
|
||||
case Keyboard::Scan::Insert: return "Insert";
|
||||
case Keyboard::Scan::Home: return "Home";
|
||||
case Keyboard::Scan::PageUp: return "Page Up";
|
||||
case Keyboard::Scan::Delete: return "Delete";
|
||||
case Keyboard::Scan::End: return "End";
|
||||
case Keyboard::Scan::PageDown: return "Page Down";
|
||||
|
||||
case Keyboard::Scan::Left: return "Left Arrow";
|
||||
case Keyboard::Scan::Right: return "Right Arrow";
|
||||
case Keyboard::Scan::Down: return "Down Arrow";
|
||||
case Keyboard::Scan::Up: return "Up Arrow";
|
||||
|
||||
case Keyboard::Scan::NumLock: return "Num Lock";
|
||||
case Keyboard::Scan::NumpadDivide: return "Divide (Numpad)";
|
||||
case Keyboard::Scan::NumpadMultiply: return "Multiply (Numpad)";
|
||||
case Keyboard::Scan::NumpadMinus: return "Minus (Numpad)";
|
||||
case Keyboard::Scan::NumpadPlus: return "Plus (Numpad)";
|
||||
case Keyboard::Scan::NumpadEqual: return "Equal (Numpad)";
|
||||
case Keyboard::Scan::NumpadEnter: return "Enter (Numpad)";
|
||||
case Keyboard::Scan::NumpadDecimal: return "Decimal (Numpad)";
|
||||
|
||||
case Keyboard::Scan::Numpad0: return "0 (Numpad)";
|
||||
case Keyboard::Scan::Numpad1: return "1 (Numpad)";
|
||||
case Keyboard::Scan::Numpad2: return "2 (Numpad)";
|
||||
case Keyboard::Scan::Numpad3: return "3 (Numpad)";
|
||||
case Keyboard::Scan::Numpad4: return "4 (Numpad)";
|
||||
case Keyboard::Scan::Numpad5: return "5 (Numpad)";
|
||||
case Keyboard::Scan::Numpad6: return "6 (Numpad)";
|
||||
case Keyboard::Scan::Numpad7: return "7 (Numpad)";
|
||||
case Keyboard::Scan::Numpad8: return "8 (Numpad)";
|
||||
case Keyboard::Scan::Numpad9: return "9 (Numpad)";
|
||||
|
||||
case Keyboard::Scan::Application: return "Application";
|
||||
case Keyboard::Scan::Execute: return "Execute";
|
||||
case Keyboard::Scan::Help: return "Help";
|
||||
case Keyboard::Scan::Menu: return "Menu";
|
||||
case Keyboard::Scan::Select: return "Select";
|
||||
case Keyboard::Scan::Stop: return "Stop";
|
||||
case Keyboard::Scan::Redo: return "Redo";
|
||||
case Keyboard::Scan::Undo: return "Undo";
|
||||
case Keyboard::Scan::Cut: return "Cut";
|
||||
case Keyboard::Scan::Copy: return "Copy";
|
||||
case Keyboard::Scan::Paste: return "Paste";
|
||||
case Keyboard::Scan::Search: return "Search";
|
||||
|
||||
case Keyboard::Scan::VolumeMute: return "Volume Mute";
|
||||
case Keyboard::Scan::VolumeUp: return "Volume Up";
|
||||
case Keyboard::Scan::VolumeDown: return "Volume Down";
|
||||
|
||||
case Keyboard::Scan::LControl: return "Left Control";
|
||||
case Keyboard::Scan::LShift: return "Left Shift";
|
||||
case Keyboard::Scan::LAlt: return "Left Alt";
|
||||
case Keyboard::Scan::LSystem: return "Left System";
|
||||
case Keyboard::Scan::RControl: return "Right Control";
|
||||
case Keyboard::Scan::RShift: return "Right Shift";
|
||||
case Keyboard::Scan::RAlt: return "Right Alt";
|
||||
case Keyboard::Scan::RSystem: return "Right System";
|
||||
|
||||
case Keyboard::Scan::LaunchApplication1: return "Launch Application 1";
|
||||
case Keyboard::Scan::LaunchApplication2: return "Launch Application 2";
|
||||
case Keyboard::Scan::Favorites: return "Favorites";
|
||||
case Keyboard::Scan::Back: return "Back";
|
||||
case Keyboard::Scan::Forward: return "Forward";
|
||||
case Keyboard::Scan::MediaNextTrack: return "Media Next Track";
|
||||
case Keyboard::Scan::MediaPlayPause: return "Media Play Pause";
|
||||
case Keyboard::Scan::MediaPreviousTrack: return "Media Previous Track";
|
||||
case Keyboard::Scan::MediaStop: return "Media Stop";
|
||||
case Keyboard::Scan::HomePage: return "Home Page";
|
||||
case Keyboard::Scan::Refresh: return "Refresh";
|
||||
case Keyboard::Scan::LaunchMail: return "Launch Mail";
|
||||
case Keyboard::Scan::LaunchMediaSelect: return "Launch Media Select";
|
||||
|
||||
default: return "Unknown Scancode";
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key KeyboardImpl::getKeyFromEvent(XKeyEvent& event)
|
||||
{
|
||||
// Try each KeySym index (modifier group) until we get a match
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// Get the SFML keyboard code from the keysym of the key that has been pressed
|
||||
KeySym keysym = XLookupKeysym(&event, i);
|
||||
Keyboard::Key key = keySymToKey(keysym);
|
||||
if (key != Keyboard::Unknown)
|
||||
return key;
|
||||
}
|
||||
|
||||
return Keyboard::Unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode KeyboardImpl::getScancodeFromEvent(XKeyEvent& event)
|
||||
{
|
||||
return keyCodeToScancode(static_cast<KeyCode>(event.keycode));
|
||||
}
|
||||
|
||||
} // namespace sf::priv
|
97
src/SFML/Window/Unix/KeyboardImpl.hpp
Normal file
97
src/SFML/Window/Unix/KeyboardImpl.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Keyboard.hpp>
|
||||
|
||||
#include <X11/Xlib.h> // XKeyEvent
|
||||
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief sf::priv::KeyboardImpl helper
|
||||
///
|
||||
/// This class implements keyboard handling functions
|
||||
/// to help sf::priv::InputImpl class.
|
||||
////////////////////////////////////////////////////////////
|
||||
class KeyboardImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the sf::Keyboard::Key from XKeyEvent
|
||||
///
|
||||
/// \param event Event from which key is gotten
|
||||
///
|
||||
/// \return A key being pressed or released
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key getKeyFromEvent(XKeyEvent& event);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the sf::Keyboard::Scancode from XKeyEvent
|
||||
///
|
||||
/// \param event Event from which scancode is gotten
|
||||
///
|
||||
/// \return A scancode of a key being pressed or released
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode getScancodeFromEvent(XKeyEvent& event);
|
||||
};
|
||||
|
||||
} // namespace sf::priv
|
@ -34,6 +34,7 @@
|
||||
#include <SFML/Window/Unix/ClipboardImpl.hpp>
|
||||
#include <SFML/Window/Unix/Display.hpp>
|
||||
#include <SFML/Window/Unix/InputImpl.hpp>
|
||||
#include <SFML/Window/Unix/KeyboardImpl.hpp>
|
||||
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
@ -357,119 +358,6 @@ bool isWMAbsolutePositionGood()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sf::Keyboard::Key keysymToSF(KeySym symbol)
|
||||
{
|
||||
// clang-format off
|
||||
switch (symbol)
|
||||
{
|
||||
case XK_Shift_L: return sf::Keyboard::LShift;
|
||||
case XK_Shift_R: return sf::Keyboard::RShift;
|
||||
case XK_Control_L: return sf::Keyboard::LControl;
|
||||
case XK_Control_R: return sf::Keyboard::RControl;
|
||||
case XK_Alt_L: return sf::Keyboard::LAlt;
|
||||
case XK_Alt_R: return sf::Keyboard::RAlt;
|
||||
case XK_Super_L: return sf::Keyboard::LSystem;
|
||||
case XK_Super_R: return sf::Keyboard::RSystem;
|
||||
case XK_Menu: return sf::Keyboard::Menu;
|
||||
case XK_Escape: return sf::Keyboard::Escape;
|
||||
case XK_semicolon: return sf::Keyboard::Semicolon;
|
||||
case XK_slash: return sf::Keyboard::Slash;
|
||||
case XK_equal: return sf::Keyboard::Equal;
|
||||
case XK_minus: return sf::Keyboard::Hyphen;
|
||||
case XK_bracketleft: return sf::Keyboard::LBracket;
|
||||
case XK_bracketright: return sf::Keyboard::RBracket;
|
||||
case XK_comma: return sf::Keyboard::Comma;
|
||||
case XK_period: return sf::Keyboard::Period;
|
||||
case XK_apostrophe: return sf::Keyboard::Quote;
|
||||
case XK_backslash: return sf::Keyboard::Backslash;
|
||||
case XK_grave: return sf::Keyboard::Tilde;
|
||||
case XK_space: return sf::Keyboard::Space;
|
||||
case XK_Return: return sf::Keyboard::Enter;
|
||||
case XK_KP_Enter: return sf::Keyboard::Enter;
|
||||
case XK_BackSpace: return sf::Keyboard::Backspace;
|
||||
case XK_Tab: return sf::Keyboard::Tab;
|
||||
case XK_Prior: return sf::Keyboard::PageUp;
|
||||
case XK_Next: return sf::Keyboard::PageDown;
|
||||
case XK_End: return sf::Keyboard::End;
|
||||
case XK_Home: return sf::Keyboard::Home;
|
||||
case XK_Insert: return sf::Keyboard::Insert;
|
||||
case XK_Delete: return sf::Keyboard::Delete;
|
||||
case XK_KP_Add: return sf::Keyboard::Add;
|
||||
case XK_KP_Subtract: return sf::Keyboard::Subtract;
|
||||
case XK_KP_Multiply: return sf::Keyboard::Multiply;
|
||||
case XK_KP_Divide: return sf::Keyboard::Divide;
|
||||
case XK_Pause: return sf::Keyboard::Pause;
|
||||
case XK_F1: return sf::Keyboard::F1;
|
||||
case XK_F2: return sf::Keyboard::F2;
|
||||
case XK_F3: return sf::Keyboard::F3;
|
||||
case XK_F4: return sf::Keyboard::F4;
|
||||
case XK_F5: return sf::Keyboard::F5;
|
||||
case XK_F6: return sf::Keyboard::F6;
|
||||
case XK_F7: return sf::Keyboard::F7;
|
||||
case XK_F8: return sf::Keyboard::F8;
|
||||
case XK_F9: return sf::Keyboard::F9;
|
||||
case XK_F10: return sf::Keyboard::F10;
|
||||
case XK_F11: return sf::Keyboard::F11;
|
||||
case XK_F12: return sf::Keyboard::F12;
|
||||
case XK_F13: return sf::Keyboard::F13;
|
||||
case XK_F14: return sf::Keyboard::F14;
|
||||
case XK_F15: return sf::Keyboard::F15;
|
||||
case XK_Left: return sf::Keyboard::Left;
|
||||
case XK_Right: return sf::Keyboard::Right;
|
||||
case XK_Up: return sf::Keyboard::Up;
|
||||
case XK_Down: return sf::Keyboard::Down;
|
||||
case XK_KP_Insert: return sf::Keyboard::Numpad0;
|
||||
case XK_KP_End: return sf::Keyboard::Numpad1;
|
||||
case XK_KP_Down: return sf::Keyboard::Numpad2;
|
||||
case XK_KP_Page_Down: return sf::Keyboard::Numpad3;
|
||||
case XK_KP_Left: return sf::Keyboard::Numpad4;
|
||||
case XK_KP_Begin: return sf::Keyboard::Numpad5;
|
||||
case XK_KP_Right: return sf::Keyboard::Numpad6;
|
||||
case XK_KP_Home: return sf::Keyboard::Numpad7;
|
||||
case XK_KP_Up: return sf::Keyboard::Numpad8;
|
||||
case XK_KP_Page_Up: return sf::Keyboard::Numpad9;
|
||||
case XK_a: return sf::Keyboard::A;
|
||||
case XK_b: return sf::Keyboard::B;
|
||||
case XK_c: return sf::Keyboard::C;
|
||||
case XK_d: return sf::Keyboard::D;
|
||||
case XK_e: return sf::Keyboard::E;
|
||||
case XK_f: return sf::Keyboard::F;
|
||||
case XK_g: return sf::Keyboard::G;
|
||||
case XK_h: return sf::Keyboard::H;
|
||||
case XK_i: return sf::Keyboard::I;
|
||||
case XK_j: return sf::Keyboard::J;
|
||||
case XK_k: return sf::Keyboard::K;
|
||||
case XK_l: return sf::Keyboard::L;
|
||||
case XK_m: return sf::Keyboard::M;
|
||||
case XK_n: return sf::Keyboard::N;
|
||||
case XK_o: return sf::Keyboard::O;
|
||||
case XK_p: return sf::Keyboard::P;
|
||||
case XK_q: return sf::Keyboard::Q;
|
||||
case XK_r: return sf::Keyboard::R;
|
||||
case XK_s: return sf::Keyboard::S;
|
||||
case XK_t: return sf::Keyboard::T;
|
||||
case XK_u: return sf::Keyboard::U;
|
||||
case XK_v: return sf::Keyboard::V;
|
||||
case XK_w: return sf::Keyboard::W;
|
||||
case XK_x: return sf::Keyboard::X;
|
||||
case XK_y: return sf::Keyboard::Y;
|
||||
case XK_z: return sf::Keyboard::Z;
|
||||
case XK_0: return sf::Keyboard::Num0;
|
||||
case XK_1: return sf::Keyboard::Num1;
|
||||
case XK_2: return sf::Keyboard::Num2;
|
||||
case XK_3: return sf::Keyboard::Num3;
|
||||
case XK_4: return sf::Keyboard::Num4;
|
||||
case XK_5: return sf::Keyboard::Num5;
|
||||
case XK_6: return sf::Keyboard::Num6;
|
||||
case XK_7: return sf::Keyboard::Num7;
|
||||
case XK_8: return sf::Keyboard::Num8;
|
||||
case XK_9: return sf::Keyboard::Num9;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return sf::Keyboard::Unknown;
|
||||
}
|
||||
} // namespace WindowsImplX11Impl
|
||||
} // namespace
|
||||
|
||||
@ -1870,23 +1758,12 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
||||
// Key down event
|
||||
case KeyPress:
|
||||
{
|
||||
Keyboard::Key key = Keyboard::Unknown;
|
||||
|
||||
// Try each KeySym index (modifier group) until we get a match
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// Get the SFML keyboard code from the keysym of the key that has been pressed
|
||||
key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i));
|
||||
|
||||
if (key != Keyboard::Unknown)
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill the event parameters
|
||||
// TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping
|
||||
Event event;
|
||||
event.type = Event::KeyPressed;
|
||||
event.key.code = key;
|
||||
event.key.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
|
||||
event.key.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
|
||||
event.key.alt = windowEvent.xkey.state & Mod1Mask;
|
||||
event.key.control = windowEvent.xkey.state & ControlMask;
|
||||
event.key.shift = windowEvent.xkey.state & ShiftMask;
|
||||
@ -1976,22 +1853,11 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
||||
// Key up event
|
||||
case KeyRelease:
|
||||
{
|
||||
Keyboard::Key key = Keyboard::Unknown;
|
||||
|
||||
// Try each KeySym index (modifier group) until we get a match
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// Get the SFML keyboard code from the keysym of the key that has been released
|
||||
key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i));
|
||||
|
||||
if (key != Keyboard::Unknown)
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill the event parameters
|
||||
Event event;
|
||||
event.type = Event::KeyReleased;
|
||||
event.key.code = key;
|
||||
event.key.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
|
||||
event.key.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
|
||||
event.key.alt = windowEvent.xkey.state & Mod1Mask;
|
||||
event.key.control = windowEvent.xkey.state & ControlMask;
|
||||
event.key.shift = windowEvent.xkey.state & ShiftMask;
|
||||
@ -2121,6 +1987,15 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
||||
break;
|
||||
}
|
||||
|
||||
// Keyboard mapping changed
|
||||
case MappingNotify:
|
||||
{
|
||||
if (windowEvent.xmapping.request == MappingKeyboard)
|
||||
XRefreshKeyboardMapping(&windowEvent.xmapping);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Window unmapped
|
||||
case UnmapNotify:
|
||||
{
|
||||
|
@ -25,129 +25,584 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <SFML/System/Win32/WindowsHeader.hpp>
|
||||
#include <SFML/Window/Win32/InputImpl.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
int vkey = 0;
|
||||
Keyboard::Scancode InputImpl::m_keyToScancodeMapping[Keyboard::KeyCount]; ///< Mapping from Key to Scancode
|
||||
Keyboard::Key InputImpl::m_scancodeToKeyMapping[Keyboard::Scan::ScancodeCount]; ///< Mapping from Scancode to Key
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key virtualKeyToSfKey(UINT virtualKey)
|
||||
{
|
||||
// clang-format off
|
||||
switch (virtualKey)
|
||||
{
|
||||
case 'A': return Keyboard::A;
|
||||
case 'B': return Keyboard::B;
|
||||
case 'C': return Keyboard::C;
|
||||
case 'D': return Keyboard::D;
|
||||
case 'E': return Keyboard::E;
|
||||
case 'F': return Keyboard::F;
|
||||
case 'G': return Keyboard::G;
|
||||
case 'H': return Keyboard::H;
|
||||
case 'I': return Keyboard::I;
|
||||
case 'J': return Keyboard::J;
|
||||
case 'K': return Keyboard::K;
|
||||
case 'L': return Keyboard::L;
|
||||
case 'M': return Keyboard::M;
|
||||
case 'N': return Keyboard::N;
|
||||
case 'O': return Keyboard::O;
|
||||
case 'P': return Keyboard::P;
|
||||
case 'Q': return Keyboard::Q;
|
||||
case 'R': return Keyboard::R;
|
||||
case 'S': return Keyboard::S;
|
||||
case 'T': return Keyboard::T;
|
||||
case 'U': return Keyboard::U;
|
||||
case 'V': return Keyboard::V;
|
||||
case 'W': return Keyboard::W;
|
||||
case 'X': return Keyboard::X;
|
||||
case 'Y': return Keyboard::Y;
|
||||
case 'Z': return Keyboard::Z;
|
||||
case '0': return Keyboard::Num0;
|
||||
case '1': return Keyboard::Num1;
|
||||
case '2': return Keyboard::Num2;
|
||||
case '3': return Keyboard::Num3;
|
||||
case '4': return Keyboard::Num4;
|
||||
case '5': return Keyboard::Num5;
|
||||
case '6': return Keyboard::Num6;
|
||||
case '7': return Keyboard::Num7;
|
||||
case '8': return Keyboard::Num8;
|
||||
case '9': return Keyboard::Num9;
|
||||
case VK_ESCAPE: return Keyboard::Escape;
|
||||
case VK_LCONTROL: return Keyboard::LControl;
|
||||
case VK_LSHIFT: return Keyboard::LShift;
|
||||
case VK_LMENU: return Keyboard::LAlt;
|
||||
case VK_LWIN: return Keyboard::LSystem;
|
||||
case VK_RCONTROL: return Keyboard::RControl;
|
||||
case VK_RSHIFT: return Keyboard::RShift;
|
||||
case VK_RMENU: return Keyboard::RAlt;
|
||||
case VK_RWIN: return Keyboard::RSystem;
|
||||
case VK_APPS: return Keyboard::Menu;
|
||||
case VK_OEM_4: return Keyboard::LBracket;
|
||||
case VK_OEM_6: return Keyboard::RBracket;
|
||||
case VK_OEM_1: return Keyboard::Semicolon;
|
||||
case VK_OEM_COMMA: return Keyboard::Comma;
|
||||
case VK_OEM_PERIOD: return Keyboard::Period;
|
||||
case VK_OEM_7: return Keyboard::Apostrophe;
|
||||
case VK_OEM_2: return Keyboard::Slash;
|
||||
case VK_OEM_5: return Keyboard::Backslash;
|
||||
case VK_OEM_3: return Keyboard::Grave;
|
||||
case VK_OEM_PLUS: return Keyboard::Equal;
|
||||
case VK_OEM_MINUS: return Keyboard::Hyphen;
|
||||
case VK_SPACE: return Keyboard::Space;
|
||||
case VK_RETURN: return Keyboard::Enter;
|
||||
case VK_BACK: return Keyboard::Backspace;
|
||||
case VK_TAB: return Keyboard::Tab;
|
||||
case VK_PRIOR: return Keyboard::PageUp;
|
||||
case VK_NEXT: return Keyboard::PageDown;
|
||||
case VK_END: return Keyboard::End;
|
||||
case VK_HOME: return Keyboard::Home;
|
||||
case VK_INSERT: return Keyboard::Insert;
|
||||
case VK_DELETE: return Keyboard::Delete;
|
||||
case VK_ADD: return Keyboard::Add;
|
||||
case VK_SUBTRACT: return Keyboard::Subtract;
|
||||
case VK_MULTIPLY: return Keyboard::Multiply;
|
||||
case VK_DIVIDE: return Keyboard::Divide;
|
||||
case VK_LEFT: return Keyboard::Left;
|
||||
case VK_RIGHT: return Keyboard::Right;
|
||||
case VK_UP: return Keyboard::Up;
|
||||
case VK_DOWN: return Keyboard::Down;
|
||||
case VK_NUMPAD0: return Keyboard::Numpad0;
|
||||
case VK_NUMPAD1: return Keyboard::Numpad1;
|
||||
case VK_NUMPAD2: return Keyboard::Numpad2;
|
||||
case VK_NUMPAD3: return Keyboard::Numpad3;
|
||||
case VK_NUMPAD4: return Keyboard::Numpad4;
|
||||
case VK_NUMPAD5: return Keyboard::Numpad5;
|
||||
case VK_NUMPAD6: return Keyboard::Numpad6;
|
||||
case VK_NUMPAD7: return Keyboard::Numpad7;
|
||||
case VK_NUMPAD8: return Keyboard::Numpad8;
|
||||
case VK_NUMPAD9: return Keyboard::Numpad9;
|
||||
case VK_F1: return Keyboard::F1;
|
||||
case VK_F2: return Keyboard::F2;
|
||||
case VK_F3: return Keyboard::F3;
|
||||
case VK_F4: return Keyboard::F4;
|
||||
case VK_F5: return Keyboard::F5;
|
||||
case VK_F6: return Keyboard::F6;
|
||||
case VK_F7: return Keyboard::F7;
|
||||
case VK_F8: return Keyboard::F8;
|
||||
case VK_F9: return Keyboard::F9;
|
||||
case VK_F10: return Keyboard::F10;
|
||||
case VK_F11: return Keyboard::F11;
|
||||
case VK_F12: return Keyboard::F12;
|
||||
case VK_F13: return Keyboard::F13;
|
||||
case VK_F14: return Keyboard::F14;
|
||||
case VK_F15: return Keyboard::F15;
|
||||
case VK_PAUSE: return Keyboard::Pause;
|
||||
default: return Keyboard::Unknown;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
int sfKeyToVirtualKey(Keyboard::Key key)
|
||||
{
|
||||
// clang-format off
|
||||
switch (key)
|
||||
{
|
||||
default: vkey = 0; break;
|
||||
case Keyboard::A: vkey = 'A'; break;
|
||||
case Keyboard::B: vkey = 'B'; break;
|
||||
case Keyboard::C: vkey = 'C'; break;
|
||||
case Keyboard::D: vkey = 'D'; break;
|
||||
case Keyboard::E: vkey = 'E'; break;
|
||||
case Keyboard::F: vkey = 'F'; break;
|
||||
case Keyboard::G: vkey = 'G'; break;
|
||||
case Keyboard::H: vkey = 'H'; break;
|
||||
case Keyboard::I: vkey = 'I'; break;
|
||||
case Keyboard::J: vkey = 'J'; break;
|
||||
case Keyboard::K: vkey = 'K'; break;
|
||||
case Keyboard::L: vkey = 'L'; break;
|
||||
case Keyboard::M: vkey = 'M'; break;
|
||||
case Keyboard::N: vkey = 'N'; break;
|
||||
case Keyboard::O: vkey = 'O'; break;
|
||||
case Keyboard::P: vkey = 'P'; break;
|
||||
case Keyboard::Q: vkey = 'Q'; break;
|
||||
case Keyboard::R: vkey = 'R'; break;
|
||||
case Keyboard::S: vkey = 'S'; break;
|
||||
case Keyboard::T: vkey = 'T'; break;
|
||||
case Keyboard::U: vkey = 'U'; break;
|
||||
case Keyboard::V: vkey = 'V'; break;
|
||||
case Keyboard::W: vkey = 'W'; break;
|
||||
case Keyboard::X: vkey = 'X'; break;
|
||||
case Keyboard::Y: vkey = 'Y'; break;
|
||||
case Keyboard::Z: vkey = 'Z'; break;
|
||||
case Keyboard::Num0: vkey = '0'; break;
|
||||
case Keyboard::Num1: vkey = '1'; break;
|
||||
case Keyboard::Num2: vkey = '2'; break;
|
||||
case Keyboard::Num3: vkey = '3'; break;
|
||||
case Keyboard::Num4: vkey = '4'; break;
|
||||
case Keyboard::Num5: vkey = '5'; break;
|
||||
case Keyboard::Num6: vkey = '6'; break;
|
||||
case Keyboard::Num7: vkey = '7'; break;
|
||||
case Keyboard::Num8: vkey = '8'; break;
|
||||
case Keyboard::Num9: vkey = '9'; break;
|
||||
case Keyboard::Escape: vkey = VK_ESCAPE; break;
|
||||
case Keyboard::LControl: vkey = VK_LCONTROL; break;
|
||||
case Keyboard::LShift: vkey = VK_LSHIFT; break;
|
||||
case Keyboard::LAlt: vkey = VK_LMENU; break;
|
||||
case Keyboard::LSystem: vkey = VK_LWIN; break;
|
||||
case Keyboard::RControl: vkey = VK_RCONTROL; break;
|
||||
case Keyboard::RShift: vkey = VK_RSHIFT; break;
|
||||
case Keyboard::RAlt: vkey = VK_RMENU; break;
|
||||
case Keyboard::RSystem: vkey = VK_RWIN; break;
|
||||
case Keyboard::Menu: vkey = VK_APPS; break;
|
||||
case Keyboard::LBracket: vkey = VK_OEM_4; break;
|
||||
case Keyboard::RBracket: vkey = VK_OEM_6; break;
|
||||
case Keyboard::Semicolon: vkey = VK_OEM_1; break;
|
||||
case Keyboard::Comma: vkey = VK_OEM_COMMA; break;
|
||||
case Keyboard::Period: vkey = VK_OEM_PERIOD; break;
|
||||
case Keyboard::Quote: vkey = VK_OEM_7; break;
|
||||
case Keyboard::Slash: vkey = VK_OEM_2; break;
|
||||
case Keyboard::Backslash: vkey = VK_OEM_5; break;
|
||||
case Keyboard::Tilde: vkey = VK_OEM_3; break;
|
||||
case Keyboard::Equal: vkey = VK_OEM_PLUS; break;
|
||||
case Keyboard::Hyphen: vkey = VK_OEM_MINUS; break;
|
||||
case Keyboard::Space: vkey = VK_SPACE; break;
|
||||
case Keyboard::Enter: vkey = VK_RETURN; break;
|
||||
case Keyboard::Backspace: vkey = VK_BACK; break;
|
||||
case Keyboard::Tab: vkey = VK_TAB; break;
|
||||
case Keyboard::PageUp: vkey = VK_PRIOR; break;
|
||||
case Keyboard::PageDown: vkey = VK_NEXT; break;
|
||||
case Keyboard::End: vkey = VK_END; break;
|
||||
case Keyboard::Home: vkey = VK_HOME; break;
|
||||
case Keyboard::Insert: vkey = VK_INSERT; break;
|
||||
case Keyboard::Delete: vkey = VK_DELETE; break;
|
||||
case Keyboard::Add: vkey = VK_ADD; break;
|
||||
case Keyboard::Subtract: vkey = VK_SUBTRACT; break;
|
||||
case Keyboard::Multiply: vkey = VK_MULTIPLY; break;
|
||||
case Keyboard::Divide: vkey = VK_DIVIDE; break;
|
||||
case Keyboard::Left: vkey = VK_LEFT; break;
|
||||
case Keyboard::Right: vkey = VK_RIGHT; break;
|
||||
case Keyboard::Up: vkey = VK_UP; break;
|
||||
case Keyboard::Down: vkey = VK_DOWN; break;
|
||||
case Keyboard::Numpad0: vkey = VK_NUMPAD0; break;
|
||||
case Keyboard::Numpad1: vkey = VK_NUMPAD1; break;
|
||||
case Keyboard::Numpad2: vkey = VK_NUMPAD2; break;
|
||||
case Keyboard::Numpad3: vkey = VK_NUMPAD3; break;
|
||||
case Keyboard::Numpad4: vkey = VK_NUMPAD4; break;
|
||||
case Keyboard::Numpad5: vkey = VK_NUMPAD5; break;
|
||||
case Keyboard::Numpad6: vkey = VK_NUMPAD6; break;
|
||||
case Keyboard::Numpad7: vkey = VK_NUMPAD7; break;
|
||||
case Keyboard::Numpad8: vkey = VK_NUMPAD8; break;
|
||||
case Keyboard::Numpad9: vkey = VK_NUMPAD9; break;
|
||||
case Keyboard::F1: vkey = VK_F1; break;
|
||||
case Keyboard::F2: vkey = VK_F2; break;
|
||||
case Keyboard::F3: vkey = VK_F3; break;
|
||||
case Keyboard::F4: vkey = VK_F4; break;
|
||||
case Keyboard::F5: vkey = VK_F5; break;
|
||||
case Keyboard::F6: vkey = VK_F6; break;
|
||||
case Keyboard::F7: vkey = VK_F7; break;
|
||||
case Keyboard::F8: vkey = VK_F8; break;
|
||||
case Keyboard::F9: vkey = VK_F9; break;
|
||||
case Keyboard::F10: vkey = VK_F10; break;
|
||||
case Keyboard::F11: vkey = VK_F11; break;
|
||||
case Keyboard::F12: vkey = VK_F12; break;
|
||||
case Keyboard::F13: vkey = VK_F13; break;
|
||||
case Keyboard::F14: vkey = VK_F14; break;
|
||||
case Keyboard::F15: vkey = VK_F15; break;
|
||||
case Keyboard::Pause: vkey = VK_PAUSE; break;
|
||||
case Keyboard::A: return 'A';
|
||||
case Keyboard::B: return 'B';
|
||||
case Keyboard::C: return 'C';
|
||||
case Keyboard::D: return 'D';
|
||||
case Keyboard::E: return 'E';
|
||||
case Keyboard::F: return 'F';
|
||||
case Keyboard::G: return 'G';
|
||||
case Keyboard::H: return 'H';
|
||||
case Keyboard::I: return 'I';
|
||||
case Keyboard::J: return 'J';
|
||||
case Keyboard::K: return 'K';
|
||||
case Keyboard::L: return 'L';
|
||||
case Keyboard::M: return 'M';
|
||||
case Keyboard::N: return 'N';
|
||||
case Keyboard::O: return 'O';
|
||||
case Keyboard::P: return 'P';
|
||||
case Keyboard::Q: return 'Q';
|
||||
case Keyboard::R: return 'R';
|
||||
case Keyboard::S: return 'S';
|
||||
case Keyboard::T: return 'T';
|
||||
case Keyboard::U: return 'U';
|
||||
case Keyboard::V: return 'V';
|
||||
case Keyboard::W: return 'W';
|
||||
case Keyboard::X: return 'X';
|
||||
case Keyboard::Y: return 'Y';
|
||||
case Keyboard::Z: return 'Z';
|
||||
case Keyboard::Num0: return '0';
|
||||
case Keyboard::Num1: return '1';
|
||||
case Keyboard::Num2: return '2';
|
||||
case Keyboard::Num3: return '3';
|
||||
case Keyboard::Num4: return '4';
|
||||
case Keyboard::Num5: return '5';
|
||||
case Keyboard::Num6: return '6';
|
||||
case Keyboard::Num7: return '7';
|
||||
case Keyboard::Num8: return '8';
|
||||
case Keyboard::Num9: return '9';
|
||||
case Keyboard::Escape: return VK_ESCAPE;
|
||||
case Keyboard::LControl: return VK_LCONTROL;
|
||||
case Keyboard::LShift: return VK_LSHIFT;
|
||||
case Keyboard::LAlt: return VK_LMENU;
|
||||
case Keyboard::LSystem: return VK_LWIN;
|
||||
case Keyboard::RControl: return VK_RCONTROL;
|
||||
case Keyboard::RShift: return VK_RSHIFT;
|
||||
case Keyboard::RAlt: return VK_RMENU;
|
||||
case Keyboard::RSystem: return VK_RWIN;
|
||||
case Keyboard::Menu: return VK_APPS;
|
||||
case Keyboard::LBracket: return VK_OEM_4;
|
||||
case Keyboard::RBracket: return VK_OEM_6;
|
||||
case Keyboard::Semicolon: return VK_OEM_1;
|
||||
case Keyboard::Comma: return VK_OEM_COMMA;
|
||||
case Keyboard::Period: return VK_OEM_PERIOD;
|
||||
case Keyboard::Apostrophe: return VK_OEM_7;
|
||||
case Keyboard::Slash: return VK_OEM_2;
|
||||
case Keyboard::Backslash: return VK_OEM_5;
|
||||
case Keyboard::Grave: return VK_OEM_3;
|
||||
case Keyboard::Equal: return VK_OEM_PLUS;
|
||||
case Keyboard::Hyphen: return VK_OEM_MINUS;
|
||||
case Keyboard::Space: return VK_SPACE;
|
||||
case Keyboard::Enter: return VK_RETURN;
|
||||
case Keyboard::Backspace: return VK_BACK;
|
||||
case Keyboard::Tab: return VK_TAB;
|
||||
case Keyboard::PageUp: return VK_PRIOR;
|
||||
case Keyboard::PageDown: return VK_NEXT;
|
||||
case Keyboard::End: return VK_END;
|
||||
case Keyboard::Home: return VK_HOME;
|
||||
case Keyboard::Insert: return VK_INSERT;
|
||||
case Keyboard::Delete: return VK_DELETE;
|
||||
case Keyboard::Add: return VK_ADD;
|
||||
case Keyboard::Subtract: return VK_SUBTRACT;
|
||||
case Keyboard::Multiply: return VK_MULTIPLY;
|
||||
case Keyboard::Divide: return VK_DIVIDE;
|
||||
case Keyboard::Left: return VK_LEFT;
|
||||
case Keyboard::Right: return VK_RIGHT;
|
||||
case Keyboard::Up: return VK_UP;
|
||||
case Keyboard::Down: return VK_DOWN;
|
||||
case Keyboard::Numpad0: return VK_NUMPAD0;
|
||||
case Keyboard::Numpad1: return VK_NUMPAD1;
|
||||
case Keyboard::Numpad2: return VK_NUMPAD2;
|
||||
case Keyboard::Numpad3: return VK_NUMPAD3;
|
||||
case Keyboard::Numpad4: return VK_NUMPAD4;
|
||||
case Keyboard::Numpad5: return VK_NUMPAD5;
|
||||
case Keyboard::Numpad6: return VK_NUMPAD6;
|
||||
case Keyboard::Numpad7: return VK_NUMPAD7;
|
||||
case Keyboard::Numpad8: return VK_NUMPAD8;
|
||||
case Keyboard::Numpad9: return VK_NUMPAD9;
|
||||
case Keyboard::F1: return VK_F1;
|
||||
case Keyboard::F2: return VK_F2;
|
||||
case Keyboard::F3: return VK_F3;
|
||||
case Keyboard::F4: return VK_F4;
|
||||
case Keyboard::F5: return VK_F5;
|
||||
case Keyboard::F6: return VK_F6;
|
||||
case Keyboard::F7: return VK_F7;
|
||||
case Keyboard::F8: return VK_F8;
|
||||
case Keyboard::F9: return VK_F9;
|
||||
case Keyboard::F10: return VK_F10;
|
||||
case Keyboard::F11: return VK_F11;
|
||||
case Keyboard::F12: return VK_F12;
|
||||
case Keyboard::F13: return VK_F13;
|
||||
case Keyboard::F14: return VK_F14;
|
||||
case Keyboard::F15: return VK_F15;
|
||||
case Keyboard::Pause: return VK_PAUSE;
|
||||
default: return 0;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return (GetAsyncKeyState(vkey) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WORD sfScanToWinScan(Keyboard::Scancode code)
|
||||
{
|
||||
// Convert an SFML scancode to a Windows scancode
|
||||
// Reference: https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx
|
||||
// clang-format off
|
||||
switch (code)
|
||||
{
|
||||
case Keyboard::Scan::A: return 0x1E;
|
||||
case Keyboard::Scan::B: return 0x30;
|
||||
case Keyboard::Scan::C: return 0x2E;
|
||||
case Keyboard::Scan::D: return 0x20;
|
||||
case Keyboard::Scan::E: return 0x12;
|
||||
case Keyboard::Scan::F: return 0x21;
|
||||
case Keyboard::Scan::G: return 0x22;
|
||||
case Keyboard::Scan::H: return 0x23;
|
||||
case Keyboard::Scan::I: return 0x17;
|
||||
case Keyboard::Scan::J: return 0x24;
|
||||
case Keyboard::Scan::K: return 0x25;
|
||||
case Keyboard::Scan::L: return 0x26;
|
||||
case Keyboard::Scan::M: return 0x32;
|
||||
case Keyboard::Scan::N: return 0x31;
|
||||
case Keyboard::Scan::O: return 0x18;
|
||||
case Keyboard::Scan::P: return 0x19;
|
||||
case Keyboard::Scan::Q: return 0x10;
|
||||
case Keyboard::Scan::R: return 0x13;
|
||||
case Keyboard::Scan::S: return 0x1F;
|
||||
case Keyboard::Scan::T: return 0x14;
|
||||
case Keyboard::Scan::U: return 0x16;
|
||||
case Keyboard::Scan::V: return 0x2F;
|
||||
case Keyboard::Scan::W: return 0x11;
|
||||
case Keyboard::Scan::X: return 0x2D;
|
||||
case Keyboard::Scan::Y: return 0x15;
|
||||
case Keyboard::Scan::Z: return 0x2C;
|
||||
|
||||
case Keyboard::Scan::Num1: return 0x02;
|
||||
case Keyboard::Scan::Num2: return 0x03;
|
||||
case Keyboard::Scan::Num3: return 0x04;
|
||||
case Keyboard::Scan::Num4: return 0x05;
|
||||
case Keyboard::Scan::Num5: return 0x06;
|
||||
case Keyboard::Scan::Num6: return 0x07;
|
||||
case Keyboard::Scan::Num7: return 0x08;
|
||||
case Keyboard::Scan::Num8: return 0x09;
|
||||
case Keyboard::Scan::Num9: return 0x0A;
|
||||
case Keyboard::Scan::Num0: return 0x0B;
|
||||
|
||||
case Keyboard::Scan::Enter: return 0x1C;
|
||||
case Keyboard::Scan::Escape: return 0x01;
|
||||
case Keyboard::Scan::Backspace: return 0x0E;
|
||||
case Keyboard::Scan::Tab: return 0x0F;
|
||||
case Keyboard::Scan::Space: return 0x39;
|
||||
case Keyboard::Scan::Hyphen: return 0x0C;
|
||||
case Keyboard::Scan::Equal: return 0x0D;
|
||||
case Keyboard::Scan::LBracket: return 0x1A;
|
||||
case Keyboard::Scan::RBracket: return 0x1B;
|
||||
case Keyboard::Scan::Backslash: return 0x2B;
|
||||
case Keyboard::Scan::Semicolon: return 0x27;
|
||||
case Keyboard::Scan::Apostrophe: return 0x28;
|
||||
case Keyboard::Scan::Grave: return 0x29;
|
||||
case Keyboard::Scan::Comma: return 0x33;
|
||||
case Keyboard::Scan::Period: return 0x34;
|
||||
case Keyboard::Scan::Slash: return 0x35;
|
||||
|
||||
case Keyboard::Scan::F1: return 0x3B;
|
||||
case Keyboard::Scan::F2: return 0x3C;
|
||||
case Keyboard::Scan::F3: return 0x3D;
|
||||
case Keyboard::Scan::F4: return 0x3E;
|
||||
case Keyboard::Scan::F5: return 0x3F;
|
||||
case Keyboard::Scan::F6: return 0x40;
|
||||
case Keyboard::Scan::F7: return 0x41;
|
||||
case Keyboard::Scan::F8: return 0x42;
|
||||
case Keyboard::Scan::F9: return 0x43;
|
||||
case Keyboard::Scan::F10: return 0x44;
|
||||
case Keyboard::Scan::F11: return 0x57;
|
||||
case Keyboard::Scan::F12: return 0x58;
|
||||
case Keyboard::Scan::F13: return 0x64;
|
||||
case Keyboard::Scan::F14: return 0x65;
|
||||
case Keyboard::Scan::F15: return 0x66;
|
||||
case Keyboard::Scan::F16: return 0x67;
|
||||
case Keyboard::Scan::F17: return 0x68;
|
||||
case Keyboard::Scan::F18: return 0x69;
|
||||
case Keyboard::Scan::F19: return 0x6A;
|
||||
case Keyboard::Scan::F20: return 0x6B;
|
||||
case Keyboard::Scan::F21: return 0x6C;
|
||||
case Keyboard::Scan::F22: return 0x6D;
|
||||
case Keyboard::Scan::F23: return 0x6E;
|
||||
case Keyboard::Scan::F24: return 0x76;
|
||||
|
||||
case Keyboard::Scan::CapsLock: return 0x3A;
|
||||
case Keyboard::Scan::PrintScreen: return 0xE037;
|
||||
case Keyboard::Scan::ScrollLock: return 0x46;
|
||||
case Keyboard::Scan::Pause: return 0x45;
|
||||
case Keyboard::Scan::Insert: return 0xE052;
|
||||
case Keyboard::Scan::Home: return 0xE047;
|
||||
case Keyboard::Scan::PageUp: return 0xE049;
|
||||
case Keyboard::Scan::Delete: return 0xE053;
|
||||
case Keyboard::Scan::End: return 0xE04F;
|
||||
case Keyboard::Scan::PageDown: return 0xE051;
|
||||
case Keyboard::Scan::Right: return 0xE04D;
|
||||
case Keyboard::Scan::Left: return 0xE04B;
|
||||
case Keyboard::Scan::Down: return 0xE050;
|
||||
case Keyboard::Scan::Up: return 0xE048;
|
||||
case Keyboard::Scan::NumLock: return 0xE045;
|
||||
|
||||
case Keyboard::Scan::NumpadDivide: return 0xE035;
|
||||
case Keyboard::Scan::NumpadMultiply: return 0x37;
|
||||
case Keyboard::Scan::NumpadMinus: return 0x4A;
|
||||
case Keyboard::Scan::NumpadPlus: return 0x4E;
|
||||
case Keyboard::Scan::NumpadEqual: return 0x7E;
|
||||
case Keyboard::Scan::NumpadEnter: return 0xE01C;
|
||||
case Keyboard::Scan::NumpadDecimal: return 0x53;
|
||||
|
||||
case Keyboard::Scan::Numpad1: return 0x4F;
|
||||
case Keyboard::Scan::Numpad2: return 0x50;
|
||||
case Keyboard::Scan::Numpad3: return 0x51;
|
||||
case Keyboard::Scan::Numpad4: return 0x4B;
|
||||
case Keyboard::Scan::Numpad5: return 0x4C;
|
||||
case Keyboard::Scan::Numpad6: return 0x4D;
|
||||
case Keyboard::Scan::Numpad7: return 0x47;
|
||||
case Keyboard::Scan::Numpad8: return 0x48;
|
||||
case Keyboard::Scan::Numpad9: return 0x49;
|
||||
case Keyboard::Scan::Numpad0: return 0x52;
|
||||
|
||||
case Keyboard::Scan::NonUsBackslash: return 0x56;
|
||||
// No known scancode for Keyboard::Scan::Application
|
||||
// No known scancode for Keyboard::Scan::Execute
|
||||
// No known scancode for Keyboard::Scan::ModeChange
|
||||
case Keyboard::Scan::Help: return 0xE061;
|
||||
case Keyboard::Scan::Menu: return 0xE05D;
|
||||
case Keyboard::Scan::Select: return 0xE01E;
|
||||
// No known scancode for Keyboard::Scan::Redo
|
||||
// No known scancode for Keyboard::Scan::Undo
|
||||
// No known scancode for Keyboard::Scan::Cut
|
||||
// No known scancode for Keyboard::Scan::Copy
|
||||
// No known scancode for Keyboard::Scan::Paste
|
||||
|
||||
case Keyboard::Scan::VolumeMute: return 0xE020;
|
||||
case Keyboard::Scan::VolumeUp: return 0xE02E;
|
||||
case Keyboard::Scan::VolumeDown: return 0xE02C;
|
||||
case Keyboard::Scan::MediaPlayPause: return 0xE022;
|
||||
case Keyboard::Scan::MediaStop: return 0xE024;
|
||||
case Keyboard::Scan::MediaNextTrack: return 0xE019;
|
||||
case Keyboard::Scan::MediaPreviousTrack: return 0xE010;
|
||||
|
||||
case Keyboard::Scan::LControl: return 0x1D;
|
||||
case Keyboard::Scan::LShift: return 0x2A;
|
||||
case Keyboard::Scan::LAlt: return 0x38;
|
||||
case Keyboard::Scan::LSystem: return 0xE05B;
|
||||
case Keyboard::Scan::RControl: return 0xE01D;
|
||||
case Keyboard::Scan::RShift: return 0x36;
|
||||
case Keyboard::Scan::RAlt: return 0xE038;
|
||||
case Keyboard::Scan::RSystem: return 0xE05C;
|
||||
|
||||
case Keyboard::Scan::Back: return 0xE06A;
|
||||
case Keyboard::Scan::Forward: return 0xE069;
|
||||
case Keyboard::Scan::Refresh: return 0xE067;
|
||||
case Keyboard::Scan::Stop: return 0xE068;
|
||||
case Keyboard::Scan::Search: return 0xE065;
|
||||
case Keyboard::Scan::Favorites: return 0xE066;
|
||||
case Keyboard::Scan::HomePage: return 0xE030;
|
||||
|
||||
case Keyboard::Scan::LaunchApplication1: return 0xE06B;
|
||||
case Keyboard::Scan::LaunchApplication2: return 0xE021;
|
||||
case Keyboard::Scan::LaunchMail: return 0xE06C;
|
||||
case Keyboard::Scan::LaunchMediaSelect: return 0xE06D;
|
||||
|
||||
// Unable to map to a scancode
|
||||
default: return 0x0;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WORD sfScanToWinScanExtended(Keyboard::Scancode code)
|
||||
{
|
||||
// Convert an SFML scancode to a Windows scancode
|
||||
// Reference: https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx
|
||||
// clang-format off
|
||||
switch (code)
|
||||
{
|
||||
case Keyboard::Scan::PrintScreen: return 55 | 0xE100;
|
||||
case Keyboard::Scan::Insert: return 82 | 0xE100;
|
||||
case Keyboard::Scan::Home: return 71 | 0xE100;
|
||||
case Keyboard::Scan::PageUp: return 73 | 0xE100;
|
||||
case Keyboard::Scan::Delete: return 83 | 0xE100;
|
||||
case Keyboard::Scan::End: return 79 | 0xE100;
|
||||
case Keyboard::Scan::PageDown: return 81 | 0xE100;
|
||||
case Keyboard::Scan::Right: return 77 | 0xE100;
|
||||
case Keyboard::Scan::Left: return 75 | 0xE100;
|
||||
case Keyboard::Scan::Down: return 80 | 0xE100;
|
||||
case Keyboard::Scan::Up: return 72 | 0xE100;
|
||||
case Keyboard::Scan::NumLock: return 69 | 0xE100;
|
||||
case Keyboard::Scan::NumpadEnter: return 28 | 0xE100;
|
||||
case Keyboard::Scan::NumpadDivide: return 53 | 0xE100;
|
||||
case Keyboard::Scan::Help: return 97 | 0xE100;
|
||||
case Keyboard::Scan::Menu: return 93 | 0xE100;
|
||||
case Keyboard::Scan::Select: return 30 | 0xE100;
|
||||
case Keyboard::Scan::VolumeMute: return 32 | 0xE100;
|
||||
case Keyboard::Scan::VolumeUp: return 46 | 0xE100;
|
||||
case Keyboard::Scan::VolumeDown: return 44 | 0xE100;
|
||||
case Keyboard::Scan::MediaPlayPause: return 34 | 0xE100;
|
||||
case Keyboard::Scan::MediaStop: return 36 | 0xE100;
|
||||
case Keyboard::Scan::MediaNextTrack: return 25 | 0xE100;
|
||||
case Keyboard::Scan::MediaPreviousTrack: return 16 | 0xE100;
|
||||
case Keyboard::Scan::LSystem: return 91 | 0xE100;
|
||||
case Keyboard::Scan::RControl: return 29 | 0xE100;
|
||||
case Keyboard::Scan::RAlt: return 56 | 0xE100;
|
||||
case Keyboard::Scan::RSystem: return 92 | 0xE100;
|
||||
case Keyboard::Scan::Back: return 106 | 0xE100;
|
||||
case Keyboard::Scan::Forward: return 105 | 0xE100;
|
||||
case Keyboard::Scan::Refresh: return 103 | 0xE100;
|
||||
case Keyboard::Scan::Stop: return 104 | 0xE100;
|
||||
case Keyboard::Scan::Search: return 101 | 0xE100;
|
||||
case Keyboard::Scan::Favorites: return 102 | 0xE100;
|
||||
case Keyboard::Scan::HomePage: return 48 | 0xE100;
|
||||
case Keyboard::Scan::LaunchApplication1: return 107 | 0xE100;
|
||||
case Keyboard::Scan::LaunchApplication2: return 33 | 0xE100;
|
||||
case Keyboard::Scan::LaunchMail: return 108 | 0xE100;
|
||||
case Keyboard::Scan::LaunchMediaSelect: return 109 | 0xE100;
|
||||
|
||||
// Use non-extended mapping
|
||||
default: return sfScanToWinScan(code);
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
UINT sfScanToVirtualKey(Keyboard::Scancode code)
|
||||
{
|
||||
WORD winScancode = sfScanToWinScan(code);
|
||||
|
||||
// Manually map non-extended key codes
|
||||
// clang-format off
|
||||
switch (code)
|
||||
{
|
||||
case Keyboard::Scan::Numpad0: return VK_NUMPAD0;
|
||||
case Keyboard::Scan::Numpad1: return VK_NUMPAD1;
|
||||
case Keyboard::Scan::Numpad2: return VK_NUMPAD2;
|
||||
case Keyboard::Scan::Numpad3: return VK_NUMPAD3;
|
||||
case Keyboard::Scan::Numpad4: return VK_NUMPAD4;
|
||||
case Keyboard::Scan::Numpad5: return VK_NUMPAD5;
|
||||
case Keyboard::Scan::Numpad6: return VK_NUMPAD6;
|
||||
case Keyboard::Scan::Numpad7: return VK_NUMPAD7;
|
||||
case Keyboard::Scan::Numpad8: return VK_NUMPAD8;
|
||||
case Keyboard::Scan::Numpad9: return VK_NUMPAD9;
|
||||
case Keyboard::Scan::NumpadMinus: return VK_SUBTRACT;
|
||||
case Keyboard::Scan::NumpadDecimal: return VK_DECIMAL;
|
||||
case Keyboard::Scan::NumpadDivide: return VK_DIVIDE;
|
||||
case Keyboard::Scan::Pause: return VK_PAUSE;
|
||||
case Keyboard::Scan::RControl: return VK_RCONTROL;
|
||||
case Keyboard::Scan::RAlt: return VK_RMENU;
|
||||
default: return MapVirtualKey(winScancode, MAPVK_VSC_TO_VK_EX);
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
bool isValidScancode(Keyboard::Scancode code)
|
||||
{
|
||||
return code > Keyboard::Scan::Unknown && code < Keyboard::Scan::ScancodeCount;
|
||||
}
|
||||
|
||||
bool isValidKey(Keyboard::Key key)
|
||||
{
|
||||
return key > Keyboard::Unknown && key < Keyboard::KeyCount;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::ensureMappings()
|
||||
{
|
||||
static bool isMappingInitialized = false;
|
||||
|
||||
if (isMappingInitialized)
|
||||
return;
|
||||
|
||||
// Phase 1: Initialize mappings with default values
|
||||
for (auto& scancode : m_keyToScancodeMapping)
|
||||
scancode = Keyboard::Scan::Unknown;
|
||||
|
||||
for (auto& key : m_scancodeToKeyMapping)
|
||||
key = Keyboard::Unknown;
|
||||
|
||||
// Phase 2: Translate scancode to virtual code to key names
|
||||
for (int i = 0; i < Keyboard::Scan::ScancodeCount; ++i)
|
||||
{
|
||||
Keyboard::Scancode scan = static_cast<Keyboard::Scancode>(i);
|
||||
UINT virtualKey = sfScanToVirtualKey(scan);
|
||||
Keyboard::Key key = virtualKeyToSfKey(virtualKey);
|
||||
if (key != Keyboard::Unknown && m_keyToScancodeMapping[key] == Keyboard::Scan::Unknown)
|
||||
m_keyToScancodeMapping[key] = scan;
|
||||
m_scancodeToKeyMapping[scan] = key;
|
||||
}
|
||||
|
||||
isMappingInitialized = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
int virtualKey = sfKeyToVirtualKey(key);
|
||||
return (GetAsyncKeyState(virtualKey) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode code)
|
||||
{
|
||||
UINT virtualKey = sfScanToVirtualKey(code);
|
||||
return (GetAsyncKeyState(static_cast<int>(virtualKey)) & KF_UP) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode code)
|
||||
{
|
||||
if (!isValidScancode(code))
|
||||
return Keyboard::Unknown;
|
||||
|
||||
ensureMappings();
|
||||
|
||||
return m_scancodeToKeyMapping[code];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key key)
|
||||
{
|
||||
if (!isValidKey(key))
|
||||
return Keyboard::Scan::Unknown;
|
||||
|
||||
ensureMappings();
|
||||
|
||||
return m_keyToScancodeMapping[key];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
String InputImpl::getDescription(Keyboard::Scancode code)
|
||||
{
|
||||
WORD winCode = sfScanToWinScanExtended(code);
|
||||
const int bufSize = 1024;
|
||||
WCHAR name[bufSize];
|
||||
int result = GetKeyNameText(winCode << 16, name, bufSize);
|
||||
if (result > 0)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
@ -159,30 +614,30 @@ void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
||||
{
|
||||
int vkey = 0;
|
||||
int virtualKey = 0;
|
||||
switch (button)
|
||||
{
|
||||
case Mouse::Left:
|
||||
vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
|
||||
virtualKey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
|
||||
break;
|
||||
case Mouse::Right:
|
||||
vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_LBUTTON : VK_RBUTTON;
|
||||
virtualKey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_LBUTTON : VK_RBUTTON;
|
||||
break;
|
||||
case Mouse::Middle:
|
||||
vkey = VK_MBUTTON;
|
||||
virtualKey = VK_MBUTTON;
|
||||
break;
|
||||
case Mouse::XButton1:
|
||||
vkey = VK_XBUTTON1;
|
||||
virtualKey = VK_XBUTTON1;
|
||||
break;
|
||||
case Mouse::XButton2:
|
||||
vkey = VK_XBUTTON2;
|
||||
virtualKey = VK_XBUTTON2;
|
||||
break;
|
||||
default:
|
||||
vkey = 0;
|
||||
virtualKey = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return (GetAsyncKeyState(vkey) & 0x8000) != 0;
|
||||
return (GetAsyncKeyState(virtualKey) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,19 +41,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
@ -154,6 +172,21 @@ public:
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Vector2i getTouchPosition(unsigned int finger, const WindowBase& relativeTo);
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Ensure the mappings are generated from/to Key and Scancode.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void ensureMappings();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
// NOLINTBEGIN(readability-identifier-naming)
|
||||
static Keyboard::Scancode m_keyToScancodeMapping[Keyboard::KeyCount]; ///< Mapping from Key to Scancode
|
||||
static Keyboard::Key m_scancodeToKeyMapping[Keyboard::Scan::ScancodeCount]; ///< Mapping from Scancode to Key
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
};
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -560,6 +560,133 @@ void WindowImplWin32::grabCursor(bool grabbed)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Keyboard::Scancode WindowImplWin32::toScancode(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int code = (lParam & (0xFF << 16)) >> 16;
|
||||
|
||||
// Retrieve the scancode from the VirtualKey for synthetic key messages
|
||||
if (code == 0)
|
||||
{
|
||||
code = static_cast<int>(MapVirtualKey(static_cast<UINT>(wParam), MAPVK_VK_TO_VSC));
|
||||
}
|
||||
|
||||
// Windows scancodes
|
||||
// Reference: https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx
|
||||
// clang-format off
|
||||
switch (code)
|
||||
{
|
||||
case 1: return Keyboard::Scan::Escape;
|
||||
case 2: return Keyboard::Scan::Num1;
|
||||
case 3: return Keyboard::Scan::Num2;
|
||||
case 4: return Keyboard::Scan::Num3;
|
||||
case 5: return Keyboard::Scan::Num4;
|
||||
case 6: return Keyboard::Scan::Num5;
|
||||
case 7: return Keyboard::Scan::Num6;
|
||||
case 8: return Keyboard::Scan::Num7;
|
||||
case 9: return Keyboard::Scan::Num8;
|
||||
case 10: return Keyboard::Scan::Num9;
|
||||
case 11: return Keyboard::Scan::Num0;
|
||||
case 12: return Keyboard::Scan::Hyphen;
|
||||
case 13: return Keyboard::Scan::Equal;
|
||||
case 14: return Keyboard::Scan::Backspace;
|
||||
case 15: return Keyboard::Scan::Tab;
|
||||
case 16: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaPreviousTrack : Keyboard::Scan::Q;
|
||||
case 17: return Keyboard::Scan::W;
|
||||
case 18: return Keyboard::Scan::E;
|
||||
case 19: return Keyboard::Scan::R;
|
||||
case 20: return Keyboard::Scan::T;
|
||||
case 21: return Keyboard::Scan::Y;
|
||||
case 22: return Keyboard::Scan::U;
|
||||
case 23: return Keyboard::Scan::I;
|
||||
case 24: return Keyboard::Scan::O;
|
||||
case 25: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaNextTrack : Keyboard::Scan::P;
|
||||
case 26: return Keyboard::Scan::LBracket;
|
||||
case 27: return Keyboard::Scan::RBracket;
|
||||
case 28: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumpadEnter : Keyboard::Scan::Enter;
|
||||
case 29: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RControl : Keyboard::Scan::LControl;
|
||||
case 30: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Select : Keyboard::Scan::A;
|
||||
case 31: return Keyboard::Scan::S;
|
||||
case 32: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeMute : Keyboard::Scan::D;
|
||||
case 33: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchApplication1 : Keyboard::Scan::F;
|
||||
case 34: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaPlayPause : Keyboard::Scan::G;
|
||||
case 35: return Keyboard::Scan::H;
|
||||
case 36: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaStop : Keyboard::Scan::J;
|
||||
case 37: return Keyboard::Scan::K;
|
||||
case 38: return Keyboard::Scan::L;
|
||||
case 39: return Keyboard::Scan::Semicolon;
|
||||
case 40: return Keyboard::Scan::Apostrophe;
|
||||
case 41: return Keyboard::Scan::Grave;
|
||||
case 42: return Keyboard::Scan::LShift;
|
||||
case 43: return Keyboard::Scan::Backslash;
|
||||
case 44: return Keyboard::Scan::Z;
|
||||
case 45: return Keyboard::Scan::X;
|
||||
case 46: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeDown : Keyboard::Scan::C;
|
||||
case 47: return Keyboard::Scan::V;
|
||||
case 48: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeUp : Keyboard::Scan::B;
|
||||
case 49: return Keyboard::Scan::N;
|
||||
case 50: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::HomePage : Keyboard::Scan::M;
|
||||
case 51: return Keyboard::Scan::Comma;
|
||||
case 52: return Keyboard::Scan::Period;
|
||||
case 53: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumpadDivide : Keyboard::Scan::Slash;
|
||||
case 54: return Keyboard::Scan::RShift;
|
||||
case 55: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PrintScreen : Keyboard::Scan::NumpadMultiply;
|
||||
case 56: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RAlt : Keyboard::Scan::LAlt;
|
||||
case 57: return Keyboard::Scan::Space;
|
||||
case 58: return Keyboard::Scan::CapsLock;
|
||||
case 59: return Keyboard::Scan::F1;
|
||||
case 60: return Keyboard::Scan::F2;
|
||||
case 61: return Keyboard::Scan::F3;
|
||||
case 62: return Keyboard::Scan::F4;
|
||||
case 63: return Keyboard::Scan::F5;
|
||||
case 64: return Keyboard::Scan::F6;
|
||||
case 65: return Keyboard::Scan::F7;
|
||||
case 66: return Keyboard::Scan::F8;
|
||||
case 67: return Keyboard::Scan::F9;
|
||||
case 68: return Keyboard::Scan::F10;
|
||||
case 69: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumLock : Keyboard::Scan::Pause;
|
||||
case 70: return Keyboard::Scan::ScrollLock;
|
||||
case 71: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Home : Keyboard::Scan::Numpad7;
|
||||
case 72: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Up : Keyboard::Scan::Numpad8;
|
||||
case 73: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PageUp : Keyboard::Scan::Numpad9;
|
||||
case 74: return Keyboard::Scan::NumpadMinus;
|
||||
case 75: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Left : Keyboard::Scan::Numpad4;
|
||||
case 76: return Keyboard::Scan::Numpad5;
|
||||
case 77: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Right : Keyboard::Scan::Numpad6;
|
||||
case 78: return Keyboard::Scan::NumpadPlus;
|
||||
case 79: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::End : Keyboard::Scan::Numpad1;
|
||||
case 80: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Down : Keyboard::Scan::Numpad2;
|
||||
case 81: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PageDown : Keyboard::Scan::Numpad3;
|
||||
case 82: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Insert : Keyboard::Scan::Numpad0;
|
||||
case 83: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Delete : Keyboard::Scan::NumpadDecimal;
|
||||
|
||||
case 86: return Keyboard::Scan::NonUsBackslash;
|
||||
case 87: return Keyboard::Scan::F11;
|
||||
case 88: return Keyboard::Scan::F12;
|
||||
|
||||
case 91: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LSystem : Keyboard::Scan::Unknown;
|
||||
case 92: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RSystem : Keyboard::Scan::Unknown;
|
||||
case 93: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Menu : Keyboard::Scan::Unknown;
|
||||
|
||||
case 99: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Help : Keyboard::Scan::Unknown;
|
||||
case 100: return Keyboard::Scan::F13;
|
||||
case 101: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Search : Keyboard::Scan::F14;
|
||||
case 102: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Favorites : Keyboard::Scan::F15;
|
||||
case 103: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Refresh : Keyboard::Scan::F16;
|
||||
case 104: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Stop : Keyboard::Scan::F17;
|
||||
case 105: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Forward : Keyboard::Scan::F18;
|
||||
case 106: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Back : Keyboard::Scan::F19;
|
||||
case 107: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchApplication1 : Keyboard::Scan::F20;
|
||||
case 108: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchMail : Keyboard::Scan::F21;
|
||||
case 109: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchMediaSelect : Keyboard::Scan::F22;
|
||||
case 110: return Keyboard::Scan::F23;
|
||||
|
||||
case 118: return Keyboard::Scan::F24;
|
||||
|
||||
default: return Keyboard::Scan::Unknown;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
@ -736,6 +863,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
|
||||
event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
|
||||
event.key.code = virtualKeyCodeToSF(wParam, lParam);
|
||||
event.key.scancode = toScancode(wParam, lParam);
|
||||
pushEvent(event);
|
||||
}
|
||||
break;
|
||||
@ -752,6 +880,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
|
||||
event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
|
||||
event.key.code = virtualKeyCodeToSF(wParam, lParam);
|
||||
event.key.scancode = toScancode(wParam, lParam);
|
||||
pushEvent(event);
|
||||
break;
|
||||
}
|
||||
@ -1029,9 +1158,9 @@ Keyboard::Key WindowImplWin32::virtualKeyCodeToSF(WPARAM key, LPARAM flags)
|
||||
case VK_OEM_6: return Keyboard::RBracket;
|
||||
case VK_OEM_COMMA: return Keyboard::Comma;
|
||||
case VK_OEM_PERIOD: return Keyboard::Period;
|
||||
case VK_OEM_7: return Keyboard::Quote;
|
||||
case VK_OEM_7: return Keyboard::Apostrophe;
|
||||
case VK_OEM_5: return Keyboard::Backslash;
|
||||
case VK_OEM_3: return Keyboard::Tilde;
|
||||
case VK_OEM_3: return Keyboard::Grave;
|
||||
case VK_ESCAPE: return Keyboard::Escape;
|
||||
case VK_SPACE: return Keyboard::Space;
|
||||
case VK_RETURN: return Keyboard::Enter;
|
||||
|
@ -265,6 +265,16 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
static LRESULT CALLBACK globalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert a Win32 scancode to an sfml scancode
|
||||
///
|
||||
/// \param flags input flags
|
||||
///
|
||||
/// \return SFML scancode corresponding to the key
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode toScancode(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -41,19 +41,37 @@ class InputImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a key is pressed
|
||||
///
|
||||
/// \param key Key to check
|
||||
///
|
||||
/// \return True if the key is pressed, false otherwise
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Key)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the virtual keyboard
|
||||
/// \copydoc sf::Keyboard::isKeyPressed(Scancode)
|
||||
///
|
||||
/// \param visible True to show, false to hide
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isKeyPressed(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::localize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Key localize(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::delocalize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static Keyboard::Scancode delocalize(Keyboard::Key key);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::getDescription
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static String getDescription(Keyboard::Scancode code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \copydoc sf::Keyboard::setVirtualKeyboardVisible
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setVirtualKeyboardVisible(bool visible);
|
||||
|
@ -41,6 +41,29 @@ bool InputImpl::isKeyPressed(Keyboard::Key /* key */)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputImpl::isKeyPressed(Keyboard::Scancode /* codes */)
|
||||
{
|
||||
// Not applicable
|
||||
return false;
|
||||
}
|
||||
|
||||
Keyboard::Key InputImpl::localize(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// Not applicable
|
||||
return Keyboard::Unknown;
|
||||
}
|
||||
|
||||
Keyboard::Scancode InputImpl::delocalize(Keyboard::Key /* key */)
|
||||
{
|
||||
// Not applicable
|
||||
return Keyboard::Scan::Unknown;
|
||||
}
|
||||
|
||||
String InputImpl::getDescription(Keyboard::Scancode /* code */)
|
||||
{
|
||||
// Not applicable
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setVirtualKeyboardVisible(bool visible)
|
||||
|
Loading…
Reference in New Issue
Block a user