示例#1
0
static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
    pa_scache_entry *e;

    pa_assert(c);
    pa_assert(name);

    if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE))) {
        if (e->memchunk.memblock)
            pa_memblock_unref(e->memchunk.memblock);

        pa_xfree(e->filename);
        pa_proplist_clear(e->proplist);

        pa_assert(e->core == c);

        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
    } else {
        e = pa_xnew(pa_scache_entry, 1);

        if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, TRUE)) {
            pa_xfree(e);
            return NULL;
        }

        e->name = pa_xstrdup(name);
        e->core = c;
        e->proplist = pa_proplist_new();

        pa_idxset_put(c->scache, e, &e->index);

        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index);
    }

    e->last_used_time = 0;
    pa_memchunk_reset(&e->memchunk);
    e->filename = NULL;
    e->lazy = FALSE;
    e->last_used_time = 0;

    pa_sample_spec_init(&e->sample_spec);
    pa_channel_map_init(&e->channel_map);
    pa_cvolume_init(&e->volume);
    e->volume_is_set = FALSE;

    pa_proplist_sets(e->proplist, PA_PROP_MEDIA_ROLE, "event");

    return e;
}
static void update_rule(struct rule *r) {
    char *fn = NULL;
    struct stat st;
    static pa_config_item table[] = {
        { "Name", pa_config_parse_string,              NULL, "Desktop Entry" },
        { "Icon", pa_config_parse_string,              NULL, "Desktop Entry" },
        { "Type", check_type,                          NULL, "Desktop Entry" },
        { "X-PulseAudio-Properties", parse_properties, NULL, "Desktop Entry" },
        { "Categories", parse_categories,              NULL, "Desktop Entry" },
        { NULL,  catch_all, NULL, NULL },
        { NULL, NULL, NULL, NULL },
    };
    const char *state = NULL;
    const char *xdg_data_dirs = NULL;
    char *data_dir = NULL;
    char *desktop_file_dir = NULL;

    pa_assert(r);

    if ((xdg_data_dirs = getenv("XDG_DATA_DIRS"))) {
        while ((data_dir = pa_split(xdg_data_dirs, ":", &state))) {
            desktop_file_dir = pa_sprintf_malloc("%s" PA_PATH_SEP "applications", data_dir);

            pa_xfree(fn);
            fn = find_desktop_file_in_dir(r, desktop_file_dir, &st);

            pa_xfree(desktop_file_dir);
            pa_xfree(data_dir);

            if (fn) {
                break;
            }
        }
    } else {
        fn = find_desktop_file_in_dir(r, DESKTOPFILEDIR, &st);
    }

    if (!fn) {
        r->good = false;
        return;
    }

    if (r->good) {
        if (st.st_mtime == r->mtime) {
            /* Theoretically the filename could have changed, but if so
               having the same mtime is very unlikely so not worth tracking it in r */
            pa_xfree(fn);
            return;
        }
        pa_log_debug("Found %s (which has been updated since we last checked).", fn);
    } else
        pa_log_debug("Found %s.", fn);

    r->good = true;
    r->mtime = st.st_mtime;
    pa_xfree(r->application_name);
    pa_xfree(r->icon_name);
    pa_xfree(r->role);
    r->application_name = r->icon_name = r->role = NULL;
    if (r->proplist)
        pa_proplist_clear(r->proplist);

    table[0].data = &r->application_name;
    table[1].data = &r->icon_name;

    if (pa_config_parse(fn, NULL, table, NULL, false, r) < 0)
        pa_log_warn("Failed to parse .desktop file %s.", fn);

    pa_xfree(fn);
}
static void update_rule(struct rule *r) {
    char *fn;
    struct stat st;
    static pa_config_item table[] = {
        { "Name", pa_config_parse_string,              NULL, "Desktop Entry" },
        { "Icon", pa_config_parse_string,              NULL, "Desktop Entry" },
        { "Type", check_type,                          NULL, "Desktop Entry" },
        { "X-PulseAudio-Properties", parse_properties, NULL, "Desktop Entry" },
        { "Categories", parse_categories,              NULL, "Desktop Entry" },
        { NULL,  catch_all, NULL, NULL },
        { NULL, NULL, NULL, NULL },
    };
    pa_bool_t found = FALSE;

    pa_assert(r);
    fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s.desktop", r->process_name);

    if (stat(fn, &st) == 0)
        found = TRUE;
    else {
#ifdef DT_DIR
        DIR *desktopfiles_dir;
        struct dirent *dir;

        /* Let's try a more aggressive search, but only one level */
        if ((desktopfiles_dir = opendir(DESKTOPFILEDIR))) {
            while ((dir = readdir(desktopfiles_dir))) {
                if (dir->d_type != DT_DIR
                        || strcmp(dir->d_name, ".") == 0
                        || strcmp(dir->d_name, "..") == 0)
                    continue;

                pa_xfree(fn);
                fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s" PA_PATH_SEP "%s.desktop", dir->d_name, r->process_name);

                if (stat(fn, &st) == 0) {
                    found = TRUE;
                    break;
                }
            }
            closedir(desktopfiles_dir);
        }
#endif
    }
    if (!found) {
        r->good = FALSE;
        pa_xfree(fn);
        return;
    }

    if (r->good) {
        if (st.st_mtime == r->mtime) {
            /* Theoretically the filename could have changed, but if so
               having the same mtime is very unlikely so not worth tracking it in r */
            pa_xfree(fn);
            return;
        }
        pa_log_debug("Found %s (which has been updated since we last checked).", fn);
    } else
        pa_log_debug("Found %s.", fn);

    r->good = TRUE;
    r->mtime = st.st_mtime;
    pa_xfree(r->application_name);
    pa_xfree(r->icon_name);
    pa_xfree(r->role);
    r->application_name = r->icon_name = r->role = NULL;
    if (r->proplist)
        pa_proplist_clear(r->proplist);

    table[0].data = &r->application_name;
    table[1].data = &r->icon_name;

    if (pa_config_parse(fn, NULL, table, r) < 0)
        pa_log_warn("Failed to parse .desktop file %s.", fn);

    pa_xfree(fn);
}
示例#4
0
void pa_proplist_free(pa_proplist* p) {
    pa_assert(p);

    pa_proplist_clear(p);
    pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
}