00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 #include <gimp-print/gimp-print.h>
00027 #include "gimp-print-internal.h"
00028 #include <gimp-print/gimp-print-intl-internal.h>
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <libgen.h>
00033 #include <errno.h>
00034 #include <unistd.h>
00035
00036
00037 typedef struct stpi_internal_module_class
00038 {
00039 stp_module_class_t class;
00040 const char *description;
00041 } stpi_internal_module_class_t;
00042
00043
00044 static void module_list_freefunc(void *item);
00045 static int stp_module_register(stp_module_t *module);
00046 #ifdef USE_DLOPEN
00047 static void *stp_dlsym(void *handle, const char *symbol, const char *modulename);
00048 #endif
00049
00050 static const stpi_internal_module_class_t module_classes[] =
00051 {
00052 {STP_MODULE_CLASS_MISC, N_("Miscellaneous (unclassified)")},
00053 {STP_MODULE_CLASS_FAMILY, N_("Family driver")},
00054 {STP_MODULE_CLASS_COLOR, N_("Color conversion module")},
00055 {STP_MODULE_CLASS_DITHER, N_("Dither algorithm")},
00056 {STP_MODULE_CLASS_INVALID, NULL}
00057 };
00058
00059 #if !defined(USE_LTDL) && !defined(USE_DLOPEN)
00060 extern stp_module_t print_canon_LTX_stp_module_data;
00061 extern stp_module_t print_escp2_LTX_stp_module_data;
00062 extern stp_module_t print_lexmark_LTX_stp_module_data;
00063 extern stp_module_t print_pcl_LTX_stp_module_data;
00064 extern stp_module_t print_ps_LTX_stp_module_data;
00065 extern stp_module_t print_olympus_LTX_stp_module_data;
00066 extern stp_module_t print_raw_LTX_stp_module_data;
00067 extern stp_module_t color_traditional_LTX_stp_module_data;
00068
00069
00070
00071
00072 static stp_module_t *static_modules[] =
00073 {
00074 &print_ps_LTX_stp_module_data,
00075 &print_canon_LTX_stp_module_data,
00076 &print_escp2_LTX_stp_module_data,
00077 &print_pcl_LTX_stp_module_data,
00078 &print_lexmark_LTX_stp_module_data,
00079 &print_olympus_LTX_stp_module_data,
00080 &print_raw_LTX_stp_module_data,
00081 &color_traditional_LTX_stp_module_data,
00082 NULL
00083 };
00084 #endif
00085
00086 static stp_list_t *module_list = NULL;
00087
00088
00089
00090
00091
00092 static void
00093 module_list_freefunc(void *item )
00094 {
00095 stp_module_t *module = (stp_module_t *) item;
00096 if (module && module->fini)
00097 module->fini();
00098 #if defined(USE_LTDL) || defined(USE_DLOPEN)
00099 DLCLOSE(module->handle);
00100 #endif
00101 }
00102
00103
00104
00105
00106
00107 int stp_module_load(void)
00108 {
00109
00110 #ifdef USE_LTDL
00111 static int ltdl_is_initialised = 0;
00112 #endif
00113 static int module_list_is_initialised = 0;
00114 #if defined(USE_LTDL) || defined(USE_DLOPEN)
00115 stp_list_t *dir_list;
00116 stp_list_t *file_list;
00117 stp_list_item_t *file;
00118 #endif
00119
00120 #ifdef USE_LTDL
00121 if (!ltdl_is_initialised)
00122 {
00123 if (lt_dlinit())
00124 {
00125 stp_erprintf("Error initialising libltdl: %s\n", DLERROR());
00126 return 1;
00127 }
00128 ltdl_is_initialised = 1;
00129 }
00130
00131 lt_dladdsearchdir(PKGMODULEDIR);
00132 #endif
00133
00134
00135 if (!module_list_is_initialised)
00136 {
00137 if (!(module_list = stp_list_create()))
00138 return 1;
00139 stp_list_set_freefunc(module_list, module_list_freefunc);
00140 module_list_is_initialised = 1;
00141 }
00142
00143
00144 #if defined (USE_LTDL) || defined (USE_DLOPEN)
00145 if (!(dir_list = stp_list_create()))
00146 return 1;
00147 stp_list_set_freefunc(dir_list, stp_list_node_free_data);
00148 if (getenv("STP_MODULE_PATH"))
00149 {
00150 stp_path_split(dir_list, getenv("STP_MODULE_PATH"));
00151 }
00152 else
00153 {
00154 #ifdef USE_LTDL
00155 stp_path_split(dir_list, getenv("LTDL_LIBRARY_PATH"));
00156 stp_path_split(dir_list, lt_dlgetsearchpath());
00157 #else
00158 stp_path_split(dir_list, PKGMODULEDIR);
00159 #endif
00160 }
00161 #ifdef USE_LTDL
00162 file_list = stp_path_search(dir_list, ".la");
00163 #else
00164 file_list = stp_path_search(dir_list, ".so");
00165 #endif
00166 stp_list_destroy(dir_list);
00167
00168
00169 file = stp_list_get_start(file_list);
00170 while (file)
00171 {
00172 stp_module_open((const char *) stp_list_item_get_data(file));
00173 file = stp_list_item_next(file);
00174 }
00175
00176 stp_list_destroy(file_list);
00177 #else
00178 {
00179 int i=0;
00180 while (static_modules[i])
00181 {
00182 stp_module_register(static_modules[i]);
00183 i++;
00184 }
00185 }
00186 #endif
00187 return 0;
00188 }
00189
00190
00191
00192
00193
00194 int
00195 stp_module_exit(void)
00196 {
00197
00198 if (module_list)
00199 stp_list_destroy(module_list);
00200
00201 #ifdef USE_LTDL
00202 return lt_dlexit();
00203 #else
00204 return 0;
00205 #endif
00206 }
00207
00208
00209
00210
00211
00212 stp_list_t *
00213 stp_module_get_class(stp_module_class_t class )
00214 {
00215 stp_list_t *list;
00216 stp_list_item_t *ln;
00217
00218 list = stp_list_create();
00219
00220 if (!list)
00221 return NULL;
00222
00223 ln = stp_list_get_start(module_list);
00224 while (ln)
00225 {
00226
00227 if (((stp_module_t *) stp_list_item_get_data(ln))->class == class)
00228 stp_list_item_create(list, NULL, stp_list_item_get_data(ln));
00229 ln = stp_list_item_next(ln);
00230 }
00231 return list;
00232 }
00233
00234
00235
00236
00237
00238 int
00239 stp_module_open(const char *modulename )
00240 {
00241 #if defined(USE_LTDL) || defined(USE_DLOPEN)
00242 #ifdef USE_LTDL
00243 lt_dlhandle module;
00244 #else
00245 void *module;
00246 #endif
00247 stp_module_version_t *version;
00248 stp_module_t *data;
00249 stp_list_item_t *reg_module;
00250 int error = 0;
00251
00252 stp_deprintf(STP_DBG_MODULE, "stp-module: open: %s\n", modulename);
00253 while(1)
00254 {
00255 module = DLOPEN(modulename);
00256 if (!module)
00257 break;
00258
00259
00260 version = (stp_module_version_t *) DLSYM(module, "stp_module_version");
00261 if (!version)
00262 break;
00263 if (version->major != 1 && version->minor < 0)
00264 break;
00265
00266 data = (void *) DLSYM(module, "stp_module_data");
00267 if (!data)
00268 break;
00269 data->handle = module;
00270
00271
00272 reg_module = stp_list_get_start(module_list);
00273 while (reg_module)
00274 {
00275 if (!strcmp(data->name, ((stp_module_t *)
00276 stp_list_item_get_data(reg_module))->name) &&
00277 data->class == ((stp_module_t *)
00278 stp_list_item_get_data(reg_module))->class)
00279 {
00280 stp_deprintf(STP_DBG_MODULE,
00281 "stp-module: reject duplicate: %s\n",
00282 data->name);
00283 error = 1;
00284 break;
00285 }
00286 reg_module = stp_list_item_next(reg_module);
00287 }
00288 if (error)
00289 break;
00290
00291
00292 if (stp_module_register(data))
00293 break;
00294
00295 return 0;
00296 }
00297
00298 if (module)
00299 DLCLOSE(module);
00300 #endif
00301 return 1;
00302 }
00303
00304
00305
00306
00307
00308 static int stp_module_register(stp_module_t *module )
00309 {
00310
00311 if (stp_list_item_create(module_list, NULL, module))
00312 return 1;
00313
00314 stp_deprintf(STP_DBG_MODULE, "stp-module: register: %s\n", module->name);
00315 return 0;
00316 }
00317
00318
00319
00320
00321
00322 int stp_module_init(void)
00323 {
00324 stp_list_item_t *module_item;
00325 stp_module_t *module;
00326
00327 module_item = stp_list_get_start(module_list);
00328 while (module_item)
00329 {
00330 module = (stp_module_t *) stp_list_item_get_data(module_item);
00331 if (module)
00332 {
00333 stp_deprintf(STP_DBG_MODULE, "stp-module-init: %s\n", module->name);
00334
00335 if (module->init && module->init())
00336 {
00337 stp_deprintf(STP_DBG_MODULE,
00338 "stp-module-init: %s: Module init failed\n",
00339 module->name);
00340 }
00341 }
00342 module_item = stp_list_item_next(module_item);
00343 }
00344 return 0;
00345 }
00346
00347
00348
00349
00350
00351
00352 int
00353 stp_module_close(stp_list_item_t *module )
00354 {
00355 return stp_list_item_destroy(module_list, module);
00356 }
00357
00358
00359
00360
00361
00362 #ifdef USE_DLOPEN
00363 static void *stp_dlsym(void *handle,
00364 const char *symbol,
00365 const char *modulename)
00366 {
00367 int len;
00368 static char *full_symbol = NULL;
00369 char *module;
00370 char *tmp = stp_strdup(modulename);
00371
00372 module = basename(tmp);
00373
00374 if (full_symbol)
00375 {
00376 stp_free (full_symbol);
00377 full_symbol = NULL;
00378 }
00379
00380 full_symbol = (char *) stp_malloc(sizeof(char) * (strlen(module) - 2));
00381
00382
00383 len = strlen(symbol) + strlen(module) + 3;
00384 full_symbol = (char *) stp_malloc(sizeof(char) * len);
00385
00386 len = 0;
00387 strncpy (full_symbol, module, strlen(module) - 3);
00388 len = strlen(module) - 3;
00389 strcpy (full_symbol+len, "_LTX_");
00390 len += 5;
00391 strcpy (full_symbol+len, symbol);
00392 len += strlen(symbol);
00393 full_symbol[len] = '\0';
00394
00395 #if defined(__OpenBSD__)
00396
00397 {
00398 char *prefix_symbol = stp_malloc(sizeof(char) * (strlen(full_symbol) + 2));
00399 prefix_symbol[0] = '_';
00400 strcpy(prefix_symbol+1, full_symbol);
00401 stp_free(full_symbol);
00402 full_symbol = prefix_symbol;
00403 }
00404 #endif
00405
00406
00407 for (len = 0; full_symbol[len] != '\0'; len++)
00408 if (full_symbol[len] == '-')
00409 full_symbol[len] = '_';
00410
00411 stp_deprintf(STP_DBG_MODULE, "SYMBOL: %s\n", full_symbol);
00412
00413 return dlsym(handle, full_symbol);
00414 }
00415 #endif