bool AMGenericLinuxJoystick::attemptConnection() { // Do we have a connection open already? Close the reading thread, and close the file descriptor. if(readThread_) { disconnect(readThread_, SIGNAL(finished()), this, SLOT(onReadThreadFinished())); readThread_->stop(); readThread_->wait(); delete readThread_; readThread_ = 0; close(fd_); fd_ = -1; AMErrorMon::information(this, 0, QString("Disconnected from joystick: '%1' before attempting to reconnect on '%2'").arg(deviceDescription()).arg(deviceIdentifier())); emit connected(false); } // Try opening the joystick device fd_ = open(deviceIdentifier_.toAscii().constData(), O_RDONLY | O_NONBLOCK); if(fd_ == -1) { // Failed to open. Maybe not plugged in yet? Just keep trying. We'll re-attempt in 2 seconds. QTimer::singleShot(2000, this, SLOT(attemptConnection())); return false; } // Get the number of buttons and number of axes, using special ioctl() on the file descriptor. char numAxes; ioctl(fd_, JSIOCGAXES, &numAxes); axisCount_ = numAxes; axisPositions_.resize(axisCount_); char numButtons; ioctl(fd_, JSIOCGBUTTONS, &numButtons); buttonCount_ = numButtons; buttonStates_.resize(buttonCount_); // Get the joystick description char description[256]; if(ioctl(fd_, JSIOCGNAME(sizeof(description)), description) < 0) deviceDescription_ = "Unknown"; else deviceDescription_ = QString(description); // Finally, start up the thread for reading from the joystick. readThread_ = new AMGenericLinuxJoystickThread(fd_, this); connect(readThread_, SIGNAL(finished()), this, SLOT(onReadThreadFinished())); connect(readThread_, SIGNAL(joystickEvents(QVector<AMGenericLinuxJoystickEvent>)), this, SLOT(onJoystickEvents(QVector<AMGenericLinuxJoystickEvent>))); readThread_->start(); AMErrorMon::information(this, 0, QString("Connected to joystick: '%1' on '%2'.").arg(deviceDescription()).arg(deviceIdentifier())); emit connected(true); return true; }
QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { CFMutableDictionaryRef serialPortDictionary = ::IOServiceMatching(kIOSerialBSDServiceValue); if (!serialPortDictionary) return QList<QSerialPortInfo>(); ::CFDictionaryAddValue(serialPortDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); io_iterator_t serialPortIterator = 0; if (::IOServiceGetMatchingServices(kIOMasterPortDefault, serialPortDictionary, &serialPortIterator) != KERN_SUCCESS) { return QList<QSerialPortInfo>(); } QList<QSerialPortInfo> serialPortInfoList; forever { io_registry_entry_t serialPortService = ::IOIteratorNext(serialPortIterator); if (!serialPortService) break; QSerialPortInfoPrivate priv; forever { if (priv.portName.isEmpty()) priv.portName = devicePortName(serialPortService); if (priv.device.isEmpty()) priv.device = deviceSystemLocation(serialPortService); if (priv.description.isEmpty()) priv.description = deviceDescription(serialPortService); if (priv.manufacturer.isEmpty()) priv.manufacturer = deviceManufacturer(serialPortService); if (priv.serialNumber.isEmpty()) priv.serialNumber = deviceSerialNumber(serialPortService); if (!priv.hasVendorIdentifier) { priv.vendorIdentifier = deviceVendorIdentifier(serialPortService, priv.hasVendorIdentifier); } if (!priv.hasProductIdentifier) { priv.productIdentifier = deviceProductIdentifier(serialPortService, priv.hasProductIdentifier); } if (isCompleteInfo(priv)) { ::IOObjectRelease(serialPortService); break; } serialPortService = parentSerialPortService(serialPortService); if (!serialPortService) break; } serialPortInfoList.append(priv); } ::IOObjectRelease(serialPortIterator); return serialPortInfoList; }
void AMGenericLinuxJoystick::onReadThreadFinished() { delete readThread_; readThread_ = 0; close(fd_); fd_ = -1; QTimer::singleShot(2000, this, SLOT(attemptConnection())); // try to keep re-connecting, if it gets plugged back in. AMErrorMon::alert(this, -1, QString("Disconnected from joystick: '%1' because of a read error. Is it possible the joystick was unplugged?").arg(deviceDescription())); emit connected(false); }