mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Amended based on comments from last commit.
This commit is contained in:
parent
86c81f7458
commit
eec9f7750f
@ -169,17 +169,17 @@ void JoystickImpl::initialize()
|
|||||||
updatePluggedList();
|
updatePluggedList();
|
||||||
|
|
||||||
// Map of hat values
|
// Map of hat values
|
||||||
hatValueMap[0] = std::make_pair<int, int>(0, 0); // center
|
hatValueMap[0] = std::make_pair( 0, 0); // center
|
||||||
|
|
||||||
hatValueMap[1] = std::make_pair<int, int>(0, -100); // top
|
hatValueMap[1] = std::make_pair( 0, -100); // top
|
||||||
hatValueMap[3] = std::make_pair<int, int>(100, 0); // right
|
hatValueMap[3] = std::make_pair( 100, 0); // right
|
||||||
hatValueMap[5] = std::make_pair<int, int>(0, 100); // bottom
|
hatValueMap[5] = std::make_pair( 0, 100); // bottom
|
||||||
hatValueMap[7] = std::make_pair<int, int>(-100, 0); // left
|
hatValueMap[7] = std::make_pair(-100, 0); // left
|
||||||
|
|
||||||
hatValueMap[2] = std::make_pair<int, int>(100, -100); // top-right
|
hatValueMap[2] = std::make_pair( 100, -100); // top-right
|
||||||
hatValueMap[4] = std::make_pair<int, int>(100, 100); // bottom-right
|
hatValueMap[4] = std::make_pair( 100, 100); // bottom-right
|
||||||
hatValueMap[6] = std::make_pair<int, int>(-100, 100); // bottom-left
|
hatValueMap[6] = std::make_pair(-100, 100); // bottom-left
|
||||||
hatValueMap[8] = std::make_pair<int, int>(-100, -100); // top-left
|
hatValueMap[8] = std::make_pair(-100, -100); // top-left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,47 +101,65 @@ namespace
|
|||||||
udev_unref(udevContext);
|
udev_unref(udevContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canRead(int descriptor)
|
bool hasInotifyEvent()
|
||||||
{
|
|
||||||
if (descriptor >= 0)
|
|
||||||
{
|
{
|
||||||
fd_set descriptorSet;
|
fd_set descriptorSet;
|
||||||
FD_ZERO(&descriptorSet);
|
FD_ZERO(&descriptorSet);
|
||||||
FD_SET(descriptor, &descriptorSet);
|
FD_SET(notifyFd, &descriptorSet);
|
||||||
timeval timeout = {0, 0};
|
timeval timeout = {0, 0};
|
||||||
|
|
||||||
return (select(descriptor + 1, &descriptorSet, NULL, NULL, &timeout) > 0) &&
|
return (select(notifyFd + 1, &descriptorSet, NULL, NULL, &timeout) > 0) &&
|
||||||
FD_ISSET(notifyFd, &descriptorSet);
|
FD_ISSET(notifyFd, &descriptorSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the joystick name
|
// Get the joystick name
|
||||||
std::string getJoystickName(int file, unsigned int index)
|
std::string getJoystickName(int file, unsigned int index)
|
||||||
{
|
{
|
||||||
// Get the name
|
// Get the name
|
||||||
char joyname[128];
|
char name[128];
|
||||||
|
|
||||||
if (ioctl(file, JSIOCGNAME(sizeof(joyname)), joyname) >= 0)
|
if (ioctl(file, JSIOCGNAME(sizeof(name)), name) >= 0)
|
||||||
return std::string(joyname);
|
return std::string(name);
|
||||||
|
|
||||||
sf::err() << "Unable to get name for joystick at index " << index << std::endl;
|
sf::err() << "Unable to get name for joystick at index " << index << std::endl;
|
||||||
|
|
||||||
return std::string("Unknown Joystick");
|
return std::string("Unknown Joystick");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a system attribute from a udev device as an unsigned int
|
||||||
// Get a system attribute from udev as an unsigned int
|
unsigned int getUdevAttributeUint(udev_device* device, unsigned int index, const std::string& attributeName)
|
||||||
unsigned int getUdevAttributeUint(unsigned int index, std::string attributeName)
|
{
|
||||||
|
udev_device* udevDeviceParent = udev_device_get_parent_with_subsystem_devtype(device, "usb", "usb_device");
|
||||||
|
|
||||||
|
if (!udevDeviceParent)
|
||||||
|
{
|
||||||
|
sf::err() << "Unable to get joystick attribute. "
|
||||||
|
<< "Could not find parent USB device for joystick at index " << index << "." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* attributeString = udev_device_get_sysattr_value(udevDeviceParent, attributeName.c_str());
|
||||||
|
|
||||||
|
if (!attributeString)
|
||||||
|
{
|
||||||
|
sf::err() << "Unable to get joystick attribute '" << attributeName << "'. "
|
||||||
|
<< "Attribute does not exist for joystick at index " << index << "." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<unsigned int>(std::strtoul(attributeString, NULL, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a system attribute for a joystick at index as an unsigned int
|
||||||
|
unsigned int getAttributeUint(unsigned int index, const std::string& attributeName)
|
||||||
{
|
{
|
||||||
unsigned int attribute = 0;
|
|
||||||
udev* udevContext = udev_new();
|
udev* udevContext = udev_new();
|
||||||
|
|
||||||
if (!udevContext)
|
if (!udevContext)
|
||||||
{
|
{
|
||||||
sf::err() << "Unable to get attribute '" << attributeName << "'. Cannot create udev for reading info for joystick at index " << index << std::endl;
|
sf::err() << "Unable to get joystick attribute. "
|
||||||
return attribute;
|
<< "Could not create udev context." << std::endl;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream sysname("js");
|
std::ostringstream sysname("js");
|
||||||
@ -151,21 +169,13 @@ namespace
|
|||||||
|
|
||||||
if (!udevDevice)
|
if (!udevDevice)
|
||||||
{
|
{
|
||||||
sf::err() << "Unable to get attribute '" << attributeName << "'. Could not find USB device for joystick at index " << index << std::endl;
|
sf::err() << "Unable to get joystick attribute. "
|
||||||
|
<< "Could not find USB device for joystick at index " << index << "." << std::endl;
|
||||||
udev_unref(udevContext);
|
udev_unref(udevContext);
|
||||||
return attribute;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_device* udevDeviceParent = udev_device_get_parent_with_subsystem_devtype(udevDevice, "usb", "usb_device");
|
unsigned int attribute = getUdevAttributeUint(udevDevice, index, attributeName);
|
||||||
|
|
||||||
if (!udevDeviceParent)
|
|
||||||
{
|
|
||||||
sf::err() << "Unable to get attribute '" << attributeName << "'. Could not find parent USB device for joystick at index " << index << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
attribute = static_cast<unsigned int>(strtoul(udev_device_get_sysattr_value(udevDeviceParent, attributeName.c_str()), NULL, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
udev_device_unref(udevDevice);
|
udev_device_unref(udevDevice);
|
||||||
udev_unref(udevContext);
|
udev_unref(udevContext);
|
||||||
@ -184,6 +194,9 @@ void JoystickImpl::initialize()
|
|||||||
// Reset the array of plugged joysticks
|
// Reset the array of plugged joysticks
|
||||||
std::fill(plugged, plugged + Joystick::Count, false);
|
std::fill(plugged, plugged + Joystick::Count, false);
|
||||||
|
|
||||||
|
// Do an initial scan
|
||||||
|
updatePluggedList();
|
||||||
|
|
||||||
// Create the inotify instance
|
// Create the inotify instance
|
||||||
notifyFd = inotify_init();
|
notifyFd = inotify_init();
|
||||||
if (notifyFd < 0)
|
if (notifyFd < 0)
|
||||||
@ -197,11 +210,11 @@ void JoystickImpl::initialize()
|
|||||||
if (inputFd < 0)
|
if (inputFd < 0)
|
||||||
{
|
{
|
||||||
err() << "Failed to initialize inotify, joystick connections and disconnections won't be notified" << std::endl;
|
err() << "Failed to initialize inotify, joystick connections and disconnections won't be notified" << std::endl;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do an initial scan
|
// No need to hang on to the inotify handle in this case
|
||||||
updatePluggedList();
|
::close(notifyFd);
|
||||||
|
notifyFd = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,18 +234,21 @@ void JoystickImpl::cleanup()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::isConnected(unsigned int index)
|
bool JoystickImpl::isConnected(unsigned int index)
|
||||||
{
|
{
|
||||||
// First check if new joysticks were added/removed since last update
|
// See if we can skip scanning if inotify is available
|
||||||
if (canRead(notifyFd))
|
if (notifyFd < 0)
|
||||||
{
|
{
|
||||||
|
// inotify is not available, perform a scan every query
|
||||||
|
updatePluggedList();
|
||||||
|
}
|
||||||
|
else if (hasInotifyEvent())
|
||||||
|
{
|
||||||
|
// Check if new joysticks were added/removed since last update
|
||||||
// Don't bother decomposing and interpreting the filename, just do a full scan
|
// Don't bother decomposing and interpreting the filename, just do a full scan
|
||||||
updatePluggedList();
|
updatePluggedList();
|
||||||
|
|
||||||
// Flush all the pending events
|
// Flush all the pending events
|
||||||
while (canRead(notifyFd))
|
if (lseek(notifyFd, 0, SEEK_END) < 0)
|
||||||
{
|
err() << "Failed to flush inotify of all pending joystick events." << std::endl;
|
||||||
char buffer[128];
|
|
||||||
(void)read(notifyFd, buffer, sizeof(buffer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then check if the joystick is connected
|
// Then check if the joystick is connected
|
||||||
@ -256,8 +272,8 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
m_identification.name = getJoystickName(m_file, index);
|
m_identification.name = getJoystickName(m_file, index);
|
||||||
m_identification.vendorId = getUdevAttributeUint(index, "idVendor");
|
m_identification.vendorId = getAttributeUint(index, "idVendor");
|
||||||
m_identification.productId = getUdevAttributeUint(index, "idProduct");
|
m_identification.productId = getAttributeUint(index, "idProduct");
|
||||||
|
|
||||||
// Reset the joystick state
|
// Reset the joystick state
|
||||||
m_state = JoystickState();
|
m_state = JoystickState();
|
||||||
|
Loading…
Reference in New Issue
Block a user