WIP, more context changes
[imager.git] / dynaload.c
CommitLineData
d8e0c3ba
TC
1#if defined(OS_hpux)
2#include <dl.h>
3typedef shl_t minthandle_t;
4#elif defined(WIN32)
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7typedef HMODULE minthandle_t;
8#undef WIN32_LEAN_AND_MEAN
d8e0c3ba
TC
9#else
10#include <dlfcn.h>
11typedef void *minthandle_t;
12#endif
13
696cb85d 14#include "ext.h"
d8e0c3ba
TC
15
16struct DSO_handle_tag {
17 minthandle_t handle;
18 char *filename;
19 func_ptr *function_list;
20};
21
92bda632 22#include "imager.h"
02d1d628 23#include "dynaload.h"
b33c08f8 24/* #include "XSUB.h" so we can compile on threaded perls */
92bda632 25#include "imageri.h"
02d1d628 26
696cb85d
TC
27static im_context_t
28do_get_context(void) {
29 return im_get_context();
30}
31
97ac0a96
TC
32static symbol_table_t symbol_table=
33 {
34 i_has_format,
35 ICL_set_internal,
36 ICL_info,
696cb85d 37 do_get_context,
d03fd5a4 38 i_img_empty,
696cb85d 39 im_img_empty_ch,
97ac0a96
TC
40 i_img_exorcise,
41 i_img_info,
42 i_img_setmask,
43 i_img_getmask,
44 i_box,
45 i_line,
46 i_arc,
47 i_copyto,
48 i_copyto_trans,
49 i_rubthru
50 };
b6cfd214
TC
51
52
02d1d628
AMH
53/*
54 Dynamic loading works like this:
55 dynaload opens the shared object and
56 loads all the functions into an array of functions
57 it returns a string from the dynamic function that
58 can be supplied to the parser for evaling.
59*/
60
61void
62DSO_call(DSO_handle *handle,int func_index,HV* hv) {
8d14daab
TC
63 mm_log((1,"DSO_call(handle %p, func_index %d, hv %p)\n",
64 handle, func_index, hv));
02d1d628
AMH
65 (handle->function_list[func_index].iptr)((void*)hv);
66}
67
d8e0c3ba
TC
68func_ptr *
69DSO_funclist(DSO_handle *handle) {
70 return handle->function_list;
71}
72
02d1d628
AMH
73
74#if defined( OS_hpux )
75
76void*
77DSO_open(char* file,char** evalstring) {
78 shl_t tt_handle;
79 void *d_handle,**plugin_symtab,**plugin_utiltab;
80 int rc,*iptr, (*fptr)(int);
81 func_ptr *function_list;
82 DSO_handle *dso_handle;
83 void (*f)(void *s,void *u); /* these will just have to be void for now */
84 int i;
85
86 *evalstring=NULL;
87
88 mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
89
90 if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL;
91 if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL;
92
93 /*
94 if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL;
95 if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL;
96 (*plugin_symtab)=&symbol_table;
b33c08f8 97 (*plugin_utiltab)=&i_UTIL_table;
02d1d628
AMH
98 */
99
100 if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL;
101
102 mm_log( (1,"Calling install_tables\n") );
b33c08f8 103 f(&symbol_table,&i_UTIL_table);
02d1d628
AMH
104 mm_log( (1,"Call ok.\n") );
105
106 if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL;
4131e88b
TC
107 if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
108 return NULL;
02d1d628
AMH
109
110 dso_handle->handle=tt_handle; /* needed to close again */
111 dso_handle->function_list=function_list;
4131e88b
TC
112 if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
113 free(dso_handle); return NULL;
114 }
02d1d628
AMH
115 strcpy(dso_handle->filename,file);
116
117 mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
118 return (void*)dso_handle;
119}
120
121undef_int
122DSO_close(void *ptr) {
123 DSO_handle *handle=(DSO_handle*) ptr;
124 mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
125 return !shl_unload((handle->handle));
126}
127
128#elif defined(WIN32)
129
130void *
131DSO_open(char *file, char **evalstring) {
132 HMODULE d_handle;
133 func_ptr *function_list;
134 DSO_handle *dso_handle;
135
136 void (*f)(void *s,void *u); /* these will just have to be void for now */
137
8d14daab 138 mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",file,file,evalstring) );
02d1d628
AMH
139
140 *evalstring = NULL;
141 if ((d_handle = LoadLibrary(file)) == NULL) {
142 mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
143 return NULL;
144 }
145 if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
146 mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
147 FreeLibrary(d_handle);
148 return NULL;
149 }
150 if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
151 mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
152 FreeLibrary(d_handle);
153 return NULL;
154 }
155 mm_log((1, "Calling install tables\n"));
b33c08f8 156 f(&symbol_table, &i_UTIL_table);
02d1d628
AMH
157 mm_log((1, "Call ok\n"));
158
159 if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
160 mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
161 FreeLibrary(d_handle);
162 return NULL;
163 }
4131e88b 164 if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
02d1d628
AMH
165 mm_log( (1, "DSO_Open: out of memory\n") );
166 FreeLibrary(d_handle);
167 return NULL;
168 }
169 dso_handle->handle=d_handle; /* needed to close again */
170 dso_handle->function_list=function_list;
4131e88b
TC
171 if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
172 free(dso_handle);
173 FreeLibrary(d_handle);
174 return NULL;
175 }
02d1d628
AMH
176 strcpy(dso_handle->filename,file);
177
8d14daab 178 mm_log( (1,"DSO_open <- %p\n",dso_handle) );
02d1d628
AMH
179 return (void*)dso_handle;
180
181}
182
183undef_int
184DSO_close(void *ptr) {
185 DSO_handle *handle = (DSO_handle *)ptr;
bc0b5da4 186 BOOL result = FreeLibrary(handle->handle);
02d1d628
AMH
187 free(handle->filename);
188 free(handle);
bc0b5da4
TC
189
190 return result;
02d1d628
AMH
191}
192
193#else
194
195/* OS/2 has no dlclose; Perl doesn't provide one. */
196#ifdef __EMX__ /* OS/2 */
197int
198dlclose(minthandle_t h) {
199 return DosFreeModule(h) ? -1 : 0;
200}
201#endif /* __EMX__ */
202
02d1d628
AMH
203void*
204DSO_open(char* file,char** evalstring) {
205 void *d_handle;
206 func_ptr *function_list;
207 DSO_handle *dso_handle;
208
209 void (*f)(void *s,void *u); /* these will just have to be void for now */
210
211 *evalstring=NULL;
212
8d14daab
TC
213 mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",
214 file, file, evalstring) );
02d1d628
AMH
215
216 if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
217 mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
218 return NULL;
219 }
220
221 if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
222 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
223 return NULL;
224 }
225
226 /*
227
228 I'll just leave this thing in here for now if I need it real soon
229
230 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
231 if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
232 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
233 return NULL;
234 }
235
236 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
237 if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
238 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
239 return NULL;
240 }
241
242 */
243
244 f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
245 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
246 if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
247 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
248 return NULL;
249 }
250
251 mm_log( (1,"Calling install_tables\n") );
b33c08f8 252 f(&symbol_table,&i_UTIL_table);
02d1d628
AMH
253 mm_log( (1,"Call ok.\n") );
254
255 /* (*plugin_symtab)=&symbol_table;
b33c08f8 256 (*plugin_utiltab)=&i_UTIL_table; */
02d1d628
AMH
257
258 mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
259 if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
260 mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
261 return NULL;
262 }
263
4131e88b
TC
264 if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
265 return NULL;
02d1d628
AMH
266
267 dso_handle->handle=d_handle; /* needed to close again */
268 dso_handle->function_list=function_list;
4131e88b
TC
269 if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
270 free(dso_handle);
271 return NULL;
272 }
02d1d628
AMH
273 strcpy(dso_handle->filename,file);
274
8d14daab 275 mm_log( (1,"DSO_open <- %p\n",dso_handle) );
02d1d628
AMH
276 return (void*)dso_handle;
277}
278
279undef_int
280DSO_close(void *ptr) {
281 DSO_handle *handle;
8d14daab 282 mm_log((1,"DSO_close(ptr %p)\n",ptr));
02d1d628
AMH
283 handle=(DSO_handle*) ptr;
284 return !dlclose(handle->handle);
285}
286
287#endif
288