summaryrefslogtreecommitdiff
path: root/src/xine-engine/load_plugins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine/load_plugins.c')
-rw-r--r--src/xine-engine/load_plugins.c122
1 files changed, 97 insertions, 25 deletions
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index c72241487..8e734daca 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -43,6 +43,8 @@
#include <ctype.h>
#include <signal.h>
+#include <basedir.h>
+
#define LOG_MODULE "load_plugins"
#define LOG_VERBOSE
@@ -95,6 +97,7 @@ static void remove_segv_handler(void){
#endif
#endif /* 0 */
+#define CACHE_CATALOG_VERSION 2
static const int plugin_iface_versions[] = {
INPUT_PLUGIN_IFACE_VERSION,
@@ -949,7 +952,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
file = xine_xmalloc(sizeof(plugin_file_t));
node->file = file;
file->filename = strdup(line+1);
- node->info = xine_xmalloc(2*sizeof(plugin_info_t));
+ node->info = xine_xcalloc(2, sizeof(plugin_info_t));
node->info[1].type = PLUGIN_NONE;
decoder_info = NULL;
vo_info = NULL;
@@ -1033,7 +1036,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
s = strchr(s+1, ' ');
}
- decoder_info->supported_types = xine_xmalloc((i+1)*sizeof(uint32_t));
+ decoder_info->supported_types = xine_xcalloc((i+1), sizeof(uint32_t));
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
decoder_info->supported_types[i] = lu;
s = strchr(s+1, ' ');
@@ -1066,27 +1069,68 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
}
}
+/**
+ * @brief Returns the complete filename for the plugins' cache file
+ * @param this Instance pointer, used for logging and libxdg-basedir.
+ * @param createdir If not zero, create the directory structure in which
+ * the file has to reside.
+ * @return If createdir was not zero, returns NULL if the directory hasn't
+ * been created; otherwise always returns a new string with the
+ * name of the cachefile.
+ * @internal
+ *
+ * @see XDG Base Directory specification:
+ * http://standards.freedesktop.org/basedir-spec/latest/index.html
+ */
+static char *catalog_filename(xine_t *this, int createdir) {
+ const char *const xdg_cache_home = xdgCacheHome(this->basedir_handle);
+ char *cachefile = NULL;
+
+ cachefile = xine_xmalloc( strlen(xdg_cache_home) + sizeof("/"PACKAGE"/plugins.cache") );
+ strcpy(cachefile, xdg_cache_home);
+
+ /* If we're going to create the directory structure, we concatenate
+ * piece by piece the path, so that we can try to create all the
+ * directories.
+ * If we don't need to create anything, we just concatenate the
+ * whole path at once.
+ */
+ if ( createdir ) {
+ int result = 0;
+
+ result = mkdir( cachefile, 0700 );
+ if ( result != 0 && errno != EEXIST ) {
+ /** @todo Convert this to use xine's log facility */
+ fprintf(stderr, _("Unable to create %s directory: %s\n"), cachefile, strerror(errno));
+ free(cachefile);
+ return NULL;
+ }
+
+ strcat(cachefile, "/"PACKAGE);
+ result = mkdir( cachefile, 0700 );
+ if ( result != 0 && errno != EEXIST ) {
+ /** @todo Convert this to use xine's log facility */
+ fprintf(stderr, _("Unable to create %s directory: %s\n"), cachefile, strerror(errno));
+ free(cachefile);
+ return NULL;
+ }
+
+ strcat(cachefile, "/plugins.cache");
+
+ } else
+ strcat(cachefile, "/"PACKAGE"/plugins.cache");
+
+ return cachefile;
+}
/*
* save catalog to cache file
*/
static void save_catalog (xine_t *this) {
-
FILE *fp;
- char *cachefile, *dirfile;
- const char *relname = CACHE_CATALOG_FILE;
- const char *dirname = CACHE_CATALOG_DIR;
-
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
-
- /* make sure homedir (~/.xine) exists */
- dirfile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(dirname) + 2);
- sprintf(dirfile, "%s/%s", xine_get_homedir(), dirname);
- mkdir (dirfile, 0755);
- free (dirfile);
+ char *const cachefile = catalog_filename(this, 1);
+
+ if ( ! cachefile ) return;
if( (fp = fopen(cachefile,"w")) != NULL ) {
int i;
@@ -1108,13 +1152,9 @@ static void save_catalog (xine_t *this) {
static void load_cached_catalog (xine_t *this) {
FILE *fp;
- char *cachefile;
- const char *relname = CACHE_CATALOG_FILE;
-
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
-
+ char *const cachefile = catalog_filename(this, 0);
+ /* It can't return NULL without creating directories */
+
if( (fp = fopen(cachefile,"r")) != NULL ) {
load_plugin_list (fp, this->plugin_catalog->cache_list);
fclose(fp);
@@ -1681,6 +1721,38 @@ static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
return driver;
}
+ao_driver_t *_x_load_audio_output_plugin (xine_t *this, const char *id)
+{
+ plugin_node_t *node;
+ ao_driver_t *driver = NULL;
+ ao_info_t *ao_info;
+ plugin_catalog_t *catalog = this->plugin_catalog;
+ int list_id, list_size;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ list_size = xine_sarray_size (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1]);
+ for (list_id = 0; list_id < list_size; list_id++) {
+
+ node = xine_sarray_get (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1], list_id);
+
+ ao_info = (ao_info_t *)node->info->special_info;
+
+ if (!strcasecmp(node->info->id, id)) {
+ driver = _load_audio_driver (this, node, NULL);
+ break;
+ }
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ if (!driver) {
+ xprintf (this, XINE_VERBOSITY_LOG,
+ _("load_plugins: failed to load audio output plugin <%s>\n"), id);
+ }
+ return driver;
+}
+
xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id,
void *data) {
@@ -2199,7 +2271,7 @@ const char *const *xine_list_post_plugins(xine_t *xine) {
return catalog->ids;
}
-const char *const *xine_list_post_plugins_typed(xine_t *xine, int type) {
+const char *const *xine_list_post_plugins_typed(xine_t *xine, uint32_t type) {
plugin_catalog_t *catalog = xine->plugin_catalog;
plugin_node_t *node;
int i;