Example #1
0
void backend_port_set(context_t *c, backend_entry_type type, uint32_t idx, const char *active) {
    switch(type) {
        case SINK:
            pa_context_set_sink_port_by_index(c->context, idx, active, NULL, NULL);
            break;
        case SOURCE:
            pa_context_set_source_port_by_index(c->context, idx, active, NULL, NULL);
            break;
        default:
            break;
    }
}
int set_active_port(pa_devicelist_t device, pa_portlist_t port) {
    pa_mainloop *pa_ml;
    pa_mainloop_api *pa_mlapi;
    pa_operation *pa_op;
    pa_context *pa_ctx;
    
    int pa_ready = 0;
    int state = 0;
    
    pa_ml = pa_mainloop_new();
    pa_mlapi = pa_mainloop_get_api(pa_ml);
    pa_ctx = pa_context_new(pa_mlapi, "test");
    pa_context_connect(pa_ctx, NULL, 0, NULL);
    pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
    
    pa_device_port_t dev_port_set;
    dev_port_set.device = device;
    dev_port_set.port = port;
    
    pa_clientlist_t clientlist[30];
    
    int i = 0;
    
    for (;;) {
        // We can't do anything until PA is ready, so just iterate the mainloop
        // and continue
        if (pa_ready == 0) {
            pa_mainloop_iterate(pa_ml, 1, NULL);
            continue;
        }
        // We couldn't get a connection to the server, so exit out
        if (pa_ready == 2) {
            pa_context_disconnect(pa_ctx);
            pa_context_unref(pa_ctx);
            pa_mainloop_free(pa_ml);
            return -1;
        }
        
        switch(state) {
            case 0:
                // Set source or sink
                switch(device.type) {
                    case JOAPA_SOURCE:
                        pa_op = pa_context_set_source_port_by_index(
                                pa_ctx, 
                                device.index, 
                                port.name, 
                                set_active_port_cb, 
                                &dev_port_set);
                        break;
                    case JOAPA_SINK:
                        pa_op = pa_context_set_sink_port_by_index(
                                pa_ctx, 
                                device.index, 
                                port.name, 
                                set_active_port_cb, 
                                &dev_port_set);
                        break;
                }
                state++;
                break;
            case 1:
                // get clients using a source or sink
                if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE) {
                    pa_operation_unref(pa_op);
                    switch(device.type) {
                        case JOAPA_SOURCE:
                            pa_op = pa_context_get_source_output_info_list(pa_ctx, pa_source_info_cb, &clientlist);
                            break;
                        case JOAPA_SINK:
                            pa_op = pa_context_get_sink_input_info_list(pa_ctx, pa_sink_info_cb, &clientlist);
                            break;
                    }
                    state++;
                }
                break;
            case 2:
                // move the clients to the new source or sink
                if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE) {
                    pa_operation_unref(pa_op);
                    
                    if(!clientlist[i].initialized) {
                        pa_context_disconnect(pa_ctx);
                        pa_context_unref(pa_ctx);
                        pa_mainloop_free(pa_ml);
                        return 0;
                    }
                    //printf("CLIENT: %d\n", clientlist[i].index);
                    
                    switch(device.type) {
                        case JOAPA_SOURCE:
                            pa_op = pa_context_move_source_output_by_index(
                                    pa_ctx,
                                    clientlist[i].index, 
                                    device.index, 
                                    set_active_port_cb, NULL);
                            break;
                        case JOAPA_SINK:
                            pa_op = pa_context_move_sink_input_by_index(
                                    pa_ctx, 
                                    clientlist[i].index, 
                                    device.index, 
                                    set_active_port_cb, NULL);
                            break;
                    }
                    
                    i++;
                }
                break;
            default:
                fprintf(stderr, "in state %d\n", state);
                return -1;
        }
        pa_mainloop_iterate(pa_ml, 1, NULL);       
    }

}