From 8ecdd3ae8c858249ab401c93edf50d5ecfbab846 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Fri, 28 Jun 2013 10:46:14 +0200 Subject: [PATCH] Refactor SFOpenGLView and move code related to modifiers to a new file Now SFKeyboardModifiersHelper.(h|mm) manage all the logic of modifier flags and the state of the corresponding keys Also, now modifiers key release events are correctly fired with multiple SFML windows. --- src/SFML/Window/CMakeLists.txt | 2 + .../Window/OSX/SFKeyboardModifiersHelper.h | 65 +++ .../Window/OSX/SFKeyboardModifiersHelper.mm | 249 +++++++++ src/SFML/Window/OSX/SFOpenGLView.h | 17 +- src/SFML/Window/OSX/SFOpenGLView.mm | 488 +----------------- 5 files changed, 331 insertions(+), 490 deletions(-) create mode 100644 src/SFML/Window/OSX/SFKeyboardModifiersHelper.h create mode 100644 src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 57294a83b..b1d9aca60 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -82,6 +82,8 @@ else() # MACOSX ${SRCROOT}/OSX/SFApplication.m ${SRCROOT}/OSX/SFContext.hpp ${SRCROOT}/OSX/SFContext.mm + ${SRCROOT}/OSX/SFKeyboardModifiersHelper.h + ${SRCROOT}/OSX/SFKeyboardModifiersHelper.mm ${SRCROOT}/OSX/SFOpenGLView.h ${SRCROOT}/OSX/SFOpenGLView.mm ${SRCROOT}/OSX/SFSilentResponder.h diff --git a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h new file mode 100644 index 000000000..78146fd19 --- /dev/null +++ b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2012 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent.gom@gmail.com), +// +// 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 +//////////////////////////////////////////////////////////// +#import + +namespace sf { + namespace priv { + class WindowImplCocoa; + } +} + +//////////////////////////////////////////////////////////// +/// Keyboard Modifiers Helper +/// +/// Handle modifiers (cmd, ctrl, alt, shift) events and send +/// them back to the requester. +/// +/// As I don't have the right control keycode I cannot +/// implement left-right recognition for this key. +/// (See SFKeyboardModifiersHelper.mm for more info.) +/// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +/// 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); + + +//////////////////////////////////////////////////////////// +/// Handle the state of modifiers keys and send key +/// release & pressed events to the requester. +/// +//////////////////////////////////////////////////////////// +void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& requester); + + diff --git a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm new file mode 100644 index 000000000..b019d0d5c --- /dev/null +++ b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm @@ -0,0 +1,249 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2012 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent.gom@gmail.com), +// +// 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 + +#import + + +//////////////////////////////////////////////////////////// +/// Here are define the mask value for the 'modifiers' keys (cmd, ctrl, alt, shift) +/// +/// As I don't have the right control keycode I cannot implement left-right +/// recognition for this key. +#warning Missing keycode for right control key. +/// #define NSRightControlKeyMask 0x... +/// #define NSLeftControlKeyMask 0x40101 +/// +//////////////////////////////////////////////////////////// +#define NSRightShiftKeyMask 0x020004 +#define NSLeftShiftKeyMask 0x020002 +#define NSRightCommandKeyMask 0x100010 +#define NSLeftCommandKeyMask 0x100008 +#define NSRightAlternateKeyMask 0x080040 +#define NSLeftAlternateKeyMask 0x080020 + + +//////////////////////////////////////////////////////////// +// Local Data Structures +//////////////////////////////////////////////////////////// + +/// Modifiers states +struct ModifiersState +{ + BOOL rightShiftWasDown; + BOOL leftShiftWasDown; + BOOL rightCommandWasDown; + BOOL leftCommandWasDown; + BOOL rightAlternateWasDown; + BOOL leftAlternateWasDown; + BOOL controlWasDown; + // Left & right control keys not yet supported. See the note above. +}; + + +//////////////////////////////////////////////////////////// +// Global Variables +//////////////////////////////////////////////////////////// + +/// Share 'modifiers' state with all windows to correctly fire pressed/released events +static ModifiersState state; +static BOOL isStateInitialized = NO; + + +//////////////////////////////////////////////////////////// +// Local & Private Functions +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +/// Carefully observe if the key mask is on in the modifiers +/// +//////////////////////////////////////////////////////////// +BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask); + + +//////////////////////////////////////////////////////// +/// Init the global state only if needed +/// +//////////////////////////////////////////////////////////// +void ensureModifiersStateIsInitilized(); + + +//////////////////////////////////////////////////////////// +/// Handle one modifier key mask, update the key state and +/// send events to the requester +/// +//////////////////////////////////////////////////////////// +void processOneModifier(NSUInteger modifiers, NSUInteger mask, + BOOL& wasDown, sf::Keyboard::Key key, + sf::priv::WindowImplCocoa& requester); + + +//////////////////////////////////////////////////////////// +/// Handle left & right modifier keys, update the keys state and +/// send events to the requester +/// +//////////////////////////////////////////////////////////// +void processLeftRightModifiers(NSUInteger modifiers, + NSUInteger leftMask, NSUInteger rightMask, + BOOL& leftWasDown, BOOL& rightWasDown, + sf::Keyboard::Key leftKey, sf::Keyboard::Key rightKey, + sf::priv::WindowImplCocoa& requester); + + + +//////////////////////////////////////////////////////////// +// Implementations +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////// +sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key) +{ + sf::Event::KeyEvent event; + event.code = key; + event.alt = modifiers & NSAlternateKeyMask; + event.control = modifiers & NSControlKeyMask; + event.shift = modifiers & NSShiftKeyMask; + event.system = modifiers & NSCommandKeyMask; + + return event; +} + + +//////////////////////////////////////////////////////// +void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& requester) +{ + // Handle shift + processLeftRightModifiers( + modifiers, + NSLeftShiftKeyMask, NSRightShiftKeyMask, + state.leftShiftWasDown, state.rightShiftWasDown, + sf::Keyboard::LShift, sf::Keyboard::RShift, + requester + ); + + // Handle command + processLeftRightModifiers( + modifiers, + NSLeftCommandKeyMask, NSRightCommandKeyMask, + state.leftCommandWasDown, state.rightCommandWasDown, + sf::Keyboard::LSystem, sf::Keyboard::RSystem, + requester + ); + + // Handle option (alt) + processLeftRightModifiers( + modifiers, + NSLeftAlternateKeyMask, NSRightAlternateKeyMask, + state.leftAlternateWasDown, state.rightAlternateWasDown, + sf::Keyboard::LAlt, sf::Keyboard::RAlt, + requester + ); + + // Handle control + // Currently only the left control key will be used in SFML (see note above). + processOneModifier( + modifiers, NSControlKeyMask, + state.controlWasDown, sf::Keyboard::LControl, + requester + ); +} + + +//////////////////////////////////////////////////////// +BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask) +{ + // Here we need to make sure it's exactly the mask since some masks + // share some bits such that the & operation would result in a non zero + // value without corresponding to the processed key. + return (modifiers & mask) == mask; +} + + +//////////////////////////////////////////////////////// +void ensureModifiersStateIsInitilized() +{ + if (isStateInitialized) return; + + NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; + + // Load current keyboard state + state.leftShiftWasDown = isKeyMaskActive(modifiers, NSLeftShiftKeyMask); + state.rightShiftWasDown = isKeyMaskActive(modifiers, NSRightShiftKeyMask); + state.leftCommandWasDown = isKeyMaskActive(modifiers, NSLeftCommandKeyMask); + state.rightCommandWasDown = isKeyMaskActive(modifiers, NSRightCommandKeyMask); + state.leftAlternateWasDown = isKeyMaskActive(modifiers, NSLeftAlternateKeyMask); + state.rightAlternateWasDown = isKeyMaskActive(modifiers, NSRightAlternateKeyMask); + state.controlWasDown = isKeyMaskActive(modifiers, NSControlKeyMask); + // Currently only the left control key will be used in SFML (see note above). + + isStateInitialized = YES; +} + + +//////////////////////////////////////////////////////// +void processOneModifier(NSUInteger modifiers, NSUInteger mask, + BOOL& wasDown, sf::Keyboard::Key key, + sf::priv::WindowImplCocoa& requester) +{ + ensureModifiersStateIsInitilized(); + + // Setup a potential event key. + sf::Event::KeyEvent event = keyEventWithModifiers(modifiers, key); + + // State + BOOL isDown = isKeyMaskActive(modifiers, mask); + + // Check for key pressed event + if (isDown && !wasDown) { + requester.keyDown(event); + } + // And check for key released event + else if (!isDown && wasDown) { + requester.keyUp(event); + } + // else isDown == wasDown, so no change + + // Update state + wasDown = isDown; +} + + +//////////////////////////////////////////////////////// +void processLeftRightModifiers(NSUInteger modifiers, + NSUInteger leftMask, NSUInteger rightMask, + BOOL& leftWasDown, BOOL& rightWasDown, + sf::Keyboard::Key leftKey, sf::Keyboard::Key rightKey, + sf::priv::WindowImplCocoa& requester) +{ + processOneModifier(modifiers, leftMask, leftWasDown, leftKey, requester); + processOneModifier(modifiers, rightMask, rightWasDown, rightKey, requester); +} + + diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index a8fffdc81..b95a018d5 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -47,8 +47,8 @@ namespace sf { /// bound to its default value we don't recompute the mouse position /// and assume it's correct. /// -/// As I don't have the right control keycode I cannot implement left-right -/// recognition for this key. (See SFOpenGLView.mm for more info.) +/// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class +/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm). /// //////////////////////////////////////////////////////////// @interface SFOpenGLView : NSOpenGLView { @@ -57,18 +57,9 @@ namespace sf { NSTrackingRectTag m_trackingTag; BOOL m_mouseIsIn; NSSize m_realSize; - - /// 'modifiers' state - BOOL m_rightShiftWasDown; - BOOL m_leftShiftWasDown; - BOOL m_rightCommandWasDown; - BOOL m_leftCommandWasDown; - BOOL m_rightAlternateWasDown; - BOOL m_leftAlternateWasDown; - BOOL m_controlWasDown; - // Hidden text view use to convert key event to actual chars. - // To prevent sound alert we use a silent responder. + // Hidden text view used to convert key event to actual chars. + // We use a silent responder to prevent sound alerts. SFSilentResponder* m_silentResponder; NSTextView* m_hiddenTextView; } diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index 8364bda55..d809019c9 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -32,35 +32,8 @@ #import #import +#import -//////////////////////////////////////////////////////////// -/// Here are define the mask value for the 'modifiers' keys (cmd, ctrl, alt, shift) -/// -/// As I don't have the right control keycode I cannot implement left-right -/// recognition for this key. -#warning Missing keycode for right control key. -/// #define NSRightControlKeyMask 0x... -/// #define NSLeftControlKeyMask 0x40101 -/// -//////////////////////////////////////////////////////////// -#define NSRightShiftKeyMask 0x020004 -#define NSLeftShiftKeyMask 0x020002 -#define NSRightCommandKeyMask 0x100010 -#define NSLeftCommandKeyMask 0x100008 -#define NSRightAlternateKeyMask 0x080040 -#define NSLeftAlternateKeyMask 0x080020 - -//////////////////////////////////////////////////////////// -/// Erase (replace with 0) the given bits mask from the given data bits. -/// -//////////////////////////////////////////////////////////// -NSUInteger eraseMaskFromData(NSUInteger data, NSUInteger mask); - -//////////////////////////////////////////////////////////// -/// Erase (replace with 0) everything execept the given bits mask from the given data bits. -/// -//////////////////////////////////////////////////////////// -NSUInteger keepOnlyMaskFromData(NSUInteger data, NSUInteger mask); //////////////////////////////////////////////////////////// /// Returns true if `event` represents a representable character. @@ -71,6 +44,7 @@ NSUInteger keepOnlyMaskFromData(NSUInteger data, NSUInteger mask); //////////////////////////////////////////////////////////// BOOL isValidTextUnicode(NSEvent* event); + //////////////////////////////////////////////////////////// /// SFOpenGLView class : Privates Methods Declaration /// @@ -89,12 +63,6 @@ BOOL isValidTextUnicode(NSEvent* event); //////////////////////////////////////////////////////////// -(BOOL)isMouseInside; -//////////////////////////////////////////////////////////// -/// Init the 'modifiers' key state. -/// -//////////////////////////////////////////////////////////// --(void)initModifiersState; - //////////////////////////////////////////////////////////// /// Convert the NSEvent mouse button type to SFML type. /// @@ -126,7 +94,6 @@ BOOL isValidTextUnicode(NSEvent* event); [self setRequesterTo:0]; [self enableKeyRepeat]; m_realSize = NSZeroSize; - [self initModifiersState]; // Register for mouse-move event m_mouseIsIn = [self isMouseInside]; @@ -627,445 +594,27 @@ BOOL isValidTextUnicode(NSEvent* event); if (m_requester == 0) return; NSUInteger modifiers = [theEvent modifierFlags]; - - // Setup a potential event key. - sf::Event::KeyEvent key; - key.code = sf::Keyboard::Unknown; - key.alt = modifiers & NSAlternateKeyMask; - key.control = modifiers & NSControlKeyMask; - key.shift = modifiers & NSShiftKeyMask; - key.system = modifiers & NSCommandKeyMask; - - // State - BOOL rightShiftIsDown = NO; - BOOL leftShiftIsDown = NO; - BOOL rightCommandIsDown = NO; - BOOL leftCommandIsDown = NO; - BOOL rightAlternateIsDown = NO; - BOOL leftAlternateIsDown = NO; - BOOL controlIsDown = NO; - - // Shift keys. - if (modifiers & NSShiftKeyMask) { // At least one shift key is down. - // Clean up modifiers to keep only 'shift' bits. - NSUInteger shift = keepOnlyMaskFromData(modifiers, NSRightShiftKeyMask | NSLeftShiftKeyMask); - - // Only right shift is down ? - if (shift == NSRightShiftKeyMask) { - - rightShiftIsDown = YES; - - if (m_leftShiftWasDown) { - // left shift released - leftShiftIsDown = NO; - - key.code = sf::Keyboard::LShift; - m_requester->keyUp(key); - } - - if (!m_rightShiftWasDown) { - // right shift pressed - - key.code = sf::Keyboard::RShift; - m_requester->keyDown(key); - } - } - - // Only left shift is down ? - if (shift == NSLeftShiftKeyMask) { - - leftShiftIsDown = YES; - - if (m_rightShiftWasDown) { - // right shift released - rightShiftIsDown = NO; - - key.code = sf::Keyboard::RShift; - m_requester->keyUp(key); - } - - if (!m_leftShiftWasDown) { - // left shift pressed - - key.code = sf::Keyboard::LShift; - m_requester->keyDown(key); - } - } - - // Or are they both down ? - if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) { - - rightShiftIsDown = YES; - leftShiftIsDown = YES; - - if (!m_rightShiftWasDown) { - // right shift pressed - - key.code = sf::Keyboard::RShift; - m_requester->keyDown(key); - } - - if (!m_leftShiftWasDown) { - // left shift pressed - - key.code = sf::Keyboard::LShift; - m_requester->keyDown(key); - } - } - } else { // No shift key down. - - rightShiftIsDown = NO; - leftShiftIsDown = NO; - - if (m_rightShiftWasDown) { - // right shift released - - key.code = sf::Keyboard::RShift; - m_requester->keyUp(key); - } - - if (m_leftShiftWasDown) { - // left shift released - - key.code = sf::Keyboard::LShift; - m_requester->keyUp(key); - } - } - - // Command keys. - if (modifiers & NSCommandKeyMask) { // At least one command key is down. - // Clean up modifiers to keep only 'Command' bits. - NSUInteger command = keepOnlyMaskFromData(modifiers, NSRightCommandKeyMask | NSLeftCommandKeyMask); - - // Only right Command is down ? - if (command == NSRightCommandKeyMask) { - - rightCommandIsDown = YES; - - if (m_leftCommandWasDown) { - // left command released - leftCommandIsDown = NO; - - key.code = sf::Keyboard::LSystem; - m_requester->keyUp(key); - } - - if (!m_rightCommandWasDown) { - // right command pressed - - key.code = sf::Keyboard::RSystem; - m_requester->keyDown(key); - } - } - - // Only left Command is down ? - if (command == NSLeftCommandKeyMask) { - - leftCommandIsDown = YES; - - if (m_rightCommandWasDown) { - // right command released - rightCommandIsDown = NO; - - key.code = sf::Keyboard::RSystem; - m_requester->keyUp(key); - } - - if (!m_leftCommandWasDown) { - // left command pressed - - key.code = sf::Keyboard::LSystem; - m_requester->keyDown(key); - } - } - - // Or are they both down ? - if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) { - - rightCommandIsDown = YES; - leftCommandIsDown = YES; - - if (!m_rightCommandWasDown) { - // right command pressed - - key.code = sf::Keyboard::RSystem; - m_requester->keyDown(key); - } - - if (!m_leftCommandWasDown) { - // left command pressed - - key.code = sf::Keyboard::LSystem; - m_requester->keyDown(key); - } - } - } else { // No Command key down. - - rightCommandIsDown = NO; - leftCommandIsDown = NO; - - if (m_rightCommandWasDown) { - // right command released - - key.code = sf::Keyboard::RSystem; - m_requester->keyUp(key); - } - - if (m_leftCommandWasDown) { - // left command released - - key.code = sf::Keyboard::LSystem; - m_requester->keyUp(key); - } - } - - // Alternate keys. - if (modifiers & NSAlternateKeyMask) { // At least one alternate key is down. - // Clean up modifiers to keep only 'Alternate' bits. - NSUInteger alternate = keepOnlyMaskFromData(modifiers, NSRightAlternateKeyMask | NSLeftAlternateKeyMask); - - // Only right Alternate is down ? - if (alternate == NSRightAlternateKeyMask) { - - rightAlternateIsDown = YES; - - if (m_leftAlternateWasDown) { - // left alt released - leftAlternateIsDown = NO; - - key.code = sf::Keyboard::LAlt; - m_requester->keyUp(key); - } - - if (!m_rightAlternateWasDown) { - // right alt pressed - - key.code = sf::Keyboard::RAlt; - m_requester->keyDown(key); - } - } - - // Only left Alternate is down ? - if (alternate == NSLeftAlternateKeyMask) { - - leftAlternateIsDown = YES; - - if (m_rightAlternateWasDown) { - // right alt released - rightAlternateIsDown = NO; - - key.code = sf::Keyboard::RAlt; - m_requester->keyUp(key); - } - - if (!m_leftAlternateWasDown) { - // left alt pressed - - key.code = sf::Keyboard::LAlt; - m_requester->keyDown(key); - } - } - - // Or are they both down ? - if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) { - - rightAlternateIsDown = YES; - leftAlternateIsDown = YES; - - if (!m_rightAlternateWasDown) { - // right alt pressed - - key.code = sf::Keyboard::RAlt; - m_requester->keyDown(key); - } - - if (!m_leftAlternateWasDown) { - // left alt pressed - - key.code = sf::Keyboard::LAlt; - m_requester->keyDown(key); - } - } - } else { // No Alternate key down. - - rightAlternateIsDown = NO; - leftAlternateIsDown = NO; - - if (m_rightAlternateWasDown) { - // right alt released - - key.code = sf::Keyboard::RAlt; - m_requester->keyUp(key); - } - - if (m_leftAlternateWasDown) { - // left alt released - - key.code = sf::Keyboard::LAlt; - m_requester->keyUp(key); - } - } - - // Control keys. - if (modifiers & NSControlKeyMask) { - // Currently only the left control key will be used in SFML (see note above). - - controlIsDown = YES; - - if (!m_controlWasDown) { - // ctrl pressed - - key.code = sf::Keyboard::LControl; - m_requester->keyDown(key); - } - } else { // No control key down. - controlIsDown = NO; - - if (m_controlWasDown) { - // ctrl released - - key.code = sf::Keyboard::LControl; - m_requester->keyUp(key); - } - } - - // Update the state - m_rightShiftWasDown = rightShiftIsDown; - m_leftShiftWasDown = leftShiftIsDown; - m_rightCommandWasDown = rightCommandIsDown; - m_leftCommandWasDown = leftCommandIsDown; - m_rightAlternateWasDown = rightAlternateIsDown; - m_leftAlternateWasDown = leftAlternateIsDown; - m_controlWasDown = controlIsDown; -} - - -//////////////////////////////////////////////////////// --(void)initModifiersState -{ - // Set default value to NO. - m_rightShiftWasDown = NO; - m_leftShiftWasDown = NO; - m_rightCommandWasDown = NO; - m_leftCommandWasDown = NO; - m_rightAlternateWasDown = NO; - m_leftAlternateWasDown = NO; - m_controlWasDown = NO; - - NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; - modifiers = eraseMaskFromData(modifiers, 0x100); // We erase something useless that might be present. - - // Shift keys. - if (modifiers & NSShiftKeyMask) { // At least one shift key is down. - // Clean up modifiers to keep only 'shift' bits. - NSUInteger shift = keepOnlyMaskFromData(modifiers, NSRightShiftKeyMask | NSLeftShiftKeyMask); - - // Only right shift is down ? - if (shift == NSRightShiftKeyMask) { - - m_rightShiftWasDown = YES; - } - - // Only left shift is down ? - if (shift == NSLeftShiftKeyMask) { - - m_leftShiftWasDown = YES; - } - - // Or are they both down ? - if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) { - - m_rightShiftWasDown = YES; - m_leftShiftWasDown = YES; - } - } - - // Command keys. - if (modifiers & NSCommandKeyMask) { // At least one command key is down. - // Clean up modifiers to keep only 'Command' bits. - NSUInteger command = keepOnlyMaskFromData(modifiers, NSRightCommandKeyMask | NSLeftCommandKeyMask); - - // Only right Command is down ? - if (command == NSRightCommandKeyMask) { - - m_rightCommandWasDown = YES; - } - - // Only left Command is down ? - if (command == NSLeftCommandKeyMask) { - - m_leftCommandWasDown = YES; - } - - // Or are they both down ? - if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) { - - m_rightCommandWasDown = YES; - m_leftCommandWasDown = YES; - } - } - - // Alternate keys. - if (modifiers & NSAlternateKeyMask) { // At least one alternate key is down. - // Clean up modifiers to keep only 'Alternate' bits. - NSUInteger alternate = keepOnlyMaskFromData(modifiers, NSRightAlternateKeyMask | NSLeftAlternateKeyMask); - - // Only right Alternate is down ? - if (alternate == NSRightAlternateKeyMask) { - - m_rightAlternateWasDown = YES; - } - - // Only left Alternate is down ? - if (alternate == NSLeftAlternateKeyMask) { - - m_leftAlternateWasDown = YES; - } - - // Or are they both down ? - if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) { - - m_rightAlternateWasDown = YES; - m_leftAlternateWasDown = YES; - } - - } - - // Control keys. - if (modifiers & NSControlKeyMask) { - // Currently only the left control key will be used in SFML (see note above). - - m_controlWasDown = YES; - } + handleModifiersChanged(modifiers, *m_requester); } //////////////////////////////////////////////////////// +(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent { - sf::Event::KeyEvent key; + // Key code + sf::Keyboard::Key key = sf::Keyboard::Unknown; - // Modifiers. - NSUInteger modifierFlags = [anEvent modifierFlags]; - key.alt = modifierFlags & NSAlternateKeyMask; - key.control = modifierFlags & NSControlKeyMask; - key.shift = modifierFlags & NSShiftKeyMask; - key.system = modifierFlags & NSCommandKeyMask; - - // Key code. - key.code = sf::Keyboard::Unknown; - - // First we look if the key down is from a list of caracter + // First we look if the key down is from a list of characters // that depend on keyboard localization. NSString* string = [anEvent charactersIgnoringModifiers]; if ([string length] > 0) { - key.code = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]); + key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]); } - // The key is not a localized one, so we try to find a corresponding code + // If the key is not a localized one, we try to find a corresponding code // through virtual key code. - if (key.code == sf::Keyboard::Unknown) { - key.code = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]); + if (key == sf::Keyboard::Unknown) { + key = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]); } //#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages. @@ -1078,7 +627,7 @@ BOOL isValidTextUnicode(NSEvent* event); // } //#endif - return key; + return keyEventWithModifiers([anEvent modifierFlags], key); } @end @@ -1086,21 +635,6 @@ BOOL isValidTextUnicode(NSEvent* event); #pragma mark - C-like functions - -//////////////////////////////////////////////////////// -NSUInteger eraseMaskFromData(NSUInteger data, NSUInteger mask) -{ - return (data | mask) ^ mask; -} - - -//////////////////////////////////////////////////////// -NSUInteger keepOnlyMaskFromData(NSUInteger data, NSUInteger mask) -{ - NSUInteger negative = NSUIntegerMax ^ mask; - return eraseMaskFromData(data, negative); -} - BOOL isValidTextUnicode(NSEvent* event) { if ([event keyCode] == 0x35) { // Escape