Implemented OSX/InputImpl::IsMouseButtonPressed

This commit is contained in:
Marco Antognini 2011-07-10 05:32:09 +02:00
parent 5fbf147cc0
commit d33ecd17ad
2 changed files with 183 additions and 9 deletions

View File

@ -127,6 +127,14 @@ private :
////////////////////////////////////////////////////////////
void InitializeKeyboard();
////////////////////////////////////////////////////////////
/// \brief Initialize the mouse part of this class
///
/// If something went wrong FreeUp is called
///
////////////////////////////////////////////////////////////
void InitializeMouse();
////////////////////////////////////////////////////////////
/// \brief Load the given keyboard into myKeys
///
@ -138,6 +146,17 @@ private :
////////////////////////////////////////////////////////////
void LoadKeyboard(IOHIDDeviceRef keyboard);
////////////////////////////////////////////////////////////
/// \brief Load the given mouse into myButtons
///
/// If the given mouse has no button this function simply
/// returns. FreeUp is _not_ called because this is not fatal.
///
/// \param mouse Mouse to load
///
////////////////////////////////////////////////////////////
void LoadMouse(IOHIDDeviceRef mouse);
////////////////////////////////////////////////////////////
/// \brief Load the given key into myKeys
///
@ -148,6 +167,16 @@ private :
////////////////////////////////////////////////////////////
void LoadKey(IOHIDElementRef key);
////////////////////////////////////////////////////////////
/// \brief Load the given button into myButtons
///
/// FreeUp is _not_ called by this function.
///
/// \param button Button to load
///
////////////////////////////////////////////////////////////
void LoadButton(IOHIDElementRef button);
////////////////////////////////////////////////////////////
/// \brief Release all resources
///
@ -202,7 +231,8 @@ private :
IOHIDManagerRef myManager; ///< HID Manager
typedef std::vector<IOHIDElementRef> IOHIDElements;
IOHIDElements myKeys[Keyboard::KeyCount]; ///< All the keys on the current keyboard
IOHIDElements myKeys[Keyboard::KeyCount]; ///< All the keys on any connected keyboard
IOHIDElements myButtons[Mouse::ButtonCount];///< All the buttons on any connected mouse
////////////////////////////////////////////////////////////
/// myKeys' index corresponds to sf::Keyboard::Key enum.
@ -211,6 +241,8 @@ private :
/// with the same sf::Keyboard::Key then myKeys[XYZ] contains all these
/// HID keys.
///
/// myButtons works the same way.
///
////////////////////////////////////////////////////////////
};

View File

@ -67,16 +67,12 @@ bool HIDInputManager::IsKeyPressed(Keyboard::Key key)
CFRelease(*it);
it = myKeys[key].erase(it);
sf::Err() << key
<< " is dead (cannot access its value)."
<< std::endl;
} else if (IOHIDValueGetIntegerValue(value) == 1) {
// This means the key is pressed
state = true;
break; // Stop here.
break; // Stop here
} else {
@ -97,8 +93,38 @@ bool HIDInputManager::IsMouseButtonPressed(Mouse::Button button)
return false;
}
// @to be implemented
return false;
// state = true if at least one corresponding HID button is pressed
bool state = false;
for (IOHIDElements::iterator it = myButtons[button].begin(); it != myButtons[button].end(); ++it) {
IOHIDValueRef value = 0;
IOHIDDeviceRef device = IOHIDElementGetDevice(*it);
IOHIDDeviceGetValue(device, *it, &value);
if (!value) {
// This means some kind of error / deconnection so we remove this
// element from our buttons
CFRelease(*it);
it = myButtons[button].erase(it);
} else if (IOHIDValueGetIntegerValue(value) == 1) {
// This means the button is pressed
state = true;
break; // Stop here
} else {
// This means the button is released
}
}
return state;
}
@ -147,7 +173,12 @@ HIDInputManager::HIDInputManager()
return; // Something went wrong
}
// TODO init mouse
// Initialize the mouse
InitializeMouse();
if (!amIValid) {
return; // Something went wrong
}
}
@ -193,6 +224,42 @@ void HIDInputManager::InitializeKeyboard()
}
////////////////////////////////////////////////////////////
void HIDInputManager::InitializeMouse()
{
////////////////////////////////////////////////////////////
// The purpose of this function is to initalize myButtons so we can get
// the associate IOHIDElementRef with a sf::Mouse::Button in ~constant~ time.
// Get only mouses
CFSetRef mouses = CopyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
if (mouses == NULL) {
// FreeUp was already called
return;
}
CFIndex mouseCount = CFSetGetCount(mouses); // >= 1 (asserted by CopyDevices)
// Get an iterable array
CFTypeRef devicesArray[mouseCount];
CFSetGetValues(mouses, devicesArray);
for (CFIndex i = 0; i < mouseCount; ++i) {
IOHIDDeviceRef mouse = (IOHIDDeviceRef)devicesArray[i];
LoadMouse(mouse);
}
// Release unused stuff
CFRelease(mouses);
////////////////////////////////////////////////////////////
// At this point myButtons is filled with as many IOHIDElementRef as possible
}
////////////////////////////////////////////////////////////
void HIDInputManager::LoadKeyboard(IOHIDDeviceRef keyboard)
{
@ -232,6 +299,44 @@ void HIDInputManager::LoadKeyboard(IOHIDDeviceRef keyboard)
}
////////////////////////////////////////////////////////////
void HIDInputManager::LoadMouse(IOHIDDeviceRef mouse)
{
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(mouse,
NULL,
kIOHIDOptionsTypeNone);
if (buttons == NULL) {
sf::Err() << "We got a mouse without any buttons (1)" << std::endl;
return;
}
// How many elements are there ?
CFIndex buttonCount = CFArrayGetCount(buttons);
if (buttonCount == 0) {
sf::Err() << "We got a mouse without any buttons (2)" << std::endl;
CFRelease(buttons);
return;
}
// Go through all connected elements.
for (CFIndex i = 0; i < buttonCount; ++i) {
IOHIDElementRef aButton = (IOHIDElementRef) CFArrayGetValueAtIndex(buttons, i);
// Skip non-matching keys elements
if (IOHIDElementGetUsagePage(aButton) != kHIDPage_Button) {
continue;
}
LoadButton(aButton);
}
// Release unused stuff
CFRelease(buttons);
}
////////////////////////////////////////////////////////////
void HIDInputManager::LoadKey(IOHIDElementRef key)
{
@ -330,6 +435,36 @@ void HIDInputManager::LoadKey(IOHIDElementRef key)
}
////////////////////////////////////////////////////////////
void HIDInputManager::LoadButton(IOHIDElementRef button)
{
// Identify the button
UInt32 usage = IOHIDElementGetUsage(button);
Mouse::Button dest = Mouse::ButtonCount;
// Extends kHIDUsage_Button_* enum with :
#define kHIDUsage_Button_5 0x05
switch (usage) {
case kHIDUsage_Button_1: dest = Mouse::Left; break;
case kHIDUsage_Button_2: dest = Mouse::Right; break;
case kHIDUsage_Button_3: dest = Mouse::Middle; break;
case kHIDUsage_Button_4: dest = Mouse::XButton1; break;
case kHIDUsage_Button_5: dest = Mouse::XButton2; break;
default: dest = Mouse::ButtonCount; break;
}
if (dest != Mouse::ButtonCount) {
// We know what kind of button it is!
myButtons[dest].push_back(button);
// And don't forget to keep the reference alive for our usage
CFRetain(myButtons[dest].back());
}
}
////////////////////////////////////////////////////////////
void HIDInputManager::FreeUp()
{
@ -345,6 +480,13 @@ void HIDInputManager::FreeUp()
}
myKeys[i].clear();
}
for (unsigned int i = 0; i < Mouse::ButtonCount; ++i) {
for (IOHIDElements::iterator it = myButtons[i].begin(); it != myButtons[i].end(); ++it) {
CFRelease(*it);
}
myButtons[i].clear();
}
}