summaryrefslogtreecommitdiff
path: root/src/ico_plugin_loader.c
blob: 5f3ac618e6b5c5b3ec553d7a39cef1d00fdf85f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Copyright © 2010-2011 Intel Corporation
 * Copyright © 2008-2011 Kristian Høgsberg
 * Copyright © 2013 TOYOTA MOTOR CORPORATION.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the copyright holders not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  The copyright holders make
 * no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/**
 * @brief   Weston(Wayland) Plugin Loader
 * @brief   Load the Weston plugins, because plugin loader of main body of Weston
 * @brief   cannot use other plugin functions by a other plugin.
 *
 * @date    Feb-08-2013
 */

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/time.h>
#include <time.h>

#include <weston/compositor.h>
#include "ico_ivi_common.h"

/* This function is called from the main body of Weston and initializes this module.*/
int module_init(struct weston_compositor *ec);

/* Internal function to load one plugin.    */
static void load_module(struct weston_compositor *ec, const char *path, const char *entry);

/* Static valiables                         */
static char *moddir = NULL;                 /* Answer back from configuration       */
static char *modules = NULL;                /* Answer back from configuration       */
static int  debug_level = 3;                /* Debug Level                          */

/* Configuration key                        */
static const struct config_key plugin_config_keys[] = {
        { "moddir", CONFIG_KEY_STRING, &moddir },
        { "modules", CONFIG_KEY_STRING, &modules },
    };

static const struct config_section conf_plugin[] = {
        { "plugin", plugin_config_keys, ARRAY_LENGTH(plugin_config_keys) },
    };

static const struct config_key debug_config_keys[] = {
        { "ivi_debug", CONFIG_KEY_INTEGER, &debug_level },
    };

static const struct config_section conf_debug[] = {
        { "debug", debug_config_keys, ARRAY_LENGTH(debug_config_keys) },
    };


/*--------------------------------------------------------------------------*/
/**
 * @brief   ico_ivi_debuglevel: answer debug output level.
 *
 * @param       none
 * @return      debug output level
 * @retval      0       No debug output
 * @retval      1       Only error output
 * @retval      2       Error and information output
 * @retval      3       All output with debug write
 */
/*--------------------------------------------------------------------------*/
int
ico_ivi_debuglevel(void)
{
    return debug_level;
}

/*--------------------------------------------------------------------------*/
/**
 * @brief   load_module: load one plugin module.
 *
 * @param[in]   ec          weston compositor. (from weston)
 * @param[in]   path        file path of plugin module.
 * @param[in]   entry       entry function name of plugin module.
 * @return      none
 */
/*--------------------------------------------------------------------------*/
static void
load_module(struct weston_compositor *ec, const char *path, const char *entry)
{
    void    *module;                    /* module informations (dlopen)             */
    int (*init)(struct weston_compositor *ec);
                                        /* enter function of loaded plugin          */

    uifw_info("ico_plugin_loader: Load(path=%s entry=%s)", path, entry);

    /* get module informations                      */
    module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);

    if (module) {
        /* plugin module already loaded             */
        dlclose(module);
        uifw_error("ico_plugin_loader: Load Error(%s already loaded)", path);
        return;
    }

    /* load plugin module                           */
    uifw_trace("ico_plugin_loader: %s loading", path);

    module = dlopen(path, RTLD_NOW | RTLD_GLOBAL);

    if (! module)   {
        /* plugin module dose not exist             */
        uifw_error("ico_plugin_loader: Load Error(%s error<%s>)", path, dlerror());
        return;
    }

    /* find initialize function                     */
    if (entry)  {
        init = dlsym(module, entry);
        if (! init) {
            uifw_error("ico_plugin_loader: Load Error(%s, function %s dose not exist(%s))",
                       path, entry, dlerror());
        }
        else    {
            /* call initialize function             */
            uifw_trace("ico_plugin_loader: Call %s:%s(%08x)", path, entry, (int)init);
            init(ec);
            uifw_info("ico_plugin_loader: %s Loaded", path);
        }
    }
}

/*--------------------------------------------------------------------------*/
/**
 * @brief   module_init: initialize function of ico_plugin_loader
 *                       called from weston compositor.
 *
 * @param[in]   ec          weston compositor(from weston)
 * @return      result
 * @retval      0           sccess
 * @retval      -1          error
 */
/*--------------------------------------------------------------------------*/
WL_EXPORT int
module_init(struct weston_compositor *ec)
{
    int     config_fd;
    char    *p;
    char    *end;
    char    buffer[256];

    uifw_info("ico_plugin_loader: Enter(module_init)");

    /* get plugin module name from config file(weston_ivi_plugin.ini)   */
    config_fd = open_config_file(ICO_IVI_PLUGIN_CONFIG);
    parse_config_file(config_fd, conf_plugin, ARRAY_LENGTH(conf_plugin), NULL);
    parse_config_file(config_fd, conf_debug, ARRAY_LENGTH(conf_debug), NULL);
    close(config_fd);

    if (modules == NULL)    {
        uifw_error("ico_plugin_loader: Leave(No Plugin in config)");
        return -1;
    }
    moddir = getenv("WESTON_IVI_PLUGIN_DIR");

    p = modules;
    while (*p) {
        end = strchrnul(p, ',');
        if (*p == '/')  {
            snprintf(buffer, sizeof(buffer), "%.*s", (int) (end - p), p);
        }
        else if (moddir)    {
            snprintf(buffer, sizeof(buffer), "%s/%.*s", moddir, (int) (end - p), p);
        }
        else    {
            snprintf(buffer, sizeof(buffer), "%s/%.*s", MODULEDIR, (int) (end - p), p);
        }
        load_module(ec, buffer, "module_init");
        p = end;
        while (*p == ',')   {
            p++;
        }
    }

    uifw_info("ico_plugin_loader: Leave(module_init)");

    return 0;
}