Search
lxdream.org :: lxdream/src/plugin.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/plugin.c
changeset 1024:c67f2d61ab97
next1027:4e527bc96109
author nkeynes
date Sat Jun 13 00:50:48 2009 +0000 (12 years ago)
permissions -rw-r--r--
last change Build drivers with library dependencies as shared objects (ie plugins)
file annotate diff log raw
nkeynes@1024
     1
/**
nkeynes@1024
     2
 * $Id$
nkeynes@1024
     3
 *
nkeynes@1024
     4
 * Plugin loader code
nkeynes@1024
     5
 *
nkeynes@1024
     6
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@1024
     7
 *
nkeynes@1024
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@1024
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@1024
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@1024
    11
 * (at your option) any later version.
nkeynes@1024
    12
 *
nkeynes@1024
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@1024
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@1024
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@1024
    16
 * GNU General Public License for more details.
nkeynes@1024
    17
 */
nkeynes@1024
    18
nkeynes@1024
    19
#include <dirent.h>
nkeynes@1024
    20
#include <dlfcn.h>
nkeynes@1024
    21
#include <string.h>
nkeynes@1024
    22
#include <glib/gmem.h>
nkeynes@1024
    23
#include <glib/gstrfuncs.h>
nkeynes@1024
    24
#include "plugin.h"
nkeynes@1024
    25
nkeynes@1024
    26
nkeynes@1024
    27
#ifdef APPLE_BUILD
nkeynes@1024
    28
#define SOEXT ".dylib"
nkeynes@1024
    29
#else
nkeynes@1024
    30
#define SOEXT ".so"
nkeynes@1024
    31
#endif
nkeynes@1024
    32
nkeynes@1024
    33
const char *plugin_type_string[] = { "Undefined", "Audio driver", "Input driver" };
nkeynes@1024
    34
nkeynes@1024
    35
gboolean plugin_load( const gchar *plugin_path )
nkeynes@1024
    36
{
nkeynes@1024
    37
    void *so = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);
nkeynes@1024
    38
    if( so == NULL ) {
nkeynes@1024
    39
        WARN("Failed to load plugin '%s': %s", plugin_path, dlerror());
nkeynes@1024
    40
        return FALSE;
nkeynes@1024
    41
    }
nkeynes@1024
    42
    
nkeynes@1024
    43
    struct plugin_struct *plugin = (struct plugin_struct *)dlsym(so,"lxdream_plugin_entry");
nkeynes@1024
    44
    if( plugin == NULL ) {
nkeynes@1024
    45
        WARN("Failed to load plugin: '%s': Not an lxdream plugin", plugin_path);
nkeynes@1024
    46
        dlclose(so);
nkeynes@1024
    47
        return FALSE;
nkeynes@1024
    48
    }
nkeynes@1024
    49
nkeynes@1024
    50
    if( strcmp(lxdream_short_version, plugin->version) != 0 ) {
nkeynes@1024
    51
        WARN("Failed to load plugin: '%s': Incompatible version (%s)", plugin_path, plugin->version);
nkeynes@1024
    52
        dlclose(so);
nkeynes@1024
    53
        return FALSE;
nkeynes@1024
    54
    }
nkeynes@1024
    55
nkeynes@1024
    56
    if( plugin->type < PLUGIN_MIN_TYPE || plugin->type > PLUGIN_MAX_TYPE ) {
nkeynes@1024
    57
        WARN("Failed to load plugin: '%s': Unrecognized plugin type (%d)", plugin_path, plugin->type );
nkeynes@1024
    58
        dlclose(so);
nkeynes@1024
    59
        return FALSE;
nkeynes@1024
    60
    }
nkeynes@1024
    61
nkeynes@1024
    62
    if( plugin->register_plugin() == FALSE ) {
nkeynes@1024
    63
        WARN("Failed to load plugin: '%s': Initialization failed", plugin_path);
nkeynes@1024
    64
        dlclose(so);
nkeynes@1024
    65
        return FALSE;
nkeynes@1024
    66
    }
nkeynes@1024
    67
    INFO("Loaded %s plugin '%s'", plugin_type_string[plugin->type], plugin->name);
nkeynes@1024
    68
    return TRUE;
nkeynes@1024
    69
}
nkeynes@1024
    70
nkeynes@1024
    71
/**
nkeynes@1024
    72
 * Scan the plugin dir and load all valid plugins.
nkeynes@1024
    73
 */
nkeynes@1024
    74
int plugin_init( const gchar *plugin_dir )
nkeynes@1024
    75
{
nkeynes@1024
    76
    int plugin_count;
nkeynes@1024
    77
    struct dirent *ent;
nkeynes@1024
    78
    DIR *dir = opendir(plugin_dir);
nkeynes@1024
    79
    if( dir == NULL ) {
nkeynes@1024
    80
        WARN( "Unable to open plugin directory '%s'", plugin_dir );
nkeynes@1024
    81
        return 0;
nkeynes@1024
    82
    }
nkeynes@1024
    83
    
nkeynes@1024
    84
    while( (ent = readdir(dir)) != NULL ) {
nkeynes@1024
    85
        const char *ext = strrchr(ent->d_name, '.');
nkeynes@1024
    86
        if( ext != NULL && strcasecmp(SOEXT,ext) == 0 ) {
nkeynes@1024
    87
            char *libname = g_strdup_printf( "%s/%s", plugin_dir,ent->d_name );
nkeynes@1024
    88
            if( plugin_load( libname ) ) {
nkeynes@1024
    89
                plugin_count++;
nkeynes@1024
    90
            }
nkeynes@1024
    91
            g_free(libname);
nkeynes@1024
    92
        }
nkeynes@1024
    93
    }
nkeynes@1024
    94
    return plugin_count;
nkeynes@1024
    95
}
.