blob: f45e29c6f932c8d8a3eddc0e021812966706d3cb [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum7ffa7611996-08-13 21:10:16 +000046*/
47
Guido van Rossum35d43371997-08-02 00:09:09 +000048
Guido van Rossum9722ad81995-09-22 23:49:28 +000049#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000050#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000051
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000052#ifdef macintosh
53#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000054#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000055#endif
56
Guido van Rossum18468821994-06-20 07:49:28 +000057#include <tcl.h>
58#include <tk.h>
59
Guido van Rossum3e819a71997-08-01 19:29:02 +000060#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
61
Guido van Rossum35d43371997-08-02 00:09:09 +000062#if TKMAJORMINOR < 4001
63#error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000064#endif
65
Guido van Rossum35d43371997-08-02 00:09:09 +000066extern int Tk_GetNumMainWindows();
67
Guido van Rossumec22c921996-02-25 04:50:29 +000068#ifdef macintosh
69
70/*
71** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000072** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000073*/
74
Guido van Rossum7ffa7611996-08-13 21:10:16 +000075/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000076#define FREECAST (char *)
77
Guido van Rossumec22c921996-02-25 04:50:29 +000078#include <Events.h> /* For EventRecord */
79
80typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
81void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
82int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
83
84staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
85
86#endif /* macintosh */
87
Guido van Rossum97867b21996-08-08 19:09:53 +000088#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000089#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000090#endif
91
Guido van Rossum18468821994-06-20 07:49:28 +000092/**** Tkapp Object Declaration ****/
93
94staticforward PyTypeObject Tkapp_Type;
95
96typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +000097{
98 PyObject_HEAD
99 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000100}
Guido van Rossum18468821994-06-20 07:49:28 +0000101TkappObject;
102
103#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000104#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
105#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
106
Guido van Rossum35d43371997-08-02 00:09:09 +0000107#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000108(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000109
Barry Warsawfa701a81997-01-16 00:15:11 +0000110
111
Guido van Rossum18468821994-06-20 07:49:28 +0000112/**** Error Handling ****/
113
114static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000115static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000116static int errorInCmd = 0;
117static PyObject *excInCmd;
118static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000119static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000120
Barry Warsawfa701a81997-01-16 00:15:11 +0000121
122
Guido van Rossum18468821994-06-20 07:49:28 +0000123static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000124Tkinter_Error(v)
125 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000126{
Barry Warsawfa701a81997-01-16 00:15:11 +0000127 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
128 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000129}
130
Barry Warsawfa701a81997-01-16 00:15:11 +0000131
Guido van Rossum18468821994-06-20 07:49:28 +0000132int
Barry Warsawfa701a81997-01-16 00:15:11 +0000133PythonCmd_Error(interp)
134 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000135{
Barry Warsawfa701a81997-01-16 00:15:11 +0000136 errorInCmd = 1;
137 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
138 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000139}
140
Barry Warsawfa701a81997-01-16 00:15:11 +0000141
142
Guido van Rossum18468821994-06-20 07:49:28 +0000143/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000144static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000145AsString(value, tmp)
146 PyObject *value;
147 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000148{
Guido van Rossum35d43371997-08-02 00:09:09 +0000149 if (PyString_Check(value))
150 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000151 else {
152 PyObject *v = PyObject_Str(value);
153 PyList_Append(tmp, v);
154 Py_DECREF(v);
155 return PyString_AsString(v);
156 }
Guido van Rossum18468821994-06-20 07:49:28 +0000157}
158
Barry Warsawfa701a81997-01-16 00:15:11 +0000159
160
Guido van Rossum18468821994-06-20 07:49:28 +0000161#define ARGSZ 64
162
163static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000164Merge(args)
165 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000166{
Barry Warsawfa701a81997-01-16 00:15:11 +0000167 PyObject *tmp = NULL;
168 char *argvStore[ARGSZ];
169 char **argv = NULL;
170 int fvStore[ARGSZ];
171 int *fv = NULL;
172 int argc = 0, i;
173 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000174
Barry Warsawfa701a81997-01-16 00:15:11 +0000175 if (!(tmp = PyList_New(0)))
176 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000177
Barry Warsawfa701a81997-01-16 00:15:11 +0000178 argv = argvStore;
179 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000180
Barry Warsawfa701a81997-01-16 00:15:11 +0000181 if (args == NULL)
182 argc = 0;
183
184 else if (!PyTuple_Check(args)) {
185 argc = 1;
186 fv[0] = 0;
187 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000188 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000189 else {
190 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000191
Barry Warsawfa701a81997-01-16 00:15:11 +0000192 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000193 argv = (char **)ckalloc(argc * sizeof(char *));
194 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000195 if (argv == NULL || fv == NULL) {
196 PyErr_NoMemory();
197 goto finally;
198 }
199 }
200
201 for (i = 0; i < argc; i++) {
202 PyObject *v = PyTuple_GetItem(args, i);
203 if (PyTuple_Check(v)) {
204 fv[i] = 1;
205 if (!(argv[i] = Merge(v)))
206 goto finally;
207 }
208 else if (v == Py_None) {
209 argc = i;
210 break;
211 }
212 else {
213 fv[i] = 0;
214 argv[i] = AsString(v, tmp);
215 }
216 }
Guido van Rossum18468821994-06-20 07:49:28 +0000217 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000218 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000219
Barry Warsawfa701a81997-01-16 00:15:11 +0000220 finally:
221 for (i = 0; i < argc; i++)
222 if (fv[i]) {
223 ckfree(argv[i]);
224 }
225 if (argv != argvStore)
226 ckfree(FREECAST argv);
227 if (fv != fvStore)
228 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000229
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 Py_DECREF(tmp);
231 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000232}
233
Barry Warsawfa701a81997-01-16 00:15:11 +0000234
235
Guido van Rossum18468821994-06-20 07:49:28 +0000236static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000237Split(self, list)
238 PyObject *self;
239 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000240{
Barry Warsawfa701a81997-01-16 00:15:11 +0000241 int argc;
242 char **argv;
243 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000244
Barry Warsawfa701a81997-01-16 00:15:11 +0000245 if (list == NULL) {
246 Py_INCREF(Py_None);
247 return Py_None;
248 }
Guido van Rossum18468821994-06-20 07:49:28 +0000249
Barry Warsawfa701a81997-01-16 00:15:11 +0000250 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
251 {
252 /* Not a list.
253 * Could be a quoted string containing funnies, e.g. {"}.
254 * Return the string itself.
255 */
256 PyErr_Clear();
257 return PyString_FromString(list);
258 }
Guido van Rossum18468821994-06-20 07:49:28 +0000259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260 if (argc == 0)
261 v = PyString_FromString("");
262 else if (argc == 1)
263 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000264 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000265 int i;
266 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268 for (i = 0; i < argc; i++) {
269 if ((w = Split(self, argv[i])) == NULL) {
270 Py_DECREF(v);
271 v = NULL;
272 break;
273 }
274 PyTuple_SetItem(v, i, w);
275 }
276 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000277 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000278 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000279}
280
Barry Warsawfa701a81997-01-16 00:15:11 +0000281
282
Guido van Rossum18468821994-06-20 07:49:28 +0000283/**** Tkapp Object ****/
284
285#ifndef WITH_APPINIT
286int
Guido van Rossum35d43371997-08-02 00:09:09 +0000287Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000289{
Barry Warsawfa701a81997-01-16 00:15:11 +0000290 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292 main = Tk_MainWindow(interp);
293 if (Tcl_Init(interp) == TCL_ERROR) {
294 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
295 return TCL_ERROR;
296 }
297 if (Tk_Init(interp) == TCL_ERROR) {
298 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
299 return TCL_ERROR;
300 }
301 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000302}
303#endif /* !WITH_APPINIT */
304
Guido van Rossum18468821994-06-20 07:49:28 +0000305
Barry Warsawfa701a81997-01-16 00:15:11 +0000306
307
308/* Initialize the Tk application; see the `main' function in
309 * `tkMain.c'.
310 */
311static TkappObject *
312Tkapp_New(screenName, baseName, className, interactive)
313 char *screenName;
314 char *baseName;
315 char *className;
316 int interactive;
317{
318 TkappObject *v;
319 char *argv0;
320
321 v = PyObject_NEW(TkappObject, &Tkapp_Type);
322 if (v == NULL)
323 return NULL;
324
325 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000326
Barry Warsawfa701a81997-01-16 00:15:11 +0000327 if (screenName != NULL)
328 Tcl_SetVar2(v->interp, "env", "DISPLAY",
329 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (interactive)
332 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
333 else
334 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000335
Barry Warsawfa701a81997-01-16 00:15:11 +0000336 /* This is used to get the application class for Tk 4.1 and up */
337 argv0 = (char*)ckalloc(strlen(className) + 1);
338 if (!argv0) {
339 PyErr_NoMemory();
340 Py_DECREF(v);
341 return NULL;
342 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 strcpy(argv0, className);
345 if (isupper(argv0[0]))
346 argv0[0] = tolower(argv0[0]);
347 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
348 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000349
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (Tcl_AppInit(v->interp) != TCL_OK)
351 return (TkappObject *)Tkinter_Error(v);
352
353 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000354}
355
Barry Warsawfa701a81997-01-16 00:15:11 +0000356
357
Guido van Rossum18468821994-06-20 07:49:28 +0000358/** Tcl Eval **/
359
360static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000361Tkapp_Call(self, args)
362 PyObject *self;
363 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000364{
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 char *cmd = Merge(args);
366 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000367
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 if (!cmd)
369 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000370
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
372 res = Tkinter_Error(self);
373
374 else
375 res = PyString_FromString(Tkapp_Result(self));
376
377 if (cmd)
378 ckfree(cmd);
379
380 return res;
381}
382
383
384static PyObject *
385Tkapp_GlobalCall(self, args)
386 PyObject *self;
387 PyObject *args;
388{
389 char *cmd = Merge(args);
390 PyObject *res = NULL;
391
392
393 if (!cmd)
394 PyErr_SetString(Tkinter_TclError, "merge failed");
395
396 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
397 res = Tkinter_Error(self);
398 else
399 res = PyString_FromString(Tkapp_Result(self));
400
401 if (cmd)
402 ckfree(cmd);
403
404 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000405}
406
407static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000408Tkapp_Eval(self, args)
409 PyObject *self;
410 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000411{
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000413
Guido van Rossum35d43371997-08-02 00:09:09 +0000414 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 return NULL;
416
417 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
418 return Tkinter_Error(self);
419
420 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000421}
422
423static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000424Tkapp_GlobalEval(self, args)
425 PyObject *self;
426 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000427{
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Guido van Rossum35d43371997-08-02 00:09:09 +0000430 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000434 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000435
Barry Warsawfa701a81997-01-16 00:15:11 +0000436 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000437}
438
439static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000440Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000441 PyObject *self;
442 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000443{
Barry Warsawfa701a81997-01-16 00:15:11 +0000444 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000445
Guido van Rossum35d43371997-08-02 00:09:09 +0000446 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000447 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000450 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000451
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000453}
454
455static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000456Tkapp_Record(self, args)
457 PyObject *self;
458 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000459{
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000461
Guido van Rossum35d43371997-08-02 00:09:09 +0000462 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
466 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000467 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000470}
471
472static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000473Tkapp_AddErrorInfo(self, args)
474 PyObject *self;
475 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000476{
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Guido van Rossum35d43371997-08-02 00:09:09 +0000479 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 return NULL;
481 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000482
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 Py_INCREF(Py_None);
484 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Barry Warsawfa701a81997-01-16 00:15:11 +0000487
488
Guido van Rossum18468821994-06-20 07:49:28 +0000489/** Tcl Variable **/
490
491static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000492SetVar(self, args, flags)
493 PyObject *self;
494 PyObject *args;
495 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000496{
Barry Warsawfa701a81997-01-16 00:15:11 +0000497 char *name1, *name2, *ok;
498 PyObject *newValue;
499 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000500
Barry Warsawfa701a81997-01-16 00:15:11 +0000501 if (!tmp)
502 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000503
Guido van Rossum35d43371997-08-02 00:09:09 +0000504 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000506 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
507 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000510 PyErr_Clear();
511 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
512 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
513 AsString (newValue, tmp), flags);
514 else {
515 Py_DECREF (tmp);
516 return NULL;
517 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000518 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000519 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000520
Barry Warsawfa701a81997-01-16 00:15:11 +0000521 if (!ok)
522 return Tkinter_Error(self);
523
524 Py_INCREF(Py_None);
525 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000526}
527
528static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000529Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000530 PyObject *self;
531 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000532{
Barry Warsawfa701a81997-01-16 00:15:11 +0000533 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000534}
535
536static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000537Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000538 PyObject *self;
539 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000540{
Barry Warsawfa701a81997-01-16 00:15:11 +0000541 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000542}
543
Barry Warsawfa701a81997-01-16 00:15:11 +0000544
545
Guido van Rossum18468821994-06-20 07:49:28 +0000546static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000547GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000548 PyObject *self;
549 PyObject *args;
550 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000551{
Guido van Rossum35d43371997-08-02 00:09:09 +0000552 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000553
Guido van Rossum35d43371997-08-02 00:09:09 +0000554 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
555 return NULL;
556 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000557 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000560 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000561
Barry Warsawfa701a81997-01-16 00:15:11 +0000562 if (s == NULL)
563 return Tkinter_Error(self);
564
Guido van Rossum35d43371997-08-02 00:09:09 +0000565 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000566}
567
568static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000569Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 PyObject *self;
571 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000572{
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000574}
575
576static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000577Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 PyObject *self;
579 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000580{
Barry Warsawfa701a81997-01-16 00:15:11 +0000581 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000582}
583
Barry Warsawfa701a81997-01-16 00:15:11 +0000584
585
Guido van Rossum18468821994-06-20 07:49:28 +0000586static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000587UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 PyObject *self;
589 PyObject *args;
590 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000591{
Guido van Rossum35d43371997-08-02 00:09:09 +0000592 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Guido van Rossum35d43371997-08-02 00:09:09 +0000595 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000596 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000597 if (name2 == NULL)
598 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
599
600 else
601 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000602
Barry Warsawfa701a81997-01-16 00:15:11 +0000603 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000604 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000605
606 Py_INCREF(Py_None);
607 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000608}
609
610static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000611Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 PyObject *self;
613 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000614{
Barry Warsawfa701a81997-01-16 00:15:11 +0000615 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000616}
617
618static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000619Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000620 PyObject *self;
621 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000622{
Barry Warsawfa701a81997-01-16 00:15:11 +0000623 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000624}
625
Barry Warsawfa701a81997-01-16 00:15:11 +0000626
627
Guido van Rossum18468821994-06-20 07:49:28 +0000628/** Tcl to Python **/
629
630static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000631Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000632 PyObject *self;
633 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000634{
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 char *s;
636 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Guido van Rossum35d43371997-08-02 00:09:09 +0000638 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000640 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000641 return Tkinter_Error(self);
642 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000643}
644
645static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000646Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000647 PyObject *self;
648 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000649{
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 char *s;
651 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000652
Guido van Rossum35d43371997-08-02 00:09:09 +0000653 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000654 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000655 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000656 return Tkinter_Error(self);
657 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000658}
659
660static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000661Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000662 PyObject *self;
663 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000664{
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 char *s;
666 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000667
Guido van Rossum35d43371997-08-02 00:09:09 +0000668 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000670 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
671 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000673}
674
675static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000676Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000677 PyObject *self;
678 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000679{
Barry Warsawfa701a81997-01-16 00:15:11 +0000680 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000681
Guido van Rossum35d43371997-08-02 00:09:09 +0000682 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000683 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000684 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000685 return Tkinter_Error(self);
686 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000687}
688
689static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000690Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000691 PyObject *self;
692 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000693{
Barry Warsawfa701a81997-01-16 00:15:11 +0000694 char *s;
695 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696
Guido van Rossum35d43371997-08-02 00:09:09 +0000697 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 return NULL;
699 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
700 return Tkinter_Error(self);
701 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000702}
703
704static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000705Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000706 PyObject *self;
707 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000708{
Barry Warsawfa701a81997-01-16 00:15:11 +0000709 char *s;
710 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000711 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000712
Guido van Rossum35d43371997-08-02 00:09:09 +0000713 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000714 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000715 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000716 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000717 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000718 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 return Tkinter_Error(self);
720 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000721}
722
723static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000724Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000725 PyObject *self;
726 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000727{
Barry Warsawfa701a81997-01-16 00:15:11 +0000728 char *s;
729 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000730
Guido van Rossum35d43371997-08-02 00:09:09 +0000731 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000732 return NULL;
733 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
734 return Tkinter_Error(self);
735 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000736}
737
Barry Warsawfa701a81997-01-16 00:15:11 +0000738
739
Guido van Rossum18468821994-06-20 07:49:28 +0000740static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000741Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 PyObject *self;
743 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000744{
Barry Warsawfa701a81997-01-16 00:15:11 +0000745 char *list;
746 int argc;
747 char **argv;
748 PyObject *v;
749 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000750
Guido van Rossum35d43371997-08-02 00:09:09 +0000751 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000752 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000753
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
755 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000756
Barry Warsawfa701a81997-01-16 00:15:11 +0000757 if (!(v = PyTuple_New(argc)))
758 return NULL;
759
760 for (i = 0; i < argc; i++) {
761 PyObject *s = PyString_FromString(argv[i]);
762 if (!s || PyTuple_SetItem(v, i, s)) {
763 Py_DECREF(v);
764 v = NULL;
765 goto finally;
766 }
767 }
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 finally:
770 ckfree(FREECAST argv);
771 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000772}
773
774static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000775Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000776 PyObject *self;
777 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000778{
Barry Warsawfa701a81997-01-16 00:15:11 +0000779 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000780
Guido van Rossum35d43371997-08-02 00:09:09 +0000781 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000782 return NULL;
783 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000784}
785
786static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000787Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000788 PyObject *self;
789 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000790{
Barry Warsawfa701a81997-01-16 00:15:11 +0000791 char *s = Merge(args);
792 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000793
Barry Warsawfa701a81997-01-16 00:15:11 +0000794 if (s) {
795 res = PyString_FromString(s);
796 ckfree(s);
797 }
798 else
799 PyErr_SetString(Tkinter_TclError, "merge failed");
800
801 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000802}
803
Barry Warsawfa701a81997-01-16 00:15:11 +0000804
805
Guido van Rossum18468821994-06-20 07:49:28 +0000806/** Tcl Command **/
807
808/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000809 * function or method.
810 */
Guido van Rossum18468821994-06-20 07:49:28 +0000811static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000812PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000813 ClientData clientData; /* Is (self, func) */
814 Tcl_Interp *interp;
815 int argc;
816 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000817{
Barry Warsawfa701a81997-01-16 00:15:11 +0000818 PyObject *self, *func, *arg, *res, *tmp;
819 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000820
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 /* TBD: no error checking here since we know, via the
822 * Tkapp_CreateCommand() that the client data is a two-tuple
823 */
824 self = PyTuple_GetItem((PyObject *) clientData, 0);
825 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000826
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 /* Create argument list (argv1, ..., argvN) */
828 if (!(arg = PyTuple_New(argc - 1)))
829 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000830
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 for (i = 0; i < (argc - 1); i++) {
832 PyObject *s = PyString_FromString(argv[i + 1]);
833 if (!s || PyTuple_SetItem(arg, i, s)) {
834 Py_DECREF(arg);
835 PythonCmd_Error(interp);
836 }
837 }
838 res = PyEval_CallObject(func, arg);
839 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000840
Barry Warsawfa701a81997-01-16 00:15:11 +0000841 if (res == NULL)
842 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000843
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 if (!(tmp = PyList_New(0))) {
845 Py_DECREF(res);
846 return PythonCmd_Error(interp);
847 }
848
849 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
850 Py_DECREF(res);
851 Py_DECREF(tmp);
852
853 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000854}
855
856static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000857PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000859{
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000861}
862
Barry Warsawfa701a81997-01-16 00:15:11 +0000863
864
Guido van Rossum18468821994-06-20 07:49:28 +0000865static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000866Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000867 PyObject *self;
868 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000869{
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +0000871 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +0000872 PyObject *data;
873
874 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
875 return NULL;
876 if (!PyCallable_Check(func)) {
877 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 return NULL;
879 }
Guido van Rossum18468821994-06-20 07:49:28 +0000880
Guido van Rossum35d43371997-08-02 00:09:09 +0000881 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 if (!data)
883 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000884
Guido van Rossum35d43371997-08-02 00:09:09 +0000885 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
886 (ClientData) data, PythonCmdDelete) == NULL)
887 {
888 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
889 Py_DECREF(data);
890 return NULL;
891 }
Guido van Rossum18468821994-06-20 07:49:28 +0000892
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 Py_INCREF(Py_None);
894 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
Barry Warsawfa701a81997-01-16 00:15:11 +0000897
898
Guido van Rossum18468821994-06-20 07:49:28 +0000899static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000900Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000901 PyObject *self;
902 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000903{
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000905
Guido van Rossum35d43371997-08-02 00:09:09 +0000906 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 return NULL;
908 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
909 {
910 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
911 return NULL;
912 }
913 Py_INCREF(Py_None);
914 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000915}
916
Barry Warsawfa701a81997-01-16 00:15:11 +0000917
918
Guido van Rossum18468821994-06-20 07:49:28 +0000919/** File Handler **/
920
Guido van Rossuma597dde1995-01-10 20:56:29 +0000921static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000922FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 ClientData clientData; /* Is: (func, file) */
924 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000925{
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 func = PyTuple_GetItem((PyObject *) clientData, 0);
929 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000930
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 arg = Py_BuildValue("(Oi)", file, (long) mask);
932 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +0000934
935 if (res == NULL) {
936 errorInCmd = 1;
937 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
938 }
939 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000940}
941
942static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000943GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 /* Either an int >= 0 or an object with a
945 *.fileno() method that returns an int >= 0
946 */
947 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000948{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000949 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000950 int id;
951 if (PyInt_Check(file)) {
952 id = PyInt_AsLong(file);
953 if (id < 0)
954 PyErr_SetString(PyExc_ValueError, "invalid file id");
955 return id;
956 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000957 args = PyTuple_New(0);
958 if (args == NULL)
959 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000960
961 meth = PyObject_GetAttrString(file, "fileno");
962 if (meth == NULL) {
963 Py_DECREF(args);
964 return -1;
965 }
966
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000967 res = PyEval_CallObject(meth, args);
968 Py_DECREF(args);
969 Py_DECREF(meth);
970 if (res == NULL)
971 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000972
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973 if (PyInt_Check(res))
974 id = PyInt_AsLong(res);
975 else
976 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000977
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000978 if (id < 0)
979 PyErr_SetString(PyExc_ValueError,
980 "invalid fileno() return value");
981 Py_DECREF(res);
982 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000983}
984
Barry Warsawfa701a81997-01-16 00:15:11 +0000985
986static PyObject* Tkapp_ClientDataDict = NULL;
987
Guido van Rossum02c04671997-08-07 00:12:22 +0000988#ifndef WIN32
Guido van Rossum18468821994-06-20 07:49:28 +0000989static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000990Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000991 PyObject *self;
992 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000993{
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 PyObject *file, *func, *data;
995 PyObject *idkey;
996 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +0000997#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +0000998 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +0000999#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001000
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 if (!Tkapp_ClientDataDict) {
1002 if (!(Tkapp_ClientDataDict = PyDict_New()))
1003 return NULL;
1004 }
Guido van Rossum18468821994-06-20 07:49:28 +00001005
Guido van Rossum35d43371997-08-02 00:09:09 +00001006 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001007 return NULL;
1008 id = GetFileNo(file);
1009 if (id < 0)
1010 return NULL;
1011 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001012 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 return NULL;
1014 }
1015
1016 if (!(idkey = PyInt_FromLong(id)))
1017 return NULL;
1018
1019 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001020 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1022 Py_DECREF(idkey);
1023 Py_XDECREF(data);
1024 return NULL;
1025 }
1026 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001027
Guido van Rossum3e819a71997-08-01 19:29:02 +00001028#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001029#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001030 /* We assume this is a socket... */
1031 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001032#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001033 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001034#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001035 /* Ought to check for null Tcl_File object... */
1036 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001037#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001038 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001039#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001041 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001042 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001043}
1044
Barry Warsawfa701a81997-01-16 00:15:11 +00001045
Guido van Rossum18468821994-06-20 07:49:28 +00001046static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001047Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001048 PyObject *self;
1049 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001050{
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 PyObject *file;
1052 PyObject *idkey;
1053 PyObject *data;
1054 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001055#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001057#endif
1058
Guido van Rossum35d43371997-08-02 00:09:09 +00001059 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 return NULL;
1061 id = GetFileNo(file);
1062 if (id < 0)
1063 return NULL;
1064
1065 if (!(idkey = PyInt_FromLong(id)))
1066 return NULL;
1067
1068 /* find and free the object created in the
1069 * Tkapp_CreateFileHandler() call
1070 */
1071 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1072 Py_XDECREF(data);
1073 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1074 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001075
Guido van Rossum3e819a71997-08-01 19:29:02 +00001076#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001077#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 /* We assume this is a socket... */
1079 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001080#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001082#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001083 /* Ought to check for null Tcl_File object... */
1084 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001085#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001086 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001087#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001088 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001089 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001091}
Guido van Rossum02c04671997-08-07 00:12:22 +00001092#endif /* WIN32 */
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Barry Warsawfa701a81997-01-16 00:15:11 +00001094
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001095/**** Tktt Object (timer token) ****/
1096
1097staticforward PyTypeObject Tktt_Type;
1098
1099typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001100{
1101 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001102 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001103 PyObject *func;
1104}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001105TkttObject;
1106
1107static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001108Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001109 PyObject *self;
1110 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001111{
Barry Warsawfa701a81997-01-16 00:15:11 +00001112 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001113
Guido van Rossum35d43371997-08-02 00:09:09 +00001114 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 return NULL;
1116 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001117 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001118 PyMem_DEL(v->func);
1119 v->func = NULL;
1120 }
1121 Py_INCREF(Py_None);
1122 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001123}
1124
1125static PyMethodDef Tktt_methods[] =
1126{
Guido van Rossum35d43371997-08-02 00:09:09 +00001127 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001129};
1130
1131static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001132Tktt_New(token, func)
1133 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001135{
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001137
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 v = PyObject_NEW(TkttObject, &Tktt_Type);
1139 if (v == NULL)
1140 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001141
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 v->token = token;
1143 v->func = func;
1144 Py_INCREF(v->func);
1145 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001146}
1147
1148static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001149Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001151{
Guido van Rossum35d43371997-08-02 00:09:09 +00001152 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001153}
1154
1155static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001156Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001157 PyObject *self;
1158 FILE *fp;
1159 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001160{
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001162
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1164 v->func == NULL ? ", handler deleted" : "");
1165 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001166}
1167
1168static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001169Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001170 PyObject *self;
1171 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001172{
Barry Warsawfa701a81997-01-16 00:15:11 +00001173 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001174}
1175
1176static PyTypeObject Tktt_Type =
1177{
Guido van Rossum35d43371997-08-02 00:09:09 +00001178 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001179 0, /*ob_size */
1180 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001181 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 0, /*tp_itemsize */
1183 Tktt_Dealloc, /*tp_dealloc */
1184 Tktt_Print, /*tp_print */
1185 Tktt_GetAttr, /*tp_getattr */
1186 0, /*tp_setattr */
1187 0, /*tp_compare */
1188 0, /*tp_repr */
1189 0, /*tp_as_number */
1190 0, /*tp_as_sequence */
1191 0, /*tp_as_mapping */
1192 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001193};
1194
Barry Warsawfa701a81997-01-16 00:15:11 +00001195
1196
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001197/** Timer Handler **/
1198
1199static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001200TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001202{
Barry Warsawfa701a81997-01-16 00:15:11 +00001203 PyObject *func = (PyObject *)clientData;
1204 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001205
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 if (res == NULL) {
1207 errorInCmd = 1;
1208 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1209 }
1210 else
1211 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001212}
1213
1214static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001215Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 PyObject *self;
1217 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001218{
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 int milliseconds;
1220 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001221 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001222
Guido van Rossum35d43371997-08-02 00:09:09 +00001223 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 return NULL;
1225 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001226 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001227 return NULL;
1228 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001229 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1230 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001231
1232 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001233}
1234
Barry Warsawfa701a81997-01-16 00:15:11 +00001235
1236
Guido van Rossum18468821994-06-20 07:49:28 +00001237/** Event Loop **/
1238
Guido van Rossum18468821994-06-20 07:49:28 +00001239static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001240Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001241 PyObject *self;
1242 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001243{
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001245
Barry Warsawfa701a81997-01-16 00:15:11 +00001246 if (!PyArg_ParseTuple(args, "|i", &threshold))
1247 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001248
Barry Warsawfa701a81997-01-16 00:15:11 +00001249 quitMainLoop = 0;
1250 while (Tk_GetNumMainWindows() > threshold &&
1251 !quitMainLoop &&
1252 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001253 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001254 int result;
1255 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1256 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001258 if (result)
1259 continue;
1260 /* XXX It's not *quite* certain that this is
1261 thread-safe, but it seems *rather* safe as long as
1262 no two threads call mainloop() simultaneously. */
1263 Py_BEGIN_ALLOW_THREADS
1264 result = Tcl_WaitForEvent((Tcl_Time *)NULL);
1265 Py_END_ALLOW_THREADS
1266 if (PyErr_CheckSignals() != 0)
1267 return NULL;
1268 if (result < 0)
1269 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001270 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001272
Barry Warsawfa701a81997-01-16 00:15:11 +00001273 if (errorInCmd) {
1274 errorInCmd = 0;
1275 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1276 excInCmd = valInCmd = trbInCmd = NULL;
1277 return NULL;
1278 }
1279 Py_INCREF(Py_None);
1280 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001281}
1282
1283static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001284Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 PyObject *self;
1286 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001287{
Guido van Rossum35d43371997-08-02 00:09:09 +00001288 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001289 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001290
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 if (!PyArg_ParseTuple(args, "|i", &flags))
1292 return NULL;
1293
Guido van Rossum35d43371997-08-02 00:09:09 +00001294 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001296}
1297
1298static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001299Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 PyObject *self;
1301 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001302{
1303
Guido van Rossum35d43371997-08-02 00:09:09 +00001304 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001305 return NULL;
1306
1307 quitMainLoop = 1;
1308 Py_INCREF(Py_None);
1309 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001310}
1311
Barry Warsawfa701a81997-01-16 00:15:11 +00001312
1313
Guido van Rossum18468821994-06-20 07:49:28 +00001314/**** Tkapp Method List ****/
1315
1316static PyMethodDef Tkapp_methods[] =
1317{
Guido van Rossum35d43371997-08-02 00:09:09 +00001318 {"call", Tkapp_Call, 0},
1319 {"globalcall", Tkapp_GlobalCall, 0},
1320 {"eval", Tkapp_Eval, 1},
1321 {"globaleval", Tkapp_GlobalEval, 1},
1322 {"evalfile", Tkapp_EvalFile, 1},
1323 {"record", Tkapp_Record, 1},
1324 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1325 {"setvar", Tkapp_SetVar, 1},
1326 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1327 {"getvar", Tkapp_GetVar, 1},
1328 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1329 {"unsetvar", Tkapp_UnsetVar, 1},
1330 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1331 {"getint", Tkapp_GetInt, 1},
1332 {"getdouble", Tkapp_GetDouble, 1},
1333 {"getboolean", Tkapp_GetBoolean, 1},
1334 {"exprstring", Tkapp_ExprString, 1},
1335 {"exprlong", Tkapp_ExprLong, 1},
1336 {"exprdouble", Tkapp_ExprDouble, 1},
1337 {"exprboolean", Tkapp_ExprBoolean, 1},
1338 {"splitlist", Tkapp_SplitList, 1},
1339 {"split", Tkapp_Split, 1},
1340 {"merge", Tkapp_Merge, 0},
1341 {"createcommand", Tkapp_CreateCommand, 1},
1342 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001343#ifndef WIN32
Guido van Rossum35d43371997-08-02 00:09:09 +00001344 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1345 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001346#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001347 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001348 {"mainloop", Tkapp_MainLoop, 1},
1349 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001350 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001352};
1353
Barry Warsawfa701a81997-01-16 00:15:11 +00001354
1355
Guido van Rossum18468821994-06-20 07:49:28 +00001356/**** Tkapp Type Methods ****/
1357
1358static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001359Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001360 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001361{
Guido van Rossum35d43371997-08-02 00:09:09 +00001362 Tcl_DeleteInterp(Tkapp_Interp(self));
1363 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001364}
1365
1366static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001367Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 PyObject *self;
1369 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001370{
Guido van Rossum35d43371997-08-02 00:09:09 +00001371 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001372}
1373
1374static PyTypeObject Tkapp_Type =
1375{
Guido van Rossum35d43371997-08-02 00:09:09 +00001376 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001377 0, /*ob_size */
1378 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001379 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 0, /*tp_itemsize */
1381 Tkapp_Dealloc, /*tp_dealloc */
1382 0, /*tp_print */
1383 Tkapp_GetAttr, /*tp_getattr */
1384 0, /*tp_setattr */
1385 0, /*tp_compare */
1386 0, /*tp_repr */
1387 0, /*tp_as_number */
1388 0, /*tp_as_sequence */
1389 0, /*tp_as_mapping */
1390 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001391};
1392
Barry Warsawfa701a81997-01-16 00:15:11 +00001393
1394
Guido van Rossum18468821994-06-20 07:49:28 +00001395/**** Tkinter Module ****/
1396
1397static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001398Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001399 PyObject *self;
1400 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001401{
Barry Warsawfa701a81997-01-16 00:15:11 +00001402 char *screenName = NULL;
1403 char *baseName = NULL;
1404 char *className = NULL;
1405 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001406
Guido van Rossum35d43371997-08-02 00:09:09 +00001407 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 if (baseName != NULL)
1409 baseName++;
1410 else
1411 baseName = Py_GetProgramName();
1412 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001413
Barry Warsawfa701a81997-01-16 00:15:11 +00001414 if (!PyArg_ParseTuple(args, "|zssi",
1415 &screenName, &baseName, &className,
1416 &interactive))
1417 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001418
Barry Warsawfa701a81997-01-16 00:15:11 +00001419 return (PyObject *) Tkapp_New(screenName, baseName, className,
1420 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001421}
1422
1423static PyMethodDef moduleMethods[] =
1424{
Barry Warsawfa701a81997-01-16 00:15:11 +00001425 {"create", Tkinter_Create, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001426#ifndef WIN32
Guido van Rossum35d43371997-08-02 00:09:09 +00001427 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1428 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001429#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001430 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001431 {"mainloop", Tkapp_MainLoop, 1},
1432 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001433 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001435};
1436
Guido van Rossum18468821994-06-20 07:49:28 +00001437static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001438EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001439{
Barry Warsawfa701a81997-01-16 00:15:11 +00001440 if (errorInCmd) {
1441 errorInCmd = 0;
1442 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1443 excInCmd = valInCmd = trbInCmd = NULL;
1444 PyErr_Print();
1445 }
1446 if (Tk_GetNumMainWindows() > 0)
Guido van Rossum35d43371997-08-02 00:09:09 +00001447 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001449}
Guido van Rossum18468821994-06-20 07:49:28 +00001450
Barry Warsawfa701a81997-01-16 00:15:11 +00001451
1452/* all errors will be checked in one fell swoop in init_tkinter() */
1453static void
1454ins_long(d, name, val)
1455 PyObject *d;
1456 char *name;
1457 long val;
1458{
1459 PyObject *v = PyInt_FromLong(val);
1460 if (v) {
1461 PyDict_SetItemString(d, name, v);
1462 Py_DECREF(v);
1463 }
1464}
1465static void
1466ins_string(d, name, val)
1467 PyObject *d;
1468 char *name;
1469 char *val;
1470{
1471 PyObject *v = PyString_FromString(val);
1472 if (v) {
1473 PyDict_SetItemString(d, name, v);
1474 Py_DECREF(v);
1475 }
1476}
1477
1478
Guido van Rossum18468821994-06-20 07:49:28 +00001479void
Guido van Rossum35d43371997-08-02 00:09:09 +00001480init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001481{
Guido van Rossum02c04671997-08-07 00:12:22 +00001482#ifndef WIN32
Guido van Rossum0969d361997-08-05 21:27:50 +00001483 extern int (*Py_input_hook) ();
Guido van Rossum02c04671997-08-07 00:12:22 +00001484#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001486
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 Tkapp_Type.ob_type = &PyType_Type;
1488 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001489
Barry Warsawfa701a81997-01-16 00:15:11 +00001490 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001491
Barry Warsawfa701a81997-01-16 00:15:11 +00001492 d = PyModule_GetDict(m);
1493 Tkinter_TclError = Py_BuildValue("s", "TclError");
1494 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001495
Guido van Rossum35d43371997-08-02 00:09:09 +00001496 ins_long(d, "READABLE", TCL_READABLE);
1497 ins_long(d, "WRITABLE", TCL_WRITABLE);
1498 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1499 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1500 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1501 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1502 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1503 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1504 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 ins_string(d, "TK_VERSION", TK_VERSION);
1506 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001507
Guido van Rossum02c04671997-08-07 00:12:22 +00001508#ifndef WIN32
Guido van Rossum0969d361997-08-05 21:27:50 +00001509 if (Py_input_hook == NULL)
1510 Py_input_hook = EventHook;
Guido van Rossum02c04671997-08-07 00:12:22 +00001511#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001512
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 if (PyErr_Occurred())
Guido van Rossum35d43371997-08-02 00:09:09 +00001514 Py_FatalError("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001515#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001516 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001517#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001519#endif /* GENERATINGCFM */
1520#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001521}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001522
Guido van Rossumec22c921996-02-25 04:50:29 +00001523
Barry Warsawfa701a81997-01-16 00:15:11 +00001524
Guido van Rossum9722ad81995-09-22 23:49:28 +00001525#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001526
1527/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001528** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001529*/
1530
Guido van Rossum9722ad81995-09-22 23:49:28 +00001531void
1532panic(char * format, ...)
1533{
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001535
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001537
Barry Warsawfa701a81997-01-16 00:15:11 +00001538 vfprintf(stderr, format, varg);
1539 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001540
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001542
Barry Warsawfa701a81997-01-16 00:15:11 +00001543 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001544}
Jack Jansen40b546d1995-11-14 10:34:45 +00001545
Guido van Rossumec22c921996-02-25 04:50:29 +00001546/*
1547** Pass events to SIOUX before passing them to Tk.
1548*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001549
Guido van Rossumec22c921996-02-25 04:50:29 +00001550static int
1551PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001553{
Barry Warsawfa701a81997-01-16 00:15:11 +00001554 if (SIOUXHandleOneEvent(eventPtr))
1555 return 0; /* Nothing happened to the Tcl event queue */
1556 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001557}
1558
Guido van Rossum290283b1997-06-02 22:16:43 +00001559#ifdef USE_GUSI
1560/*
1561 * For Python we have to override this routine (from TclMacNotify),
1562 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1563 * to use GUSI select to see whether our socket is ready. Note that
1564 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1565 * files and sockets.
1566 *
1567 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1568 * for other versions. */
1569
1570int
1571Tcl_FileReady(file, mask)
1572 Tcl_File file; /* File handle for a stream. */
1573 int mask; /* OR'ed combination of TCL_READABLE,
1574 * TCL_WRITABLE, and TCL_EXCEPTION:
1575 * indicates conditions caller cares about. */
1576{
1577 int type;
1578 int fd;
1579
1580 fd = (int) Tcl_GetFileInfo(file, &type);
1581
1582 if (type == TCL_MAC_SOCKET) {
1583 return TclMacSocketReady(file, mask);
1584 } else if (type == TCL_MAC_FILE) {
1585 /*
1586 * Under the Macintosh, files are always ready, so we just
1587 * return the mask that was passed in.
1588 */
1589
1590 return mask;
1591 } else if (type == TCL_UNIX_FD) {
1592 fd_set readset, writeset, excset;
1593 struct timeval tv;
1594
1595 FD_ZERO(&readset);
1596 FD_ZERO(&writeset);
1597 FD_ZERO(&excset);
1598
1599 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1600 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1601 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1602
1603 tv.tv_sec = tv.tv_usec = 0;
1604 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1605 return 0;
1606
1607 mask = 0;
1608 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1609 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1610 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1611
1612 return mask;
1613 }
1614
1615 return 0;
1616}
1617#endif /* USE_GUSI */
1618
Guido van Rossumec22c921996-02-25 04:50:29 +00001619#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001620
1621/*
1622** Additional Mac specific code for dealing with shared libraries.
1623*/
1624
1625#include <Resources.h>
1626#include <CodeFragments.h>
1627
1628static int loaded_from_shlib = 0;
1629static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001630
Jack Jansen34cc5c31995-10-31 16:15:12 +00001631/*
1632** If this module is dynamically loaded the following routine should
1633** be the init routine. It takes care of adding the shared library to
1634** the resource-file chain, so that the tk routines can find their
1635** resources.
1636*/
1637OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001638init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001639{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001640 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001641 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001642 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001643 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1644 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001645 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001646 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1647 loaded_from_shlib = 1;
1648 }
1649 return noErr;
1650}
1651
1652/*
1653** Insert the library resources into the search path. Put them after
1654** the resources from the application. Again, we ignore errors.
1655*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001656static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001657mac_addlibresources()
1658{
1659 if ( !loaded_from_shlib )
1660 return;
1661 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1662}
1663
Guido van Rossumec22c921996-02-25 04:50:29 +00001664#endif /* GENERATINGCFM */
1665#endif /* macintosh */