Exemplo n.º 1
0
void InputDevice::setDPadName(int dpadIndex, QString tempName)
{
    QHashIterator<int, SetJoystick*> iter(joystick_sets);
    while (iter.hasNext())
    {
        SetJoystick *tempSet = iter.next().value();
        disconnect(tempSet, SIGNAL(setDPadNameChange(int)), this, SLOT(updateSetDPadNames(int)));
        JoyDPad *dpad = tempSet->getJoyDPad(dpadIndex);
        if (dpad)
        {
            dpad->setDPadName(tempName);
        }
        connect(tempSet, SIGNAL(setDPadNameChange(int)), this, SLOT(updateSetDPadNames(int)));
    }
}
Exemplo n.º 2
0
void InputDaemon::secondInputPass(QQueue<SDL_Event> *sdlEventQueue)
{
    QHash<SDL_JoystickID, InputDevice*> activeDevices;

    while (!sdlEventQueue->isEmpty())
    {
        SDL_Event event = sdlEventQueue->dequeue();

        switch (event.type)
        {
            //qDebug() << QTime::currentTime() << " :";
            case SDL_JOYBUTTONDOWN:
            case SDL_JOYBUTTONUP:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jbutton.which);
#else
                InputDevice *joy = joysticks->value(event.jbutton.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyButton *button = set->getJoyButton(event.jbutton.button);

                    if (button)
                    {
                        //button->joyEvent(event.type == SDL_JOYBUTTONDOWN ? true : false);
                        button->queuePendingEvent(event.type == SDL_JOYBUTTONDOWN ? true : false);

                        if (!activeDevices.contains(event.jbutton.which))
                        {
                            activeDevices.insert(event.jbutton.which, joy);
                        }
                    }
                }
#ifdef USE_SDL_2
                else if (trackcontrollers.contains(event.jbutton.which))
                {
                    GameController *gamepad = trackcontrollers.value(event.jbutton.which);
                    gamepad->rawButtonEvent(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN ? true : false);
                }
#endif

                break;
            }

            case SDL_JOYAXISMOTION:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jaxis.which);
#else
                InputDevice *joy = joysticks->value(event.jaxis.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyAxis *axis = set->getJoyAxis(event.jaxis.axis);
                    if (axis)
                    {
                        //axis->joyEvent(event.jaxis.value);
                        axis->queuePendingEvent(event.jaxis.value);

                        if (!activeDevices.contains(event.jaxis.which))
                        {
                            activeDevices.insert(event.jaxis.which, joy);
                        }
                    }

                    joy->rawAxisEvent(event.jaxis.which, event.jaxis.value);
                }
#ifdef USE_SDL_2
                else if (trackcontrollers.contains(event.jaxis.which))
                {
                    GameController *gamepad = trackcontrollers.value(event.jaxis.which);
                    gamepad->rawAxisEvent(event.jaxis.axis, event.jaxis.value);
                }
#endif

                break;
            }

            case SDL_JOYHATMOTION:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jhat.which);
#else
                InputDevice *joy = joysticks->value(event.jhat.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyDPad *dpad = set->getJoyDPad(event.jhat.hat);
                    if (dpad)
                    {
                        //dpad->joyEvent(event.jhat.value);
                        dpad->joyEvent(event.jhat.value);

                        if (!activeDevices.contains(event.jhat.which))
                        {
                            activeDevices.insert(event.jhat.which, joy);
                        }
                    }
                }
#ifdef USE_SDL_2
                else if (trackcontrollers.contains(event.jhat.which))
                {
                    GameController *gamepad = trackcontrollers.value(event.jaxis.which);
                    gamepad->rawDPadEvent(event.jhat.hat, event.jhat.value);
                }
#endif

                break;
            }

#ifdef USE_SDL_2
            case SDL_CONTROLLERAXISMOTION:
            {
                InputDevice *joy = trackcontrollers.value(event.caxis.which);
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyAxis *axis = set->getJoyAxis(event.caxis.axis);
                    if (axis)
                    {
                        //qDebug() << QTime::currentTime() << ": " << "Axis " << event.caxis.axis+1
                        //         << ": " << event.caxis.value;
                        //axis->joyEvent(event.caxis.value);
                        axis->queuePendingEvent(event.caxis.value);

                        if (!activeDevices.contains(event.caxis.which))
                        {
                            activeDevices.insert(event.caxis.which, joy);
                        }
                    }
                }
                break;
            }

            case SDL_CONTROLLERBUTTONDOWN:
            case SDL_CONTROLLERBUTTONUP:
            {
                InputDevice *joy = trackcontrollers.value(event.cbutton.which);
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyButton *button = set->getJoyButton(event.cbutton.button);

                    if (button)
                    {
                        //button->joyEvent(event.type == SDL_CONTROLLERBUTTONDOWN ? true : false);
                        button->queuePendingEvent(event.type == SDL_CONTROLLERBUTTONDOWN ? true : false);

                        if (!activeDevices.contains(event.cbutton.which))
                        {
                            activeDevices.insert(event.cbutton.which, joy);
                        }
                    }
                }

                break;
            }

            case SDL_JOYDEVICEREMOVED:
            {
                InputDevice *device = joysticks->value(event.jdevice.which);
                if (device)
                {
                    Logger::LogInfo(QString("Removing joystick #%1 [%2]")
                                    .arg(device->getRealJoyNumber())
                                    .arg(QTime::currentTime().toString("hh:mm:ss.zzz")));

                    //activeDevices.remove(event.jdevice.which);
                    removeDevice(device);
                }

                break;
            }

            case SDL_JOYDEVICEADDED:
            {
                Logger::LogInfo(QString("New joystick found - #%1 [%2]")
                                .arg(event.jdevice.which+1)
                                .arg(QTime::currentTime().toString("hh:mm:ss.zzz")));
                addInputDevice(event.jdevice.which);
                break;
            }
#endif

            case SDL_QUIT:
            {
                stopped = true;
                break;
            }

            default:
                break;
        }

        // Active possible queued events.
        QHashIterator<SDL_JoystickID, InputDevice*> activeDevIter(activeDevices);
        while (activeDevIter.hasNext())
        {
            InputDevice *tempDevice = activeDevIter.next().value();
            tempDevice->activatePossibleControlStickEvents();
            tempDevice->activatePossibleAxisEvents();
            tempDevice->activatePossibleDPadEvents();
            tempDevice->activatePossibleVDPadEvents();
            tempDevice->activatePossibleButtonEvents();
        }

        if (JoyButton::shouldInvokeMouseEvents())
        {
            // Do not wait for next event loop run. Execute immediately.
            JoyButton::invokeMouseEvents();
        }
    }
}
Exemplo n.º 3
0
void InputDaemon::firstInputPass(QQueue<SDL_Event> *sdlEventQueue)
{
    SDL_Event event;

    while (SDL_PollEvent(&event) > 0)
    {
        switch (event.type)
        {
            case SDL_JOYBUTTONDOWN:
            case SDL_JOYBUTTONUP:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jbutton.which);
#else
                InputDevice *joy = joysticks->value(event.jbutton.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyButton *button = set->getJoyButton(event.jbutton.button);

                    if (button)
                    {
                        InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false);
                        temp->changeButtonStatus(event.jbutton.button, event.type == SDL_JOYBUTTONUP);

                        InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy);
                        pending->changeButtonStatus(event.jbutton.button,
                                                  event.type == SDL_JOYBUTTONDOWN ? true : false);
                        sdlEventQueue->append(event);
                    }
                }
#ifdef USE_SDL_2
                else
                {
                    sdlEventQueue->append(event);
                }
#endif

                break;
            }
            case SDL_JOYAXISMOTION:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jaxis.which);
#else
                InputDevice *joy = joysticks->value(event.jaxis.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyAxis *axis = set->getJoyAxis(event.jaxis.axis);

                    if (axis)
                    {
                        InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false);
                        temp->changeAxesStatus(event.jaxis.axis, event.jaxis.axis == 0);

                        InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy);
                        pending->changeAxesStatus(event.jaxis.axis, !axis->inDeadZone(event.jaxis.value));
                        sdlEventQueue->append(event);
                    }
                }
#ifdef USE_SDL_2
                else
                {
                    sdlEventQueue->append(event);
                }
#endif

                break;
            }
            case SDL_JOYHATMOTION:
            {
#ifdef USE_SDL_2
                InputDevice *joy = trackjoysticks.value(event.jhat.which);
#else
                InputDevice *joy = joysticks->value(event.jhat.which);
#endif
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyDPad *dpad = set->getJoyDPad(event.jhat.hat);

                    if (dpad)
                    {
                        InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false);
                        temp->changeHatStatus(event.jhat.hat, event.jhat.value == 0);

                        InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy);
                        pending->changeHatStatus(event.jhat.hat, event.jhat.value != 0 ? true : false);
                        sdlEventQueue->append(event);
                    }
                }
#ifdef USE_SDL_2
                else
                {
                    sdlEventQueue->append(event);
                }
#endif

                break;
            }

#ifdef USE_SDL_2
            case SDL_CONTROLLERAXISMOTION:
            {
                InputDevice *joy = trackcontrollers.value(event.caxis.which);
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyAxis *axis = set->getJoyAxis(event.caxis.axis);
                    if (axis)
                    {
                        InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false);
                        if (event.caxis.axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT &&
                            event.caxis.axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
                        {
                            temp->changeAxesStatus(event.caxis.axis, event.caxis.value == 0);
                        }
                        else
                        {
                            temp->changeAxesStatus(event.caxis.axis, event.caxis.value == GAMECONTROLLERTRIGGERRELEASE);
                        }

                        InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy);
                        pending->changeAxesStatus(event.caxis.axis, !axis->inDeadZone(event.caxis.value));
                        sdlEventQueue->append(event);
                    }
                }
                break;
            }

            case SDL_CONTROLLERBUTTONDOWN:
            case SDL_CONTROLLERBUTTONUP:
            {
                InputDevice *joy = trackcontrollers.value(event.cbutton.which);
                if (joy)
                {
                    SetJoystick* set = joy->getActiveSetJoystick();
                    JoyButton *button = set->getJoyButton(event.cbutton.button);

                    if (button)
                    {
                        InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false);
                        temp->changeButtonStatus(event.cbutton.button, event.type == SDL_CONTROLLERBUTTONUP);

                        InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy);
                        pending->changeButtonStatus(event.cbutton.button,
                                                  event.type == SDL_CONTROLLERBUTTONDOWN ? true : false);
                        sdlEventQueue->append(event);
                    }
                }

                break;
            }
            case SDL_JOYDEVICEREMOVED:
            case SDL_JOYDEVICEADDED:
            {
                sdlEventQueue->append(event);
                break;
            }
#endif
            case SDL_QUIT:
            {
                sdlEventQueue->append(event);
                break;
            }
        }
    }
}
Exemplo n.º 4
0
void InputDevice::writeConfig(QXmlStreamWriter *xml)
{
    xml->writeStartElement(getXmlName());
    xml->writeAttribute("configversion", QString::number(PadderCommon::LATESTCONFIGFILEVERSION));
    xml->writeAttribute("appversion", PadderCommon::programVersion);

    xml->writeComment("The SDL name for a joystick is included for informational purposes only.");
    xml->writeTextElement("sdlname", getSDLName());

    for (int i=0; i < getNumberSticks(); i++)
    {
        JoyControlStick *stick = getActiveSetJoystick()->getJoyStick(i);
        xml->writeStartElement("stickAxisAssociation");
        xml->writeAttribute("index", QString::number(stick->getRealJoyIndex()));
        xml->writeAttribute("xAxis", QString::number(stick->getAxisX()->getRealJoyIndex()));
        xml->writeAttribute("yAxis", QString::number(stick->getAxisY()->getRealJoyIndex()));
        xml->writeEndElement();
    }

    for (int i=0; i < getNumberVDPads(); i++)
    {
        VDPad *vdpad = getActiveSetJoystick()->getVDPad(i);
        xml->writeStartElement("vdpadButtonAssociations");
        xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber()));

        JoyButton *button = vdpad->getVButton(JoyDPadButton::DpadUp);
        if (button)
        {
            xml->writeStartElement("vdpadButtonAssociation");

            if (typeid(*button) == typeid(JoyAxisButton))
            {
                JoyAxisButton *axisbutton = static_cast<JoyAxisButton*>(button);
                xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(button->getJoyNumber()));
            }
            else
            {
                xml->writeAttribute("axis", QString::number(0));
                xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
            }

            xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadUp));
            xml->writeEndElement();
        }

        button = vdpad->getVButton(JoyDPadButton::DpadDown);
        if (button)
        {
            xml->writeStartElement("vdpadButtonAssociation");

            if (typeid(*button) == typeid(JoyAxisButton))
            {
                JoyAxisButton *axisbutton = static_cast<JoyAxisButton*>(button);
                xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(button->getJoyNumber()));
            }
            else
            {
                xml->writeAttribute("axis", QString::number(0));
                xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
            }

            xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadDown));
            xml->writeEndElement();
        }

        button = vdpad->getVButton(JoyDPadButton::DpadLeft);
        if (button)
        {
            xml->writeStartElement("vdpadButtonAssociation");

            if (typeid(*button) == typeid(JoyAxisButton))
            {
                JoyAxisButton *axisbutton = static_cast<JoyAxisButton*>(button);
                xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(button->getJoyNumber()));
            }
            else
            {
                xml->writeAttribute("axis", QString::number(0));
                xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
            }

            xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadLeft));
            xml->writeEndElement();
        }

        button = vdpad->getVButton(JoyDPadButton::DpadRight);
        if (button)
        {
            xml->writeStartElement("vdpadButtonAssociation");

            if (typeid(*button) == typeid(JoyAxisButton))
            {
                JoyAxisButton *axisbutton = static_cast<JoyAxisButton*>(button);
                xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(button->getJoyNumber()));
            }
            else
            {
                xml->writeAttribute("axis", QString::number(0));
                xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
            }

            xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadRight));
            xml->writeEndElement();
        }

        xml->writeEndElement();
    }

    xml->writeStartElement("names"); // <name>

    SetJoystick *tempSet = getActiveSetJoystick();
    for (int i=0; i < getNumberButtons(); i++)
    {
        JoyButton *button = tempSet->getJoyButton(i);
        if (button && !button->getButtonName().isEmpty())
        {
            xml->writeStartElement("buttonname");
            xml->writeAttribute("index", QString::number(button->getRealJoyNumber()));
            xml->writeCharacters(button->getButtonName());
            xml->writeEndElement();
        }
    }

    for (int i=0; i < getNumberAxes(); i++)
    {
        JoyAxis *axis = tempSet->getJoyAxis(i);
        if (axis)
        {
            if (!axis->getAxisName().isEmpty())
            {
                xml->writeStartElement("axisname");
                xml->writeAttribute("index", QString::number(axis->getRealJoyIndex()));
                xml->writeCharacters(axis->getAxisName());
                xml->writeEndElement();
            }

            JoyAxisButton *naxisbutton = axis->getNAxisButton();
            if (!naxisbutton->getButtonName().isEmpty())
            {
                xml->writeStartElement("axisbuttonname");
                xml->writeAttribute("index", QString::number(axis->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(naxisbutton->getRealJoyNumber()));
                xml->writeCharacters(naxisbutton->getButtonName());
                xml->writeEndElement();
            }

            JoyAxisButton *paxisbutton = axis->getPAxisButton();
            if (!paxisbutton->getButtonName().isEmpty())
            {
                xml->writeStartElement("axisbuttonname");
                xml->writeAttribute("index", QString::number(axis->getRealJoyIndex()));
                xml->writeAttribute("button", QString::number(paxisbutton->getRealJoyNumber()));
                xml->writeCharacters(paxisbutton->getButtonName());
                xml->writeEndElement();
            }
        }
    }

    for (int i=0; i < getNumberSticks(); i++)
    {
        JoyControlStick *stick = tempSet->getJoyStick(i);
        if (stick)
        {
            if (!stick->getStickName().isEmpty())
            {
                xml->writeStartElement("controlstickname");
                xml->writeAttribute("index", QString::number(stick->getRealJoyIndex()));
                xml->writeCharacters(stick->getStickName());
                xml->writeEndElement();
            }

            QHash<JoyControlStick::JoyStickDirections, JoyControlStickButton*> *buttons = stick->getButtons();
            QHashIterator<JoyControlStick::JoyStickDirections, JoyControlStickButton*> iter(*buttons);
            while (iter.hasNext())
            {
                JoyControlStickButton *button = iter.next().value();
                if (button && !button->getButtonName().isEmpty())
                {
                    xml->writeStartElement("controlstickbuttonname");
                    xml->writeAttribute("index", QString::number(stick->getRealJoyIndex()));
                    xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
                    xml->writeCharacters(button->getButtonName());
                    xml->writeEndElement();
                }
            }
        }
    }

    for (int i=0; i < getNumberHats(); i++)
    {
        JoyDPad *dpad = tempSet->getJoyDPad(i);
        if (dpad)
        {
            if (!dpad->getDpadName().isEmpty())
            {
                xml->writeStartElement("dpadname");
                xml->writeAttribute("index", QString::number(dpad->getRealJoyNumber()));
                xml->writeCharacters(dpad->getDpadName());
                xml->writeEndElement();
            }

            QHash<int, JoyDPadButton*> *temp = dpad->getButtons();
            QHashIterator<int, JoyDPadButton*> iter(*temp);
            while (iter.hasNext())
            {
                JoyDPadButton *button = iter.next().value();
                if (button && !button->getButtonName().isEmpty())
                {
                    xml->writeStartElement("dpadbuttonname");
                    xml->writeAttribute("index", QString::number(dpad->getRealJoyNumber()));
                    xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
                    xml->writeCharacters(button->getButtonName());
                    xml->writeEndElement();
                }
            }
        }
    }

    for (int i=0; i < getNumberVDPads(); i++)
    {
        VDPad *vdpad = getActiveSetJoystick()->getVDPad(i);
        if (vdpad)
        {
            if (!vdpad->getDpadName().isEmpty())
            {
                xml->writeStartElement("vdpadname");
                xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber()));
                xml->writeCharacters(vdpad->getDpadName());
                xml->writeEndElement();
            }

            QHash<int, JoyDPadButton*> *temp = vdpad->getButtons();
            QHashIterator<int, JoyDPadButton*> iter(*temp);
            while (iter.hasNext())
            {
                JoyDPadButton *button = iter.next().value();
                if (button && !button->getButtonName().isEmpty())
                {
                    xml->writeStartElement("vdpadbutton");
                    xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber()));
                    xml->writeAttribute("button", QString::number(button->getRealJoyNumber()));
                    xml->writeCharacters(button->getButtonName());
                    xml->writeEndElement();
                }
            }
        }
    }
    xml->writeEndElement(); // </names>

    if (keyDelay > 0)
    {
        xml->writeTextElement("keyPressTime", QString::number(keyDelay));
    }

    xml->writeStartElement("sets");
    for (int i=0; i < joystick_sets.size(); i++)
    {
        joystick_sets.value(i)->writeConfig(xml);
    }
    xml->writeEndElement();

    xml->writeEndElement();
}
Exemplo n.º 5
0
InputDaemon::InputDaemon(QHash<SDL_JoystickID, InputDevice*> *joysticks, bool graphical, QObject *parent) :
#else
InputDaemon::InputDaemon(QHash<int, InputDevice*> *joysticks, bool graphical, QObject *parent) :
#endif
    QObject(parent)
{
    this->joysticks = joysticks;
    this->stopped = false;
    this->graphical = graphical;

    eventWorker = new SDLEventReader(joysticks);
    thread = new QThread();
    eventWorker->moveToThread(thread);

    if (graphical)
    {
        connect(thread, SIGNAL(started()), eventWorker, SLOT(performWork()));
        connect(eventWorker, SIGNAL(eventRaised()), this, SLOT(run()));
        thread->start();
    }
    refreshJoysticks();
}

InputDaemon::~InputDaemon()
{
    if (eventWorker)
    {
        quit();
    }

    if (thread)
    {
        thread->quit();
        thread->wait();
        delete thread;
        thread = 0;
    }
}

void InputDaemon::run ()
{
    SDL_Event event;
#ifdef USE_SDL_2
    event.type = SDL_FIRSTEVENT;

#else
    event.type = SDL_NOEVENT;
#endif

    if (!stopped)
    {
        event = eventWorker->getCurrentEvent();

        do
        {
            switch (event.type)
            {
                case SDL_JOYBUTTONDOWN:
                {
#ifdef USE_SDL_2
                    InputDevice *joy = trackjoysticks.value(event.jbutton.which);
#else
                    InputDevice *joy = joysticks->value(event.jbutton.which);
#endif
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyButton *button = set->getJoyButton(event.jbutton.button);

                        if (button)
                        {
                            button->joyEvent(true);
                        }
                    }

                    break;
                }

                case SDL_JOYBUTTONUP:
                {
#ifdef USE_SDL_2
                    InputDevice *joy = trackjoysticks.value(event.jbutton.which);
#else
                    InputDevice *joy = joysticks->value(event.jbutton.which);
#endif
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyButton *button = set->getJoyButton(event.jbutton.button);

                        if (button)
                        {
                            button->joyEvent(false);
                        }
                    }

                    break;
                }

                case SDL_JOYAXISMOTION:
                {
#ifdef USE_SDL_2
                    InputDevice *joy = trackjoysticks.value(event.jaxis.which);
#else
                    InputDevice *joy = joysticks->value(event.jaxis.which);
#endif
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyAxis *axis = set->getJoyAxis(event.jaxis.axis);
                        if (axis)
                        {
                            axis->joyEvent(event.jaxis.value);
                        }
                    }

                    break;
                }

                case SDL_JOYHATMOTION:
                {
#ifdef USE_SDL_2
                    InputDevice *joy = trackjoysticks.value(event.jhat.which);
#else
                    InputDevice *joy = joysticks->value(event.jhat.which);
#endif
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyDPad *dpad = set->getJoyDPad(event.jhat.hat);
                        if (dpad)
                        {
                            dpad->joyEvent(event.jhat.value);
                        }
                    }

                    break;
                }

#ifdef USE_SDL_2
                case SDL_CONTROLLERAXISMOTION:
                {
                    InputDevice *joy = trackcontrollers.value(event.caxis.which);
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyAxis *axis = set->getJoyAxis(event.caxis.axis);
                        if (axis)
                        {
                            axis->joyEvent(event.caxis.value);
                        }
                    }
                    break;
                }

                case SDL_CONTROLLERBUTTONDOWN:
                case SDL_CONTROLLERBUTTONUP:
                {
                    InputDevice *joy = trackcontrollers.value(event.cbutton.which);
                    if (joy)
                    {
                        SetJoystick* set = joy->getActiveSetJoystick();
                        JoyButton *button = set->getJoyButton(event.cbutton.button);

                        if (button)
                        {
                            button->joyEvent(event.type == SDL_CONTROLLERBUTTONDOWN ? true : false);
                        }
                    }

                    break;
                }

                case SDL_JOYDEVICEREMOVED:
                {
                    InputDevice *device = joysticks->value(event.jdevice.which);
                    if (device)
                    {
                        removeDevice(device);
                    }

                    break;
                }

                case SDL_JOYDEVICEADDED:
                {
                    addInputDevice(event.jdevice.which);
                    break;
                }
#endif

                case SDL_QUIT:
                {
                    stopped = true;
                    break;
                }

                default:
                    break;
            }
        }
        while (SDL_PollEvent(&event) > 0);
    }

    if (stopped)
    {
        if (joysticks->count() > 0)
        {
            emit complete(joysticks->value(0));
        }
        emit complete();
        stopped = false;

        // Check for a grabbed instance of an SDL_QUIT event. If the last event was
        // not an SDL_QUIT event, push an event onto the queue so SdlEventReader
        // will finish properly.
#ifdef USE_SDL_2
        if (event.type != SDL_FIRSTEVENT && event.type != SDL_QUIT)
#else
        if (event.type != SDL_NOEVENT && event.type != SDL_QUIT)
#endif
        {
            event.type = SDL_QUIT;
            SDL_PushEvent(&event);
            QTimer::singleShot(0, eventWorker, SLOT(performWork()));
        }
    }
    else
    {
        QTimer::singleShot(0, eventWorker, SLOT(performWork()));
    }
}