WIP, more context changes
[imager.git] / dynaload.c
1 #if defined(OS_hpux)
2 #include <dl.h>
3 typedef shl_t minthandle_t;
4 #elif defined(WIN32)
5 #define WIN32_LEAN_AND_MEAN
6 #include <windows.h>
7 typedef HMODULE minthandle_t;
8 #undef WIN32_LEAN_AND_MEAN
9 #else 
10 #include <dlfcn.h>
11 typedef void *minthandle_t; 
12 #endif 
13
14 #include "ext.h"
15
16 struct DSO_handle_tag {
17   minthandle_t handle;
18   char *filename;
19   func_ptr *function_list;
20 };
21
22 #include "imager.h"
23 #include "dynaload.h"
24 /* #include "XSUB.h"  so we can compile on threaded perls */
25 #include "imageri.h"
26
27 static im_context_t
28 do_get_context(void) {
29   return im_get_context();
30 }
31
32 static symbol_table_t symbol_table=
33   {
34     i_has_format,
35     ICL_set_internal,
36     ICL_info,
37     do_get_context,
38     i_img_empty,
39     im_img_empty_ch,
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   };
51
52
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
61 void
62 DSO_call(DSO_handle *handle,int func_index,HV* hv) {
63   mm_log((1,"DSO_call(handle %p, func_index %d, hv %p)\n",
64           handle, func_index, hv));
65   (handle->function_list[func_index].iptr)((void*)hv);
66 }
67
68 func_ptr *
69 DSO_funclist(DSO_handle *handle) {
70   return handle->function_list;
71 }
72
73
74 #if defined( OS_hpux )
75
76 void*
77 DSO_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;
97   (*plugin_utiltab)=&i_UTIL_table;
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") );
103   f(&symbol_table,&i_UTIL_table);
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; 
107   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
108     return NULL;
109
110   dso_handle->handle=tt_handle; /* needed to close again */
111   dso_handle->function_list=function_list;
112   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
113     free(dso_handle); return NULL;
114   }
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
121 undef_int
122 DSO_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
130 void *
131 DSO_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
138   mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",file,file,evalstring) );
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"));
156   f(&symbol_table, &i_UTIL_table);
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   }
164   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
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;
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   }
176   strcpy(dso_handle->filename,file);
177
178   mm_log( (1,"DSO_open <- %p\n",dso_handle) );
179   return (void*)dso_handle;
180
181 }
182
183 undef_int
184 DSO_close(void *ptr) {
185   DSO_handle *handle = (DSO_handle *)ptr;
186   BOOL result = FreeLibrary(handle->handle);
187   free(handle->filename);
188   free(handle);
189
190   return result;
191 }
192
193 #else
194
195 /* OS/2 has no dlclose; Perl doesn't provide one. */
196 #ifdef __EMX__ /* OS/2 */
197 int
198 dlclose(minthandle_t h) {
199   return DosFreeModule(h) ? -1 : 0;
200 }
201 #endif /* __EMX__ */
202
203 void*
204 DSO_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
213   mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",
214            file, file, evalstring) );
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") );
252   f(&symbol_table,&i_UTIL_table);
253   mm_log( (1,"Call ok.\n") );
254
255   /* (*plugin_symtab)=&symbol_table;
256      (*plugin_utiltab)=&i_UTIL_table; */
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   
264   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
265     return NULL;
266   
267   dso_handle->handle=d_handle; /* needed to close again */
268   dso_handle->function_list=function_list;
269   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
270     free(dso_handle); 
271     return NULL;
272   }
273   strcpy(dso_handle->filename,file);
274
275   mm_log( (1,"DSO_open <- %p\n",dso_handle) );
276   return (void*)dso_handle;
277 }
278
279 undef_int
280 DSO_close(void *ptr) {
281   DSO_handle *handle;
282   mm_log((1,"DSO_close(ptr %p)\n",ptr));
283   handle=(DSO_handle*) ptr;
284   return !dlclose(handle->handle);
285 }
286
287 #endif
288