blob: 1c2c7932b74efc3bd29cb5f49b647c86a0909e6e [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 Rossum2a5119b1998-05-29 01:28:40 +000065#ifdef MS_WINDOWS
66#include <windows.h>
67#endif
68
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000069#ifdef macintosh
70#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000071#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000072#endif
73
Guido van Rossum18468821994-06-20 07:49:28 +000074#include <tcl.h>
75#include <tk.h>
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Guido van Rossum00d93061998-05-28 23:06:38 +000079#if TKMAJORMINOR < 4001
80 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
81#endif
82
Guido van Rossum0d2390c1997-08-14 19:57:07 +000083#if TKMAJORMINOR >= 8000 && defined(macintosh)
84/* Sigh, we have to include this to get at the tcl qd pointer */
85#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000086/* And this one we need to clear the menu bar */
87#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000088#endif
89
Guido van Rossumb0105441997-10-08 15:25:37 +000090#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000091#define HAVE_CREATEFILEHANDLER
92#endif
93
Guido van Rossum00d93061998-05-28 23:06:38 +000094#ifdef HAVE_CREATEFILEHANDLER
95
96/* Tcl_CreateFileHandler() changed several times; these macros deal with the
97 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
98 Unix, only because Jack added it back); when available on Windows, it only
99 applies to sockets. */
100
Guido van Rossum7bf15641998-05-22 18:28:17 +0000101#ifdef MS_WINDOWS
102#define FHANDLETYPE TCL_WIN_SOCKET
103#else
104#define FHANDLETYPE TCL_UNIX_FD
105#endif
106
107#if TKMAJORMINOR < 8000
108#define FHANDLE Tcl_File
109#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
110#else
111#define FHANDLE int
112#define MAKEFHANDLE(fd) (fd)
113#endif
114
Guido van Rossum00d93061998-05-28 23:06:38 +0000115/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
116 which uses this to handle Tcl events while the user is typing commands. */
117
118#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000119#define WAIT_FOR_STDIN
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122#endif /* HAVE_CREATEFILEHANDLER */
123
124#ifdef WITH_THREAD
125
126/* The threading situation is complicated. Tcl is not thread-safe, except for
127 Tcl 8.1, which will probably remain in alpha status for another 6 months
128 (and the README says that Tk will probably remain thread-unsafe forever).
129 So we need to use a lock around all uses of Tcl. Previously, the Python
130 interpreter lock was used for this. However, this causes problems when
131 other Python threads need to run while Tcl is blocked waiting for events.
132
133 To solve this problem, a separate lock for Tcl is introduced. Holding it
134 is incompatible with holding Python's interpreter lock. The following four
135 macros manipulate both locks together.
136
137 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
138 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
139 that could call an event handler, or otherwise affect the state of a Tcl
140 interpreter. These assume that the surrounding code has the Python
141 interpreter lock; inside the brackets, the Python interpreter lock has been
142 released and the lock for Tcl has been acquired.
143
144 By contrast, ENTER_PYTHON(tstate) and LEAVE_PYTHON are used in Tcl event
145 handlers when the handler needs to use Python. Such event handlers are
146 entered while the lock for Tcl is held; the event handler presumably needs
147 to use Python. ENTER_PYTHON(tstate) releases the lock for Tcl and acquires
148 the Python interpreter lock, restoring the appropriate thread state, and
149 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
150 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
151 the code between ENTER_PYTHON(tstate) and LEAVE_PYTHON.
152
153 These locks expand to several statements and brackets; they should not be
154 used in branches of if statements and the like.
155
156*/
157
158static type_lock tcl_lock = 0;
159
160#define ENTER_TCL \
161 Py_BEGIN_ALLOW_THREADS acquire_lock(tcl_lock, 1);
162
163#define LEAVE_TCL \
164 release_lock(tcl_lock); Py_END_ALLOW_THREADS
165
166#define ENTER_PYTHON(tstate) \
167 if (PyThreadState_Swap(NULL) != NULL) \
168 Py_FatalError("ENTER_PYTHON with non-NULL tstate\n"); \
169 release_lock(tcl_lock); PyEval_RestoreThread((tstate));
170
171#define LEAVE_PYTHON \
172 PyEval_SaveThread(); acquire_lock(tcl_lock, 1);
173
174#else
175
176#define ENTER_TCL
177#define LEAVE_TCL
178#define ENTER_PYTHON(tstate)
179#define LEAVE_PYTHON
180
181#endif
182
Guido van Rossum35d43371997-08-02 00:09:09 +0000183extern int Tk_GetNumMainWindows();
184
Guido van Rossumec22c921996-02-25 04:50:29 +0000185#ifdef macintosh
186
187/*
188** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000189** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000190*/
191
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000192/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000193#define FREECAST (char *)
194
Guido van Rossumec22c921996-02-25 04:50:29 +0000195#include <Events.h> /* For EventRecord */
196
197typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000198/* They changed the name... */
199#if TKMAJORMINOR < 8000
200#define Tcl_MacSetEventProc TclMacSetEventProc
201#endif
202void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000203int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
204
205staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
206
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000207#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
208 #pragma import on
209#endif
210
211#include <SIOUX.h>
212extern int SIOUXIsAppWindow(WindowPtr);
213
214#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
215 #pragma import reset
216#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000217#endif /* macintosh */
218
Guido van Rossum97867b21996-08-08 19:09:53 +0000219#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000220#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000221#endif
222
Guido van Rossum18468821994-06-20 07:49:28 +0000223/**** Tkapp Object Declaration ****/
224
225staticforward PyTypeObject Tkapp_Type;
226
Guido van Rossum00d93061998-05-28 23:06:38 +0000227typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000228 PyObject_HEAD
229 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000230} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000231
232#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000233#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
234#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
235
Guido van Rossum35d43371997-08-02 00:09:09 +0000236#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000237(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000238
Barry Warsawfa701a81997-01-16 00:15:11 +0000239
240
Guido van Rossum18468821994-06-20 07:49:28 +0000241/**** Error Handling ****/
242
243static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000244static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000245static int errorInCmd = 0;
246static PyObject *excInCmd;
247static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000249
Barry Warsawfa701a81997-01-16 00:15:11 +0000250
251
Guido van Rossum18468821994-06-20 07:49:28 +0000252static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000253Tkinter_Error(v)
254 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000255{
Barry Warsawfa701a81997-01-16 00:15:11 +0000256 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
257 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000258}
259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260
Barry Warsawfa701a81997-01-16 00:15:11 +0000261
Guido van Rossum18468821994-06-20 07:49:28 +0000262/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000263
264#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000265#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +0000266/* Millisecond sleep() for Unix platforms. */
267
268static void
269Sleep(milli)
270 int milli;
271{
272 /* XXX Too bad if you don't have select(). */
273 struct timeval t;
274 double frac;
275 t.tv_sec = milli/1000;
276 t.tv_usec = (milli%1000) * 1000;
277 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
278}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000279#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000280#endif /* WITH_THREAD */
281
282
Guido van Rossum18468821994-06-20 07:49:28 +0000283static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000284AsString(value, tmp)
285 PyObject *value;
286 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000287{
Guido van Rossum35d43371997-08-02 00:09:09 +0000288 if (PyString_Check(value))
289 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000290 else {
291 PyObject *v = PyObject_Str(value);
292 PyList_Append(tmp, v);
293 Py_DECREF(v);
294 return PyString_AsString(v);
295 }
Guido van Rossum18468821994-06-20 07:49:28 +0000296}
297
Barry Warsawfa701a81997-01-16 00:15:11 +0000298
299
Guido van Rossum18468821994-06-20 07:49:28 +0000300#define ARGSZ 64
301
302static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000303Merge(args)
304 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000305{
Barry Warsawfa701a81997-01-16 00:15:11 +0000306 PyObject *tmp = NULL;
307 char *argvStore[ARGSZ];
308 char **argv = NULL;
309 int fvStore[ARGSZ];
310 int *fv = NULL;
311 int argc = 0, i;
312 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000313
Barry Warsawfa701a81997-01-16 00:15:11 +0000314 if (!(tmp = PyList_New(0)))
315 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000316
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 argv = argvStore;
318 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000319
Barry Warsawfa701a81997-01-16 00:15:11 +0000320 if (args == NULL)
321 argc = 0;
322
323 else if (!PyTuple_Check(args)) {
324 argc = 1;
325 fv[0] = 0;
326 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000327 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 else {
329 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000332 argv = (char **)ckalloc(argc * sizeof(char *));
333 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000334 if (argv == NULL || fv == NULL) {
335 PyErr_NoMemory();
336 goto finally;
337 }
338 }
339
340 for (i = 0; i < argc; i++) {
341 PyObject *v = PyTuple_GetItem(args, i);
342 if (PyTuple_Check(v)) {
343 fv[i] = 1;
344 if (!(argv[i] = Merge(v)))
345 goto finally;
346 }
347 else if (v == Py_None) {
348 argc = i;
349 break;
350 }
351 else {
352 fv[i] = 0;
353 argv[i] = AsString(v, tmp);
354 }
355 }
Guido van Rossum18468821994-06-20 07:49:28 +0000356 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000358
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 finally:
360 for (i = 0; i < argc; i++)
361 if (fv[i]) {
362 ckfree(argv[i]);
363 }
364 if (argv != argvStore)
365 ckfree(FREECAST argv);
366 if (fv != fvStore)
367 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 Py_DECREF(tmp);
370 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000371}
372
Barry Warsawfa701a81997-01-16 00:15:11 +0000373
374
Guido van Rossum18468821994-06-20 07:49:28 +0000375static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000376Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000378{
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 int argc;
380 char **argv;
381 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000382
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 if (list == NULL) {
384 Py_INCREF(Py_None);
385 return Py_None;
386 }
Guido van Rossum18468821994-06-20 07:49:28 +0000387
Guido van Rossum00d93061998-05-28 23:06:38 +0000388 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 /* Not a list.
390 * Could be a quoted string containing funnies, e.g. {"}.
391 * Return the string itself.
392 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000393 return PyString_FromString(list);
394 }
Guido van Rossum18468821994-06-20 07:49:28 +0000395
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 if (argc == 0)
397 v = PyString_FromString("");
398 else if (argc == 1)
399 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000400 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000401 int i;
402 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000403
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000405 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 Py_DECREF(v);
407 v = NULL;
408 break;
409 }
410 PyTuple_SetItem(v, i, w);
411 }
412 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000413 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000414 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000415}
416
Barry Warsawfa701a81997-01-16 00:15:11 +0000417
418
Guido van Rossum18468821994-06-20 07:49:28 +0000419/**** Tkapp Object ****/
420
421#ifndef WITH_APPINIT
422int
Guido van Rossum35d43371997-08-02 00:09:09 +0000423Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000425{
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000427
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 main = Tk_MainWindow(interp);
429 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000430 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 return TCL_ERROR;
432 }
433 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000434 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 return TCL_ERROR;
436 }
437 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000438}
439#endif /* !WITH_APPINIT */
440
Guido van Rossum18468821994-06-20 07:49:28 +0000441
Barry Warsawfa701a81997-01-16 00:15:11 +0000442
443
444/* Initialize the Tk application; see the `main' function in
445 * `tkMain.c'.
446 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000447
448static void EnableEventHook(); /* Forward */
449static void DisableEventHook(); /* Forward */
450
Barry Warsawfa701a81997-01-16 00:15:11 +0000451static TkappObject *
452Tkapp_New(screenName, baseName, className, interactive)
453 char *screenName;
454 char *baseName;
455 char *className;
456 int interactive;
457{
458 TkappObject *v;
459 char *argv0;
460
461 v = PyObject_NEW(TkappObject, &Tkapp_Type);
462 if (v == NULL)
463 return NULL;
464
465 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000466
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000467#if defined(macintosh) && TKMAJORMINOR >= 8000
468 /* This seems to be needed since Tk 8.0 */
469 ClearMenuBar();
470 TkMacInitMenus(v->interp);
471#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000472 /* Delete the 'exit' command, which can screw things up */
473 Tcl_DeleteCommand(v->interp, "exit");
474
Barry Warsawfa701a81997-01-16 00:15:11 +0000475 if (screenName != NULL)
476 Tcl_SetVar2(v->interp, "env", "DISPLAY",
477 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 if (interactive)
480 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
481 else
482 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000483
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 /* This is used to get the application class for Tk 4.1 and up */
485 argv0 = (char*)ckalloc(strlen(className) + 1);
486 if (!argv0) {
487 PyErr_NoMemory();
488 Py_DECREF(v);
489 return NULL;
490 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000491
Barry Warsawfa701a81997-01-16 00:15:11 +0000492 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000493 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000494 argv0[0] = tolower(argv0[0]);
495 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
496 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000497
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 if (Tcl_AppInit(v->interp) != TCL_OK)
499 return (TkappObject *)Tkinter_Error(v);
500
Guido van Rossum7bf15641998-05-22 18:28:17 +0000501 EnableEventHook();
502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000504}
505
Barry Warsawfa701a81997-01-16 00:15:11 +0000506
507
Guido van Rossum18468821994-06-20 07:49:28 +0000508/** Tcl Eval **/
509
510static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000511Tkapp_Call(self, args)
512 PyObject *self;
513 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000514{
Guido van Rossum212643f1998-04-29 16:22:14 +0000515 /* This is copied from Merge() */
516 PyObject *tmp = NULL;
517 char *argvStore[ARGSZ];
518 char **argv = NULL;
519 int fvStore[ARGSZ];
520 int *fv = NULL;
521 int argc = 0, i;
522 PyObject *res = NULL; /* except this has a different type */
523 Tcl_CmdInfo info; /* and this is added */
524 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000525
Guido van Rossum212643f1998-04-29 16:22:14 +0000526 if (!(tmp = PyList_New(0)))
527 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000528
Guido van Rossum212643f1998-04-29 16:22:14 +0000529 argv = argvStore;
530 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000531
Guido van Rossum212643f1998-04-29 16:22:14 +0000532 if (args == NULL)
533 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000534
Guido van Rossum212643f1998-04-29 16:22:14 +0000535 else if (!PyTuple_Check(args)) {
536 argc = 1;
537 fv[0] = 0;
538 argv[0] = AsString(args, tmp);
539 }
540 else {
541 argc = PyTuple_Size(args);
542
543 if (argc > ARGSZ) {
544 argv = (char **)ckalloc(argc * sizeof(char *));
545 fv = (int *)ckalloc(argc * sizeof(int));
546 if (argv == NULL || fv == NULL) {
547 PyErr_NoMemory();
548 goto finally;
549 }
550 }
551
552 for (i = 0; i < argc; i++) {
553 PyObject *v = PyTuple_GetItem(args, i);
554 if (PyTuple_Check(v)) {
555 fv[i] = 1;
556 if (!(argv[i] = Merge(v)))
557 goto finally;
558 }
559 else if (v == Py_None) {
560 argc = i;
561 break;
562 }
563 else {
564 fv[i] = 0;
565 argv[i] = AsString(v, tmp);
566 }
567 }
568 }
569 /* End code copied from Merge() */
570
571 /* All this to avoid a call to Tcl_Merge() and the corresponding call
572 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
573 if (Py_VerboseFlag >= 2) {
574 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000575 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000576 }
577 if (argc < 1 ||
578 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
579 info.proc == NULL)
580 {
581 char *cmd;
582 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000583 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 cmd = Tcl_Merge(argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000585 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000586 i = Tcl_Eval(interp, cmd);
Guido van Rossum00d93061998-05-28 23:06:38 +0000587 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000589 }
590 else {
591 Tcl_ResetResult(interp);
Guido van Rossum00d93061998-05-28 23:06:38 +0000592 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 i = (*info.proc)(info.clientData, interp, argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000594 LEAVE_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000595 }
596 if (i == TCL_ERROR) {
597 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000598 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000599 interp->result);
600 Tkinter_Error(self);
601 }
602 else {
603 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000604 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000605 res = PyString_FromString(interp->result);
606 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000607
Guido van Rossum212643f1998-04-29 16:22:14 +0000608 /* Copied from Merge() again */
609 finally:
610 for (i = 0; i < argc; i++)
611 if (fv[i]) {
612 ckfree(argv[i]);
613 }
614 if (argv != argvStore)
615 ckfree(FREECAST argv);
616 if (fv != fvStore)
617 ckfree(FREECAST fv);
618
619 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000620 return res;
621}
622
623
624static PyObject *
625Tkapp_GlobalCall(self, args)
626 PyObject *self;
627 PyObject *args;
628{
Guido van Rossum212643f1998-04-29 16:22:14 +0000629 /* Could do the same here as for Tkapp_Call(), but this is not used
630 much, so I can't be bothered. Unfortunately Tcl doesn't export a
631 way for the user to do what all its Global* variants do (save and
632 reset the scope pointer, call the local version, restore the saved
633 scope pointer). */
634
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 char *cmd = Merge(args);
636 PyObject *res = NULL;
637
638
639 if (!cmd)
640 PyErr_SetString(Tkinter_TclError, "merge failed");
641
Guido van Rossum00d93061998-05-28 23:06:38 +0000642 else {
643 int err;
644 ENTER_TCL
645 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
646 LEAVE_TCL
647 if (err == TCL_ERROR)
648 res = Tkinter_Error(self);
649 else
650 res = PyString_FromString(Tkapp_Result(self));
651 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000652
653 if (cmd)
654 ckfree(cmd);
655
656 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000657}
658
659static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000660Tkapp_Eval(self, args)
661 PyObject *self;
662 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000663{
Barry Warsawfa701a81997-01-16 00:15:11 +0000664 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000665 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000666
Guido van Rossum35d43371997-08-02 00:09:09 +0000667 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000668 return NULL;
669
Guido van Rossum00d93061998-05-28 23:06:38 +0000670 ENTER_TCL
671 err = Tcl_Eval(Tkapp_Interp(self), script);
672 LEAVE_TCL
673 if (err == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000674 return Tkinter_Error(self);
675
676 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000677}
678
679static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000680Tkapp_GlobalEval(self, args)
681 PyObject *self;
682 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000683{
Barry Warsawfa701a81997-01-16 00:15:11 +0000684 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000685 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000686
Guido van Rossum35d43371997-08-02 00:09:09 +0000687 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000688 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000689
Guido van Rossum00d93061998-05-28 23:06:38 +0000690 ENTER_TCL
691 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
692 LEAVE_TCL
693 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000694 return Tkinter_Error(self);
Guido van Rossum00d93061998-05-28 23:06:38 +0000695
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000697}
698
699static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000700Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000701 PyObject *self;
702 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000703{
Barry Warsawfa701a81997-01-16 00:15:11 +0000704 char *fileName;
Guido van Rossum00d93061998-05-28 23:06:38 +0000705 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000706
Guido van Rossum35d43371997-08-02 00:09:09 +0000707 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000708 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000709
Guido van Rossum00d93061998-05-28 23:06:38 +0000710 ENTER_TCL
711 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
712 LEAVE_TCL
713 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000714 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000715
Barry Warsawfa701a81997-01-16 00:15:11 +0000716 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000717}
718
719static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000720Tkapp_Record(self, args)
721 PyObject *self;
722 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000723{
Barry Warsawfa701a81997-01-16 00:15:11 +0000724 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000725 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000726
Guido van Rossum35d43371997-08-02 00:09:09 +0000727 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000728 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000729
Guido van Rossum00d93061998-05-28 23:06:38 +0000730 ENTER_TCL
731 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
732 LEAVE_TCL
733 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000734 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000735
Barry Warsawfa701a81997-01-16 00:15:11 +0000736 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000737}
738
739static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000740Tkapp_AddErrorInfo(self, args)
741 PyObject *self;
742 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000743{
Barry Warsawfa701a81997-01-16 00:15:11 +0000744 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000745
Guido van Rossum35d43371997-08-02 00:09:09 +0000746 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000747 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000748 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000749 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000750 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000751
Barry Warsawfa701a81997-01-16 00:15:11 +0000752 Py_INCREF(Py_None);
753 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000754}
755
Barry Warsawfa701a81997-01-16 00:15:11 +0000756
757
Guido van Rossum18468821994-06-20 07:49:28 +0000758/** Tcl Variable **/
759
760static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000761SetVar(self, args, flags)
762 PyObject *self;
763 PyObject *args;
764 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000765{
Guido van Rossum00d93061998-05-28 23:06:38 +0000766 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000767 PyObject *newValue;
768 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000769
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 if (!tmp)
771 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000772
Guido van Rossum00d93061998-05-28 23:06:38 +0000773 if (PyArg_ParseTuple(args, "sO", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000774 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000775 s = AsString(newValue, tmp);
776 ENTER_TCL
777 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
778 LEAVE_TCL
779 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000780 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000781 PyErr_Clear();
Guido van Rossum00d93061998-05-28 23:06:38 +0000782 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue)) {
783 s = AsString (newValue, tmp);
784 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000785 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000786 s, flags);
787 LEAVE_TCL
788 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000789 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000790 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000791 return NULL;
792 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000793 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000794 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000795
Barry Warsawfa701a81997-01-16 00:15:11 +0000796 if (!ok)
797 return Tkinter_Error(self);
798
799 Py_INCREF(Py_None);
800 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000801}
802
803static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000804Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 PyObject *self;
806 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000807{
Barry Warsawfa701a81997-01-16 00:15:11 +0000808 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000809}
810
811static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000812Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000813 PyObject *self;
814 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000815{
Barry Warsawfa701a81997-01-16 00:15:11 +0000816 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000817}
818
Barry Warsawfa701a81997-01-16 00:15:11 +0000819
820
Guido van Rossum18468821994-06-20 07:49:28 +0000821static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000822GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 PyObject *self;
824 PyObject *args;
825 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000826{
Guido van Rossum35d43371997-08-02 00:09:09 +0000827 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000828
Guido van Rossum35d43371997-08-02 00:09:09 +0000829 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
830 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000831 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000832 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000833 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000834
Barry Warsawfa701a81997-01-16 00:15:11 +0000835 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000836 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000837 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000838
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 if (s == NULL)
840 return Tkinter_Error(self);
841
Guido van Rossum35d43371997-08-02 00:09:09 +0000842 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000843}
844
845static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000846Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000847 PyObject *self;
848 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000849{
Barry Warsawfa701a81997-01-16 00:15:11 +0000850 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000851}
852
853static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000854Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000855 PyObject *self;
856 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000857{
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000859}
860
Barry Warsawfa701a81997-01-16 00:15:11 +0000861
862
Guido van Rossum18468821994-06-20 07:49:28 +0000863static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000864UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000865 PyObject *self;
866 PyObject *args;
867 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000868{
Guido van Rossum35d43371997-08-02 00:09:09 +0000869 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum35d43371997-08-02 00:09:09 +0000872 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000873 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000874 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000875 if (name2 == NULL)
876 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
877
878 else
879 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000880 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000881
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000883 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000884
885 Py_INCREF(Py_None);
886 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000887}
888
889static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000890Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 PyObject *self;
892 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000893{
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
897static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000898Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 PyObject *self;
900 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000901{
Barry Warsawfa701a81997-01-16 00:15:11 +0000902 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000903}
904
Barry Warsawfa701a81997-01-16 00:15:11 +0000905
906
Guido van Rossum18468821994-06-20 07:49:28 +0000907/** Tcl to Python **/
908
909static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000910Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000911 PyObject *self;
912 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000913{
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 char *s;
915 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000916
Guido van Rossum35d43371997-08-02 00:09:09 +0000917 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000918 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000919 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 return Tkinter_Error(self);
921 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000922}
923
924static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000925Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 PyObject *self;
927 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000928{
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 char *s;
930 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000931
Guido van Rossum35d43371997-08-02 00:09:09 +0000932 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000933 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000934 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000935 return Tkinter_Error(self);
936 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000937}
938
939static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000940Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000941 PyObject *self;
942 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000943{
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 char *s;
945 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000946
Guido van Rossum35d43371997-08-02 00:09:09 +0000947 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000949 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
950 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000952}
953
954static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000955Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 PyObject *self;
957 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000958{
Barry Warsawfa701a81997-01-16 00:15:11 +0000959 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000960 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000961
Guido van Rossum35d43371997-08-02 00:09:09 +0000962 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000964 ENTER_TCL
965 retval = Tcl_ExprString(Tkapp_Interp(self), s);
966 LEAVE_TCL
967 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 return Tkinter_Error(self);
969 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000970}
971
972static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000973Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000974 PyObject *self;
975 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000976{
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000978 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000980
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000982 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000983 ENTER_TCL
984 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
985 LEAVE_TCL
986 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000987 return Tkinter_Error(self);
988 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000989}
990
991static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000992Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000993 PyObject *self;
994 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000995{
Barry Warsawfa701a81997-01-16 00:15:11 +0000996 char *s;
997 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000998 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000999
Guido van Rossum35d43371997-08-02 00:09:09 +00001000 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001002 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001003 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001004 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum00d93061998-05-28 23:06:38 +00001005 LEAVE_TCL
Guido van Rossum45b83911997-03-14 04:32:50 +00001006 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001007 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 return Tkinter_Error(self);
1009 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001010}
1011
1012static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001013Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 PyObject *self;
1015 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001016{
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +00001018 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001019 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001020
Guido van Rossum35d43371997-08-02 00:09:09 +00001021 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001023 ENTER_TCL
1024 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1025 LEAVE_TCL
1026 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 return Tkinter_Error(self);
1028 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001029}
1030
Barry Warsawfa701a81997-01-16 00:15:11 +00001031
1032
Guido van Rossum18468821994-06-20 07:49:28 +00001033static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001034Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001035 PyObject *self;
1036 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001037{
Barry Warsawfa701a81997-01-16 00:15:11 +00001038 char *list;
1039 int argc;
1040 char **argv;
1041 PyObject *v;
1042 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001043
Guido van Rossum35d43371997-08-02 00:09:09 +00001044 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001045 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001046
Barry Warsawfa701a81997-01-16 00:15:11 +00001047 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1048 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001049
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 if (!(v = PyTuple_New(argc)))
1051 return NULL;
1052
1053 for (i = 0; i < argc; i++) {
1054 PyObject *s = PyString_FromString(argv[i]);
1055 if (!s || PyTuple_SetItem(v, i, s)) {
1056 Py_DECREF(v);
1057 v = NULL;
1058 goto finally;
1059 }
1060 }
Guido van Rossum18468821994-06-20 07:49:28 +00001061
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 finally:
1063 ckfree(FREECAST argv);
1064 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001065}
1066
1067static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001068Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 PyObject *self;
1070 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001071{
Barry Warsawfa701a81997-01-16 00:15:11 +00001072 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001073
Guido van Rossum35d43371997-08-02 00:09:09 +00001074 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001076 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001077}
1078
1079static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001080Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 PyObject *self;
1082 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001083{
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 char *s = Merge(args);
1085 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001086
Barry Warsawfa701a81997-01-16 00:15:11 +00001087 if (s) {
1088 res = PyString_FromString(s);
1089 ckfree(s);
1090 }
1091 else
1092 PyErr_SetString(Tkinter_TclError, "merge failed");
1093
1094 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001095}
1096
Barry Warsawfa701a81997-01-16 00:15:11 +00001097
1098
Guido van Rossum18468821994-06-20 07:49:28 +00001099/** Tcl Command **/
1100
Guido van Rossum00d93061998-05-28 23:06:38 +00001101/* Client data struct */
1102typedef struct {
1103 PyThreadState *tstate;
1104 PyObject *self;
1105 PyObject *func;
1106} PythonCmd_ClientData;
1107
1108static int
1109PythonCmd_Error(interp)
1110 Tcl_Interp *interp;
1111{
1112 errorInCmd = 1;
1113 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1114 LEAVE_PYTHON
1115 return TCL_ERROR;
1116}
1117
Guido van Rossum18468821994-06-20 07:49:28 +00001118/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 * function or method.
1120 */
Guido van Rossum18468821994-06-20 07:49:28 +00001121static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001122PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001123 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001124 Tcl_Interp *interp;
1125 int argc;
1126 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001127{
Guido van Rossum00d93061998-05-28 23:06:38 +00001128 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001129 PyObject *self, *func, *arg, *res, *tmp;
1130 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001131
Guido van Rossum00d93061998-05-28 23:06:38 +00001132 /* XXX Should create fresh thread state? */
1133 ENTER_PYTHON(data->tstate)
1134
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 /* TBD: no error checking here since we know, via the
1136 * Tkapp_CreateCommand() that the client data is a two-tuple
1137 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001138 self = data->self;
1139 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001140
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 /* Create argument list (argv1, ..., argvN) */
1142 if (!(arg = PyTuple_New(argc - 1)))
1143 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001144
Barry Warsawfa701a81997-01-16 00:15:11 +00001145 for (i = 0; i < (argc - 1); i++) {
1146 PyObject *s = PyString_FromString(argv[i + 1]);
1147 if (!s || PyTuple_SetItem(arg, i, s)) {
1148 Py_DECREF(arg);
1149 PythonCmd_Error(interp);
1150 }
1151 }
1152 res = PyEval_CallObject(func, arg);
1153 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001154
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 if (res == NULL)
1156 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001157
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 if (!(tmp = PyList_New(0))) {
1159 Py_DECREF(res);
1160 return PythonCmd_Error(interp);
1161 }
1162
1163 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1164 Py_DECREF(res);
1165 Py_DECREF(tmp);
1166
Guido van Rossum00d93061998-05-28 23:06:38 +00001167 LEAVE_PYTHON
1168
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001170}
1171
1172static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001173PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001174 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001175{
Guido van Rossum00d93061998-05-28 23:06:38 +00001176 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1177
1178 ENTER_PYTHON(data->tstate)
1179 Py_XDECREF(data->self);
1180 Py_XDECREF(data->func);
1181 PyMem_DEL(data);
1182 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001183}
1184
Barry Warsawfa701a81997-01-16 00:15:11 +00001185
1186
Guido van Rossum18468821994-06-20 07:49:28 +00001187static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001188Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 PyObject *self;
1190 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001191{
Guido van Rossum00d93061998-05-28 23:06:38 +00001192 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001193 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001195 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001196
1197 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1198 return NULL;
1199 if (!PyCallable_Check(func)) {
1200 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 return NULL;
1202 }
Guido van Rossum18468821994-06-20 07:49:28 +00001203
Guido van Rossum00d93061998-05-28 23:06:38 +00001204 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 if (!data)
1206 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001207 data->tstate = PyThreadState_Get();
1208 Py_XINCREF(self);
1209 Py_XINCREF(func);
1210 data->self = self;
1211 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001212
Guido van Rossum00d93061998-05-28 23:06:38 +00001213 ENTER_TCL
1214 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1215 (ClientData)data, PythonCmdDelete);
1216 LEAVE_TCL
1217 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001218 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001219 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001220 return NULL;
1221 }
Guido van Rossum18468821994-06-20 07:49:28 +00001222
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 Py_INCREF(Py_None);
1224 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001225}
1226
Barry Warsawfa701a81997-01-16 00:15:11 +00001227
1228
Guido van Rossum18468821994-06-20 07:49:28 +00001229static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001230Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001231 PyObject *self;
1232 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001233{
Barry Warsawfa701a81997-01-16 00:15:11 +00001234 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001235 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001236
Guido van Rossum35d43371997-08-02 00:09:09 +00001237 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001239 ENTER_TCL
1240 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1241 LEAVE_TCL
1242 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1244 return NULL;
1245 }
1246 Py_INCREF(Py_None);
1247 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001248}
1249
Barry Warsawfa701a81997-01-16 00:15:11 +00001250
1251
Guido van Rossum00d93061998-05-28 23:06:38 +00001252#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001253/** File Handler **/
1254
Guido van Rossum00d93061998-05-28 23:06:38 +00001255typedef struct _fhcdata {
1256 PyThreadState *tstate;
1257 PyObject *func;
1258 PyObject *file;
1259 int id;
1260 struct _fhcdata *next;
1261} FileHandler_ClientData;
1262
1263static FileHandler_ClientData *HeadFHCD;
1264
1265static FileHandler_ClientData *
1266NewFHCD(func, file, id)
1267 PyObject *func;
1268 PyObject *file;
1269 int id;
1270{
1271 FileHandler_ClientData *p;
1272 p = PyMem_NEW(FileHandler_ClientData, 1);
1273 if (p != NULL) {
1274 Py_XINCREF(func);
1275 Py_XINCREF(file);
1276 p->tstate = PyThreadState_Get();
1277 p->func = func;
1278 p->file = file;
1279 p->id = id;
1280 p->next = HeadFHCD;
1281 HeadFHCD = p;
1282 }
1283 return p;
1284}
1285
1286static void
1287DeleteFHCD(id)
1288 int id;
1289{
1290 FileHandler_ClientData *p, **pp;
1291
1292 pp = &HeadFHCD;
1293 while ((p = *pp) != NULL) {
1294 if (p->id == id) {
1295 *pp = p->next;
1296 Py_XDECREF(p->func);
1297 Py_XDECREF(p->file);
1298 PyMem_DEL(p);
1299 }
1300 else
1301 pp = &p->next;
1302 }
1303}
1304
Guido van Rossuma597dde1995-01-10 20:56:29 +00001305static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001306FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001307 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001308 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001309{
Guido van Rossum00d93061998-05-28 23:06:38 +00001310 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001311 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001312
Guido van Rossum00d93061998-05-28 23:06:38 +00001313 /* XXX Should create fresh thread state? */
1314 ENTER_PYTHON(data->tstate)
1315 func = data->func;
1316 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001317
Barry Warsawfa701a81997-01-16 00:15:11 +00001318 arg = Py_BuildValue("(Oi)", file, (long) mask);
1319 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001320 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001321
1322 if (res == NULL) {
1323 errorInCmd = 1;
1324 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1325 }
1326 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001327 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001328}
1329
1330static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001331GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001332 /* Either an int >= 0 or an object with a
1333 *.fileno() method that returns an int >= 0
1334 */
1335 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001336{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001337 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001338 int id;
1339 if (PyInt_Check(file)) {
1340 id = PyInt_AsLong(file);
1341 if (id < 0)
1342 PyErr_SetString(PyExc_ValueError, "invalid file id");
1343 return id;
1344 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001345 args = PyTuple_New(0);
1346 if (args == NULL)
1347 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001348
1349 meth = PyObject_GetAttrString(file, "fileno");
1350 if (meth == NULL) {
1351 Py_DECREF(args);
1352 return -1;
1353 }
1354
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001355 res = PyEval_CallObject(meth, args);
1356 Py_DECREF(args);
1357 Py_DECREF(meth);
1358 if (res == NULL)
1359 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001360
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001361 if (PyInt_Check(res))
1362 id = PyInt_AsLong(res);
1363 else
1364 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001365
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001366 if (id < 0)
1367 PyErr_SetString(PyExc_ValueError,
1368 "invalid fileno() return value");
1369 Py_DECREF(res);
1370 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001371}
1372
1373static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001374Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 PyObject *self;
1376 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001377{
Guido van Rossum00d93061998-05-28 23:06:38 +00001378 FileHandler_ClientData *data;
1379 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001381 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001382
Guido van Rossum35d43371997-08-02 00:09:09 +00001383 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 return NULL;
1385 id = GetFileNo(file);
1386 if (id < 0)
1387 return NULL;
1388 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001389 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001390 return NULL;
1391 }
1392
Guido van Rossum00d93061998-05-28 23:06:38 +00001393 data = NewFHCD(func, file, id);
1394 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 return NULL;
1396
Guido van Rossum7bf15641998-05-22 18:28:17 +00001397 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001399 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001400 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001401 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001402 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001403 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001404}
1405
1406static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001407Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 PyObject *self;
1409 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001410{
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001412 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001414 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001415
Guido van Rossum35d43371997-08-02 00:09:09 +00001416 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001417 return NULL;
1418 id = GetFileNo(file);
1419 if (id < 0)
1420 return NULL;
1421
Guido van Rossum00d93061998-05-28 23:06:38 +00001422 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001423
Guido van Rossum7bf15641998-05-22 18:28:17 +00001424 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001425 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001426 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001428 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001429 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001431}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001432#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001433
Barry Warsawfa701a81997-01-16 00:15:11 +00001434
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001435/**** Tktt Object (timer token) ****/
1436
1437staticforward PyTypeObject Tktt_Type;
1438
Guido van Rossum00d93061998-05-28 23:06:38 +00001439typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001440 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001441 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001442 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001443 PyThreadState *tstate;
1444} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001445
1446static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001447Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 PyObject *self;
1449 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001450{
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001453
Guido van Rossum35d43371997-08-02 00:09:09 +00001454 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001455 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001456 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001457 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001458 v->token = NULL;
1459 }
1460 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001462 Py_DECREF(func);
1463 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 }
1465 Py_INCREF(Py_None);
1466 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001467}
1468
1469static PyMethodDef Tktt_methods[] =
1470{
Guido van Rossum35d43371997-08-02 00:09:09 +00001471 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001473};
1474
1475static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001476Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001478{
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001480
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 v = PyObject_NEW(TkttObject, &Tktt_Type);
1482 if (v == NULL)
1483 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001484
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 Py_INCREF(func);
1486 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001488 v->tstate = PyThreadState_Get();
1489
1490 /* Extra reference, deleted when called or when handler is deleted */
1491 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001492 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001493}
1494
1495static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001496Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001498{
Guido van Rossum00d93061998-05-28 23:06:38 +00001499 TkttObject *v = (TkttObject *)self;
1500 PyObject *func = v->func;
1501
1502 Py_XDECREF(func);
1503
Guido van Rossum35d43371997-08-02 00:09:09 +00001504 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001505}
1506
Guido van Rossum597ac201998-05-12 14:36:19 +00001507static PyObject *
1508Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001510{
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001512 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001513
Guido van Rossum597ac201998-05-12 14:36:19 +00001514 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001516 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001517}
1518
1519static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001520Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 PyObject *self;
1522 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001523{
Barry Warsawfa701a81997-01-16 00:15:11 +00001524 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001525}
1526
1527static PyTypeObject Tktt_Type =
1528{
Guido van Rossum35d43371997-08-02 00:09:09 +00001529 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 0, /*ob_size */
1531 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001532 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 0, /*tp_itemsize */
1534 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001535 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 Tktt_GetAttr, /*tp_getattr */
1537 0, /*tp_setattr */
1538 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001539 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001540 0, /*tp_as_number */
1541 0, /*tp_as_sequence */
1542 0, /*tp_as_mapping */
1543 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001544};
1545
Barry Warsawfa701a81997-01-16 00:15:11 +00001546
1547
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001548/** Timer Handler **/
1549
1550static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001551TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001553{
Guido van Rossum00d93061998-05-28 23:06:38 +00001554 TkttObject *v = (TkttObject *)clientData;
1555 PyObject *func = v->func;
1556 PyObject *res;
1557
1558 if (func == NULL)
1559 return;
1560
1561 v->func = NULL;
1562
1563 ENTER_PYTHON(v->tstate)
1564
1565 res = PyEval_CallObject(func, NULL);
1566 Py_DECREF(func);
1567 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001568
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 if (res == NULL) {
1570 errorInCmd = 1;
1571 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1572 }
1573 else
1574 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001575
1576 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001577}
1578
1579static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001580Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 PyObject *self;
1582 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001583{
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 int milliseconds;
1585 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001586 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001587
Guido van Rossum35d43371997-08-02 00:09:09 +00001588 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 return NULL;
1590 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001591 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 return NULL;
1593 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001594 v = Tktt_New(func);
1595 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1596 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001597
Guido van Rossum00d93061998-05-28 23:06:38 +00001598 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001599}
1600
Barry Warsawfa701a81997-01-16 00:15:11 +00001601
Guido van Rossum18468821994-06-20 07:49:28 +00001602/** Event Loop **/
1603
Guido van Rossum18468821994-06-20 07:49:28 +00001604static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001605Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001606 PyObject *self;
1607 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001608{
Barry Warsawfa701a81997-01-16 00:15:11 +00001609 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001610
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 if (!PyArg_ParseTuple(args, "|i", &threshold))
1612 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001613
Barry Warsawfa701a81997-01-16 00:15:11 +00001614 quitMainLoop = 0;
1615 while (Tk_GetNumMainWindows() > threshold &&
1616 !quitMainLoop &&
1617 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001618 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001619 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001620
1621#ifdef WITH_THREAD
1622 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001623 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossum00d93061998-05-28 23:06:38 +00001624 release_lock(tcl_lock);
1625 if (result == 0)
1626 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001627 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001628#else
1629 result = Tcl_DoOneEvent(0);
1630#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001631
Guido van Rossum35d43371997-08-02 00:09:09 +00001632 if (PyErr_CheckSignals() != 0)
1633 return NULL;
1634 if (result < 0)
1635 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001636 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001638
Barry Warsawfa701a81997-01-16 00:15:11 +00001639 if (errorInCmd) {
1640 errorInCmd = 0;
1641 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1642 excInCmd = valInCmd = trbInCmd = NULL;
1643 return NULL;
1644 }
1645 Py_INCREF(Py_None);
1646 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001647}
1648
1649static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001650Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 PyObject *self;
1652 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001653{
Guido van Rossum35d43371997-08-02 00:09:09 +00001654 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001655 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001656
Barry Warsawfa701a81997-01-16 00:15:11 +00001657 if (!PyArg_ParseTuple(args, "|i", &flags))
1658 return NULL;
1659
Guido van Rossum00d93061998-05-28 23:06:38 +00001660 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001661 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001662 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001663 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001664}
1665
1666static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001667Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001668 PyObject *self;
1669 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001670{
1671
Guido van Rossum35d43371997-08-02 00:09:09 +00001672 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001673 return NULL;
1674
1675 quitMainLoop = 1;
1676 Py_INCREF(Py_None);
1677 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001678}
1679
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001680static PyObject *
1681Tkapp_InterpAddr(self, args)
1682 PyObject *self;
1683 PyObject *args;
1684{
1685
1686 if (!PyArg_ParseTuple(args, ""))
1687 return NULL;
1688
1689 return PyInt_FromLong((long)Tkapp_Interp(self));
1690}
1691
Barry Warsawfa701a81997-01-16 00:15:11 +00001692
1693
Guido van Rossum18468821994-06-20 07:49:28 +00001694/**** Tkapp Method List ****/
1695
1696static PyMethodDef Tkapp_methods[] =
1697{
Guido van Rossum35d43371997-08-02 00:09:09 +00001698 {"call", Tkapp_Call, 0},
1699 {"globalcall", Tkapp_GlobalCall, 0},
1700 {"eval", Tkapp_Eval, 1},
1701 {"globaleval", Tkapp_GlobalEval, 1},
1702 {"evalfile", Tkapp_EvalFile, 1},
1703 {"record", Tkapp_Record, 1},
1704 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1705 {"setvar", Tkapp_SetVar, 1},
1706 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1707 {"getvar", Tkapp_GetVar, 1},
1708 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1709 {"unsetvar", Tkapp_UnsetVar, 1},
1710 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1711 {"getint", Tkapp_GetInt, 1},
1712 {"getdouble", Tkapp_GetDouble, 1},
1713 {"getboolean", Tkapp_GetBoolean, 1},
1714 {"exprstring", Tkapp_ExprString, 1},
1715 {"exprlong", Tkapp_ExprLong, 1},
1716 {"exprdouble", Tkapp_ExprDouble, 1},
1717 {"exprboolean", Tkapp_ExprBoolean, 1},
1718 {"splitlist", Tkapp_SplitList, 1},
1719 {"split", Tkapp_Split, 1},
1720 {"merge", Tkapp_Merge, 0},
1721 {"createcommand", Tkapp_CreateCommand, 1},
1722 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001723#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001724 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1725 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001726#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001727 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 {"mainloop", Tkapp_MainLoop, 1},
1729 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001730 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001731 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001732 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001733};
1734
Barry Warsawfa701a81997-01-16 00:15:11 +00001735
1736
Guido van Rossum18468821994-06-20 07:49:28 +00001737/**** Tkapp Type Methods ****/
1738
1739static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001740Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001741 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001742{
Guido van Rossum00d93061998-05-28 23:06:38 +00001743 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001744 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001745 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001746 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001747 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001748}
1749
1750static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001751Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001752 PyObject *self;
1753 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001754{
Guido van Rossum35d43371997-08-02 00:09:09 +00001755 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001756}
1757
1758static PyTypeObject Tkapp_Type =
1759{
Guido van Rossum35d43371997-08-02 00:09:09 +00001760 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001761 0, /*ob_size */
1762 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001763 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001764 0, /*tp_itemsize */
1765 Tkapp_Dealloc, /*tp_dealloc */
1766 0, /*tp_print */
1767 Tkapp_GetAttr, /*tp_getattr */
1768 0, /*tp_setattr */
1769 0, /*tp_compare */
1770 0, /*tp_repr */
1771 0, /*tp_as_number */
1772 0, /*tp_as_sequence */
1773 0, /*tp_as_mapping */
1774 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001775};
1776
Barry Warsawfa701a81997-01-16 00:15:11 +00001777
1778
Guido van Rossum18468821994-06-20 07:49:28 +00001779/**** Tkinter Module ****/
1780
1781static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001782Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001783 PyObject *self;
1784 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001785{
Barry Warsawfa701a81997-01-16 00:15:11 +00001786 char *screenName = NULL;
1787 char *baseName = NULL;
1788 char *className = NULL;
1789 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001790
Guido van Rossum35d43371997-08-02 00:09:09 +00001791 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001792 if (baseName != NULL)
1793 baseName++;
1794 else
1795 baseName = Py_GetProgramName();
1796 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001797
Barry Warsawfa701a81997-01-16 00:15:11 +00001798 if (!PyArg_ParseTuple(args, "|zssi",
1799 &screenName, &baseName, &className,
1800 &interactive))
1801 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001802
Barry Warsawfa701a81997-01-16 00:15:11 +00001803 return (PyObject *) Tkapp_New(screenName, baseName, className,
1804 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001805}
1806
1807static PyMethodDef moduleMethods[] =
1808{
Barry Warsawfa701a81997-01-16 00:15:11 +00001809 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001810#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001811 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1812 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001813#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001814 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001815 {"mainloop", Tkapp_MainLoop, 1},
1816 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001817 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001818 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001819};
1820
Guido van Rossum7bf15641998-05-22 18:28:17 +00001821#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001822
1823static int stdin_ready = 0;
1824
1825static void
1826MyFileProc(clientData, mask)
1827 void *clientData;
1828 int mask;
1829{
1830 stdin_ready = 1;
1831}
Guido van Rossum7bf15641998-05-22 18:28:17 +00001832
Guido van Rossum00d93061998-05-28 23:06:38 +00001833static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001834
Guido van Rossum18468821994-06-20 07:49:28 +00001835static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001836EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001837{
Guido van Rossum00d93061998-05-28 23:06:38 +00001838 FHANDLE tfile;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001839
Guido van Rossum00d93061998-05-28 23:06:38 +00001840 ENTER_PYTHON(event_tstate)
1841 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001842 stdin_ready = 0;
1843 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossum00d93061998-05-28 23:06:38 +00001844 while (!errorInCmd && !stdin_ready) {
1845 int result;
1846
1847#ifdef WITH_THREAD
1848 ENTER_TCL
1849 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1850 release_lock(tcl_lock);
1851 if (result == 0)
1852 Sleep(20);
1853 Py_END_ALLOW_THREADS
1854#else
1855 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001856#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001857
1858 if (result < 0)
1859 break;
1860 }
1861 Tcl_DeleteFileHandler(tfile);
Barry Warsawfa701a81997-01-16 00:15:11 +00001862 if (errorInCmd) {
1863 errorInCmd = 0;
1864 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1865 excInCmd = valInCmd = trbInCmd = NULL;
1866 PyErr_Print();
1867 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001868 LEAVE_PYTHON
Barry Warsawfa701a81997-01-16 00:15:11 +00001869 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001870}
Guido van Rossum18468821994-06-20 07:49:28 +00001871
Guido van Rossum00d93061998-05-28 23:06:38 +00001872#endif
1873
Guido van Rossum7bf15641998-05-22 18:28:17 +00001874static void
1875EnableEventHook()
1876{
Guido van Rossum00d93061998-05-28 23:06:38 +00001877#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001878 if (PyOS_InputHook == NULL) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001879 event_tstate = PyThreadState_Get();
Guido van Rossum7bf15641998-05-22 18:28:17 +00001880 PyOS_InputHook = EventHook;
1881 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001882#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001883}
1884
1885static void
1886DisableEventHook()
1887{
Guido van Rossum00d93061998-05-28 23:06:38 +00001888#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001889 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1890 PyOS_InputHook = NULL;
1891 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001892#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001893}
1894
Barry Warsawfa701a81997-01-16 00:15:11 +00001895
1896/* all errors will be checked in one fell swoop in init_tkinter() */
1897static void
1898ins_long(d, name, val)
1899 PyObject *d;
1900 char *name;
1901 long val;
1902{
1903 PyObject *v = PyInt_FromLong(val);
1904 if (v) {
1905 PyDict_SetItemString(d, name, v);
1906 Py_DECREF(v);
1907 }
1908}
1909static void
1910ins_string(d, name, val)
1911 PyObject *d;
1912 char *name;
1913 char *val;
1914{
1915 PyObject *v = PyString_FromString(val);
1916 if (v) {
1917 PyDict_SetItemString(d, name, v);
1918 Py_DECREF(v);
1919 }
1920}
1921
1922
Guido van Rossum18468821994-06-20 07:49:28 +00001923void
Guido van Rossum35d43371997-08-02 00:09:09 +00001924init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001925{
Barry Warsawfa701a81997-01-16 00:15:11 +00001926 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001927
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00001929
1930#ifdef WITH_THREAD
1931 tcl_lock = allocate_lock();
1932#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00001933
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001935
Barry Warsawfa701a81997-01-16 00:15:11 +00001936 d = PyModule_GetDict(m);
1937 Tkinter_TclError = Py_BuildValue("s", "TclError");
1938 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001939
Guido van Rossum35d43371997-08-02 00:09:09 +00001940 ins_long(d, "READABLE", TCL_READABLE);
1941 ins_long(d, "WRITABLE", TCL_WRITABLE);
1942 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1943 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1944 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1945 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1946 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1947 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1948 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001949 ins_string(d, "TK_VERSION", TK_VERSION);
1950 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001951
Guido van Rossum83551bf1997-09-13 00:44:23 +00001952 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00001953
1954 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00001955 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1956
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001958 return;
1959
Guido van Rossum26216371998-04-20 18:47:52 +00001960#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001961 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001962#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001963
Jack Jansen34cc5c31995-10-31 16:15:12 +00001964#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001965 /*
1966 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1967 ** Most of the initializations in that routine (toolbox init calls and
1968 ** such) have already been done for us, so we only need these.
1969 */
1970#if TKMAJORMINOR >= 8000
1971 tcl_macQdPtr = &qd;
1972#endif
1973
1974 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001975#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001977#endif /* GENERATINGCFM */
1978#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001979}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001980
Guido van Rossumec22c921996-02-25 04:50:29 +00001981
Barry Warsawfa701a81997-01-16 00:15:11 +00001982
Guido van Rossum9722ad81995-09-22 23:49:28 +00001983#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001984
1985/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001986** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001987*/
1988
Guido van Rossum9722ad81995-09-22 23:49:28 +00001989void
1990panic(char * format, ...)
1991{
Barry Warsawfa701a81997-01-16 00:15:11 +00001992 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001993
Barry Warsawfa701a81997-01-16 00:15:11 +00001994 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001995
Guido van Rossumb41addf1998-05-12 15:02:41 +00001996 vPySys_WriteStderr(format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001997 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001998
Barry Warsawfa701a81997-01-16 00:15:11 +00001999 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002000
Barry Warsawfa701a81997-01-16 00:15:11 +00002001 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002002}
Jack Jansen40b546d1995-11-14 10:34:45 +00002003
Guido van Rossumec22c921996-02-25 04:50:29 +00002004/*
2005** Pass events to SIOUX before passing them to Tk.
2006*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002007
Guido van Rossumec22c921996-02-25 04:50:29 +00002008static int
2009PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002010 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002011{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002012 WindowPtr frontwin;
2013 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002014 ** Sioux eats too many events, so we don't pass it everything. We
2015 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002016 ** the Sioux window is frontmost. This means that Tk menus don't work
2017 ** in that case, but at least we can scroll the sioux window.
2018 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2019 ** part of the external interface of Sioux...
2020 */
2021 frontwin = FrontWindow();
2022 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2023 if (SIOUXHandleOneEvent(eventPtr))
2024 return 0; /* Nothing happened to the Tcl event queue */
2025 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002026 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002027}
2028
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002029#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002030/*
2031 * For Python we have to override this routine (from TclMacNotify),
2032 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2033 * to use GUSI select to see whether our socket is ready. Note that
2034 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2035 * files and sockets.
2036 *
2037 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2038 * for other versions. */
2039
2040int
2041Tcl_FileReady(file, mask)
2042 Tcl_File file; /* File handle for a stream. */
2043 int mask; /* OR'ed combination of TCL_READABLE,
2044 * TCL_WRITABLE, and TCL_EXCEPTION:
2045 * indicates conditions caller cares about. */
2046{
2047 int type;
2048 int fd;
2049
2050 fd = (int) Tcl_GetFileInfo(file, &type);
2051
2052 if (type == TCL_MAC_SOCKET) {
2053 return TclMacSocketReady(file, mask);
2054 } else if (type == TCL_MAC_FILE) {
2055 /*
2056 * Under the Macintosh, files are always ready, so we just
2057 * return the mask that was passed in.
2058 */
2059
2060 return mask;
2061 } else if (type == TCL_UNIX_FD) {
2062 fd_set readset, writeset, excset;
2063 struct timeval tv;
2064
2065 FD_ZERO(&readset);
2066 FD_ZERO(&writeset);
2067 FD_ZERO(&excset);
2068
2069 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2070 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2071 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2072
2073 tv.tv_sec = tv.tv_usec = 0;
2074 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2075 return 0;
2076
2077 mask = 0;
2078 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2079 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2080 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2081
2082 return mask;
2083 }
2084
2085 return 0;
2086}
2087#endif /* USE_GUSI */
2088
Guido van Rossumec22c921996-02-25 04:50:29 +00002089#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002090
2091/*
2092** Additional Mac specific code for dealing with shared libraries.
2093*/
2094
2095#include <Resources.h>
2096#include <CodeFragments.h>
2097
2098static int loaded_from_shlib = 0;
2099static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002100
Jack Jansen34cc5c31995-10-31 16:15:12 +00002101/*
2102** If this module is dynamically loaded the following routine should
2103** be the init routine. It takes care of adding the shared library to
2104** the resource-file chain, so that the tk routines can find their
2105** resources.
2106*/
2107OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002108init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002109{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002110 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002111 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002112 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002113 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2114 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002115 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002116 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2117 loaded_from_shlib = 1;
2118 }
2119 return noErr;
2120}
2121
2122/*
2123** Insert the library resources into the search path. Put them after
2124** the resources from the application. Again, we ignore errors.
2125*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002126static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002127mac_addlibresources()
2128{
2129 if ( !loaded_from_shlib )
2130 return;
2131 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2132}
2133
Guido van Rossumec22c921996-02-25 04:50:29 +00002134#endif /* GENERATINGCFM */
2135#endif /* macintosh */