9
9
*/
10
10
#define PY_SSIZE_T_CLEAN
11
11
#include < Python.h>
12
- #include < cstdlib>
13
- #include < cstdio>
14
- #include < sstream>
15
-
16
- #include < agg_basics.h> // agg:int8u
17
12
18
13
#ifdef _WIN32
19
14
#include < windows.h>
15
+ #define PSAPI_VERSION 1
16
+ #include < psapi.h> // Must be linked with 'psapi' library
17
+ #define dlsym GetProcAddress
18
+ #else
19
+ #include < dlfcn.h>
20
20
#endif
21
21
22
22
// Include our own excerpts from the Tcl / Tk headers
23
23
#include " _tkmini.h"
24
-
25
24
#include " py_converters.h"
26
25
27
- #if defined(_MSC_VER)
28
- # define IMG_FORMAT " %d %d %Iu"
29
- #else
30
- # define IMG_FORMAT " %d %d %zu"
31
- #endif
32
- #define BBOX_FORMAT " %f %f %f %f"
33
-
34
- typedef struct
35
- {
36
- PyObject_HEAD
37
- Tcl_Interp *interp;
38
- } TkappObject;
39
-
40
26
// Global vars for Tcl / Tk functions. We load these symbols from the tkinter
41
27
// extension module or loaded Tcl / Tk libraries at run-time.
42
- static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
43
- static Tcl_AppendResult_t TCL_APPEND_RESULT;
44
- static Tk_MainWindow_t TK_MAIN_WINDOW;
45
28
static Tk_FindPhoto_t TK_FIND_PHOTO;
46
29
static Tk_PhotoPutBlock_NoComposite_t TK_PHOTO_PUT_BLOCK_NO_COMPOSITE;
47
- static Tk_PhotoBlank_t TK_PHOTO_BLANK;
48
30
49
31
static PyObject *mpl_tk_blit (PyObject *self, PyObject *args)
50
32
{
@@ -118,7 +100,6 @@ Win32_SetForegroundWindow(PyObject *module, PyObject *args)
118
100
#endif
119
101
120
102
static PyMethodDef functions[] = {
121
- /* Tkinter interface stuff */
122
103
{ " blit" , (PyCFunction)mpl_tk_blit, METH_VARARGS },
123
104
#ifdef _WIN32
124
105
{ " Win32_GetForegroundWindow" , (PyCFunction)Win32_GetForegroundWindow, METH_VARARGS },
@@ -128,6 +109,19 @@ static PyMethodDef functions[] = {
128
109
};
129
110
130
111
// Functions to fill global TCL / Tk function pointers by dynamic loading
112
+
113
+ template <class T >
114
+ int load_tk (T lib)
115
+ {
116
+ // Try to fill Tk global vars with function pointers. Return the number of
117
+ // functions found.
118
+ return
119
+ !!(TK_FIND_PHOTO =
120
+ (Tk_FindPhoto_t)dlsym (lib, " Tk_FindPhoto" )) +
121
+ !!(TK_PHOTO_PUT_BLOCK_NO_COMPOSITE =
122
+ (Tk_PhotoPutBlock_NoComposite_t)dlsym (lib, " Tk_PhotoPutBlock_NoComposite" ));
123
+ }
124
+
131
125
#ifdef _WIN32
132
126
133
127
/*
@@ -137,102 +131,24 @@ static PyMethodDef functions[] = {
137
131
* Python, we scan all modules in the running process for the TCL and Tk
138
132
* function names.
139
133
*/
140
- #define PSAPI_VERSION 1
141
- #include < psapi.h>
142
- // Must be linked with 'psapi' library
143
-
144
- FARPROC _dfunc (HMODULE lib_handle, const char *func_name)
145
- {
146
- // Load function `func_name` from `lib_handle`.
147
- // Set Python exception if we can't find `func_name` in `lib_handle`.
148
- // Returns function pointer or NULL if not present.
149
-
150
- char message[100 ];
151
-
152
- FARPROC func = GetProcAddress (lib_handle, func_name);
153
- if (func == NULL ) {
154
- sprintf (message, " Cannot load function %s" , func_name);
155
- PyErr_SetString (PyExc_RuntimeError, message);
156
- }
157
- return func;
158
- }
159
-
160
- int get_tcl (HMODULE hMod)
161
- {
162
- // Try to fill TCL global vars with function pointers. Return 0 for no
163
- // functions found, 1 for all functions found, -1 for some but not all
164
- // functions found.
165
- TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
166
- GetProcAddress (hMod, " Tcl_CreateCommand" );
167
- if (TCL_CREATE_COMMAND == NULL ) { // Maybe not TCL module
168
- return 0 ;
169
- }
170
- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc (hMod, " Tcl_AppendResult" );
171
- return (TCL_APPEND_RESULT == NULL ) ? -1 : 1 ;
172
- }
173
-
174
- int get_tk (HMODULE hMod)
175
- {
176
- // Try to fill Tk global vars with function pointers. Return 0 for no
177
- // functions found, 1 for all functions found, -1 for some but not all
178
- // functions found.
179
- TK_MAIN_WINDOW = (Tk_MainWindow_t)
180
- GetProcAddress (hMod, " Tk_MainWindow" );
181
- if (TK_MAIN_WINDOW == NULL ) { // Maybe not Tk module
182
- return 0 ;
183
- }
184
- return // -1 if any remaining symbols are NULL
185
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
186
- _dfunc (hMod, " Tk_FindPhoto" )) == NULL ) ||
187
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
188
- _dfunc (hMod, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
189
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
190
- _dfunc (hMod, " Tk_PhotoBlank" )) == NULL )
191
- ? -1 : 1 ;
192
- }
193
134
194
135
void load_tkinter_funcs (void )
195
136
{
196
137
// Load TCL and Tk functions by searching all modules in current process.
197
- // Sets an error on failure.
198
-
199
138
HMODULE hMods[1024 ];
200
139
HANDLE hProcess;
201
140
DWORD cbNeeded;
202
141
unsigned int i;
203
- int found_tcl = 0 ;
204
- int found_tk = 0 ;
205
-
206
142
// Returns pseudo-handle that does not need to be closed
207
143
hProcess = GetCurrentProcess ();
208
-
209
144
// Iterate through modules in this process looking for TCL / Tk names
210
145
if (EnumProcessModules (hProcess, hMods, sizeof (hMods), &cbNeeded)) {
211
146
for (i = 0 ; i < (cbNeeded / sizeof (HMODULE)); i++) {
212
- if (!found_tcl) {
213
- found_tcl = get_tcl (hMods[i]);
214
- if (found_tcl == -1 ) {
215
- return ;
216
- }
217
- }
218
- if (!found_tk) {
219
- found_tk = get_tk (hMods[i]);
220
- if (found_tk == -1 ) {
221
- return ;
222
- }
223
- }
224
- if (found_tcl && found_tk) {
147
+ if (load_tk (hMods[i])) {
225
148
return ;
226
149
}
227
150
}
228
151
}
229
-
230
- if (found_tcl == 0 ) {
231
- PyErr_SetString (PyExc_RuntimeError, " Could not find TCL routines" );
232
- } else {
233
- PyErr_SetString (PyExc_RuntimeError, " Could not find Tk routines" );
234
- }
235
- return ;
236
152
}
237
153
238
154
#else // not Windows
@@ -243,54 +159,16 @@ void load_tkinter_funcs(void)
243
159
* tkinter dynamic library (module).
244
160
*/
245
161
246
- #include < dlfcn.h>
247
-
248
- void *_dfunc (void *lib_handle, const char *func_name)
249
- {
250
- // Load function `func_name` from `lib_handle`.
251
- // Set Python exception if we can't find `func_name` in `lib_handle`.
252
- // Returns function pointer or NULL if not present.
253
-
254
- void * func;
255
- // Reset errors.
256
- dlerror ();
257
- func = dlsym (lib_handle, func_name);
258
- if (func == NULL ) {
259
- PyErr_SetString (PyExc_RuntimeError, dlerror ());
260
- }
261
- return func;
262
- }
263
-
264
- int _func_loader (void *lib)
265
- {
266
- // Fill global function pointers from dynamic lib.
267
- // Return 1 if any pointer is NULL, 0 otherwise.
268
- return
269
- ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
270
- _dfunc (lib, " Tcl_CreateCommand" )) == NULL ) ||
271
- ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
272
- _dfunc (lib, " Tcl_AppendResult" )) == NULL ) ||
273
- ((TK_MAIN_WINDOW = (Tk_MainWindow_t)
274
- _dfunc (lib, " Tk_MainWindow" )) == NULL ) ||
275
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
276
- _dfunc (lib, " Tk_FindPhoto" )) == NULL ) ||
277
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
278
- _dfunc (lib, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
279
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
280
- _dfunc (lib, " Tk_PhotoBlank" )) == NULL );
281
- }
282
-
283
162
void load_tkinter_funcs (void )
284
163
{
285
164
// Load tkinter global funcs from tkinter compiled module.
286
- // Sets an error on failure.
287
165
void *main_program, *tkinter_lib;
288
166
PyObject *module = NULL , *py_path = NULL , *py_path_b = NULL ;
289
167
char *path;
290
168
291
169
// Try loading from the main program namespace first.
292
170
main_program = dlopen (NULL , RTLD_LAZY);
293
- if (_func_loader (main_program) == 0 ) {
171
+ if (load_tk (main_program)) {
294
172
goto exit ;
295
173
}
296
174
// Clear exception triggered when we didn't find symbols above.
@@ -313,7 +191,7 @@ void load_tkinter_funcs(void)
313
191
PyErr_SetString (PyExc_RuntimeError, dlerror ());
314
192
goto exit ;
315
193
}
316
- _func_loader (tkinter_lib);
194
+ load_tk (tkinter_lib);
317
195
// dlclose is safe because tkinter has been imported.
318
196
dlclose (tkinter_lib);
319
197
goto exit ;
@@ -331,5 +209,14 @@ static PyModuleDef _tkagg_module = {
331
209
PyMODINIT_FUNC PyInit__tkagg (void )
332
210
{
333
211
load_tkinter_funcs ();
334
- return PyErr_Occurred () ? NULL : PyModule_Create (&_tkagg_module);
212
+ if (PyErr_Occurred ()) {
213
+ return NULL ;
214
+ } else if (!TK_FIND_PHOTO) {
215
+ PyErr_SetString (PyExc_RuntimeError, " Failed to load Tk_FindPhoto" );
216
+ return NULL ;
217
+ } else if (!TK_PHOTO_PUT_BLOCK_NO_COMPOSITE) {
218
+ PyErr_SetString (PyExc_RuntimeError, " Failed to load Tk_PhotoPutBlock_NoComposite" );
219
+ return NULL ;
220
+ }
221
+ return PyModule_Create (&_tkagg_module);
335
222
}
0 commit comments