예제 #1
0
파일: context.cpp 프로젝트: KDE/plasma-pa
void Context::subscribeCallback(pa_context *context, pa_subscription_event_type_t type, uint32_t index)
{
    Q_ASSERT(context == m_context);

    switch (type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
    case PA_SUBSCRIPTION_EVENT_SINK:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_sinks.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_sink_info_by_index(context, index, sink_cb, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_sink_info_by_index() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_SOURCE:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_sources.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_source_info_by_index(context, index, source_cb, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_source_info_by_index() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_sinkInputs.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_sink_input_info(context, index, sink_input_callback, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_sink_input_info() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_sourceOutputs.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_source_output_info(context, index, source_output_cb, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_sink_input_info() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_CLIENT:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_clients.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_client_info(context, index, client_cb, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_client_info() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_CARD:
        if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
            m_cards.removeEntry(index);
        } else {
            if (!PAOperation(pa_context_get_card_info_by_index(context, index, card_cb, this))) {
                qCWarning(PLASMAPA) << "pa_context_get_card_info_by_index() failed";
                return;
            }
        }
        break;

    case PA_SUBSCRIPTION_EVENT_SERVER:
        if (!PAOperation(pa_context_get_server_info(context, server_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_server_info() failed";
            return;
        }
        break;

    }
}
    static void onContextSubscription(pa_context* context, pa_subscription_event_type_t event, uint32_t idx, void* userData)
    {        
        long facility = (event & PA_SUBSCRIPTION_EVENT_FACILITY_MASK);
        long eventType = (event & PA_SUBSCRIPTION_EVENT_TYPE_MASK);

//        static QHash< long, QString > facilities;

//        if (facilities.isEmpty())
//        {
//            facilities.insert(PA_SUBSCRIPTION_EVENT_SINK, "PA_SUBSCRIPTION_EVENT_SINK");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_SOURCE, "PA_SUBSCRIPTION_EVENT_SOURCE");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_SINK_INPUT, "PA_SUBSCRIPTION_EVENT_SINK_INPUT");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT, "PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_MODULE, "PA_SUBSCRIPTION_EVENT_MODULE");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_CLIENT, "PA_SUBSCRIPTION_EVENT_CLIENT");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE, "PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE");
//            facilities.insert(PA_SUBSCRIPTION_EVENT_CARD, "PA_SUBSCRIPTION_EVENT_CARD");
//        }

//        static QHash< long, QString > eventTypes;

//        if (eventTypes.isEmpty())
//        {
//            eventTypes.insert(PA_SUBSCRIPTION_EVENT_NEW, "PA_SUBSCRIPTION_EVENT_NEW");
//            eventTypes.insert(PA_SUBSCRIPTION_EVENT_CHANGE, "PA_SUBSCRIPTION_EVENT_CHANGE");
//            eventTypes.insert(PA_SUBSCRIPTION_EVENT_REMOVE, "PA_SUBSCRIPTION_EVENT_REMOVE");
//        }

//        qDebug() << "Facility:" << facilities.value(facility, "Other") <<
//                    "Event Type:" << eventTypes.value(eventType, "Other") <<
//                    "idx:" << idx;

        PulseAudioWrapperPrivate* d = reinterpret_cast< PulseAudioWrapperPrivate* >(userData);

        if (facility == PA_SUBSCRIPTION_EVENT_CARD)
        {
            if (eventType == PA_SUBSCRIPTION_EVENT_NEW ||
                    eventType == PA_SUBSCRIPTION_EVENT_CHANGE)
            {
                pa_operation_unref(pa_context_get_card_info_by_index(
                                       PulseAudioWrapperPrivate::paContext,
                                       idx,
                                       &PulseAudioWrapperPrivate::onCardInfoByIndex,
                                       userData));
            }
            else if (eventType == PA_SUBSCRIPTION_EVENT_REMOVE)
            {
                qDebug() << "Removing card at idx: " << idx;

                if (d->cardsByIndex.contains(idx))
                {
                    PulseAudioCard* card = d->cardsByIndex.value(idx);

                    d->cards.remove(card);
                    d->cardsByIndex.remove(idx);
                    d->cardsByName.remove(card->name());

                    delete card;
                }
                else
                    qDebug() << "No card at idx " << idx;
            }
        }
        else if (facility == PA_SUBSCRIPTION_EVENT_SINK)
        {
            if (eventType == PA_SUBSCRIPTION_EVENT_NEW ||
                    eventType == PA_SUBSCRIPTION_EVENT_CHANGE)
            {
                pa_operation_unref(pa_context_get_sink_info_by_index(
                                       PulseAudioWrapperPrivate::paContext,
                                       idx,
                                       &PulseAudioWrapperPrivate::onSinkInfoByIndex,
                                       userData));
            }
            else if (eventType == PA_SUBSCRIPTION_EVENT_REMOVE)
            {
                qDebug() << "Removing sink at idx: " << idx;

                if (d->sinksByIndex.contains(idx))
                {
                    PulseAudioSink* sink = d->sinksByIndex.value(idx);

                    d->sinks.remove(sink);
                    d->sinksByIndex.remove(idx);
                    d->sinksByName.remove(sink->name());

                    delete sink;
                }
                else
                    qDebug() << "No sink at idx " << idx;
            }
        }
        else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE)
        {
            if (eventType == PA_SUBSCRIPTION_EVENT_NEW)
            {
                pa_operation_unref(pa_context_get_source_info_by_index(
                                       PulseAudioWrapperPrivate::paContext,
                                       idx,
                                       &PulseAudioWrapperPrivate::onSourceInfoByIndex,
                                       userData));
            }
            else if (eventType == PA_SUBSCRIPTION_EVENT_REMOVE)
            {
                qDebug() << "Removing source at idx: " << idx;

                if (d->sourcesByIndex.contains(idx))
                {
                    PulseAudioSource* source = d->sourcesByIndex.value(idx);

                    QString sourceName = source->name();

                    d->sources.remove(source);
                    d->sourcesByIndex.remove(idx);
                    d->sourcesByName.remove(source->name());

                    delete source;

                    emit d->q->sourceRemoved(idx, sourceName);
                }
                else
                    qDebug() << "No source at idx " << idx;
            }
        }
    }