Esempio n. 1
0
static pa_hook_result_t servers_changed_cb(void *hook_data, void *call_data, void *slot_data) {
    pa_strlist *servers = call_data;
    struct userdata *u = slot_data;
    char t[256];
    int screen;

    pa_assert(u);

    screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));
    if (!pa_x11_get_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID", t, sizeof(t)) || !pa_streq(t, u->id)) {
        pa_log_warn("PulseAudio information vanished from X11!");
        return PA_HOOK_OK;
    }

    publish_servers(u, servers);
    return PA_HOOK_OK;
}
Esempio n. 2
0
void pa__done(pa_module*m) {
    struct userdata*u;

    pa_assert(m);

    if (!(u = m->userdata))
        return;

    if (u->x11_client)
        pa_x11_client_free(u->x11_client);

    if (u->x11_wrapper) {
        char t[256];
        int screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));

        /* Yes, here is a race condition */
        if (!pa_x11_get_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID", t, sizeof(t)) || !pa_streq(t, u->id))
            pa_log_warn("PulseAudio information vanished from X11!");
        else {
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID");
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SERVER");
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SINK");
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SOURCE");
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_COOKIE");
            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SESSION_ID");
            xcb_flush(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper));
        }

        pa_x11_wrapper_unref(u->x11_wrapper);
    }

    if (u->auth_cookie)
        pa_auth_cookie_unref(u->auth_cookie);

    if (u->hook_slot)
        pa_hook_slot_free(u->hook_slot);

    if (u->protocol)
        pa_native_protocol_unref(u->protocol);

    pa_xfree(u->id);
    pa_xfree(u);
}
Esempio n. 3
0
int main(int argc, char *argv[]) {
    const char *dname = NULL, *sink = NULL, *source = NULL, *server = NULL, *cookie_file = PA_NATIVE_COOKIE_FILE;
    int c, ret = 1;
    Display *d = NULL;
    enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP;

    while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) {
        switch (c) {
            case 'D' :
                dname = optarg;
                break;
            case 'h':
                printf("%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n\n"
                       " -d    Show current PulseAudio data attached to X11 display (default)\n"
                       " -e    Export local PulseAudio data to X11 display\n"
                       " -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
                       " -r    Remove PulseAudio data from X11 display\n",
                       pa_path_get_filename(argv[0]));
                ret = 0;
                goto finish;
            case 'd':
                mode = DUMP;
                break;
            case 'e':
                mode = EXPORT;
                break;
            case 'i':
                mode = IMPORT;
                break;
            case 'r':
                mode = REMOVE;
                break;
            case 'c':
                cookie_file = optarg;
                break;
            case 'I':
                source = optarg;
                break;
            case 'O':
                sink = optarg;
                break;
            case 'S':
                server = optarg;
                break;
            default:
                fprintf(stderr, "Failed to parse command line.\n");
                goto finish;
        }
    }

    if (!(d = XOpenDisplay(dname))) {
        pa_log("XOpenDisplay() failed");
        goto finish;
    }

    switch (mode) {
        case DUMP: {
            char t[1024];
            if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t)))
                printf("Server: %s\n", t);
            if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t)))
                printf("Source: %s\n", t);
            if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t)))
                printf("Sink: %s\n", t);
            if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t)))
                printf("Cookie: %s\n", t);

            break;
        }

        case IMPORT: {
            char t[1024];
            if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t)))
                printf("PULSE_SERVER='%s'\nexport PULSE_SERVER\n", t);
            if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t)))
                printf("PULSE_SOURCE='%s'\nexport PULSE_SOURCE\n", t);
            if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t)))
                printf("PULSE_SINK='%s'\nexport PULSE_SINK\n", t);

            if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t))) {
                uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
                size_t l;
                if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) {
                    fprintf(stderr, "Failed to parse cookie data\n");
                    goto finish;
                }

                if (pa_authkey_save(cookie_file, cookie, l) < 0) {
                    fprintf(stderr, "Failed to save cookie data\n");
                    goto finish;
                }
            }

            break;
        }

        case EXPORT: {
            pa_client_conf *conf = pa_client_conf_new();
            uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
            char hx[PA_NATIVE_COOKIE_LENGTH*2+1];
            assert(conf);

            if (pa_client_conf_load(conf, NULL) < 0) {
                fprintf(stderr, "Failed to load client configuration file.\n");
                goto finish;
            }

            if (pa_client_conf_env(conf) < 0) {
                fprintf(stderr, "Failed to read environment configuration data.\n");
                goto finish;
            }

            pa_x11_del_prop(d, "PULSE_SERVER");
            pa_x11_del_prop(d, "PULSE_SINK");
            pa_x11_del_prop(d, "PULSE_SOURCE");
            pa_x11_del_prop(d, "PULSE_ID");
            pa_x11_del_prop(d, "PULSE_COOKIE");

            if (server)
                pa_x11_set_prop(d, "PULSE_SERVER", server);
            else if (conf->default_server)
                pa_x11_set_prop(d, "PULSE_SERVER", conf->default_server);
            else {
                char hn[256];
                if (!pa_get_fqdn(hn, sizeof(hn))) {
                    fprintf(stderr, "Failed to get FQDN.\n");
                    goto finish;
                }

                pa_x11_set_prop(d, "PULSE_SERVER", hn);
            }

            if (sink)
                pa_x11_set_prop(d, "PULSE_SINK", sink);
            else if (conf->default_sink)
                pa_x11_set_prop(d, "PULSE_SINK", conf->default_sink);

            if (source)
                pa_x11_set_prop(d, "PULSE_SOURCE", source);
            if (conf->default_source)
                pa_x11_set_prop(d, "PULSE_SOURCE", conf->default_source);

            pa_client_conf_free(conf);

            if (pa_authkey_load_auto(cookie_file, cookie, sizeof(cookie)) < 0) {
                fprintf(stderr, "Failed to load cookie data\n");
                goto finish;
            }

            pa_x11_set_prop(d, "PULSE_COOKIE", pa_hexstr(cookie, sizeof(cookie), hx, sizeof(hx)));
            break;
        }

        case REMOVE:
            pa_x11_del_prop(d, "PULSE_SERVER");
            pa_x11_del_prop(d, "PULSE_SINK");
            pa_x11_del_prop(d, "PULSE_SOURCE");
            pa_x11_del_prop(d, "PULSE_ID");
            pa_x11_del_prop(d, "PULSE_COOKIE");
            break;

        default:
            fprintf(stderr, "No yet implemented.\n");
            goto finish;
    }

    ret = 0;

finish:

    if (d) {
        XSync(d, False);
        XCloseDisplay(d);
    }

    return ret;
}
Esempio n. 4
0
int main(int argc, char *argv[]) {
    const char *dname = NULL, *sink = NULL, *source = NULL, *server = NULL, *cookie_file = PA_NATIVE_COOKIE_FILE;
    int c, ret = 1, screen = 0;
    xcb_connection_t *xcb = NULL;
    enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP;

    setlocale(LC_ALL, "");
#ifdef ENABLE_NLS
    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
#endif

    while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) {
        switch (c) {
            case 'D' :
                dname = optarg;
                break;
            case 'h':
                printf(_("%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n\n"
                       " -d    Show current PulseAudio data attached to X11 display (default)\n"
                       " -e    Export local PulseAudio data to X11 display\n"
                       " -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
                       " -r    Remove PulseAudio data from X11 display\n"),
                       pa_path_get_filename(argv[0]));
                ret = 0;
                goto finish;
            case 'd':
                mode = DUMP;
                break;
            case 'e':
                mode = EXPORT;
                break;
            case 'i':
                mode = IMPORT;
                break;
            case 'r':
                mode = REMOVE;
                break;
            case 'c':
                cookie_file = optarg;
                break;
            case 'I':
                source = optarg;
                break;
            case 'O':
                sink = optarg;
                break;
            case 'S':
                server = optarg;
                break;
            default:
                fprintf(stderr, _("Failed to parse command line.\n"));
                goto finish;
        }
    }

    if (!(xcb = xcb_connect(dname, &screen))) {
        pa_log(_("xcb_connect() failed"));
        goto finish;
    }

    if (xcb_connection_has_error(xcb)) {
        pa_log(_("xcb_connection_has_error() returned true"));
        goto finish;
    }

    switch (mode) {
        case DUMP: {
            char t[1024];
            if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
                printf(_("Server: %s\n"), t);
            if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
                printf(_("Source: %s\n"), t);
            if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
                printf(_("Sink: %s\n"), t);
            if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t)))
                printf(_("Cookie: %s\n"), t);

            break;
        }

        case IMPORT: {
            char t[1024];
            if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
                printf("PULSE_SERVER='%s'\nexport PULSE_SERVER\n", t);
            if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
                printf("PULSE_SOURCE='%s'\nexport PULSE_SOURCE\n", t);
            if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
                printf("PULSE_SINK='%s'\nexport PULSE_SINK\n", t);

            if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) {
                uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
                size_t l;
                if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) {
                    fprintf(stderr, _("Failed to parse cookie data\n"));
                    goto finish;
                }

                if (pa_authkey_save(cookie_file, cookie, l) < 0) {
                    fprintf(stderr, _("Failed to save cookie data\n"));
                    goto finish;
                }
            }

            break;
        }

        case EXPORT: {
            pa_client_conf *conf = pa_client_conf_new();
            uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
            char hx[PA_NATIVE_COOKIE_LENGTH*2+1];
            assert(conf);

            pa_client_conf_load(conf, false, true);

            pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
            pa_x11_del_prop(xcb, screen, "PULSE_SINK");
            pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
            pa_x11_del_prop(xcb, screen, "PULSE_ID");
            pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");

            if (server)
                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", server);
            else if (conf->default_server)
                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", conf->default_server);
            else {
                char hn[256];
                if (!pa_get_fqdn(hn, sizeof(hn))) {
                    fprintf(stderr, _("Failed to get FQDN.\n"));
                    goto finish;
                }

                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", hn);
            }

            if (sink)
                pa_x11_set_prop(xcb, screen, "PULSE_SINK", sink);
            else if (conf->default_sink)
                pa_x11_set_prop(xcb, screen, "PULSE_SINK", conf->default_sink);

            if (source)
                pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", source);
            if (conf->default_source)
                pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", conf->default_source);

            pa_client_conf_free(conf);

            if (pa_authkey_load(cookie_file, true, cookie, sizeof(cookie)) < 0) {
                fprintf(stderr, _("Failed to load cookie data\n"));
                goto finish;
            }

            pa_x11_set_prop(xcb, screen, "PULSE_COOKIE", pa_hexstr(cookie, sizeof(cookie), hx, sizeof(hx)));
            break;
        }

        case REMOVE:
            pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
            pa_x11_del_prop(xcb, screen, "PULSE_SINK");
            pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
            pa_x11_del_prop(xcb, screen, "PULSE_ID");
            pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");
            pa_x11_del_prop(xcb, screen, "PULSE_SESSION_ID");
            break;

        default:
            fprintf(stderr, _("Not yet implemented.\n"));
            goto finish;
    }

    ret = 0;

finish:

    if (xcb) {
        xcb_flush(xcb);
        xcb_disconnect(xcb);
    }

    return ret;
}