blob: 601a70c56e570d06790ac8a02e38269a0cc23e75 [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
Guido van Rossuma80649b2000-03-28 20:07:05 +000037 Only Tcl/Tk 8.0 and later are supported. Older versions are not
38 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
39 libraries.)
40*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
Guido van Rossuma80649b2000-03-28 20:07:05 +000042/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000043
44 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
45 intelligent mappings between Python objects and Tcl objects (e.g. ints,
46 floats and Tcl window pointers could be handled specially).
47
48 - Register a new Tcl type, "Python callable", which can be called more
49 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
50
Guido van Rossum7ffa7611996-08-13 21:10:16 +000051*/
52
Guido van Rossum35d43371997-08-02 00:09:09 +000053
Guido van Rossum9722ad81995-09-22 23:49:28 +000054#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000055#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000056
Guido van Rossum00d93061998-05-28 23:06:38 +000057#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000058#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000059#endif
60
Guido van Rossum2a5119b1998-05-29 01:28:40 +000061#ifdef MS_WINDOWS
62#include <windows.h>
63#endif
64
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000065#ifdef macintosh
66#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000067#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000068#endif
69
Guido van Rossum49b56061998-10-01 20:42:43 +000070#ifdef PYOS_OS2
71#include "myselect.h"
72#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 Rossuma80649b2000-03-28 20:07:05 +000079#if TKMAJORMINOR < 8000
80#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Guido van Rossuma80649b2000-03-28 20:07:05 +000083#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084/* 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 Rossuma80649b2000-03-28 20:07:05 +000090#if !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
Guido van Rossum00d93061998-05-28 23:06:38 +0000107/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
108 which uses this to handle Tcl events while the user is typing commands. */
109
110#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000111#define WAIT_FOR_STDIN
112#endif
113
Guido van Rossum00d93061998-05-28 23:06:38 +0000114#endif /* HAVE_CREATEFILEHANDLER */
115
Guido van Rossumad4db171998-06-13 13:56:28 +0000116#ifdef MS_WINDOWS
117#include <conio.h>
118#define WAIT_FOR_STDIN
119#endif
120
Guido van Rossum00d93061998-05-28 23:06:38 +0000121#ifdef WITH_THREAD
122
123/* The threading situation is complicated. Tcl is not thread-safe, except for
124 Tcl 8.1, which will probably remain in alpha status for another 6 months
125 (and the README says that Tk will probably remain thread-unsafe forever).
126 So we need to use a lock around all uses of Tcl. Previously, the Python
127 interpreter lock was used for this. However, this causes problems when
128 other Python threads need to run while Tcl is blocked waiting for events.
129
130 To solve this problem, a separate lock for Tcl is introduced. Holding it
131 is incompatible with holding Python's interpreter lock. The following four
132 macros manipulate both locks together.
133
134 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
135 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
136 that could call an event handler, or otherwise affect the state of a Tcl
137 interpreter. These assume that the surrounding code has the Python
138 interpreter lock; inside the brackets, the Python interpreter lock has been
139 released and the lock for Tcl has been acquired.
140
Guido van Rossum5e977831998-06-15 14:03:52 +0000141 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
142 (For example, when transferring data from the Tcl interpreter result to a
143 Python string object.) This can be done by using different macros to close
144 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
145 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
146 releases the Tcl lock.
147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000149 handlers when the handler needs to use Python. Such event handlers are
150 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000152 the Python interpreter lock, restoring the appropriate thread state, and
153 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
154 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000155 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157 These locks expand to several statements and brackets; they should not be
158 used in branches of if statements and the like.
159
160*/
161
Guido van Rossum65d5b571998-12-21 19:32:43 +0000162static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000164
165#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000166 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000170 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000171
Guido van Rossum62320c91998-06-15 04:36:09 +0000172#define ENTER_OVERLAP \
173 Py_END_ALLOW_THREADS
174
175#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000176 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000177
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178#define ENTER_PYTHON \
179 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000181
182#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000184 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000185
186#else
187
188#define ENTER_TCL
189#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000190#define ENTER_OVERLAP
191#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000192#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000193#define LEAVE_PYTHON
194
195#endif
196
Guido van Rossumec22c921996-02-25 04:50:29 +0000197#ifdef macintosh
198
199/*
200** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000201** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000202*/
203
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000204/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000205#define FREECAST (char *)
206
Guido van Rossumec22c921996-02-25 04:50:29 +0000207#include <Events.h> /* For EventRecord */
208
209typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000210void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000211int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
212
213staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
214
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000215#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
216 #pragma import on
217#endif
218
219#include <SIOUX.h>
220extern int SIOUXIsAppWindow(WindowPtr);
221
222#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
223 #pragma import reset
224#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000225#endif /* macintosh */
226
Guido van Rossum97867b21996-08-08 19:09:53 +0000227#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000228#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000229#endif
230
Guido van Rossum18468821994-06-20 07:49:28 +0000231/**** Tkapp Object Declaration ****/
232
233staticforward PyTypeObject Tkapp_Type;
234
Guido van Rossum00d93061998-05-28 23:06:38 +0000235typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000236 PyObject_HEAD
237 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000238} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000239
240#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000241#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
242#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
243
Guido van Rossum35d43371997-08-02 00:09:09 +0000244#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000245(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Barry Warsawfa701a81997-01-16 00:15:11 +0000247
248
Guido van Rossum18468821994-06-20 07:49:28 +0000249/**** Error Handling ****/
250
251static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000252static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000253static int errorInCmd = 0;
254static PyObject *excInCmd;
255static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000257
Barry Warsawfa701a81997-01-16 00:15:11 +0000258
259
Guido van Rossum18468821994-06-20 07:49:28 +0000260static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000261Tkinter_Error(v)
262 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000263{
Barry Warsawfa701a81997-01-16 00:15:11 +0000264 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
265 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000266}
267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268
Barry Warsawfa701a81997-01-16 00:15:11 +0000269
Guido van Rossum18468821994-06-20 07:49:28 +0000270/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000271
272#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000273#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000274#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000275#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000276
Guido van Rossum00d93061998-05-28 23:06:38 +0000277/* Millisecond sleep() for Unix platforms. */
278
279static void
280Sleep(milli)
281 int milli;
282{
283 /* XXX Too bad if you don't have select(). */
284 struct timeval t;
285 double frac;
286 t.tv_sec = milli/1000;
287 t.tv_usec = (milli%1000) * 1000;
288 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
289}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000290#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000291#endif /* WITH_THREAD */
292
293
Guido van Rossum18468821994-06-20 07:49:28 +0000294static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000295AsString(value, tmp)
296 PyObject *value;
297 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000298{
Guido van Rossum35d43371997-08-02 00:09:09 +0000299 if (PyString_Check(value))
300 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 else {
302 PyObject *v = PyObject_Str(value);
303 PyList_Append(tmp, v);
304 Py_DECREF(v);
305 return PyString_AsString(v);
306 }
Guido van Rossum18468821994-06-20 07:49:28 +0000307}
308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309
310
Guido van Rossum18468821994-06-20 07:49:28 +0000311#define ARGSZ 64
312
313static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000314Merge(args)
315 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000316{
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 PyObject *tmp = NULL;
318 char *argvStore[ARGSZ];
319 char **argv = NULL;
320 int fvStore[ARGSZ];
321 int *fv = NULL;
322 int argc = 0, i;
323 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (!(tmp = PyList_New(0)))
326 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000327
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 argv = argvStore;
329 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (args == NULL)
332 argc = 0;
333
334 else if (!PyTuple_Check(args)) {
335 argc = 1;
336 fv[0] = 0;
337 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000338 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 else {
340 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000341
Barry Warsawfa701a81997-01-16 00:15:11 +0000342 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000343 argv = (char **)ckalloc(argc * sizeof(char *));
344 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000345 if (argv == NULL || fv == NULL) {
346 PyErr_NoMemory();
347 goto finally;
348 }
349 }
350
351 for (i = 0; i < argc; i++) {
352 PyObject *v = PyTuple_GetItem(args, i);
353 if (PyTuple_Check(v)) {
354 fv[i] = 1;
355 if (!(argv[i] = Merge(v)))
356 goto finally;
357 }
358 else if (v == Py_None) {
359 argc = i;
360 break;
361 }
362 else {
363 fv[i] = 0;
364 argv[i] = AsString(v, tmp);
365 }
366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 finally:
371 for (i = 0; i < argc; i++)
372 if (fv[i]) {
373 ckfree(argv[i]);
374 }
375 if (argv != argvStore)
376 ckfree(FREECAST argv);
377 if (fv != fvStore)
378 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 Py_DECREF(tmp);
381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000382}
383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384
385
Guido van Rossum18468821994-06-20 07:49:28 +0000386static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000387Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000389{
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 int argc;
391 char **argv;
392 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 if (list == NULL) {
395 Py_INCREF(Py_None);
396 return Py_None;
397 }
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 /* Not a list.
401 * Could be a quoted string containing funnies, e.g. {"}.
402 * Return the string itself.
403 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 return PyString_FromString(list);
405 }
Guido van Rossum18468821994-06-20 07:49:28 +0000406
Barry Warsawfa701a81997-01-16 00:15:11 +0000407 if (argc == 0)
408 v = PyString_FromString("");
409 else if (argc == 1)
410 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000411 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 int i;
413 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000416 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 Py_DECREF(v);
418 v = NULL;
419 break;
420 }
421 PyTuple_SetItem(v, i, w);
422 }
423 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000424 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427
Barry Warsawfa701a81997-01-16 00:15:11 +0000428
429
Guido van Rossum18468821994-06-20 07:49:28 +0000430/**** Tkapp Object ****/
431
432#ifndef WITH_APPINIT
433int
Guido van Rossum35d43371997-08-02 00:09:09 +0000434Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000436{
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000438
Barry Warsawfa701a81997-01-16 00:15:11 +0000439 main = Tk_MainWindow(interp);
440 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000441 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000442 return TCL_ERROR;
443 }
444 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000445 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000446 return TCL_ERROR;
447 }
448 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000449}
450#endif /* !WITH_APPINIT */
451
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453
454
455/* Initialize the Tk application; see the `main' function in
456 * `tkMain.c'.
457 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000458
459static void EnableEventHook(); /* Forward */
460static void DisableEventHook(); /* Forward */
461
Barry Warsawfa701a81997-01-16 00:15:11 +0000462static TkappObject *
463Tkapp_New(screenName, baseName, className, interactive)
464 char *screenName;
465 char *baseName;
466 char *className;
467 int interactive;
468{
469 TkappObject *v;
470 char *argv0;
471
472 v = PyObject_NEW(TkappObject, &Tkapp_Type);
473 if (v == NULL)
474 return NULL;
475
476 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000477
Guido van Rossuma80649b2000-03-28 20:07:05 +0000478#if defined(macintosh)
479 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000480 ClearMenuBar();
481 TkMacInitMenus(v->interp);
482#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000483 /* Delete the 'exit' command, which can screw things up */
484 Tcl_DeleteCommand(v->interp, "exit");
485
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 if (screenName != NULL)
487 Tcl_SetVar2(v->interp, "env", "DISPLAY",
488 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 if (interactive)
491 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
492 else
493 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000494
Barry Warsawfa701a81997-01-16 00:15:11 +0000495 /* This is used to get the application class for Tk 4.1 and up */
496 argv0 = (char*)ckalloc(strlen(className) + 1);
497 if (!argv0) {
498 PyErr_NoMemory();
499 Py_DECREF(v);
500 return NULL;
501 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000504 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 argv0[0] = tolower(argv0[0]);
506 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
507 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000510 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000511
Guido van Rossum7bf15641998-05-22 18:28:17 +0000512 EnableEventHook();
513
Barry Warsawfa701a81997-01-16 00:15:11 +0000514 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000515}
516
Barry Warsawfa701a81997-01-16 00:15:11 +0000517
518
Guido van Rossum18468821994-06-20 07:49:28 +0000519/** Tcl Eval **/
520
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000521#if TKMAJORMINOR >= 8001
522#define USING_OBJECTS
523#endif
524
525#ifdef USING_OBJECTS
526
527static Tcl_Obj*
528AsObj(value)
529 PyObject *value;
530{
531 Tcl_Obj *result;
532
533 if (PyString_Check(value))
534 return Tcl_NewStringObj(PyString_AS_STRING(value),
535 PyString_GET_SIZE(value));
536 else if (PyInt_Check(value))
537 return Tcl_NewLongObj(PyInt_AS_LONG(value));
538 else if (PyFloat_Check(value))
539 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
540 else if (PyTuple_Check(value)) {
541 Tcl_Obj **argv = (Tcl_Obj**)
542 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
543 int i;
544 if(!argv)
545 return 0;
546 for(i=0;i<PyTuple_Size(value);i++)
547 argv[i] = AsObj(PyTuple_GetItem(value,i));
548 result = Tcl_NewListObj(PyTuple_Size(value), argv);
549 ckfree(FREECAST argv);
550 return result;
551 }
552 else if (PyUnicode_Check(value)) {
553 PyObject* utf8 = PyUnicode_AsUTF8String (value);
554 if (!utf8)
555 return 0;
556 return Tcl_NewStringObj (PyString_AS_STRING (utf8),
557 PyString_GET_SIZE (utf8));
558 }
559 else {
560 PyObject *v = PyObject_Str(value);
561 if (!v)
562 return 0;
563 result = AsObj(v);
564 Py_DECREF(v);
565 return result;
566 }
567}
568
Guido van Rossum18468821994-06-20 07:49:28 +0000569static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000570Tkapp_Call(self, args)
571 PyObject *self;
572 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000573{
Guido van Rossum632de272000-03-29 00:19:50 +0000574 Tcl_Obj *objStore[ARGSZ];
575 Tcl_Obj **objv = NULL;
576 int objc = 0, i;
577 PyObject *res = NULL;
578 Tcl_Interp *interp = Tkapp_Interp(self);
579 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
580 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000581
Guido van Rossum632de272000-03-29 00:19:50 +0000582 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000583
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000585 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000586
Guido van Rossum212643f1998-04-29 16:22:14 +0000587 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000588 objc = 1;
589 objv[0] = AsObj(args);
590 if (objv[0] == 0)
591 goto finally;
592 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 }
594 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000595 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000596
Guido van Rossum632de272000-03-29 00:19:50 +0000597 if (objc > ARGSZ) {
598 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
599 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000600 PyErr_NoMemory();
601 goto finally;
602 }
603 }
604
Guido van Rossum632de272000-03-29 00:19:50 +0000605 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000606 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000607 if (v == Py_None) {
608 objc = i;
609 break;
610 }
Guido van Rossum632de272000-03-29 00:19:50 +0000611 objv[i] = AsObj(v);
612 if (!objv[i])
613 goto finally;
614 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000615 }
616 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000617
Guido van Rossum62320c91998-06-15 04:36:09 +0000618 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000619
620 i = Tcl_EvalObjv(interp, objc, objv, flags);
621
Guido van Rossum62320c91998-06-15 04:36:09 +0000622 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000623 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000624 Tkinter_Error(self);
Guido van Rossum632de272000-03-29 00:19:50 +0000625 else
626 /* We could request the object result here, but doing
627 so would confuse applications that expect a string. */
628 res = PyString_FromString(Tcl_GetStringResult(interp));
629
Guido van Rossum62320c91998-06-15 04:36:09 +0000630 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000631
Guido van Rossum212643f1998-04-29 16:22:14 +0000632 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000633 for (i = 0; i < objc; i++)
634 Tcl_DecrRefCount(objv[i]);
635 if (objv != objStore)
636 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000637 return res;
638}
639
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000640#else /* !USING_OBJECTS */
641
642static PyObject *
643Tkapp_Call(self, args)
644 PyObject *self;
645 PyObject *args;
646{
647 /* This is copied from Merge() */
648 PyObject *tmp = NULL;
649 char *argvStore[ARGSZ];
650 char **argv = NULL;
651 int fvStore[ARGSZ];
652 int *fv = NULL;
653 int argc = 0, i;
654 PyObject *res = NULL; /* except this has a different type */
655 Tcl_CmdInfo info; /* and this is added */
656 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
657
658 if (!(tmp = PyList_New(0)))
659 return NULL;
660
661 argv = argvStore;
662 fv = fvStore;
663
664 if (args == NULL)
665 argc = 0;
666
667 else if (!PyTuple_Check(args)) {
668 argc = 1;
669 fv[0] = 0;
670 argv[0] = AsString(args, tmp);
671 }
672 else {
673 argc = PyTuple_Size(args);
674
675 if (argc > ARGSZ) {
676 argv = (char **)ckalloc(argc * sizeof(char *));
677 fv = (int *)ckalloc(argc * sizeof(int));
678 if (argv == NULL || fv == NULL) {
679 PyErr_NoMemory();
680 goto finally;
681 }
682 }
683
684 for (i = 0; i < argc; i++) {
685 PyObject *v = PyTuple_GetItem(args, i);
686 if (PyTuple_Check(v)) {
687 fv[i] = 1;
688 if (!(argv[i] = Merge(v)))
689 goto finally;
690 }
691 else if (v == Py_None) {
692 argc = i;
693 break;
694 }
695 else {
696 fv[i] = 0;
697 argv[i] = AsString(v, tmp);
698 }
699 }
700 }
701 /* End code copied from Merge() */
702
703 /* All this to avoid a call to Tcl_Merge() and the corresponding call
704 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
705 if (Py_VerboseFlag >= 2) {
706 for (i = 0; i < argc; i++)
707 PySys_WriteStderr("%s ", argv[i]);
708 }
709 ENTER_TCL
710 info.proc = NULL;
711 if (argc < 1 ||
712 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
713 info.proc == NULL)
714 {
715 char *cmd;
716 cmd = Tcl_Merge(argc, argv);
717 i = Tcl_Eval(interp, cmd);
718 ckfree(cmd);
719 }
720 else {
721 Tcl_ResetResult(interp);
722 i = (*info.proc)(info.clientData, interp, argc, argv);
723 }
724 ENTER_OVERLAP
725 if (info.proc == NULL && Py_VerboseFlag >= 2)
726 PySys_WriteStderr("... use TclEval ");
727 if (i == TCL_ERROR) {
728 if (Py_VerboseFlag >= 2)
729 PySys_WriteStderr("... error: '%s'\n",
730 interp->result);
731 Tkinter_Error(self);
732 }
733 else {
734 if (Py_VerboseFlag >= 2)
735 PySys_WriteStderr("-> '%s'\n", interp->result);
736 res = PyString_FromString(interp->result);
737 }
738 LEAVE_OVERLAP_TCL
739
740 /* Copied from Merge() again */
741 finally:
742 for (i = 0; i < argc; i++)
743 if (fv[i]) {
744 ckfree(argv[i]);
745 }
746 if (argv != argvStore)
747 ckfree(FREECAST argv);
748 if (fv != fvStore)
749 ckfree(FREECAST fv);
750
751 Py_DECREF(tmp);
752 return res;
753}
754
755#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000756
757static PyObject *
758Tkapp_GlobalCall(self, args)
759 PyObject *self;
760 PyObject *args;
761{
Guido van Rossum212643f1998-04-29 16:22:14 +0000762 /* Could do the same here as for Tkapp_Call(), but this is not used
763 much, so I can't be bothered. Unfortunately Tcl doesn't export a
764 way for the user to do what all its Global* variants do (save and
765 reset the scope pointer, call the local version, restore the saved
766 scope pointer). */
767
Guido van Rossum62320c91998-06-15 04:36:09 +0000768 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000770
Guido van Rossum62320c91998-06-15 04:36:09 +0000771 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000772 if (!cmd)
773 PyErr_SetString(Tkinter_TclError, "merge failed");
774
Guido van Rossum00d93061998-05-28 23:06:38 +0000775 else {
776 int err;
777 ENTER_TCL
778 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000779 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000780 if (err == TCL_ERROR)
781 res = Tkinter_Error(self);
782 else
783 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000784 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000785 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000786
787 if (cmd)
788 ckfree(cmd);
789
790 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000791}
792
793static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000794Tkapp_Eval(self, args)
795 PyObject *self;
796 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000797{
Barry Warsawfa701a81997-01-16 00:15:11 +0000798 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000799 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000800 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000801
Guido van Rossum43713e52000-02-29 13:59:29 +0000802 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000803 return NULL;
804
Guido van Rossum00d93061998-05-28 23:06:38 +0000805 ENTER_TCL
806 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000807 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000808 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000809 res = Tkinter_Error(self);
810 else
811 res = PyString_FromString(Tkapp_Result(self));
812 LEAVE_OVERLAP_TCL
813 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000814}
815
816static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000817Tkapp_GlobalEval(self, args)
818 PyObject *self;
819 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000820{
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000822 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000823 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000824
Guido van Rossum43713e52000-02-29 13:59:29 +0000825 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000827
Guido van Rossum00d93061998-05-28 23:06:38 +0000828 ENTER_TCL
829 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000830 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000831 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000832 res = Tkinter_Error(self);
833 else
834 res = PyString_FromString(Tkapp_Result(self));
835 LEAVE_OVERLAP_TCL
836 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000837}
838
839static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000840Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000841 PyObject *self;
842 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000843{
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000845 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000846 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000847
Guido van Rossum43713e52000-02-29 13:59:29 +0000848 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000850
Guido van Rossum00d93061998-05-28 23:06:38 +0000851 ENTER_TCL
852 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000853 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000854 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000855 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Guido van Rossum62320c91998-06-15 04:36:09 +0000857 else
858 res = PyString_FromString(Tkapp_Result(self));
859 LEAVE_OVERLAP_TCL
860 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000861}
862
863static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000864Tkapp_Record(self, args)
865 PyObject *self;
866 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000867{
Barry Warsawfa701a81997-01-16 00:15:11 +0000868 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000869 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000870 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum35d43371997-08-02 00:09:09 +0000872 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000873 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000874
Guido van Rossum00d93061998-05-28 23:06:38 +0000875 ENTER_TCL
876 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000877 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000878 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000879 res = Tkinter_Error(self);
880 else
881 res = PyString_FromString(Tkapp_Result(self));
882 LEAVE_OVERLAP_TCL
883 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000884}
885
886static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000887Tkapp_AddErrorInfo(self, args)
888 PyObject *self;
889 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000890{
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000892
Guido van Rossum43713e52000-02-29 13:59:29 +0000893 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000895 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000897 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000898
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 Py_INCREF(Py_None);
900 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000901}
902
Barry Warsawfa701a81997-01-16 00:15:11 +0000903
904
Guido van Rossum18468821994-06-20 07:49:28 +0000905/** Tcl Variable **/
906
907static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000908SetVar(self, args, flags)
909 PyObject *self;
910 PyObject *args;
911 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000912{
Guido van Rossum00d93061998-05-28 23:06:38 +0000913 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000915 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000916
Guido van Rossum62320c91998-06-15 04:36:09 +0000917 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000918 if (!tmp)
919 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000920
Guido van Rossum43713e52000-02-29 13:59:29 +0000921 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000923 s = AsString(newValue, tmp);
924 ENTER_TCL
925 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
926 LEAVE_TCL
927 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000929 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000930 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000931 s = AsString (newValue, tmp);
932 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000934 s, flags);
935 LEAVE_TCL
936 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000937 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000938 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 return NULL;
940 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000941 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000942 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000943
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 if (!ok)
945 return Tkinter_Error(self);
946
947 Py_INCREF(Py_None);
948 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000949}
950
951static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000952Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000953 PyObject *self;
954 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000955{
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000957}
958
959static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000960Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 PyObject *self;
962 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000963{
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000965}
966
Barry Warsawfa701a81997-01-16 00:15:11 +0000967
968
Guido van Rossum18468821994-06-20 07:49:28 +0000969static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000970GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000971 PyObject *self;
972 PyObject *args;
973 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000974{
Guido van Rossum35d43371997-08-02 00:09:09 +0000975 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000976 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000977
Guido van Rossum43713e52000-02-29 13:59:29 +0000978 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000979 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000980 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000982 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000983
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000985 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000986 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000987
Barry Warsawfa701a81997-01-16 00:15:11 +0000988 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000989 res = Tkinter_Error(self);
990 else
991 res = PyString_FromString(s);
992 LEAVE_OVERLAP_TCL
993 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000994}
995
996static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000997Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000998 PyObject *self;
999 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001000{
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001002}
1003
1004static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001005Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 PyObject *self;
1007 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001008{
Barry Warsawfa701a81997-01-16 00:15:11 +00001009 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001010}
1011
Barry Warsawfa701a81997-01-16 00:15:11 +00001012
1013
Guido van Rossum18468821994-06-20 07:49:28 +00001014static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001015UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 PyObject *self;
1017 PyObject *args;
1018 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001019{
Guido van Rossum35d43371997-08-02 00:09:09 +00001020 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001021 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001023
Guido van Rossum43713e52000-02-29 13:59:29 +00001024 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001025 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001026 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001027 if (name2 == NULL)
1028 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1029
1030 else
1031 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001032 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001033
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001035 res = Tkinter_Error(self);
1036 else {
1037 Py_INCREF(Py_None);
1038 res = Py_None;
1039 }
1040 LEAVE_OVERLAP_TCL
1041 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001042}
1043
1044static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001045Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 PyObject *self;
1047 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001048{
Barry Warsawfa701a81997-01-16 00:15:11 +00001049 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001050}
1051
1052static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001053Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 PyObject *self;
1055 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001056{
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001058}
1059
Barry Warsawfa701a81997-01-16 00:15:11 +00001060
1061
Guido van Rossum18468821994-06-20 07:49:28 +00001062/** Tcl to Python **/
1063
1064static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001065Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001066 PyObject *self;
1067 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001068{
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 char *s;
1070 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum43713e52000-02-29 13:59:29 +00001072 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001074 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return Tkinter_Error(self);
1076 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001077}
1078
1079static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001080Tkapp_GetDouble(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;
1085 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001086
Guido van Rossum43713e52000-02-29 13:59:29 +00001087 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001088 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001089 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 return Tkinter_Error(self);
1091 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001092}
1093
1094static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001095Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 PyObject *self;
1097 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001098{
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 char *s;
1100 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001101
Guido van Rossum43713e52000-02-29 13:59:29 +00001102 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001103 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001104 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1105 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001107}
1108
1109static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001110Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 PyObject *self;
1112 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001113{
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001115 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001116 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001117
Guido van Rossum43713e52000-02-29 13:59:29 +00001118 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001120 ENTER_TCL
1121 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001122 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001123 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001124 res = Tkinter_Error(self);
1125 else
1126 res = Py_BuildValue("s", Tkapp_Result(self));
1127 LEAVE_OVERLAP_TCL
1128 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001129}
1130
1131static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001132Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001133 PyObject *self;
1134 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001135{
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001137 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001138 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001139 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001140
Guido van Rossum43713e52000-02-29 13:59:29 +00001141 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001143 ENTER_TCL
1144 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001145 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001146 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001147 res = Tkinter_Error(self);
1148 else
1149 res = Py_BuildValue("l", v);
1150 LEAVE_OVERLAP_TCL
1151 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001152}
1153
1154static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001155Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001156 PyObject *self;
1157 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001158{
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001160 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001162 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001163
Guido van Rossum43713e52000-02-29 13:59:29 +00001164 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001165 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001166 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001167 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001168 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001169 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001170 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001171 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001172 res = Tkinter_Error(self);
1173 else
1174 res = Py_BuildValue("d", v);
1175 LEAVE_OVERLAP_TCL
1176 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001177}
1178
1179static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001180Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001181 PyObject *self;
1182 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001183{
Barry Warsawfa701a81997-01-16 00:15:11 +00001184 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001185 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001186 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001188
Guido van Rossum43713e52000-02-29 13:59:29 +00001189 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001191 ENTER_TCL
1192 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001193 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001194 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001195 res = Tkinter_Error(self);
1196 else
1197 res = Py_BuildValue("i", v);
1198 LEAVE_OVERLAP_TCL
1199 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001200}
1201
Barry Warsawfa701a81997-01-16 00:15:11 +00001202
1203
Guido van Rossum18468821994-06-20 07:49:28 +00001204static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001205Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 PyObject *self;
1207 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001208{
Barry Warsawfa701a81997-01-16 00:15:11 +00001209 char *list;
1210 int argc;
1211 char **argv;
1212 PyObject *v;
1213 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001214
Guido van Rossum43713e52000-02-29 13:59:29 +00001215 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001217
Barry Warsawfa701a81997-01-16 00:15:11 +00001218 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1219 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001220
Barry Warsawfa701a81997-01-16 00:15:11 +00001221 if (!(v = PyTuple_New(argc)))
1222 return NULL;
1223
1224 for (i = 0; i < argc; i++) {
1225 PyObject *s = PyString_FromString(argv[i]);
1226 if (!s || PyTuple_SetItem(v, i, s)) {
1227 Py_DECREF(v);
1228 v = NULL;
1229 goto finally;
1230 }
1231 }
Guido van Rossum18468821994-06-20 07:49:28 +00001232
Barry Warsawfa701a81997-01-16 00:15:11 +00001233 finally:
1234 ckfree(FREECAST argv);
1235 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001236}
1237
1238static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001239Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 PyObject *self;
1241 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001242{
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001244
Guido van Rossum43713e52000-02-29 13:59:29 +00001245 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001246 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001247 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001248}
1249
1250static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001251Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 PyObject *self;
1253 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001254{
Barry Warsawfa701a81997-01-16 00:15:11 +00001255 char *s = Merge(args);
1256 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001257
Barry Warsawfa701a81997-01-16 00:15:11 +00001258 if (s) {
1259 res = PyString_FromString(s);
1260 ckfree(s);
1261 }
1262 else
1263 PyErr_SetString(Tkinter_TclError, "merge failed");
1264
1265 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001266}
1267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268
1269
Guido van Rossum18468821994-06-20 07:49:28 +00001270/** Tcl Command **/
1271
Guido van Rossum00d93061998-05-28 23:06:38 +00001272/* Client data struct */
1273typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001274 PyObject *self;
1275 PyObject *func;
1276} PythonCmd_ClientData;
1277
1278static int
1279PythonCmd_Error(interp)
1280 Tcl_Interp *interp;
1281{
1282 errorInCmd = 1;
1283 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1284 LEAVE_PYTHON
1285 return TCL_ERROR;
1286}
1287
Guido van Rossum18468821994-06-20 07:49:28 +00001288/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001289 * function or method.
1290 */
Guido van Rossum18468821994-06-20 07:49:28 +00001291static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001292PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001293 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001294 Tcl_Interp *interp;
1295 int argc;
1296 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001297{
Guido van Rossum00d93061998-05-28 23:06:38 +00001298 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 PyObject *self, *func, *arg, *res, *tmp;
1300 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001301
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001302 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001303
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 /* TBD: no error checking here since we know, via the
1305 * Tkapp_CreateCommand() that the client data is a two-tuple
1306 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001307 self = data->self;
1308 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001309
Barry Warsawfa701a81997-01-16 00:15:11 +00001310 /* Create argument list (argv1, ..., argvN) */
1311 if (!(arg = PyTuple_New(argc - 1)))
1312 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001313
Barry Warsawfa701a81997-01-16 00:15:11 +00001314 for (i = 0; i < (argc - 1); i++) {
1315 PyObject *s = PyString_FromString(argv[i + 1]);
1316 if (!s || PyTuple_SetItem(arg, i, s)) {
1317 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001318 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001319 }
1320 }
1321 res = PyEval_CallObject(func, arg);
1322 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001323
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 if (res == NULL)
1325 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001326
Barry Warsawfa701a81997-01-16 00:15:11 +00001327 if (!(tmp = PyList_New(0))) {
1328 Py_DECREF(res);
1329 return PythonCmd_Error(interp);
1330 }
1331
1332 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1333 Py_DECREF(res);
1334 Py_DECREF(tmp);
1335
Guido van Rossum00d93061998-05-28 23:06:38 +00001336 LEAVE_PYTHON
1337
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001339}
1340
1341static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001342PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001343 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001344{
Guido van Rossum00d93061998-05-28 23:06:38 +00001345 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1346
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001347 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001348 Py_XDECREF(data->self);
1349 Py_XDECREF(data->func);
1350 PyMem_DEL(data);
1351 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001352}
1353
Barry Warsawfa701a81997-01-16 00:15:11 +00001354
1355
Guido van Rossum18468821994-06-20 07:49:28 +00001356static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001357Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 PyObject *self;
1359 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001360{
Guido van Rossum00d93061998-05-28 23:06:38 +00001361 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001363 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001365
Guido van Rossum43713e52000-02-29 13:59:29 +00001366 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001367 return NULL;
1368 if (!PyCallable_Check(func)) {
1369 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 return NULL;
1371 }
Guido van Rossum18468821994-06-20 07:49:28 +00001372
Guido van Rossum00d93061998-05-28 23:06:38 +00001373 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 if (!data)
1375 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001376 Py_XINCREF(self);
1377 Py_XINCREF(func);
1378 data->self = self;
1379 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001380
Guido van Rossum00d93061998-05-28 23:06:38 +00001381 ENTER_TCL
1382 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1383 (ClientData)data, PythonCmdDelete);
1384 LEAVE_TCL
1385 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001386 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001388 return NULL;
1389 }
Guido van Rossum18468821994-06-20 07:49:28 +00001390
Barry Warsawfa701a81997-01-16 00:15:11 +00001391 Py_INCREF(Py_None);
1392 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001393}
1394
Barry Warsawfa701a81997-01-16 00:15:11 +00001395
1396
Guido van Rossum18468821994-06-20 07:49:28 +00001397static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001398Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001399 PyObject *self;
1400 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001401{
Barry Warsawfa701a81997-01-16 00:15:11 +00001402 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001403 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001404
Guido van Rossum43713e52000-02-29 13:59:29 +00001405 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001406 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 ENTER_TCL
1408 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1409 LEAVE_TCL
1410 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1412 return NULL;
1413 }
1414 Py_INCREF(Py_None);
1415 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001416}
1417
Barry Warsawfa701a81997-01-16 00:15:11 +00001418
1419
Guido van Rossum00d93061998-05-28 23:06:38 +00001420#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001421/** File Handler **/
1422
Guido van Rossum00d93061998-05-28 23:06:38 +00001423typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001424 PyObject *func;
1425 PyObject *file;
1426 int id;
1427 struct _fhcdata *next;
1428} FileHandler_ClientData;
1429
1430static FileHandler_ClientData *HeadFHCD;
1431
1432static FileHandler_ClientData *
1433NewFHCD(func, file, id)
1434 PyObject *func;
1435 PyObject *file;
1436 int id;
1437{
1438 FileHandler_ClientData *p;
1439 p = PyMem_NEW(FileHandler_ClientData, 1);
1440 if (p != NULL) {
1441 Py_XINCREF(func);
1442 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001443 p->func = func;
1444 p->file = file;
1445 p->id = id;
1446 p->next = HeadFHCD;
1447 HeadFHCD = p;
1448 }
1449 return p;
1450}
1451
1452static void
1453DeleteFHCD(id)
1454 int id;
1455{
1456 FileHandler_ClientData *p, **pp;
1457
1458 pp = &HeadFHCD;
1459 while ((p = *pp) != NULL) {
1460 if (p->id == id) {
1461 *pp = p->next;
1462 Py_XDECREF(p->func);
1463 Py_XDECREF(p->file);
1464 PyMem_DEL(p);
1465 }
1466 else
1467 pp = &p->next;
1468 }
1469}
1470
Guido van Rossuma597dde1995-01-10 20:56:29 +00001471static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001472FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001473 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001475{
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001478
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001479 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001480 func = data->func;
1481 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001482
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 arg = Py_BuildValue("(Oi)", file, (long) mask);
1484 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001485 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001486
1487 if (res == NULL) {
1488 errorInCmd = 1;
1489 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1490 }
1491 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001492 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001493}
1494
1495static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001496GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 /* Either an int >= 0 or an object with a
1498 *.fileno() method that returns an int >= 0
1499 */
1500 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001501{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001502 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001503 int id;
1504 if (PyInt_Check(file)) {
1505 id = PyInt_AsLong(file);
1506 if (id < 0)
1507 PyErr_SetString(PyExc_ValueError, "invalid file id");
1508 return id;
1509 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001510 args = PyTuple_New(0);
1511 if (args == NULL)
1512 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001513
1514 meth = PyObject_GetAttrString(file, "fileno");
1515 if (meth == NULL) {
1516 Py_DECREF(args);
1517 return -1;
1518 }
1519
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001520 res = PyEval_CallObject(meth, args);
1521 Py_DECREF(args);
1522 Py_DECREF(meth);
1523 if (res == NULL)
1524 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001525
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001526 if (PyInt_Check(res))
1527 id = PyInt_AsLong(res);
1528 else
1529 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001530
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001531 if (id < 0)
1532 PyErr_SetString(PyExc_ValueError,
1533 "invalid fileno() return value");
1534 Py_DECREF(res);
1535 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001536}
1537
1538static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001539Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001540 PyObject *self;
1541 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001542{
Guido van Rossum00d93061998-05-28 23:06:38 +00001543 FileHandler_ClientData *data;
1544 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001545 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001546
Guido van Rossum43713e52000-02-29 13:59:29 +00001547 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001549 tfile = GetFileNo(file);
1550 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001551 return NULL;
1552 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001553 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001554 return NULL;
1555 }
1556
Guido van Rossuma80649b2000-03-28 20:07:05 +00001557 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001558 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001559 return NULL;
1560
Barry Warsawfa701a81997-01-16 00:15:11 +00001561 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001562 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001563 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001564 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001565 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001566 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001567}
1568
1569static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001570Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001571 PyObject *self;
1572 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001573{
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001575 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001576 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001577
Guido van Rossum43713e52000-02-29 13:59:29 +00001578 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001580 tfile = GetFileNo(file);
1581 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001582 return NULL;
1583
Guido van Rossuma80649b2000-03-28 20:07:05 +00001584 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001585
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001587 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001589 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001590 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001591 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001592}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001593#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001594
Barry Warsawfa701a81997-01-16 00:15:11 +00001595
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001596/**** Tktt Object (timer token) ****/
1597
1598staticforward PyTypeObject Tktt_Type;
1599
Guido van Rossum00d93061998-05-28 23:06:38 +00001600typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001602 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001603 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001604} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001605
1606static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001607Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001608 PyObject *self;
1609 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001610{
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001612 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001613
Guido van Rossum43713e52000-02-29 13:59:29 +00001614 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001615 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001616 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001617 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001618 v->token = NULL;
1619 }
1620 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001621 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001622 Py_DECREF(func);
1623 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001624 }
1625 Py_INCREF(Py_None);
1626 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001627}
1628
1629static PyMethodDef Tktt_methods[] =
1630{
Guido van Rossum35d43371997-08-02 00:09:09 +00001631 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001632 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001633};
1634
1635static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001636Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001638{
Barry Warsawfa701a81997-01-16 00:15:11 +00001639 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640
Barry Warsawfa701a81997-01-16 00:15:11 +00001641 v = PyObject_NEW(TkttObject, &Tktt_Type);
1642 if (v == NULL)
1643 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001644
Guido van Rossum00d93061998-05-28 23:06:38 +00001645 Py_INCREF(func);
1646 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001648
1649 /* Extra reference, deleted when called or when handler is deleted */
1650 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001652}
1653
1654static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001655Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001656 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001657{
Guido van Rossum00d93061998-05-28 23:06:38 +00001658 TkttObject *v = (TkttObject *)self;
1659 PyObject *func = v->func;
1660
1661 Py_XDECREF(func);
1662
Guido van Rossum35d43371997-08-02 00:09:09 +00001663 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001664}
1665
Guido van Rossum597ac201998-05-12 14:36:19 +00001666static PyObject *
1667Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001668 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001669{
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001671 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001672
Guido van Rossum597ac201998-05-12 14:36:19 +00001673 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001674 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001675 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001676}
1677
1678static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001679Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001680 PyObject *self;
1681 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001682{
Barry Warsawfa701a81997-01-16 00:15:11 +00001683 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001684}
1685
1686static PyTypeObject Tktt_Type =
1687{
Guido van Rossum35d43371997-08-02 00:09:09 +00001688 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001689 0, /*ob_size */
1690 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001691 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001692 0, /*tp_itemsize */
1693 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001694 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 Tktt_GetAttr, /*tp_getattr */
1696 0, /*tp_setattr */
1697 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001698 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001699 0, /*tp_as_number */
1700 0, /*tp_as_sequence */
1701 0, /*tp_as_mapping */
1702 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001703};
1704
Barry Warsawfa701a81997-01-16 00:15:11 +00001705
1706
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001707/** Timer Handler **/
1708
1709static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001710TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001712{
Guido van Rossum00d93061998-05-28 23:06:38 +00001713 TkttObject *v = (TkttObject *)clientData;
1714 PyObject *func = v->func;
1715 PyObject *res;
1716
1717 if (func == NULL)
1718 return;
1719
1720 v->func = NULL;
1721
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001722 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001723
1724 res = PyEval_CallObject(func, NULL);
1725 Py_DECREF(func);
1726 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001727
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 if (res == NULL) {
1729 errorInCmd = 1;
1730 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1731 }
1732 else
1733 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001734
1735 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001736}
1737
1738static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001739Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001740 PyObject *self;
1741 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001742{
Barry Warsawfa701a81997-01-16 00:15:11 +00001743 int milliseconds;
1744 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001745 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001746
Guido van Rossum43713e52000-02-29 13:59:29 +00001747 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001748 return NULL;
1749 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001750 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001751 return NULL;
1752 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001753 v = Tktt_New(func);
1754 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1755 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001756
Guido van Rossum00d93061998-05-28 23:06:38 +00001757 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001758}
1759
Barry Warsawfa701a81997-01-16 00:15:11 +00001760
Guido van Rossum18468821994-06-20 07:49:28 +00001761/** Event Loop **/
1762
Guido van Rossum18468821994-06-20 07:49:28 +00001763static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001764Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001765 PyObject *self;
1766 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001767{
Barry Warsawfa701a81997-01-16 00:15:11 +00001768 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001769#ifdef WITH_THREAD
1770 PyThreadState *tstate = PyThreadState_Get();
1771#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001772
Guido van Rossum43713e52000-02-29 13:59:29 +00001773 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001774 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001775
Barry Warsawfa701a81997-01-16 00:15:11 +00001776 quitMainLoop = 0;
1777 while (Tk_GetNumMainWindows() > threshold &&
1778 !quitMainLoop &&
1779 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001780 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001781 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001782
1783#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001784 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001785 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001786 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001787 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001788 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001789 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001790 if (result == 0)
1791 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001792 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001793#else
1794 result = Tcl_DoOneEvent(0);
1795#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001796
Guido van Rossum35d43371997-08-02 00:09:09 +00001797 if (PyErr_CheckSignals() != 0)
1798 return NULL;
1799 if (result < 0)
1800 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001801 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001802 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001803
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 if (errorInCmd) {
1805 errorInCmd = 0;
1806 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1807 excInCmd = valInCmd = trbInCmd = NULL;
1808 return NULL;
1809 }
1810 Py_INCREF(Py_None);
1811 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001812}
1813
1814static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001815Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001816 PyObject *self;
1817 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001818{
Guido van Rossum35d43371997-08-02 00:09:09 +00001819 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001820 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001821
Guido van Rossum43713e52000-02-29 13:59:29 +00001822 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 return NULL;
1824
Guido van Rossum00d93061998-05-28 23:06:38 +00001825 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001826 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001827 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001829}
1830
1831static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001832Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001833 PyObject *self;
1834 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001835{
1836
Guido van Rossum43713e52000-02-29 13:59:29 +00001837 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001838 return NULL;
1839
1840 quitMainLoop = 1;
1841 Py_INCREF(Py_None);
1842 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001843}
1844
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001845static PyObject *
1846Tkapp_InterpAddr(self, args)
1847 PyObject *self;
1848 PyObject *args;
1849{
1850
Guido van Rossum43713e52000-02-29 13:59:29 +00001851 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001852 return NULL;
1853
1854 return PyInt_FromLong((long)Tkapp_Interp(self));
1855}
1856
Barry Warsawfa701a81997-01-16 00:15:11 +00001857
1858
Guido van Rossum18468821994-06-20 07:49:28 +00001859/**** Tkapp Method List ****/
1860
1861static PyMethodDef Tkapp_methods[] =
1862{
Guido van Rossum35d43371997-08-02 00:09:09 +00001863 {"call", Tkapp_Call, 0},
1864 {"globalcall", Tkapp_GlobalCall, 0},
1865 {"eval", Tkapp_Eval, 1},
1866 {"globaleval", Tkapp_GlobalEval, 1},
1867 {"evalfile", Tkapp_EvalFile, 1},
1868 {"record", Tkapp_Record, 1},
1869 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1870 {"setvar", Tkapp_SetVar, 1},
1871 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1872 {"getvar", Tkapp_GetVar, 1},
1873 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1874 {"unsetvar", Tkapp_UnsetVar, 1},
1875 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1876 {"getint", Tkapp_GetInt, 1},
1877 {"getdouble", Tkapp_GetDouble, 1},
1878 {"getboolean", Tkapp_GetBoolean, 1},
1879 {"exprstring", Tkapp_ExprString, 1},
1880 {"exprlong", Tkapp_ExprLong, 1},
1881 {"exprdouble", Tkapp_ExprDouble, 1},
1882 {"exprboolean", Tkapp_ExprBoolean, 1},
1883 {"splitlist", Tkapp_SplitList, 1},
1884 {"split", Tkapp_Split, 1},
1885 {"merge", Tkapp_Merge, 0},
1886 {"createcommand", Tkapp_CreateCommand, 1},
1887 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001888#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001889 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1890 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001891#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001892 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001893 {"mainloop", Tkapp_MainLoop, 1},
1894 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001895 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001896 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001897 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001898};
1899
Barry Warsawfa701a81997-01-16 00:15:11 +00001900
1901
Guido van Rossum18468821994-06-20 07:49:28 +00001902/**** Tkapp Type Methods ****/
1903
1904static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001905Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001906 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001907{
Guido van Rossum00d93061998-05-28 23:06:38 +00001908 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001909 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001910 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001911 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001912 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001913}
1914
1915static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001916Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001917 PyObject *self;
1918 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001919{
Guido van Rossum35d43371997-08-02 00:09:09 +00001920 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001921}
1922
1923static PyTypeObject Tkapp_Type =
1924{
Guido van Rossum35d43371997-08-02 00:09:09 +00001925 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001926 0, /*ob_size */
1927 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001928 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001929 0, /*tp_itemsize */
1930 Tkapp_Dealloc, /*tp_dealloc */
1931 0, /*tp_print */
1932 Tkapp_GetAttr, /*tp_getattr */
1933 0, /*tp_setattr */
1934 0, /*tp_compare */
1935 0, /*tp_repr */
1936 0, /*tp_as_number */
1937 0, /*tp_as_sequence */
1938 0, /*tp_as_mapping */
1939 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001940};
1941
Barry Warsawfa701a81997-01-16 00:15:11 +00001942
1943
Guido van Rossum18468821994-06-20 07:49:28 +00001944/**** Tkinter Module ****/
1945
1946static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001947Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 PyObject *self;
1949 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001950{
Barry Warsawfa701a81997-01-16 00:15:11 +00001951 char *screenName = NULL;
1952 char *baseName = NULL;
1953 char *className = NULL;
1954 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001955
Guido van Rossum35d43371997-08-02 00:09:09 +00001956 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 if (baseName != NULL)
1958 baseName++;
1959 else
1960 baseName = Py_GetProgramName();
1961 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001962
Guido van Rossum43713e52000-02-29 13:59:29 +00001963 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 &screenName, &baseName, &className,
1965 &interactive))
1966 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001967
Barry Warsawfa701a81997-01-16 00:15:11 +00001968 return (PyObject *) Tkapp_New(screenName, baseName, className,
1969 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001970}
1971
1972static PyMethodDef moduleMethods[] =
1973{
Barry Warsawfa701a81997-01-16 00:15:11 +00001974 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001975#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001976 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1977 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001978#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001979 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001980 {"mainloop", Tkapp_MainLoop, 1},
1981 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001982 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001983 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001984};
1985
Guido van Rossum7bf15641998-05-22 18:28:17 +00001986#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001987
1988static int stdin_ready = 0;
1989
Guido van Rossumad4db171998-06-13 13:56:28 +00001990#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001991static void
1992MyFileProc(clientData, mask)
1993 void *clientData;
1994 int mask;
1995{
1996 stdin_ready = 1;
1997}
Guido van Rossumad4db171998-06-13 13:56:28 +00001998#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001999
Guido van Rossum00d93061998-05-28 23:06:38 +00002000static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002001
Guido van Rossum18468821994-06-20 07:49:28 +00002002static int
Guido van Rossum35d43371997-08-02 00:09:09 +00002003EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00002004{
Guido van Rossumad4db171998-06-13 13:56:28 +00002005#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002006 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002007#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002008#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002009 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002010#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002011 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002012 errorInCmd = 0;
2013#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002014 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002015 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002016#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002017 while (!errorInCmd && !stdin_ready) {
2018 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002019#ifdef MS_WINDOWS
2020 if (_kbhit()) {
2021 stdin_ready = 1;
2022 break;
2023 }
2024#endif
2025#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002026 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002027 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002028 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002029
Guido van Rossum00d93061998-05-28 23:06:38 +00002030 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002031
2032 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002033 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002034 if (result == 0)
2035 Sleep(20);
2036 Py_END_ALLOW_THREADS
2037#else
2038 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002039#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002040
2041 if (result < 0)
2042 break;
2043 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002044#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002045 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002046#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002047 if (errorInCmd) {
2048 errorInCmd = 0;
2049 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2050 excInCmd = valInCmd = trbInCmd = NULL;
2051 PyErr_Print();
2052 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002053#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002054 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002055#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002056 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002057}
Guido van Rossum18468821994-06-20 07:49:28 +00002058
Guido van Rossum00d93061998-05-28 23:06:38 +00002059#endif
2060
Guido van Rossum7bf15641998-05-22 18:28:17 +00002061static void
2062EnableEventHook()
2063{
Guido van Rossum00d93061998-05-28 23:06:38 +00002064#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002065 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002066#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002067 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002068#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002069 PyOS_InputHook = EventHook;
2070 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002071#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002072}
2073
2074static void
2075DisableEventHook()
2076{
Guido van Rossum00d93061998-05-28 23:06:38 +00002077#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002078 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2079 PyOS_InputHook = NULL;
2080 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002081#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002082}
2083
Barry Warsawfa701a81997-01-16 00:15:11 +00002084
2085/* all errors will be checked in one fell swoop in init_tkinter() */
2086static void
2087ins_long(d, name, val)
2088 PyObject *d;
2089 char *name;
2090 long val;
2091{
2092 PyObject *v = PyInt_FromLong(val);
2093 if (v) {
2094 PyDict_SetItemString(d, name, v);
2095 Py_DECREF(v);
2096 }
2097}
2098static void
2099ins_string(d, name, val)
2100 PyObject *d;
2101 char *name;
2102 char *val;
2103{
2104 PyObject *v = PyString_FromString(val);
2105 if (v) {
2106 PyDict_SetItemString(d, name, v);
2107 Py_DECREF(v);
2108 }
2109}
2110
2111
Guido van Rossum3886bb61998-12-04 18:50:17 +00002112DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002113init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002114{
Barry Warsawfa701a81997-01-16 00:15:11 +00002115 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002116
Barry Warsawfa701a81997-01-16 00:15:11 +00002117 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002118
2119#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002120 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002121#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002122
Barry Warsawfa701a81997-01-16 00:15:11 +00002123 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002124
Barry Warsawfa701a81997-01-16 00:15:11 +00002125 d = PyModule_GetDict(m);
2126 Tkinter_TclError = Py_BuildValue("s", "TclError");
2127 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002128
Guido van Rossum35d43371997-08-02 00:09:09 +00002129 ins_long(d, "READABLE", TCL_READABLE);
2130 ins_long(d, "WRITABLE", TCL_WRITABLE);
2131 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2132 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2133 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2134 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2135 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2136 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2137 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002138 ins_string(d, "TK_VERSION", TK_VERSION);
2139 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002140
Guido van Rossum83551bf1997-09-13 00:44:23 +00002141 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002142
2143 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002144 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2145
Guido van Rossume187b0e2000-03-27 21:46:29 +00002146 /* This helps the dynamic loader; in Unicode aware Tcl versions
2147 it also helps Tcl find its encodings. */
2148 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002149
Barry Warsawfa701a81997-01-16 00:15:11 +00002150 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002151 return;
2152
Guido van Rossum43ff8681998-07-14 18:02:13 +00002153#if 0
2154 /* This was not a good idea; through <Destroy> bindings,
2155 Tcl_Finalize() may invoke Python code but at that point the
2156 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002157 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002158#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002159
Jack Jansen34cc5c31995-10-31 16:15:12 +00002160#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002161 /*
2162 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2163 ** Most of the initializations in that routine (toolbox init calls and
2164 ** such) have already been done for us, so we only need these.
2165 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002166 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002167
2168 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002169#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002170 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002171#endif /* GENERATINGCFM */
2172#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002173}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002174
Guido van Rossumec22c921996-02-25 04:50:29 +00002175
Barry Warsawfa701a81997-01-16 00:15:11 +00002176
Guido van Rossum9722ad81995-09-22 23:49:28 +00002177#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002178
2179/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002180** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002181*/
2182
Guido van Rossum9722ad81995-09-22 23:49:28 +00002183void
2184panic(char * format, ...)
2185{
Barry Warsawfa701a81997-01-16 00:15:11 +00002186 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002187
Barry Warsawfa701a81997-01-16 00:15:11 +00002188 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002189
Guido van Rossum227cf761998-08-05 13:53:32 +00002190 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002191 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002192
Barry Warsawfa701a81997-01-16 00:15:11 +00002193 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002194
Barry Warsawfa701a81997-01-16 00:15:11 +00002195 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002196}
Jack Jansen40b546d1995-11-14 10:34:45 +00002197
Guido van Rossumec22c921996-02-25 04:50:29 +00002198/*
2199** Pass events to SIOUX before passing them to Tk.
2200*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002201
Guido van Rossumec22c921996-02-25 04:50:29 +00002202static int
2203PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002204 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002205{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002206 WindowPtr frontwin;
2207 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002208 ** Sioux eats too many events, so we don't pass it everything. We
2209 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002210 ** the Sioux window is frontmost. This means that Tk menus don't work
2211 ** in that case, but at least we can scroll the sioux window.
2212 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2213 ** part of the external interface of Sioux...
2214 */
2215 frontwin = FrontWindow();
2216 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2217 if (SIOUXHandleOneEvent(eventPtr))
2218 return 0; /* Nothing happened to the Tcl event queue */
2219 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002220 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002221}
2222
Guido van Rossumec22c921996-02-25 04:50:29 +00002223#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002224
2225/*
2226** Additional Mac specific code for dealing with shared libraries.
2227*/
2228
2229#include <Resources.h>
2230#include <CodeFragments.h>
2231
2232static int loaded_from_shlib = 0;
2233static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002234
Jack Jansen34cc5c31995-10-31 16:15:12 +00002235/*
2236** If this module is dynamically loaded the following routine should
2237** be the init routine. It takes care of adding the shared library to
2238** the resource-file chain, so that the tk routines can find their
2239** resources.
2240*/
2241OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002242init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002243{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002244 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002245 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002246 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002247 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2248 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002249 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002250 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2251 loaded_from_shlib = 1;
2252 }
2253 return noErr;
2254}
2255
2256/*
2257** Insert the library resources into the search path. Put them after
2258** the resources from the application. Again, we ignore errors.
2259*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002260static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002261mac_addlibresources()
2262{
2263 if ( !loaded_from_shlib )
2264 return;
2265 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2266}
2267
Guido van Rossumec22c921996-02-25 04:50:29 +00002268#endif /* GENERATINGCFM */
2269#endif /* macintosh */