6 * Copyright (c) 2009 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
28 #define SOEXT ".dylib"
33 /** Dummy plugin used as a plugin directory marker */
34 #define DUMMY_PLUGIN ("lxdream_dummy" SOEXT)
36 const char *plugin_type_string[] = { "undefined", "audio driver", "input driver" };
38 int main(int argc, char *argv[]);
39 static const char *exec_path = NULL;
42 * Return the full path to the main binary
44 static const char *get_exec_path()
46 if( exec_path == NULL ) {
49 /* Use dladdr for this, since it should be available for any platform
50 * that we can support plugins on at all.
52 if( dladdr( main, &dli) ) {
53 gchar *path = g_strdup( dli.dli_fname );
54 char *i = strrchr( path, '/' );
66 static gboolean plugin_load( const gchar *plugin_path )
68 void *so = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);
70 WARN("Failed to load plugin '%s': %s", plugin_path, dlerror());
74 struct plugin_struct *plugin = (struct plugin_struct *)dlsym(so,"lxdream_plugin_entry");
75 if( plugin == NULL ) {
76 WARN("Failed to load plugin: '%s': Not an lxdream plugin", plugin_path);
81 if( strcmp(lxdream_short_version, plugin->version) != 0 ) {
82 WARN("Failed to load plugin: '%s': Incompatible version (%s)", plugin_path, plugin->version);
87 if( plugin->type == PLUGIN_NONE ) {
88 /* 'dummy' plugin - we don't actually want to load it */
93 if( plugin->type < PLUGIN_MIN_TYPE || plugin->type > PLUGIN_MAX_TYPE ) {
94 WARN("Failed to load plugin: '%s': Unrecognized plugin type (%d)", plugin_path, plugin->type );
99 if( plugin->register_plugin() == FALSE ) {
100 WARN("Failed to load plugin: '%s': Initialization failed", plugin_path);
104 DEBUG("Loaded %s '%s'", plugin_type_string[plugin->type], plugin->name);
108 static gboolean has_plugins( const gchar *path )
112 gchar *dummy_name = g_strdup_printf( "%s/%s", path, DUMMY_PLUGIN );
113 if( stat( dummy_name, &st ) == 0 ) {
121 * Scan the plugin dir and load all valid plugins.
123 static int plugin_load_all( const gchar *plugin_dir )
125 int plugin_count = 0;
128 DIR *dir = opendir(plugin_dir);
130 WARN( "Unable to open plugin directory '%s'", plugin_dir );
134 while( (ent = readdir(dir)) != NULL ) {
135 const char *ext = strrchr(ent->d_name, '.');
136 if( ext != NULL && strcasecmp(SOEXT,ext) == 0 ) {
137 char *libname = g_strdup_printf( "%s/%s", plugin_dir,ent->d_name );
138 if( plugin_load( libname ) ) {
149 const char *path = get_exec_path();
150 if( path == NULL || !has_plugins(path) ) {
151 path = get_plugin_path();
154 DEBUG( "Plugin directory: %s", path );
155 return plugin_load_all( path );
.