Adds name, vendor ID and product ID for joysticks.

- Implemented on Windows, Mac OS and Linux.
- Adds sf::Joystick::Identification structure to hold
  name, vendor ID and product ID.
This commit is contained in:
NoobsArePeople2 2014-01-03 18:12:26 -08:00
parent a8ba35171a
commit 29c0f14911
14 changed files with 447 additions and 27 deletions

View File

@ -29,6 +29,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/Export.hpp> #include <SFML/Window/Export.hpp>
#include <SFML/System/String.hpp>
namespace sf namespace sf
@ -68,6 +69,19 @@ public :
PovY ///< The Y axis of the point-of-view hat PovY ///< The Y axis of the point-of-view hat
}; };
////////////////////////////////////////////////////////////
/// \brief Structure holding a joystick's identification
///
////////////////////////////////////////////////////////////
struct Identification
{
Identification();
sf::String name; ///< Name of the joystick
unsigned int vendorId; ///< Manufacturer identifier
unsigned int productId; ///< Product identifier
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Check if a joystick is connected /// \brief Check if a joystick is connected
/// ///
@ -129,6 +143,16 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static float getAxisPosition(unsigned int joystick, Axis axis); static float getAxisPosition(unsigned int joystick, Axis axis);
////////////////////////////////////////////////////////////
/// \brief Get the joystick information
///
/// \param joystick Index of the joystick
///
/// \return Structure containing joystick information.
///
////////////////////////////////////////////////////////////
static Identification getIdentification(unsigned int joystick);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the states of all joysticks /// \brief Update the states of all joysticks
/// ///

View File

@ -51,7 +51,7 @@ if(SFML_OS_WINDOWS)
source_group("windows" FILES ${PLATFORM_SRC}) source_group("windows" FILES ${PLATFORM_SRC})
# make sure that we use the Unicode version of the Win API functions # make sure that we use the Unicode version of the Win API functions
add_definitions(-DUNICODE) add_definitions(-DUNICODE -D_UNICODE)
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD) elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD)
set(PLATFORM_SRC set(PLATFORM_SRC
${SRCROOT}/Unix/Display.cpp ${SRCROOT}/Unix/Display.cpp
@ -136,7 +136,7 @@ set(WINDOW_EXT_LIBS ${OPENGL_gl_LIBRARY})
if(SFML_OS_WINDOWS) if(SFML_OS_WINDOWS)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32) set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32)
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD) elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB}) set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB} udev)
if(SFML_OS_FREEBSD) if(SFML_OS_FREEBSD)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} usbhid) set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} usbhid)
endif() endif()

View File

@ -319,6 +319,13 @@ JoystickCaps JoystickImpl::getCapabilities() const
} }
////////////////////////////////////////////////////////////
Identifcation JoystickImpl::getIdentification() const
{
return m_identification;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickState JoystickImpl::JoystickImpl::update() JoystickState JoystickImpl::JoystickImpl::update()
{ {

View File

@ -91,6 +91,14 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickCaps getCapabilities() const; JoystickCaps getCapabilities() const;
////////////////////////////////////////////////////////////
/// \brief Get the joystick identification
///
/// \return Joystick identification
///
////////////////////////////////////////////////////////////
Identification getIdentification() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the joystick and get its new state /// \brief Update the joystick and get its new state
/// ///
@ -104,15 +112,16 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
int m_file; ///< File descriptor of the joystick int m_file; ///< File descriptor of the joystick
report_desc_t m_desc; ///< USB report descriptor report_desc_t m_desc; ///< USB report descriptor
int m_id; ///< USB id int m_id; ///< USB id
void *m_buffer; ///< USB HID buffer void *m_buffer; ///< USB HID buffer
int m_length; ///< Buffer length int m_length; ///< Buffer length
Identification m_identificaion; ///< Joystick identification
JoystickState m_state; ///< Current state of the joystick JoystickState m_state; ///< Current state of the joystick
}; };
} // namespace priv } // namespace priv

View File

@ -66,10 +66,27 @@ float Joystick::getAxisPosition(unsigned int joystick, Axis axis)
} }
////////////////////////////////////////////////////////////
Joystick::Identification Joystick::getIdentification(unsigned int joystick)
{
return priv::JoystickManager::getInstance().getIdentification(joystick);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Joystick::update() void Joystick::update()
{ {
return priv::JoystickManager::getInstance().update(); return priv::JoystickManager::getInstance().update();
} }
////////////////////////////////////////////////////////////
Joystick::Identification::Identification() :
name ("No Joystick"),
vendorId (0),
productId(0)
{
}
} // namespace sf } // namespace sf

View File

@ -30,6 +30,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Config.hpp> #include <SFML/Config.hpp>
#include <SFML/Window/Joystick.hpp> #include <SFML/Window/Joystick.hpp>
#include <SFML/System/String.hpp>
#include <algorithm> #include <algorithm>
@ -38,7 +39,7 @@ namespace sf
namespace priv namespace priv
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Structure holding a joystick's capabilities /// \brief Structure holding a joystick's information
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct JoystickCaps struct JoystickCaps

View File

@ -54,6 +54,13 @@ const JoystickState& JoystickManager::getState(unsigned int joystick) const
} }
////////////////////////////////////////////////////////////
const Joystick::Identification& JoystickManager::getIdentification(unsigned int joystick) const
{
return m_joysticks[joystick].identification;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void JoystickManager::update() void JoystickManager::update()
{ {
@ -72,6 +79,7 @@ void JoystickManager::update()
item.joystick.close(); item.joystick.close();
item.capabilities = JoystickCaps(); item.capabilities = JoystickCaps();
item.state = JoystickState(); item.state = JoystickState();
item.identification = Joystick::Identification();
} }
} }
else else
@ -83,6 +91,7 @@ void JoystickManager::update()
{ {
item.capabilities = item.joystick.getCapabilities(); item.capabilities = item.joystick.getCapabilities();
item.state = item.joystick.update(); item.state = item.joystick.update();
item.identification = item.joystick.getIdentification();
} }
} }
} }

View File

@ -54,7 +54,7 @@ public :
static JoystickManager& getInstance(); static JoystickManager& getInstance();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the capabilities of an open joystick /// \brief Get the capabilities for an open joystick
/// ///
/// \param joystick Index of the joystick /// \param joystick Index of the joystick
/// ///
@ -73,6 +73,16 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const JoystickState& getState(unsigned int joystick) const; const JoystickState& getState(unsigned int joystick) const;
////////////////////////////////////////////////////////////
/// \brief Get the identification for an open joystick
///
/// \param joystick Index of the joystick
///
/// \return Identification for the joystick
///
////////////////////////////////////////////////////////////
const Joystick::Identification& getIdentification(unsigned int joystick) const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the state of all the joysticks /// \brief Update the state of all the joysticks
/// ///
@ -99,9 +109,10 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct Item struct Item
{ {
JoystickImpl joystick; ///< Joystick implementation JoystickImpl joystick; ///< Joystick implementation
JoystickState state; ///< The current joystick state JoystickState state; ///< The current joystick state
JoystickCaps capabilities; ///< The joystick capabilities JoystickCaps capabilities; ///< The joystick capabilities
Joystick::Identification identification; ///< The joystick identification
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -29,6 +29,7 @@
#include <SFML/Window/JoystickImpl.hpp> #include <SFML/Window/JoystickImpl.hpp>
#include <SFML/Window/OSX/HIDInputManager.hpp> #include <SFML/Window/OSX/HIDInputManager.hpp>
#include <SFML/Window/OSX/HIDJoystickManager.hpp> #include <SFML/Window/OSX/HIDJoystickManager.hpp>
#include <SFML/System/Err.hpp>
namespace namespace
@ -171,6 +172,10 @@ bool JoystickImpl::open(unsigned int index)
return false; return false;
} }
m_identification.name = getDeviceString(self, CFSTR(kIOHIDProductKey));
m_identification.vendorId = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey));
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey));
// Get a list of all elements attached to the device. // Get a list of all elements attached to the device.
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self,
NULL, NULL,
@ -302,6 +307,13 @@ JoystickCaps JoystickImpl::getCapabilities() const
} }
////////////////////////////////////////////////////////////
Joystick::Identification JoystickImpl::getIdentification() const
{
return m_identification;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickState JoystickImpl::update() JoystickState JoystickImpl::update()
{ {
@ -397,6 +409,48 @@ JoystickState JoystickImpl::update()
return state; return state;
} }
////////////////////////////////////////////////////////////
std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
{
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
if (ref && CFGetTypeID(typeRef) == CFStringGetTypeID())
{
CFStringRef str = static_cast<CFStringRef>(typeRef);
return stringFromCFString(str);
}
err() << "Unable to read string value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
return "Unknown Joystick";
}
////////////////////////////////////////////////////////////
unsigned int JoystickImpl::getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop)
{
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
if (ref && CFGetTypeID(typeRef) == CFNumberGetTypeID())
{
SInt32 value;
CFNumberGetValue((CFNumberRef)typeRef, kCFNumberSInt32Type, &value);
return value;
}
err() << "Unable to read uint value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
return 0;
}
////////////////////////////////////////////////////////////
std::string JoystickImpl::stringFromCFString(CFStringRef cfString)
{
CFIndex length = CFStringGetLength(cfString);
std::vector<char> str(length);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
CFStringGetCString(cfString, &str[0], maxSize, kCFStringEncodingUTF8);
return &str[0];
}
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf

View File

@ -30,7 +30,10 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/JoystickImpl.hpp> #include <SFML/Window/JoystickImpl.hpp>
#include <SFML/System/String.hpp>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/hid/IOHIDDevice.h> #include <IOKit/hid/IOHIDDevice.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <map> #include <map>
#include <vector> #include <vector>
@ -92,6 +95,14 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickCaps getCapabilities() const; JoystickCaps getCapabilities() const;
////////////////////////////////////////////////////////////
/// \brief Get the joystick identification
///
/// \return Joystick identification
///
////////////////////////////////////////////////////////////
Joystick::Identification getIdentification() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the joystick and get its new state /// \brief Update the joystick and get its new state
/// ///
@ -102,6 +113,37 @@ public :
private : private :
////////////////////////////////////////////////////////////
/// Get HID device property key as a string
///
/// \param ref HID device
/// \param prop Property to retrieve from the device
///
/// \return Value for the property as a string
///
////////////////////////////////////////////////////////////
std::string getDeviceString(IOHIDDeviceRef ref, CFStringRef prop);
////////////////////////////////////////////////////////////
/// Get HID device property key as an unsigned int
///
/// \param ref HID device
/// \param prop Property to retrieve from the device
///
/// \return Value for the propery as an unsigned int
///
////////////////////////////////////////////////////////////
unsigned int getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop);
////////////////////////////////////////////////////////////
/// Convert a CFStringRef to std::string
///
/// \param cfString CFStringRef to convert
///
/// \return std::string
////////////////////////////////////////////////////////////
std::string stringFromCFString(CFStringRef cfString);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -109,9 +151,10 @@ private :
typedef std::map<sf::Joystick::Axis, IOHIDElementRef> AxisMap; typedef std::map<sf::Joystick::Axis, IOHIDElementRef> AxisMap;
typedef std::vector<IOHIDElementRef> ButtonsVector; typedef std::vector<IOHIDElementRef> ButtonsVector;
AxisMap m_axis; ///< Axis (IOHIDElementRef) connected to the joystick AxisMap m_axis; ///< Axis (IOHIDElementRef) connected to the joystick
ButtonsVector m_buttons; ///< Buttons (IOHIDElementRef) connected to the joystick ButtonsVector m_buttons; ///< Buttons (IOHIDElementRef) connected to the joystick
unsigned int m_index; ///< SFML index unsigned int m_index; ///< SFML index
Joystick::Identification m_identification; ///< Joystick identification
static Location m_locationIDs[sf::Joystick::Count]; ///< Global Joystick register static Location m_locationIDs[sf::Joystick::Count]; ///< Global Joystick register
/// For a corresponding SFML index, m_locationIDs is either some usb /// For a corresponding SFML index, m_locationIDs is either some usb

View File

@ -28,11 +28,13 @@
#include <SFML/Window/JoystickImpl.hpp> #include <SFML/Window/JoystickImpl.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <sys/inotify.h> #include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <cstdio> #include <cstdio>
#include <libudev.h>
#include <sstream>
namespace namespace
{ {
@ -144,7 +146,6 @@ bool JoystickImpl::isConnected(unsigned int index)
return plugged[index]; return plugged[index];
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool JoystickImpl::open(unsigned int index) bool JoystickImpl::open(unsigned int index)
{ {
@ -160,6 +161,11 @@ bool JoystickImpl::open(unsigned int index)
// Retrieve the axes mapping // Retrieve the axes mapping
ioctl(m_file, JSIOCGAXMAP, m_mapping); ioctl(m_file, JSIOCGAXMAP, m_mapping);
// Get info
m_identification.name = getJoystickName(index);
m_identification.vendorId = getUdevAttributeUint(index, "idVendor");
m_identification.productId = getUdevAttributeUint(index, "idProduct");
// Reset the joystick state // Reset the joystick state
m_state = JoystickState(); m_state = JoystickState();
@ -221,6 +227,13 @@ JoystickCaps JoystickImpl::getCapabilities() const
} }
////////////////////////////////////////////////////////////
Joystick::Identification JoystickImpl::getIdentification() const
{
return m_identification;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickState JoystickImpl::JoystickImpl::update() JoystickState JoystickImpl::JoystickImpl::update()
{ {
@ -267,6 +280,57 @@ JoystickState JoystickImpl::JoystickImpl::update()
return m_state; return m_state;
} }
////////////////////////////////////////////////////////////
std::string JoystickImpl::getJoystickName(unsigned int index)
{
// Get the name
char joyname[128];
if (ioctl(m_file, JSIOCGNAME(sizeof(joyname)), joyname) >= 0)
{
return std::string(joyname);
}
err() << "Unable to get name for joystick at index " << index << std::endl;
return std::string("Unknown Joystick");
}
////////////////////////////////////////////////////////////
unsigned int JoystickImpl::getUdevAttributeUint(unsigned int index, std::string attributeName)
{
unsigned int attr = 0;
udev* udevContext = udev_new();
if (udevContext)
{
char sysname[32];
std::snprintf(sysname, sizeof(sysname), "js%u", index);
udev_device* dev = udev_device_new_from_subsystem_sysname(udevContext, "input", sysname);
dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
if (dev)
{
std::stringstream ss;
ss << std::hex << udev_device_get_sysattr_value(dev, attributeName.c_str());
ss >> attr;
}
else
{
err() << "Unable to get attribute '" << attributeName << "'. Could not find parent USB device for joystick at index " << index << std::endl;
}
udev_device_unref(dev);
udev_unref(udevContext);
}
else
{
err() << "Unable to get attribute '" << attributeName << "'. Cannot create udev for reading info for joystick at index " << index << std::endl;
}
return attr;
}
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf

View File

@ -30,6 +30,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <linux/joystick.h> #include <linux/joystick.h>
#include <fcntl.h> #include <fcntl.h>
#include <string>
namespace sf namespace sf
@ -90,6 +91,14 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickCaps getCapabilities() const; JoystickCaps getCapabilities() const;
////////////////////////////////////////////////////////////
/// \brief Get the joystick identification
///
/// \return Joystick identification
///
////////////////////////////////////////////////////////////
Joystick::Identification getIdentification() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the joystick and get its new state /// \brief Update the joystick and get its new state
/// ///
@ -100,12 +109,34 @@ public :
private : private :
////////////////////////////////////////////////////////////
/// Get the joystick name
///
/// \param index Index of the joystick
///
/// \return Joystick name
///
////////////////////////////////////////////////////////////
std::string getJoystickName(unsigned int index);
////////////////////////////////////////////////////////////
/// Get a system attribute from udev as an unsigned int
///
/// \param index Index of the joystick
/// \param attributeName Name of the attribute to retrieve
///
/// \return Attribute value as unsigned int
///
////////////////////////////////////////////////////////////
unsigned int getUdevAttributeUint(unsigned int index, std::string attributeName);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
int m_file; ///< File descriptor of the joystick int m_file; ///< File descriptor of the joystick
char m_mapping[ABS_MAX + 1]; ///< Axes mapping (index to axis id) char m_mapping[ABS_MAX + 1]; ///< Axes mapping (index to axis id)
JoystickState m_state; ///< Current state of the joystick JoystickState m_state; ///< Current state of the joystick
sf::Joystick::Identification m_identification; ///< Identification of the joystick
}; };
} // namespace priv } // namespace priv

View File

@ -25,11 +25,19 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/JoystickImpl.hpp> #include <SFML/Window/JoystickImpl.hpp>
#include <SFML/System/Clock.hpp> #include <SFML/System/Clock.hpp>
#include <SFML/System/Err.hpp>
#include <windows.h> #include <windows.h>
#include <stdlib.h>
#include <cmath> #include <cmath>
#include <stdio.h>
#include <regstr.h>
#include <tchar.h>
#include <string>
#include <sstream>
#include <vector>
namespace namespace
{ {
@ -107,7 +115,16 @@ bool JoystickImpl::open(unsigned int index)
m_index = JOYSTICKID1 + index; m_index = JOYSTICKID1 + index;
// Store the joystick capabilities // Store the joystick capabilities
return joyGetDevCaps(m_index, &m_caps, sizeof(m_caps)) == JOYERR_NOERROR; bool success = joyGetDevCaps(m_index, &m_caps, sizeof(m_caps)) == JOYERR_NOERROR;
if (success)
{
m_identification.name = getDeviceName(m_index, m_caps);
m_identification.productId = m_caps.wPid;
m_identification.vendorId = m_caps.wMid;
}
return success;
} }
@ -117,7 +134,6 @@ void JoystickImpl::close()
// Nothing to do // Nothing to do
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickCaps JoystickImpl::getCapabilities() const JoystickCaps JoystickImpl::getCapabilities() const
{ {
@ -140,6 +156,13 @@ JoystickCaps JoystickImpl::getCapabilities() const
} }
////////////////////////////////////////////////////////////
Joystick::Identification JoystickImpl::getIdentification() const
{
return m_identification;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickState JoystickImpl::update() JoystickState JoystickImpl::update()
{ {
@ -184,6 +207,101 @@ JoystickState JoystickImpl::update()
return state; return state;
} }
////////////////////////////////////////////////////////////
sf::String JoystickImpl::getDeviceName(unsigned int index, JOYCAPS caps)
{
// Give the joystick a default name
sf::String joystickDescription = "Unknown Joystick";
std::basic_ostringstream<TCHAR, std::char_traits<TCHAR> > ss;
ss << REGSTR_PATH_JOYCONFIG << "\\" << caps.szRegKey << "\\" << REGSTR_KEY_JOYCURR;
std::basic_string<TCHAR> subkey = ss.str().substr(0, 255);
HKEY currentKey;
LONG result;
HKEY rootKey = HKEY_LOCAL_MACHINE;
result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
if (result != ERROR_SUCCESS)
{
rootKey = HKEY_CURRENT_USER;
result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
}
if (result == ERROR_SUCCESS)
{
ss.clear();
ss.str(_T(""));
ss << "Joystick" << index + 1 << REGSTR_VAL_JOYOEMNAME;
std::basic_string<TCHAR> keyName = ss.str().substr(0, 255);
TCHAR keyData[256];
DWORD keyNameSize = sizeof(keyData);
result = RegQueryValueEx(currentKey, keyName.c_str(), NULL, NULL, (LPBYTE)keyData, &keyNameSize);
RegCloseKey(currentKey);
if (result == ERROR_SUCCESS)
{
ss.clear();
ss.str(_T(""));
ss << REGSTR_PATH_JOYOEM << "\\" << keyData;
subkey = ss.str().substr(0, 255);
result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
if (result == ERROR_SUCCESS)
{
keyNameSize = sizeof(keyData);
unsigned int productKeyLength = keyNameSize / sizeof(TCHAR);
std::vector<TCHAR> productKey(productKeyLength);
result = RegQueryValueEx(currentKey, REGSTR_VAL_JOYOEMNAME, NULL, NULL, (LPBYTE) &productKey[0], &keyNameSize);
if (result == ERROR_SUCCESS)
{
while (productKeyLength > 0 && productKey[productKeyLength - 1] == 0)
{
--productKeyLength;
}
joystickDescription = std::basic_string<TCHAR>(&productKey[0], productKeyLength);
}
else
{
err() << "Unable to query name for joystick at index " << index << ": " << getErrorString(GetLastError()).toAnsiString() << std::endl;
}
RegCloseKey(currentKey);
}
else
{
err() << "Unable to open registry key for joystick at index " << index << ": " << getErrorString(GetLastError()).toAnsiString() << std::endl;
}
}
else
{
err() << "Unable to query registry key for joystick at index " << index << ": " << getErrorString(GetLastError()).toAnsiString() << std::endl;
}
}
else
{
err() << "Unable to open registry for joystick at index " << index << ": " << getErrorString(GetLastError()).toAnsiString() << std::endl;
}
return joystickDescription;
}
////////////////////////////////////////////////////////////
sf::String JoystickImpl::getErrorString(DWORD errorCode)
{
std::basic_ostringstream<TCHAR, std::char_traits<TCHAR> > ss;
TCHAR errBuff[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, errBuff, sizeof(errBuff), NULL);
ss << errBuff;
sf::String errMsg(ss.str());
return errMsg;
}
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf

View File

@ -36,7 +36,9 @@
#endif #endif
#define _WIN32_WINDOWS 0x0501 #define _WIN32_WINDOWS 0x0501
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0501
#include <SFML/Window/Joystick.hpp>
#include <SFML/Window/JoystickImpl.hpp> #include <SFML/Window/JoystickImpl.hpp>
#include <SFML/System/String.hpp>
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#include <cmath> #include <cmath>
@ -100,6 +102,14 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
JoystickCaps getCapabilities() const; JoystickCaps getCapabilities() const;
////////////////////////////////////////////////////////////
/// \brief Get the joystick identification
///
/// \return Joystick identification
///
////////////////////////////////////////////////////////////
Joystick::Identification getIdentification() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Update the joystick and get its new state /// \brief Update the joystick and get its new state
/// ///
@ -110,11 +120,33 @@ public :
private : private :
////////////////////////////////////////////////////////////
/// Get the joystick's name
///
/// \param index Index of the joystick
/// \param caps JOYCAPS
///
/// \return Joystick name
///
////////////////////////////////////////////////////////////
sf::String getDeviceName(unsigned int index, JOYCAPS caps);
////////////////////////////////////////////////////////////
/// Get a system error string from an error code
///
/// \param errorCode Error code
///
/// \return Error message string
///
////////////////////////////////////////////////////////////
sf::String getErrorString(DWORD errorCode);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int m_index; ///< Index of the joystick unsigned int m_index; ///< Index of the joystick
JOYCAPS m_caps; ///< Joystick capabilities JOYCAPS m_caps; ///< Joystick capabilities
Joystick::Identification m_identification; ///< Joystick identification
}; };
} // namespace priv } // namespace priv