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); }
void pa_proplist_free(pa_proplist* p) { pa_assert(p); pa_proplist_clear(p); pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL); }