blob: d2bbff743e18f60686ff8ceab74c7e9a1858f01b [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 Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossum00d93061998-05-28 23:06:38 +000061#ifdef WITH_THREAD
62#include "thread.h"
63#endif
64
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000065#ifdef macintosh
66#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000067#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000068#endif
69
Guido van Rossum18468821994-06-20 07:49:28 +000070#include <tcl.h>
71#include <tk.h>
72
Guido van Rossum3e819a71997-08-01 19:29:02 +000073#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
74
Guido van Rossum00d93061998-05-28 23:06:38 +000075#if TKMAJORMINOR < 4001
76 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
77#endif
78
Guido van Rossum0d2390c1997-08-14 19:57:07 +000079#if TKMAJORMINOR >= 8000 && defined(macintosh)
80/* Sigh, we have to include this to get at the tcl qd pointer */
81#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000082/* And this one we need to clear the menu bar */
83#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084#endif
85
Guido van Rossumb0105441997-10-08 15:25:37 +000086#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000087#define HAVE_CREATEFILEHANDLER
88#endif
89
Guido van Rossum00d93061998-05-28 23:06:38 +000090#ifdef HAVE_CREATEFILEHANDLER
91
92/* Tcl_CreateFileHandler() changed several times; these macros deal with the
93 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
94 Unix, only because Jack added it back); when available on Windows, it only
95 applies to sockets. */
96
Guido van Rossum7bf15641998-05-22 18:28:17 +000097#ifdef MS_WINDOWS
98#define FHANDLETYPE TCL_WIN_SOCKET
99#else
100#define FHANDLETYPE TCL_UNIX_FD
101#endif
102
103#if TKMAJORMINOR < 8000
104#define FHANDLE Tcl_File
105#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
106#else
107#define FHANDLE int
108#define MAKEFHANDLE(fd) (fd)
109#endif
110
Guido van Rossum00d93061998-05-28 23:06:38 +0000111/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
112 which uses this to handle Tcl events while the user is typing commands. */
113
114#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000115#define WAIT_FOR_STDIN
116#endif
117
Guido van Rossum00d93061998-05-28 23:06:38 +0000118#endif /* HAVE_CREATEFILEHANDLER */
119
120#ifdef WITH_THREAD
121
122/* The threading situation is complicated. Tcl is not thread-safe, except for
123 Tcl 8.1, which will probably remain in alpha status for another 6 months
124 (and the README says that Tk will probably remain thread-unsafe forever).
125 So we need to use a lock around all uses of Tcl. Previously, the Python
126 interpreter lock was used for this. However, this causes problems when
127 other Python threads need to run while Tcl is blocked waiting for events.
128
129 To solve this problem, a separate lock for Tcl is introduced. Holding it
130 is incompatible with holding Python's interpreter lock. The following four
131 macros manipulate both locks together.
132
133 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
134 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
135 that could call an event handler, or otherwise affect the state of a Tcl
136 interpreter. These assume that the surrounding code has the Python
137 interpreter lock; inside the brackets, the Python interpreter lock has been
138 released and the lock for Tcl has been acquired.
139
140 By contrast, ENTER_PYTHON(tstate) and LEAVE_PYTHON are used in Tcl event
141 handlers when the handler needs to use Python. Such event handlers are
142 entered while the lock for Tcl is held; the event handler presumably needs
143 to use Python. ENTER_PYTHON(tstate) releases the lock for Tcl and acquires
144 the Python interpreter lock, restoring the appropriate thread state, and
145 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
146 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
147 the code between ENTER_PYTHON(tstate) and LEAVE_PYTHON.
148
149 These locks expand to several statements and brackets; they should not be
150 used in branches of if statements and the like.
151
152*/
153
154static type_lock tcl_lock = 0;
155
156#define ENTER_TCL \
157 Py_BEGIN_ALLOW_THREADS acquire_lock(tcl_lock, 1);
158
159#define LEAVE_TCL \
160 release_lock(tcl_lock); Py_END_ALLOW_THREADS
161
162#define ENTER_PYTHON(tstate) \
163 if (PyThreadState_Swap(NULL) != NULL) \
164 Py_FatalError("ENTER_PYTHON with non-NULL tstate\n"); \
165 release_lock(tcl_lock); PyEval_RestoreThread((tstate));
166
167#define LEAVE_PYTHON \
168 PyEval_SaveThread(); acquire_lock(tcl_lock, 1);
169
170#else
171
172#define ENTER_TCL
173#define LEAVE_TCL
174#define ENTER_PYTHON(tstate)
175#define LEAVE_PYTHON
176
177#endif
178
Guido van Rossum35d43371997-08-02 00:09:09 +0000179extern int Tk_GetNumMainWindows();
180
Guido van Rossumec22c921996-02-25 04:50:29 +0000181#ifdef macintosh
182
183/*
184** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000185** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000186*/
187
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000188/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000189#define FREECAST (char *)
190
Guido van Rossumec22c921996-02-25 04:50:29 +0000191#include <Events.h> /* For EventRecord */
192
193typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000194/* They changed the name... */
195#if TKMAJORMINOR < 8000
196#define Tcl_MacSetEventProc TclMacSetEventProc
197#endif
198void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000199int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
200
201staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
202
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000203#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
204 #pragma import on
205#endif
206
207#include <SIOUX.h>
208extern int SIOUXIsAppWindow(WindowPtr);
209
210#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
211 #pragma import reset
212#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000213#endif /* macintosh */
214
Guido van Rossum97867b21996-08-08 19:09:53 +0000215#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000216#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000217#endif
218
Guido van Rossum18468821994-06-20 07:49:28 +0000219/**** Tkapp Object Declaration ****/
220
221staticforward PyTypeObject Tkapp_Type;
222
Guido van Rossum00d93061998-05-28 23:06:38 +0000223typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000224 PyObject_HEAD
225 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000226} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000227
228#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000229#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
230#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
231
Guido van Rossum35d43371997-08-02 00:09:09 +0000232#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000233(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000234
Barry Warsawfa701a81997-01-16 00:15:11 +0000235
236
Guido van Rossum18468821994-06-20 07:49:28 +0000237/**** Error Handling ****/
238
239static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000240static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000241static int errorInCmd = 0;
242static PyObject *excInCmd;
243static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000245
Barry Warsawfa701a81997-01-16 00:15:11 +0000246
247
Guido van Rossum18468821994-06-20 07:49:28 +0000248static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000249Tkinter_Error(v)
250 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000251{
Barry Warsawfa701a81997-01-16 00:15:11 +0000252 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
253 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000254}
255
Barry Warsawfa701a81997-01-16 00:15:11 +0000256
Barry Warsawfa701a81997-01-16 00:15:11 +0000257
Guido van Rossum18468821994-06-20 07:49:28 +0000258/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000259
260#ifdef WITH_THREAD
261#ifndef MS_WIN32
262/* Millisecond sleep() for Unix platforms. */
263
264static void
265Sleep(milli)
266 int milli;
267{
268 /* XXX Too bad if you don't have select(). */
269 struct timeval t;
270 double frac;
271 t.tv_sec = milli/1000;
272 t.tv_usec = (milli%1000) * 1000;
273 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
274}
275#endif /* MS_WIN32 */
276#endif /* WITH_THREAD */
277
278
Guido van Rossum18468821994-06-20 07:49:28 +0000279static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000280AsString(value, tmp)
281 PyObject *value;
282 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000283{
Guido van Rossum35d43371997-08-02 00:09:09 +0000284 if (PyString_Check(value))
285 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000286 else {
287 PyObject *v = PyObject_Str(value);
288 PyList_Append(tmp, v);
289 Py_DECREF(v);
290 return PyString_AsString(v);
291 }
Guido van Rossum18468821994-06-20 07:49:28 +0000292}
293
Barry Warsawfa701a81997-01-16 00:15:11 +0000294
295
Guido van Rossum18468821994-06-20 07:49:28 +0000296#define ARGSZ 64
297
298static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000299Merge(args)
300 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000301{
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 PyObject *tmp = NULL;
303 char *argvStore[ARGSZ];
304 char **argv = NULL;
305 int fvStore[ARGSZ];
306 int *fv = NULL;
307 int argc = 0, i;
308 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000309
Barry Warsawfa701a81997-01-16 00:15:11 +0000310 if (!(tmp = PyList_New(0)))
311 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000312
Barry Warsawfa701a81997-01-16 00:15:11 +0000313 argv = argvStore;
314 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000315
Barry Warsawfa701a81997-01-16 00:15:11 +0000316 if (args == NULL)
317 argc = 0;
318
319 else if (!PyTuple_Check(args)) {
320 argc = 1;
321 fv[0] = 0;
322 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000323 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 else {
325 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000326
Barry Warsawfa701a81997-01-16 00:15:11 +0000327 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000328 argv = (char **)ckalloc(argc * sizeof(char *));
329 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000330 if (argv == NULL || fv == NULL) {
331 PyErr_NoMemory();
332 goto finally;
333 }
334 }
335
336 for (i = 0; i < argc; i++) {
337 PyObject *v = PyTuple_GetItem(args, i);
338 if (PyTuple_Check(v)) {
339 fv[i] = 1;
340 if (!(argv[i] = Merge(v)))
341 goto finally;
342 }
343 else if (v == Py_None) {
344 argc = i;
345 break;
346 }
347 else {
348 fv[i] = 0;
349 argv[i] = AsString(v, tmp);
350 }
351 }
Guido van Rossum18468821994-06-20 07:49:28 +0000352 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000353 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 finally:
356 for (i = 0; i < argc; i++)
357 if (fv[i]) {
358 ckfree(argv[i]);
359 }
360 if (argv != argvStore)
361 ckfree(FREECAST argv);
362 if (fv != fvStore)
363 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000364
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 Py_DECREF(tmp);
366 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000372Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000374{
Barry Warsawfa701a81997-01-16 00:15:11 +0000375 int argc;
376 char **argv;
377 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (list == NULL) {
380 Py_INCREF(Py_None);
381 return Py_None;
382 }
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Guido van Rossum00d93061998-05-28 23:06:38 +0000384 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 /* Not a list.
386 * Could be a quoted string containing funnies, e.g. {"}.
387 * Return the string itself.
388 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 return PyString_FromString(list);
390 }
Guido van Rossum18468821994-06-20 07:49:28 +0000391
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 if (argc == 0)
393 v = PyString_FromString("");
394 else if (argc == 1)
395 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000396 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 int i;
398 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000401 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 Py_DECREF(v);
403 v = NULL;
404 break;
405 }
406 PyTuple_SetItem(v, i, w);
407 }
408 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000409 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000410 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000411}
412
Barry Warsawfa701a81997-01-16 00:15:11 +0000413
414
Guido van Rossum18468821994-06-20 07:49:28 +0000415/**** Tkapp Object ****/
416
417#ifndef WITH_APPINIT
418int
Guido van Rossum35d43371997-08-02 00:09:09 +0000419Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000421{
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000423
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 main = Tk_MainWindow(interp);
425 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000426 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000427 return TCL_ERROR;
428 }
429 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000430 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 return TCL_ERROR;
432 }
433 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000434}
435#endif /* !WITH_APPINIT */
436
Guido van Rossum18468821994-06-20 07:49:28 +0000437
Barry Warsawfa701a81997-01-16 00:15:11 +0000438
439
440/* Initialize the Tk application; see the `main' function in
441 * `tkMain.c'.
442 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000443
444static void EnableEventHook(); /* Forward */
445static void DisableEventHook(); /* Forward */
446
Barry Warsawfa701a81997-01-16 00:15:11 +0000447static TkappObject *
448Tkapp_New(screenName, baseName, className, interactive)
449 char *screenName;
450 char *baseName;
451 char *className;
452 int interactive;
453{
454 TkappObject *v;
455 char *argv0;
456
457 v = PyObject_NEW(TkappObject, &Tkapp_Type);
458 if (v == NULL)
459 return NULL;
460
461 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000462
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000463#if defined(macintosh) && TKMAJORMINOR >= 8000
464 /* This seems to be needed since Tk 8.0 */
465 ClearMenuBar();
466 TkMacInitMenus(v->interp);
467#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000468 /* Delete the 'exit' command, which can screw things up */
469 Tcl_DeleteCommand(v->interp, "exit");
470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 if (screenName != NULL)
472 Tcl_SetVar2(v->interp, "env", "DISPLAY",
473 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000474
Barry Warsawfa701a81997-01-16 00:15:11 +0000475 if (interactive)
476 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
477 else
478 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000479
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 /* This is used to get the application class for Tk 4.1 and up */
481 argv0 = (char*)ckalloc(strlen(className) + 1);
482 if (!argv0) {
483 PyErr_NoMemory();
484 Py_DECREF(v);
485 return NULL;
486 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000489 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 argv0[0] = tolower(argv0[0]);
491 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
492 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000493
Barry Warsawfa701a81997-01-16 00:15:11 +0000494 if (Tcl_AppInit(v->interp) != TCL_OK)
495 return (TkappObject *)Tkinter_Error(v);
496
Guido van Rossum7bf15641998-05-22 18:28:17 +0000497 EnableEventHook();
498
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000500}
501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502
503
Guido van Rossum18468821994-06-20 07:49:28 +0000504/** Tcl Eval **/
505
506static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000507Tkapp_Call(self, args)
508 PyObject *self;
509 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000510{
Guido van Rossum212643f1998-04-29 16:22:14 +0000511 /* This is copied from Merge() */
512 PyObject *tmp = NULL;
513 char *argvStore[ARGSZ];
514 char **argv = NULL;
515 int fvStore[ARGSZ];
516 int *fv = NULL;
517 int argc = 0, i;
518 PyObject *res = NULL; /* except this has a different type */
519 Tcl_CmdInfo info; /* and this is added */
520 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000521
Guido van Rossum212643f1998-04-29 16:22:14 +0000522 if (!(tmp = PyList_New(0)))
523 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000524
Guido van Rossum212643f1998-04-29 16:22:14 +0000525 argv = argvStore;
526 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000527
Guido van Rossum212643f1998-04-29 16:22:14 +0000528 if (args == NULL)
529 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000530
Guido van Rossum212643f1998-04-29 16:22:14 +0000531 else if (!PyTuple_Check(args)) {
532 argc = 1;
533 fv[0] = 0;
534 argv[0] = AsString(args, tmp);
535 }
536 else {
537 argc = PyTuple_Size(args);
538
539 if (argc > ARGSZ) {
540 argv = (char **)ckalloc(argc * sizeof(char *));
541 fv = (int *)ckalloc(argc * sizeof(int));
542 if (argv == NULL || fv == NULL) {
543 PyErr_NoMemory();
544 goto finally;
545 }
546 }
547
548 for (i = 0; i < argc; i++) {
549 PyObject *v = PyTuple_GetItem(args, i);
550 if (PyTuple_Check(v)) {
551 fv[i] = 1;
552 if (!(argv[i] = Merge(v)))
553 goto finally;
554 }
555 else if (v == Py_None) {
556 argc = i;
557 break;
558 }
559 else {
560 fv[i] = 0;
561 argv[i] = AsString(v, tmp);
562 }
563 }
564 }
565 /* End code copied from Merge() */
566
567 /* All this to avoid a call to Tcl_Merge() and the corresponding call
568 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
569 if (Py_VerboseFlag >= 2) {
570 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000571 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000572 }
573 if (argc < 1 ||
574 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
575 info.proc == NULL)
576 {
577 char *cmd;
578 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000579 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000580 cmd = Tcl_Merge(argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000581 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000582 i = Tcl_Eval(interp, cmd);
Guido van Rossum00d93061998-05-28 23:06:38 +0000583 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000584 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000585 }
586 else {
587 Tcl_ResetResult(interp);
Guido van Rossum00d93061998-05-28 23:06:38 +0000588 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000589 i = (*info.proc)(info.clientData, interp, argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000590 LEAVE_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000591 }
592 if (i == TCL_ERROR) {
593 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000594 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000595 interp->result);
596 Tkinter_Error(self);
597 }
598 else {
599 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000600 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000601 res = PyString_FromString(interp->result);
602 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000603
Guido van Rossum212643f1998-04-29 16:22:14 +0000604 /* Copied from Merge() again */
605 finally:
606 for (i = 0; i < argc; i++)
607 if (fv[i]) {
608 ckfree(argv[i]);
609 }
610 if (argv != argvStore)
611 ckfree(FREECAST argv);
612 if (fv != fvStore)
613 ckfree(FREECAST fv);
614
615 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000616 return res;
617}
618
619
620static PyObject *
621Tkapp_GlobalCall(self, args)
622 PyObject *self;
623 PyObject *args;
624{
Guido van Rossum212643f1998-04-29 16:22:14 +0000625 /* Could do the same here as for Tkapp_Call(), but this is not used
626 much, so I can't be bothered. Unfortunately Tcl doesn't export a
627 way for the user to do what all its Global* variants do (save and
628 reset the scope pointer, call the local version, restore the saved
629 scope pointer). */
630
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 char *cmd = Merge(args);
632 PyObject *res = NULL;
633
634
635 if (!cmd)
636 PyErr_SetString(Tkinter_TclError, "merge failed");
637
Guido van Rossum00d93061998-05-28 23:06:38 +0000638 else {
639 int err;
640 ENTER_TCL
641 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
642 LEAVE_TCL
643 if (err == TCL_ERROR)
644 res = Tkinter_Error(self);
645 else
646 res = PyString_FromString(Tkapp_Result(self));
647 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000648
649 if (cmd)
650 ckfree(cmd);
651
652 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000653}
654
655static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000656Tkapp_Eval(self, args)
657 PyObject *self;
658 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000659{
Barry Warsawfa701a81997-01-16 00:15:11 +0000660 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000661 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000662
Guido van Rossum35d43371997-08-02 00:09:09 +0000663 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000664 return NULL;
665
Guido van Rossum00d93061998-05-28 23:06:38 +0000666 ENTER_TCL
667 err = Tcl_Eval(Tkapp_Interp(self), script);
668 LEAVE_TCL
669 if (err == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000670 return Tkinter_Error(self);
671
672 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000673}
674
675static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000676Tkapp_GlobalEval(self, args)
677 PyObject *self;
678 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000679{
Barry Warsawfa701a81997-01-16 00:15:11 +0000680 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000681 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000682
Guido van Rossum35d43371997-08-02 00:09:09 +0000683 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000684 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000685
Guido van Rossum00d93061998-05-28 23:06:38 +0000686 ENTER_TCL
687 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
688 LEAVE_TCL
689 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000690 return Tkinter_Error(self);
Guido van Rossum00d93061998-05-28 23:06:38 +0000691
Barry Warsawfa701a81997-01-16 00:15:11 +0000692 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000693}
694
695static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000696Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000697 PyObject *self;
698 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000699{
Barry Warsawfa701a81997-01-16 00:15:11 +0000700 char *fileName;
Guido van Rossum00d93061998-05-28 23:06:38 +0000701 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000702
Guido van Rossum35d43371997-08-02 00:09:09 +0000703 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000704 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000705
Guido van Rossum00d93061998-05-28 23:06:38 +0000706 ENTER_TCL
707 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
708 LEAVE_TCL
709 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000710 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000711
Barry Warsawfa701a81997-01-16 00:15:11 +0000712 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000713}
714
715static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000716Tkapp_Record(self, args)
717 PyObject *self;
718 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000719{
Barry Warsawfa701a81997-01-16 00:15:11 +0000720 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000721 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000722
Guido van Rossum35d43371997-08-02 00:09:09 +0000723 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000724 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000725
Guido van Rossum00d93061998-05-28 23:06:38 +0000726 ENTER_TCL
727 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
728 LEAVE_TCL
729 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000730 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000731
Barry Warsawfa701a81997-01-16 00:15:11 +0000732 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000733}
734
735static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000736Tkapp_AddErrorInfo(self, args)
737 PyObject *self;
738 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000739{
Barry Warsawfa701a81997-01-16 00:15:11 +0000740 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000741
Guido van Rossum35d43371997-08-02 00:09:09 +0000742 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000743 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000744 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000745 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000746 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000747
Barry Warsawfa701a81997-01-16 00:15:11 +0000748 Py_INCREF(Py_None);
749 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000750}
751
Barry Warsawfa701a81997-01-16 00:15:11 +0000752
753
Guido van Rossum18468821994-06-20 07:49:28 +0000754/** Tcl Variable **/
755
756static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000757SetVar(self, args, flags)
758 PyObject *self;
759 PyObject *args;
760 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000761{
Guido van Rossum00d93061998-05-28 23:06:38 +0000762 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000763 PyObject *newValue;
764 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000765
Barry Warsawfa701a81997-01-16 00:15:11 +0000766 if (!tmp)
767 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Guido van Rossum00d93061998-05-28 23:06:38 +0000769 if (PyArg_ParseTuple(args, "sO", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000771 s = AsString(newValue, tmp);
772 ENTER_TCL
773 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
774 LEAVE_TCL
775 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000776 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000777 PyErr_Clear();
Guido van Rossum00d93061998-05-28 23:06:38 +0000778 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue)) {
779 s = AsString (newValue, tmp);
780 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000781 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000782 s, flags);
783 LEAVE_TCL
784 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000785 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000786 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000787 return NULL;
788 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000790 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000791
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 if (!ok)
793 return Tkinter_Error(self);
794
795 Py_INCREF(Py_None);
796 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000797}
798
799static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000800Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000801 PyObject *self;
802 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000803{
Barry Warsawfa701a81997-01-16 00:15:11 +0000804 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000805}
806
807static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000808Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000809 PyObject *self;
810 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000811{
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000813}
814
Barry Warsawfa701a81997-01-16 00:15:11 +0000815
816
Guido van Rossum18468821994-06-20 07:49:28 +0000817static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000818GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000819 PyObject *self;
820 PyObject *args;
821 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000822{
Guido van Rossum35d43371997-08-02 00:09:09 +0000823 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000824
Guido van Rossum35d43371997-08-02 00:09:09 +0000825 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
826 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000827 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000828 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000829 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000830
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000832 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000833 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000834
Barry Warsawfa701a81997-01-16 00:15:11 +0000835 if (s == NULL)
836 return Tkinter_Error(self);
837
Guido van Rossum35d43371997-08-02 00:09:09 +0000838 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000839}
840
841static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000842Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 PyObject *self;
844 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000845{
Barry Warsawfa701a81997-01-16 00:15:11 +0000846 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000847}
848
849static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000850Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000851 PyObject *self;
852 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000853{
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000855}
856
Barry Warsawfa701a81997-01-16 00:15:11 +0000857
858
Guido van Rossum18468821994-06-20 07:49:28 +0000859static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000860UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 PyObject *self;
862 PyObject *args;
863 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000864{
Guido van Rossum35d43371997-08-02 00:09:09 +0000865 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000866 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000867
Guido van Rossum35d43371997-08-02 00:09:09 +0000868 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000869 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000870 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000871 if (name2 == NULL)
872 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
873
874 else
875 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000876 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000877
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000879 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000880
881 Py_INCREF(Py_None);
882 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000883}
884
885static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000886Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 PyObject *self;
888 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000889{
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000891}
892
893static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000894Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 PyObject *self;
896 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000897{
Barry Warsawfa701a81997-01-16 00:15:11 +0000898 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000899}
900
Barry Warsawfa701a81997-01-16 00:15:11 +0000901
902
Guido van Rossum18468821994-06-20 07:49:28 +0000903/** Tcl to Python **/
904
905static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000906Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 PyObject *self;
908 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000909{
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 char *s;
911 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000912
Guido van Rossum35d43371997-08-02 00:09:09 +0000913 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000915 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 return Tkinter_Error(self);
917 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000918}
919
920static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000921Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 PyObject *self;
923 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000924{
Barry Warsawfa701a81997-01-16 00:15:11 +0000925 char *s;
926 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Guido van Rossum35d43371997-08-02 00:09:09 +0000928 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000930 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 return Tkinter_Error(self);
932 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000933}
934
935static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000936Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000937 PyObject *self;
938 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000939{
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 char *s;
941 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000942
Guido van Rossum35d43371997-08-02 00:09:09 +0000943 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000945 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
946 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000948}
949
950static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000951Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 PyObject *self;
953 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000954{
Barry Warsawfa701a81997-01-16 00:15:11 +0000955 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000956 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000957
Guido van Rossum35d43371997-08-02 00:09:09 +0000958 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000959 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000960 ENTER_TCL
961 retval = Tcl_ExprString(Tkapp_Interp(self), s);
962 LEAVE_TCL
963 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 return Tkinter_Error(self);
965 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000966}
967
968static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000969Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000970 PyObject *self;
971 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000972{
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000974 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +0000975 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000976
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000978 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000979 ENTER_TCL
980 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
981 LEAVE_TCL
982 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000983 return Tkinter_Error(self);
984 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000985}
986
987static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000988Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000989 PyObject *self;
990 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000991{
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 char *s;
993 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000994 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000995
Guido van Rossum35d43371997-08-02 00:09:09 +0000996 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000998 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +0000999 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001000 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum00d93061998-05-28 23:06:38 +00001001 LEAVE_TCL
Guido van Rossum45b83911997-03-14 04:32:50 +00001002 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001003 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 return Tkinter_Error(self);
1005 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001006}
1007
1008static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001009Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001010 PyObject *self;
1011 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001012{
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +00001014 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001015 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001016
Guido van Rossum35d43371997-08-02 00:09:09 +00001017 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001019 ENTER_TCL
1020 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1021 LEAVE_TCL
1022 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 return Tkinter_Error(self);
1024 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001025}
1026
Barry Warsawfa701a81997-01-16 00:15:11 +00001027
1028
Guido van Rossum18468821994-06-20 07:49:28 +00001029static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001030Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001031 PyObject *self;
1032 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001033{
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 char *list;
1035 int argc;
1036 char **argv;
1037 PyObject *v;
1038 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001039
Guido van Rossum35d43371997-08-02 00:09:09 +00001040 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001042
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1044 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001045
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 if (!(v = PyTuple_New(argc)))
1047 return NULL;
1048
1049 for (i = 0; i < argc; i++) {
1050 PyObject *s = PyString_FromString(argv[i]);
1051 if (!s || PyTuple_SetItem(v, i, s)) {
1052 Py_DECREF(v);
1053 v = NULL;
1054 goto finally;
1055 }
1056 }
Guido van Rossum18468821994-06-20 07:49:28 +00001057
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 finally:
1059 ckfree(FREECAST argv);
1060 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001061}
1062
1063static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001064Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 PyObject *self;
1066 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001067{
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001069
Guido van Rossum35d43371997-08-02 00:09:09 +00001070 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001072 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001073}
1074
1075static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001076Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 PyObject *self;
1078 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001079{
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 char *s = Merge(args);
1081 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001082
Barry Warsawfa701a81997-01-16 00:15:11 +00001083 if (s) {
1084 res = PyString_FromString(s);
1085 ckfree(s);
1086 }
1087 else
1088 PyErr_SetString(Tkinter_TclError, "merge failed");
1089
1090 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001091}
1092
Barry Warsawfa701a81997-01-16 00:15:11 +00001093
1094
Guido van Rossum18468821994-06-20 07:49:28 +00001095/** Tcl Command **/
1096
Guido van Rossum00d93061998-05-28 23:06:38 +00001097/* Client data struct */
1098typedef struct {
1099 PyThreadState *tstate;
1100 PyObject *self;
1101 PyObject *func;
1102} PythonCmd_ClientData;
1103
1104static int
1105PythonCmd_Error(interp)
1106 Tcl_Interp *interp;
1107{
1108 errorInCmd = 1;
1109 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1110 LEAVE_PYTHON
1111 return TCL_ERROR;
1112}
1113
Guido van Rossum18468821994-06-20 07:49:28 +00001114/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 * function or method.
1116 */
Guido van Rossum18468821994-06-20 07:49:28 +00001117static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001118PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001119 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001120 Tcl_Interp *interp;
1121 int argc;
1122 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001123{
Guido van Rossum00d93061998-05-28 23:06:38 +00001124 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 PyObject *self, *func, *arg, *res, *tmp;
1126 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001127
Guido van Rossum00d93061998-05-28 23:06:38 +00001128 /* XXX Should create fresh thread state? */
1129 ENTER_PYTHON(data->tstate)
1130
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 /* TBD: no error checking here since we know, via the
1132 * Tkapp_CreateCommand() that the client data is a two-tuple
1133 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001134 self = data->self;
1135 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Barry Warsawfa701a81997-01-16 00:15:11 +00001137 /* Create argument list (argv1, ..., argvN) */
1138 if (!(arg = PyTuple_New(argc - 1)))
1139 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001140
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 for (i = 0; i < (argc - 1); i++) {
1142 PyObject *s = PyString_FromString(argv[i + 1]);
1143 if (!s || PyTuple_SetItem(arg, i, s)) {
1144 Py_DECREF(arg);
1145 PythonCmd_Error(interp);
1146 }
1147 }
1148 res = PyEval_CallObject(func, arg);
1149 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001150
Barry Warsawfa701a81997-01-16 00:15:11 +00001151 if (res == NULL)
1152 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001153
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 if (!(tmp = PyList_New(0))) {
1155 Py_DECREF(res);
1156 return PythonCmd_Error(interp);
1157 }
1158
1159 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1160 Py_DECREF(res);
1161 Py_DECREF(tmp);
1162
Guido van Rossum00d93061998-05-28 23:06:38 +00001163 LEAVE_PYTHON
1164
Barry Warsawfa701a81997-01-16 00:15:11 +00001165 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001166}
1167
1168static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001169PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001170 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001171{
Guido van Rossum00d93061998-05-28 23:06:38 +00001172 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1173
1174 ENTER_PYTHON(data->tstate)
1175 Py_XDECREF(data->self);
1176 Py_XDECREF(data->func);
1177 PyMem_DEL(data);
1178 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001179}
1180
Barry Warsawfa701a81997-01-16 00:15:11 +00001181
1182
Guido van Rossum18468821994-06-20 07:49:28 +00001183static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001184Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 PyObject *self;
1186 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001187{
Guido van Rossum00d93061998-05-28 23:06:38 +00001188 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001191 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001192
1193 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1194 return NULL;
1195 if (!PyCallable_Check(func)) {
1196 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 return NULL;
1198 }
Guido van Rossum18468821994-06-20 07:49:28 +00001199
Guido van Rossum00d93061998-05-28 23:06:38 +00001200 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 if (!data)
1202 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001203 data->tstate = PyThreadState_Get();
1204 Py_XINCREF(self);
1205 Py_XINCREF(func);
1206 data->self = self;
1207 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001208
Guido van Rossum00d93061998-05-28 23:06:38 +00001209 ENTER_TCL
1210 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1211 (ClientData)data, PythonCmdDelete);
1212 LEAVE_TCL
1213 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001214 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001215 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001216 return NULL;
1217 }
Guido van Rossum18468821994-06-20 07:49:28 +00001218
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 Py_INCREF(Py_None);
1220 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001221}
1222
Barry Warsawfa701a81997-01-16 00:15:11 +00001223
1224
Guido van Rossum18468821994-06-20 07:49:28 +00001225static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001226Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001227 PyObject *self;
1228 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001229{
Barry Warsawfa701a81997-01-16 00:15:11 +00001230 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001231 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001232
Guido van Rossum35d43371997-08-02 00:09:09 +00001233 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001234 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001235 ENTER_TCL
1236 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1237 LEAVE_TCL
1238 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1240 return NULL;
1241 }
1242 Py_INCREF(Py_None);
1243 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001244}
1245
Barry Warsawfa701a81997-01-16 00:15:11 +00001246
1247
Guido van Rossum00d93061998-05-28 23:06:38 +00001248#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001249/** File Handler **/
1250
Guido van Rossum00d93061998-05-28 23:06:38 +00001251typedef struct _fhcdata {
1252 PyThreadState *tstate;
1253 PyObject *func;
1254 PyObject *file;
1255 int id;
1256 struct _fhcdata *next;
1257} FileHandler_ClientData;
1258
1259static FileHandler_ClientData *HeadFHCD;
1260
1261static FileHandler_ClientData *
1262NewFHCD(func, file, id)
1263 PyObject *func;
1264 PyObject *file;
1265 int id;
1266{
1267 FileHandler_ClientData *p;
1268 p = PyMem_NEW(FileHandler_ClientData, 1);
1269 if (p != NULL) {
1270 Py_XINCREF(func);
1271 Py_XINCREF(file);
1272 p->tstate = PyThreadState_Get();
1273 p->func = func;
1274 p->file = file;
1275 p->id = id;
1276 p->next = HeadFHCD;
1277 HeadFHCD = p;
1278 }
1279 return p;
1280}
1281
1282static void
1283DeleteFHCD(id)
1284 int id;
1285{
1286 FileHandler_ClientData *p, **pp;
1287
1288 pp = &HeadFHCD;
1289 while ((p = *pp) != NULL) {
1290 if (p->id == id) {
1291 *pp = p->next;
1292 Py_XDECREF(p->func);
1293 Py_XDECREF(p->file);
1294 PyMem_DEL(p);
1295 }
1296 else
1297 pp = &p->next;
1298 }
1299}
1300
Guido van Rossuma597dde1995-01-10 20:56:29 +00001301static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001302FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001303 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001305{
Guido van Rossum00d93061998-05-28 23:06:38 +00001306 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001307 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001308
Guido van Rossum00d93061998-05-28 23:06:38 +00001309 /* XXX Should create fresh thread state? */
1310 ENTER_PYTHON(data->tstate)
1311 func = data->func;
1312 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001313
Barry Warsawfa701a81997-01-16 00:15:11 +00001314 arg = Py_BuildValue("(Oi)", file, (long) mask);
1315 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001316 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001317
1318 if (res == NULL) {
1319 errorInCmd = 1;
1320 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1321 }
1322 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001323 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001324}
1325
1326static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001327GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001328 /* Either an int >= 0 or an object with a
1329 *.fileno() method that returns an int >= 0
1330 */
1331 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001332{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001333 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001334 int id;
1335 if (PyInt_Check(file)) {
1336 id = PyInt_AsLong(file);
1337 if (id < 0)
1338 PyErr_SetString(PyExc_ValueError, "invalid file id");
1339 return id;
1340 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001341 args = PyTuple_New(0);
1342 if (args == NULL)
1343 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001344
1345 meth = PyObject_GetAttrString(file, "fileno");
1346 if (meth == NULL) {
1347 Py_DECREF(args);
1348 return -1;
1349 }
1350
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001351 res = PyEval_CallObject(meth, args);
1352 Py_DECREF(args);
1353 Py_DECREF(meth);
1354 if (res == NULL)
1355 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001356
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001357 if (PyInt_Check(res))
1358 id = PyInt_AsLong(res);
1359 else
1360 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001361
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001362 if (id < 0)
1363 PyErr_SetString(PyExc_ValueError,
1364 "invalid fileno() return value");
1365 Py_DECREF(res);
1366 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001367}
1368
1369static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001370Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001371 PyObject *self;
1372 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001373{
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 FileHandler_ClientData *data;
1375 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001377 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001378
Guido van Rossum35d43371997-08-02 00:09:09 +00001379 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 return NULL;
1381 id = GetFileNo(file);
1382 if (id < 0)
1383 return NULL;
1384 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001385 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001386 return NULL;
1387 }
1388
Guido van Rossum00d93061998-05-28 23:06:38 +00001389 data = NewFHCD(func, file, id);
1390 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001391 return NULL;
1392
Guido van Rossum7bf15641998-05-22 18:28:17 +00001393 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001394 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001395 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001396 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001397 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001398 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001399 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001400}
1401
1402static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001403Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001404 PyObject *self;
1405 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001406{
Barry Warsawfa701a81997-01-16 00:15:11 +00001407 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001408 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001409 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001410 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001411
Guido van Rossum35d43371997-08-02 00:09:09 +00001412 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 return NULL;
1414 id = GetFileNo(file);
1415 if (id < 0)
1416 return NULL;
1417
Guido van Rossum00d93061998-05-28 23:06:38 +00001418 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001419
Guido van Rossum7bf15641998-05-22 18:28:17 +00001420 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001422 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001423 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001424 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001425 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001427}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001428#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001429
Barry Warsawfa701a81997-01-16 00:15:11 +00001430
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001431/**** Tktt Object (timer token) ****/
1432
1433staticforward PyTypeObject Tktt_Type;
1434
Guido van Rossum00d93061998-05-28 23:06:38 +00001435typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001436 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001437 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001439 PyThreadState *tstate;
1440} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001441
1442static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001443Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 PyObject *self;
1445 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001446{
Barry Warsawfa701a81997-01-16 00:15:11 +00001447 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001449
Guido van Rossum35d43371997-08-02 00:09:09 +00001450 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001453 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001454 v->token = NULL;
1455 }
1456 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001458 Py_DECREF(func);
1459 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001460 }
1461 Py_INCREF(Py_None);
1462 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001463}
1464
1465static PyMethodDef Tktt_methods[] =
1466{
Guido van Rossum35d43371997-08-02 00:09:09 +00001467 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001469};
1470
1471static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001472Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001474{
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001476
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 v = PyObject_NEW(TkttObject, &Tktt_Type);
1478 if (v == NULL)
1479 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001480
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 Py_INCREF(func);
1482 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001484 v->tstate = PyThreadState_Get();
1485
1486 /* Extra reference, deleted when called or when handler is deleted */
1487 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001489}
1490
1491static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001492Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001494{
Guido van Rossum00d93061998-05-28 23:06:38 +00001495 TkttObject *v = (TkttObject *)self;
1496 PyObject *func = v->func;
1497
1498 Py_XDECREF(func);
1499
Guido van Rossum35d43371997-08-02 00:09:09 +00001500 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001501}
1502
Guido van Rossum597ac201998-05-12 14:36:19 +00001503static PyObject *
1504Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001506{
Barry Warsawfa701a81997-01-16 00:15:11 +00001507 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001508 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001509
Guido van Rossum597ac201998-05-12 14:36:19 +00001510 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001512 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001513}
1514
1515static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001516Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 PyObject *self;
1518 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001519{
Barry Warsawfa701a81997-01-16 00:15:11 +00001520 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001521}
1522
1523static PyTypeObject Tktt_Type =
1524{
Guido van Rossum35d43371997-08-02 00:09:09 +00001525 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 0, /*ob_size */
1527 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001528 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 0, /*tp_itemsize */
1530 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001531 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 Tktt_GetAttr, /*tp_getattr */
1533 0, /*tp_setattr */
1534 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001535 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 0, /*tp_as_number */
1537 0, /*tp_as_sequence */
1538 0, /*tp_as_mapping */
1539 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001540};
1541
Barry Warsawfa701a81997-01-16 00:15:11 +00001542
1543
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001544/** Timer Handler **/
1545
1546static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001547TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001549{
Guido van Rossum00d93061998-05-28 23:06:38 +00001550 TkttObject *v = (TkttObject *)clientData;
1551 PyObject *func = v->func;
1552 PyObject *res;
1553
1554 if (func == NULL)
1555 return;
1556
1557 v->func = NULL;
1558
1559 ENTER_PYTHON(v->tstate)
1560
1561 res = PyEval_CallObject(func, NULL);
1562 Py_DECREF(func);
1563 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001564
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 if (res == NULL) {
1566 errorInCmd = 1;
1567 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1568 }
1569 else
1570 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001571
1572 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001573}
1574
1575static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001576Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001577 PyObject *self;
1578 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001579{
Barry Warsawfa701a81997-01-16 00:15:11 +00001580 int milliseconds;
1581 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001582 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001583
Guido van Rossum35d43371997-08-02 00:09:09 +00001584 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 return NULL;
1586 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001587 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 return NULL;
1589 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001590 v = Tktt_New(func);
1591 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1592 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001593
Guido van Rossum00d93061998-05-28 23:06:38 +00001594 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001595}
1596
Barry Warsawfa701a81997-01-16 00:15:11 +00001597
Guido van Rossum18468821994-06-20 07:49:28 +00001598/** Event Loop **/
1599
Guido van Rossum18468821994-06-20 07:49:28 +00001600static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001601Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001602 PyObject *self;
1603 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001604{
Barry Warsawfa701a81997-01-16 00:15:11 +00001605 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001606
Barry Warsawfa701a81997-01-16 00:15:11 +00001607 if (!PyArg_ParseTuple(args, "|i", &threshold))
1608 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001609
Barry Warsawfa701a81997-01-16 00:15:11 +00001610 quitMainLoop = 0;
1611 while (Tk_GetNumMainWindows() > threshold &&
1612 !quitMainLoop &&
1613 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001614 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001615 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001616
1617#ifdef WITH_THREAD
1618 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001619 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossum00d93061998-05-28 23:06:38 +00001620 release_lock(tcl_lock);
1621 if (result == 0)
1622 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001623 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001624#else
1625 result = Tcl_DoOneEvent(0);
1626#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001627
Guido van Rossum35d43371997-08-02 00:09:09 +00001628 if (PyErr_CheckSignals() != 0)
1629 return NULL;
1630 if (result < 0)
1631 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001632 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001633 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001634
Barry Warsawfa701a81997-01-16 00:15:11 +00001635 if (errorInCmd) {
1636 errorInCmd = 0;
1637 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1638 excInCmd = valInCmd = trbInCmd = NULL;
1639 return NULL;
1640 }
1641 Py_INCREF(Py_None);
1642 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001643}
1644
1645static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001646Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 PyObject *self;
1648 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001649{
Guido van Rossum35d43371997-08-02 00:09:09 +00001650 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001652
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 if (!PyArg_ParseTuple(args, "|i", &flags))
1654 return NULL;
1655
Guido van Rossum00d93061998-05-28 23:06:38 +00001656 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001657 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001658 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001659 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001660}
1661
1662static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001663Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001664 PyObject *self;
1665 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001666{
1667
Guido van Rossum35d43371997-08-02 00:09:09 +00001668 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001669 return NULL;
1670
1671 quitMainLoop = 1;
1672 Py_INCREF(Py_None);
1673 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001674}
1675
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001676static PyObject *
1677Tkapp_InterpAddr(self, args)
1678 PyObject *self;
1679 PyObject *args;
1680{
1681
1682 if (!PyArg_ParseTuple(args, ""))
1683 return NULL;
1684
1685 return PyInt_FromLong((long)Tkapp_Interp(self));
1686}
1687
Barry Warsawfa701a81997-01-16 00:15:11 +00001688
1689
Guido van Rossum18468821994-06-20 07:49:28 +00001690/**** Tkapp Method List ****/
1691
1692static PyMethodDef Tkapp_methods[] =
1693{
Guido van Rossum35d43371997-08-02 00:09:09 +00001694 {"call", Tkapp_Call, 0},
1695 {"globalcall", Tkapp_GlobalCall, 0},
1696 {"eval", Tkapp_Eval, 1},
1697 {"globaleval", Tkapp_GlobalEval, 1},
1698 {"evalfile", Tkapp_EvalFile, 1},
1699 {"record", Tkapp_Record, 1},
1700 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1701 {"setvar", Tkapp_SetVar, 1},
1702 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1703 {"getvar", Tkapp_GetVar, 1},
1704 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1705 {"unsetvar", Tkapp_UnsetVar, 1},
1706 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1707 {"getint", Tkapp_GetInt, 1},
1708 {"getdouble", Tkapp_GetDouble, 1},
1709 {"getboolean", Tkapp_GetBoolean, 1},
1710 {"exprstring", Tkapp_ExprString, 1},
1711 {"exprlong", Tkapp_ExprLong, 1},
1712 {"exprdouble", Tkapp_ExprDouble, 1},
1713 {"exprboolean", Tkapp_ExprBoolean, 1},
1714 {"splitlist", Tkapp_SplitList, 1},
1715 {"split", Tkapp_Split, 1},
1716 {"merge", Tkapp_Merge, 0},
1717 {"createcommand", Tkapp_CreateCommand, 1},
1718 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001719#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001720 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1721 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001722#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001723 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001724 {"mainloop", Tkapp_MainLoop, 1},
1725 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001726 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001727 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001729};
1730
Barry Warsawfa701a81997-01-16 00:15:11 +00001731
1732
Guido van Rossum18468821994-06-20 07:49:28 +00001733/**** Tkapp Type Methods ****/
1734
1735static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001736Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001737 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001738{
Guido van Rossum00d93061998-05-28 23:06:38 +00001739 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001740 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001741 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001742 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001743 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001744}
1745
1746static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001747Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001748 PyObject *self;
1749 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001750{
Guido van Rossum35d43371997-08-02 00:09:09 +00001751 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001752}
1753
1754static PyTypeObject Tkapp_Type =
1755{
Guido van Rossum35d43371997-08-02 00:09:09 +00001756 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001757 0, /*ob_size */
1758 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001759 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001760 0, /*tp_itemsize */
1761 Tkapp_Dealloc, /*tp_dealloc */
1762 0, /*tp_print */
1763 Tkapp_GetAttr, /*tp_getattr */
1764 0, /*tp_setattr */
1765 0, /*tp_compare */
1766 0, /*tp_repr */
1767 0, /*tp_as_number */
1768 0, /*tp_as_sequence */
1769 0, /*tp_as_mapping */
1770 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001771};
1772
Barry Warsawfa701a81997-01-16 00:15:11 +00001773
1774
Guido van Rossum18468821994-06-20 07:49:28 +00001775/**** Tkinter Module ****/
1776
1777static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001778Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 PyObject *self;
1780 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001781{
Barry Warsawfa701a81997-01-16 00:15:11 +00001782 char *screenName = NULL;
1783 char *baseName = NULL;
1784 char *className = NULL;
1785 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001786
Guido van Rossum35d43371997-08-02 00:09:09 +00001787 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001788 if (baseName != NULL)
1789 baseName++;
1790 else
1791 baseName = Py_GetProgramName();
1792 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001793
Barry Warsawfa701a81997-01-16 00:15:11 +00001794 if (!PyArg_ParseTuple(args, "|zssi",
1795 &screenName, &baseName, &className,
1796 &interactive))
1797 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001798
Barry Warsawfa701a81997-01-16 00:15:11 +00001799 return (PyObject *) Tkapp_New(screenName, baseName, className,
1800 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001801}
1802
1803static PyMethodDef moduleMethods[] =
1804{
Barry Warsawfa701a81997-01-16 00:15:11 +00001805 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001806#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001807 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1808 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001809#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001810 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001811 {"mainloop", Tkapp_MainLoop, 1},
1812 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001813 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001815};
1816
Guido van Rossum7bf15641998-05-22 18:28:17 +00001817#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001818
1819static int stdin_ready = 0;
1820
1821static void
1822MyFileProc(clientData, mask)
1823 void *clientData;
1824 int mask;
1825{
1826 stdin_ready = 1;
1827}
Guido van Rossum7bf15641998-05-22 18:28:17 +00001828
Guido van Rossum00d93061998-05-28 23:06:38 +00001829static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001830
Guido van Rossum18468821994-06-20 07:49:28 +00001831static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001832EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001833{
Guido van Rossum00d93061998-05-28 23:06:38 +00001834 FHANDLE tfile;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001835
Guido van Rossum00d93061998-05-28 23:06:38 +00001836 ENTER_PYTHON(event_tstate)
1837 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001838 stdin_ready = 0;
1839 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossum00d93061998-05-28 23:06:38 +00001840 while (!errorInCmd && !stdin_ready) {
1841 int result;
1842
1843#ifdef WITH_THREAD
1844 ENTER_TCL
1845 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1846 release_lock(tcl_lock);
1847 if (result == 0)
1848 Sleep(20);
1849 Py_END_ALLOW_THREADS
1850#else
1851 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001852#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001853
1854 if (result < 0)
1855 break;
1856 }
1857 Tcl_DeleteFileHandler(tfile);
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 if (errorInCmd) {
1859 errorInCmd = 0;
1860 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1861 excInCmd = valInCmd = trbInCmd = NULL;
1862 PyErr_Print();
1863 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001864 LEAVE_PYTHON
Barry Warsawfa701a81997-01-16 00:15:11 +00001865 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001866}
Guido van Rossum18468821994-06-20 07:49:28 +00001867
Guido van Rossum00d93061998-05-28 23:06:38 +00001868#endif
1869
Guido van Rossum7bf15641998-05-22 18:28:17 +00001870static void
1871EnableEventHook()
1872{
Guido van Rossum00d93061998-05-28 23:06:38 +00001873#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001874 if (PyOS_InputHook == NULL) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001875 event_tstate = PyThreadState_Get();
Guido van Rossum7bf15641998-05-22 18:28:17 +00001876 PyOS_InputHook = EventHook;
1877 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001878#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001879}
1880
1881static void
1882DisableEventHook()
1883{
Guido van Rossum00d93061998-05-28 23:06:38 +00001884#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001885 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1886 PyOS_InputHook = NULL;
1887 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001888#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001889}
1890
Barry Warsawfa701a81997-01-16 00:15:11 +00001891
1892/* all errors will be checked in one fell swoop in init_tkinter() */
1893static void
1894ins_long(d, name, val)
1895 PyObject *d;
1896 char *name;
1897 long val;
1898{
1899 PyObject *v = PyInt_FromLong(val);
1900 if (v) {
1901 PyDict_SetItemString(d, name, v);
1902 Py_DECREF(v);
1903 }
1904}
1905static void
1906ins_string(d, name, val)
1907 PyObject *d;
1908 char *name;
1909 char *val;
1910{
1911 PyObject *v = PyString_FromString(val);
1912 if (v) {
1913 PyDict_SetItemString(d, name, v);
1914 Py_DECREF(v);
1915 }
1916}
1917
1918
Guido van Rossum18468821994-06-20 07:49:28 +00001919void
Guido van Rossum35d43371997-08-02 00:09:09 +00001920init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001921{
Barry Warsawfa701a81997-01-16 00:15:11 +00001922 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001923
Barry Warsawfa701a81997-01-16 00:15:11 +00001924 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00001925
1926#ifdef WITH_THREAD
1927 tcl_lock = allocate_lock();
1928#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00001929
Barry Warsawfa701a81997-01-16 00:15:11 +00001930 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001931
Barry Warsawfa701a81997-01-16 00:15:11 +00001932 d = PyModule_GetDict(m);
1933 Tkinter_TclError = Py_BuildValue("s", "TclError");
1934 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001935
Guido van Rossum35d43371997-08-02 00:09:09 +00001936 ins_long(d, "READABLE", TCL_READABLE);
1937 ins_long(d, "WRITABLE", TCL_WRITABLE);
1938 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1939 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1940 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1941 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1942 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1943 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1944 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001945 ins_string(d, "TK_VERSION", TK_VERSION);
1946 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001947
Guido van Rossum83551bf1997-09-13 00:44:23 +00001948 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00001949
1950 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00001951 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1952
Barry Warsawfa701a81997-01-16 00:15:11 +00001953 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001954 return;
1955
Guido van Rossum26216371998-04-20 18:47:52 +00001956#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001957 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001958#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001959
Jack Jansen34cc5c31995-10-31 16:15:12 +00001960#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001961 /*
1962 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1963 ** Most of the initializations in that routine (toolbox init calls and
1964 ** such) have already been done for us, so we only need these.
1965 */
1966#if TKMAJORMINOR >= 8000
1967 tcl_macQdPtr = &qd;
1968#endif
1969
1970 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001971#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001972 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001973#endif /* GENERATINGCFM */
1974#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001975}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001976
Guido van Rossumec22c921996-02-25 04:50:29 +00001977
Barry Warsawfa701a81997-01-16 00:15:11 +00001978
Guido van Rossum9722ad81995-09-22 23:49:28 +00001979#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001980
1981/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001982** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001983*/
1984
Guido van Rossum9722ad81995-09-22 23:49:28 +00001985void
1986panic(char * format, ...)
1987{
Barry Warsawfa701a81997-01-16 00:15:11 +00001988 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001989
Barry Warsawfa701a81997-01-16 00:15:11 +00001990 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001991
Guido van Rossumb41addf1998-05-12 15:02:41 +00001992 vPySys_WriteStderr(format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001993 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001994
Barry Warsawfa701a81997-01-16 00:15:11 +00001995 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001996
Barry Warsawfa701a81997-01-16 00:15:11 +00001997 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001998}
Jack Jansen40b546d1995-11-14 10:34:45 +00001999
Guido van Rossumec22c921996-02-25 04:50:29 +00002000/*
2001** Pass events to SIOUX before passing them to Tk.
2002*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002003
Guido van Rossumec22c921996-02-25 04:50:29 +00002004static int
2005PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002006 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002007{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002008 WindowPtr frontwin;
2009 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002010 ** Sioux eats too many events, so we don't pass it everything. We
2011 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002012 ** the Sioux window is frontmost. This means that Tk menus don't work
2013 ** in that case, but at least we can scroll the sioux window.
2014 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2015 ** part of the external interface of Sioux...
2016 */
2017 frontwin = FrontWindow();
2018 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2019 if (SIOUXHandleOneEvent(eventPtr))
2020 return 0; /* Nothing happened to the Tcl event queue */
2021 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002022 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002023}
2024
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002025#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002026/*
2027 * For Python we have to override this routine (from TclMacNotify),
2028 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2029 * to use GUSI select to see whether our socket is ready. Note that
2030 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2031 * files and sockets.
2032 *
2033 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2034 * for other versions. */
2035
2036int
2037Tcl_FileReady(file, mask)
2038 Tcl_File file; /* File handle for a stream. */
2039 int mask; /* OR'ed combination of TCL_READABLE,
2040 * TCL_WRITABLE, and TCL_EXCEPTION:
2041 * indicates conditions caller cares about. */
2042{
2043 int type;
2044 int fd;
2045
2046 fd = (int) Tcl_GetFileInfo(file, &type);
2047
2048 if (type == TCL_MAC_SOCKET) {
2049 return TclMacSocketReady(file, mask);
2050 } else if (type == TCL_MAC_FILE) {
2051 /*
2052 * Under the Macintosh, files are always ready, so we just
2053 * return the mask that was passed in.
2054 */
2055
2056 return mask;
2057 } else if (type == TCL_UNIX_FD) {
2058 fd_set readset, writeset, excset;
2059 struct timeval tv;
2060
2061 FD_ZERO(&readset);
2062 FD_ZERO(&writeset);
2063 FD_ZERO(&excset);
2064
2065 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2066 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2067 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2068
2069 tv.tv_sec = tv.tv_usec = 0;
2070 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2071 return 0;
2072
2073 mask = 0;
2074 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2075 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2076 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2077
2078 return mask;
2079 }
2080
2081 return 0;
2082}
2083#endif /* USE_GUSI */
2084
Guido van Rossumec22c921996-02-25 04:50:29 +00002085#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002086
2087/*
2088** Additional Mac specific code for dealing with shared libraries.
2089*/
2090
2091#include <Resources.h>
2092#include <CodeFragments.h>
2093
2094static int loaded_from_shlib = 0;
2095static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002096
Jack Jansen34cc5c31995-10-31 16:15:12 +00002097/*
2098** If this module is dynamically loaded the following routine should
2099** be the init routine. It takes care of adding the shared library to
2100** the resource-file chain, so that the tk routines can find their
2101** resources.
2102*/
2103OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002104init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002105{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002106 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002107 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002108 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002109 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2110 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002111 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002112 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2113 loaded_from_shlib = 1;
2114 }
2115 return noErr;
2116}
2117
2118/*
2119** Insert the library resources into the search path. Put them after
2120** the resources from the application. Again, we ignore errors.
2121*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002122static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002123mac_addlibresources()
2124{
2125 if ( !loaded_from_shlib )
2126 return;
2127 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2128}
2129
Guido van Rossumec22c921996-02-25 04:50:29 +00002130#endif /* GENERATINGCFM */
2131#endif /* macintosh */