blob: 008378dff4fc3ff0d0634c29f36e5fc682d23917 [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;
Guido van Rossum8823acc2000-04-27 20:14:31 +0000556 result = Tcl_NewStringObj (PyString_AS_STRING (utf8),
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000557 PyString_GET_SIZE (utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000558 Py_DECREF(utf8);
559 return result;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000560 }
561 else {
562 PyObject *v = PyObject_Str(value);
563 if (!v)
564 return 0;
565 result = AsObj(v);
566 Py_DECREF(v);
567 return result;
568 }
569}
570
Guido van Rossum18468821994-06-20 07:49:28 +0000571static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000572Tkapp_Call(self, args)
573 PyObject *self;
574 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000575{
Guido van Rossum632de272000-03-29 00:19:50 +0000576 Tcl_Obj *objStore[ARGSZ];
577 Tcl_Obj **objv = NULL;
578 int objc = 0, i;
579 PyObject *res = NULL;
580 Tcl_Interp *interp = Tkapp_Interp(self);
581 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
582 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000583
Guido van Rossum632de272000-03-29 00:19:50 +0000584 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000585
Guido van Rossum212643f1998-04-29 16:22:14 +0000586 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000587 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000588
Guido van Rossum212643f1998-04-29 16:22:14 +0000589 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000590 objc = 1;
591 objv[0] = AsObj(args);
592 if (objv[0] == 0)
593 goto finally;
594 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000595 }
596 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000597 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000598
Guido van Rossum632de272000-03-29 00:19:50 +0000599 if (objc > ARGSZ) {
600 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
601 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000602 PyErr_NoMemory();
603 goto finally;
604 }
605 }
606
Guido van Rossum632de272000-03-29 00:19:50 +0000607 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000608 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000609 if (v == Py_None) {
610 objc = i;
611 break;
612 }
Guido van Rossum632de272000-03-29 00:19:50 +0000613 objv[i] = AsObj(v);
614 if (!objv[i])
615 goto finally;
616 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000617 }
618 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000619
Guido van Rossum62320c91998-06-15 04:36:09 +0000620 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000621
622 i = Tcl_EvalObjv(interp, objc, objv, flags);
623
Guido van Rossum62320c91998-06-15 04:36:09 +0000624 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000625 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000626 Tkinter_Error(self);
Guido van Rossum632de272000-03-29 00:19:50 +0000627 else
628 /* We could request the object result here, but doing
629 so would confuse applications that expect a string. */
630 res = PyString_FromString(Tcl_GetStringResult(interp));
631
Guido van Rossum62320c91998-06-15 04:36:09 +0000632 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000633
Guido van Rossum212643f1998-04-29 16:22:14 +0000634 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000635 for (i = 0; i < objc; i++)
636 Tcl_DecrRefCount(objv[i]);
637 if (objv != objStore)
638 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return res;
640}
641
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000642#else /* !USING_OBJECTS */
643
644static PyObject *
645Tkapp_Call(self, args)
646 PyObject *self;
647 PyObject *args;
648{
649 /* This is copied from Merge() */
650 PyObject *tmp = NULL;
651 char *argvStore[ARGSZ];
652 char **argv = NULL;
653 int fvStore[ARGSZ];
654 int *fv = NULL;
655 int argc = 0, i;
656 PyObject *res = NULL; /* except this has a different type */
657 Tcl_CmdInfo info; /* and this is added */
658 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
659
660 if (!(tmp = PyList_New(0)))
661 return NULL;
662
663 argv = argvStore;
664 fv = fvStore;
665
666 if (args == NULL)
667 argc = 0;
668
669 else if (!PyTuple_Check(args)) {
670 argc = 1;
671 fv[0] = 0;
672 argv[0] = AsString(args, tmp);
673 }
674 else {
675 argc = PyTuple_Size(args);
676
677 if (argc > ARGSZ) {
678 argv = (char **)ckalloc(argc * sizeof(char *));
679 fv = (int *)ckalloc(argc * sizeof(int));
680 if (argv == NULL || fv == NULL) {
681 PyErr_NoMemory();
682 goto finally;
683 }
684 }
685
686 for (i = 0; i < argc; i++) {
687 PyObject *v = PyTuple_GetItem(args, i);
688 if (PyTuple_Check(v)) {
689 fv[i] = 1;
690 if (!(argv[i] = Merge(v)))
691 goto finally;
692 }
693 else if (v == Py_None) {
694 argc = i;
695 break;
696 }
697 else {
698 fv[i] = 0;
699 argv[i] = AsString(v, tmp);
700 }
701 }
702 }
703 /* End code copied from Merge() */
704
705 /* All this to avoid a call to Tcl_Merge() and the corresponding call
706 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
707 if (Py_VerboseFlag >= 2) {
708 for (i = 0; i < argc; i++)
709 PySys_WriteStderr("%s ", argv[i]);
710 }
711 ENTER_TCL
712 info.proc = NULL;
713 if (argc < 1 ||
714 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
715 info.proc == NULL)
716 {
717 char *cmd;
718 cmd = Tcl_Merge(argc, argv);
719 i = Tcl_Eval(interp, cmd);
720 ckfree(cmd);
721 }
722 else {
723 Tcl_ResetResult(interp);
724 i = (*info.proc)(info.clientData, interp, argc, argv);
725 }
726 ENTER_OVERLAP
727 if (info.proc == NULL && Py_VerboseFlag >= 2)
728 PySys_WriteStderr("... use TclEval ");
729 if (i == TCL_ERROR) {
730 if (Py_VerboseFlag >= 2)
731 PySys_WriteStderr("... error: '%s'\n",
732 interp->result);
733 Tkinter_Error(self);
734 }
735 else {
736 if (Py_VerboseFlag >= 2)
737 PySys_WriteStderr("-> '%s'\n", interp->result);
738 res = PyString_FromString(interp->result);
739 }
740 LEAVE_OVERLAP_TCL
741
742 /* Copied from Merge() again */
743 finally:
744 for (i = 0; i < argc; i++)
745 if (fv[i]) {
746 ckfree(argv[i]);
747 }
748 if (argv != argvStore)
749 ckfree(FREECAST argv);
750 if (fv != fvStore)
751 ckfree(FREECAST fv);
752
753 Py_DECREF(tmp);
754 return res;
755}
756
757#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000758
759static PyObject *
760Tkapp_GlobalCall(self, args)
761 PyObject *self;
762 PyObject *args;
763{
Guido van Rossum212643f1998-04-29 16:22:14 +0000764 /* Could do the same here as for Tkapp_Call(), but this is not used
765 much, so I can't be bothered. Unfortunately Tcl doesn't export a
766 way for the user to do what all its Global* variants do (save and
767 reset the scope pointer, call the local version, restore the saved
768 scope pointer). */
769
Guido van Rossum62320c91998-06-15 04:36:09 +0000770 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000771 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000772
Guido van Rossum62320c91998-06-15 04:36:09 +0000773 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000774 if (!cmd)
775 PyErr_SetString(Tkinter_TclError, "merge failed");
776
Guido van Rossum00d93061998-05-28 23:06:38 +0000777 else {
778 int err;
779 ENTER_TCL
780 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000781 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000782 if (err == TCL_ERROR)
783 res = Tkinter_Error(self);
784 else
785 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000786 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000787 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000788
789 if (cmd)
790 ckfree(cmd);
791
792 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000793}
794
795static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000796Tkapp_Eval(self, args)
797 PyObject *self;
798 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000799{
Barry Warsawfa701a81997-01-16 00:15:11 +0000800 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000801 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000802 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000803
Guido van Rossum43713e52000-02-29 13:59:29 +0000804 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 return NULL;
806
Guido van Rossum00d93061998-05-28 23:06:38 +0000807 ENTER_TCL
808 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000809 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000810 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000811 res = Tkinter_Error(self);
812 else
813 res = PyString_FromString(Tkapp_Result(self));
814 LEAVE_OVERLAP_TCL
815 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000816}
817
818static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000819Tkapp_GlobalEval(self, args)
820 PyObject *self;
821 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000822{
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000824 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000825 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000826
Guido van Rossum43713e52000-02-29 13:59:29 +0000827 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000828 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000829
Guido van Rossum00d93061998-05-28 23:06:38 +0000830 ENTER_TCL
831 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000832 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000833 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000834 res = Tkinter_Error(self);
835 else
836 res = PyString_FromString(Tkapp_Result(self));
837 LEAVE_OVERLAP_TCL
838 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000839}
840
841static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000842Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 PyObject *self;
844 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000845{
Barry Warsawfa701a81997-01-16 00:15:11 +0000846 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000847 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000848 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000849
Guido van Rossum43713e52000-02-29 13:59:29 +0000850 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000851 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000852
Guido van Rossum00d93061998-05-28 23:06:38 +0000853 ENTER_TCL
854 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000855 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000856 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000857 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000858
Guido van Rossum62320c91998-06-15 04:36:09 +0000859 else
860 res = PyString_FromString(Tkapp_Result(self));
861 LEAVE_OVERLAP_TCL
862 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000863}
864
865static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000866Tkapp_Record(self, args)
867 PyObject *self;
868 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000869{
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000871 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000872 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000873
Guido van Rossum35d43371997-08-02 00:09:09 +0000874 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000875 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Guido van Rossum00d93061998-05-28 23:06:38 +0000877 ENTER_TCL
878 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000879 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000880 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000881 res = Tkinter_Error(self);
882 else
883 res = PyString_FromString(Tkapp_Result(self));
884 LEAVE_OVERLAP_TCL
885 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000886}
887
888static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000889Tkapp_AddErrorInfo(self, args)
890 PyObject *self;
891 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000892{
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000894
Guido van Rossum43713e52000-02-29 13:59:29 +0000895 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000897 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000898 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000899 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000900
Barry Warsawfa701a81997-01-16 00:15:11 +0000901 Py_INCREF(Py_None);
902 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000903}
904
Barry Warsawfa701a81997-01-16 00:15:11 +0000905
906
Guido van Rossum18468821994-06-20 07:49:28 +0000907/** Tcl Variable **/
908
909static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000910SetVar(self, args, flags)
911 PyObject *self;
912 PyObject *args;
913 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000914{
Guido van Rossum00d93061998-05-28 23:06:38 +0000915 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000917 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000918
Guido van Rossum62320c91998-06-15 04:36:09 +0000919 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 if (!tmp)
921 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000922
Guido van Rossum43713e52000-02-29 13:59:29 +0000923 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000924 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000925 s = AsString(newValue, tmp);
926 ENTER_TCL
927 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
928 LEAVE_TCL
929 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000930 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000931 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000932 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000933 s = AsString (newValue, tmp);
934 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000935 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000936 s, flags);
937 LEAVE_TCL
938 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000940 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000941 return NULL;
942 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000943 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000944 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000945
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 if (!ok)
947 return Tkinter_Error(self);
948
949 Py_INCREF(Py_None);
950 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000951}
952
953static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000954Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000955 PyObject *self;
956 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000957{
Barry Warsawfa701a81997-01-16 00:15:11 +0000958 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000959}
960
961static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000962Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 PyObject *self;
964 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000965{
Barry Warsawfa701a81997-01-16 00:15:11 +0000966 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000967}
968
Barry Warsawfa701a81997-01-16 00:15:11 +0000969
970
Guido van Rossum18468821994-06-20 07:49:28 +0000971static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000972GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 PyObject *self;
974 PyObject *args;
975 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000976{
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000978 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Guido van Rossum43713e52000-02-29 13:59:29 +0000980 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000982 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000983 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000984 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000985
Barry Warsawfa701a81997-01-16 00:15:11 +0000986 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000987 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000988 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000989
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000991 res = Tkinter_Error(self);
992 else
993 res = PyString_FromString(s);
994 LEAVE_OVERLAP_TCL
995 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000996}
997
998static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000999Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001000 PyObject *self;
1001 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001002{
Barry Warsawfa701a81997-01-16 00:15:11 +00001003 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001004}
1005
1006static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001007Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 PyObject *self;
1009 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001010{
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001012}
1013
Barry Warsawfa701a81997-01-16 00:15:11 +00001014
1015
Guido van Rossum18468821994-06-20 07:49:28 +00001016static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001017UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 PyObject *self;
1019 PyObject *args;
1020 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001021{
Guido van Rossum35d43371997-08-02 00:09:09 +00001022 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001023 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001025
Guido van Rossum43713e52000-02-29 13:59:29 +00001026 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001028 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001029 if (name2 == NULL)
1030 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1031
1032 else
1033 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001034 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001035
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001037 res = Tkinter_Error(self);
1038 else {
1039 Py_INCREF(Py_None);
1040 res = Py_None;
1041 }
1042 LEAVE_OVERLAP_TCL
1043 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001044}
1045
1046static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001047Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001048 PyObject *self;
1049 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001050{
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001052}
1053
1054static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001055Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 PyObject *self;
1057 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001058{
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001060}
1061
Barry Warsawfa701a81997-01-16 00:15:11 +00001062
1063
Guido van Rossum18468821994-06-20 07:49:28 +00001064/** Tcl to Python **/
1065
1066static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001067Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 PyObject *self;
1069 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001070{
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 char *s;
1072 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001073
Guido van Rossum43713e52000-02-29 13:59:29 +00001074 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001076 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 return Tkinter_Error(self);
1078 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001079}
1080
1081static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001082Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001083 PyObject *self;
1084 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001085{
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 char *s;
1087 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001088
Guido van Rossum43713e52000-02-29 13:59:29 +00001089 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001091 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001092 return Tkinter_Error(self);
1093 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001094}
1095
1096static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001097Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001098 PyObject *self;
1099 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001100{
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 char *s;
1102 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001103
Guido van Rossum43713e52000-02-29 13:59:29 +00001104 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001105 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001106 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1107 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001108 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001109}
1110
1111static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001112Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001113 PyObject *self;
1114 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001115{
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001117 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001118 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001119
Guido van Rossum43713e52000-02-29 13:59:29 +00001120 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001121 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001122 ENTER_TCL
1123 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001124 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001125 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001126 res = Tkinter_Error(self);
1127 else
1128 res = Py_BuildValue("s", Tkapp_Result(self));
1129 LEAVE_OVERLAP_TCL
1130 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001131}
1132
1133static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001134Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 PyObject *self;
1136 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001137{
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001139 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001140 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001142
Guido van Rossum43713e52000-02-29 13:59:29 +00001143 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001144 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001145 ENTER_TCL
1146 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001147 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001148 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001149 res = Tkinter_Error(self);
1150 else
1151 res = Py_BuildValue("l", v);
1152 LEAVE_OVERLAP_TCL
1153 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001154}
1155
1156static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001157Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 PyObject *self;
1159 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001160{
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001162 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001164 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001165
Guido van Rossum43713e52000-02-29 13:59:29 +00001166 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001168 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001169 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001170 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001171 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001172 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001173 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001174 res = Tkinter_Error(self);
1175 else
1176 res = Py_BuildValue("d", v);
1177 LEAVE_OVERLAP_TCL
1178 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001179}
1180
1181static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001182Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 PyObject *self;
1184 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001185{
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001187 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001188 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001190
Guido van Rossum43713e52000-02-29 13:59:29 +00001191 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001193 ENTER_TCL
1194 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001195 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001196 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001197 res = Tkinter_Error(self);
1198 else
1199 res = Py_BuildValue("i", v);
1200 LEAVE_OVERLAP_TCL
1201 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001202}
1203
Barry Warsawfa701a81997-01-16 00:15:11 +00001204
1205
Guido van Rossum18468821994-06-20 07:49:28 +00001206static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001207Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001208 PyObject *self;
1209 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001210{
Barry Warsawfa701a81997-01-16 00:15:11 +00001211 char *list;
1212 int argc;
1213 char **argv;
1214 PyObject *v;
1215 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001216
Guido van Rossum43713e52000-02-29 13:59:29 +00001217 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001218 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001219
Barry Warsawfa701a81997-01-16 00:15:11 +00001220 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1221 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001222
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 if (!(v = PyTuple_New(argc)))
1224 return NULL;
1225
1226 for (i = 0; i < argc; i++) {
1227 PyObject *s = PyString_FromString(argv[i]);
1228 if (!s || PyTuple_SetItem(v, i, s)) {
1229 Py_DECREF(v);
1230 v = NULL;
1231 goto finally;
1232 }
1233 }
Guido van Rossum18468821994-06-20 07:49:28 +00001234
Barry Warsawfa701a81997-01-16 00:15:11 +00001235 finally:
1236 ckfree(FREECAST argv);
1237 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001238}
1239
1240static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001241Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001242 PyObject *self;
1243 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001244{
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001246
Guido van Rossum43713e52000-02-29 13:59:29 +00001247 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001249 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001250}
1251
1252static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001253Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001254 PyObject *self;
1255 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001256{
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 char *s = Merge(args);
1258 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001259
Barry Warsawfa701a81997-01-16 00:15:11 +00001260 if (s) {
1261 res = PyString_FromString(s);
1262 ckfree(s);
1263 }
1264 else
1265 PyErr_SetString(Tkinter_TclError, "merge failed");
1266
1267 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001268}
1269
Barry Warsawfa701a81997-01-16 00:15:11 +00001270
1271
Guido van Rossum18468821994-06-20 07:49:28 +00001272/** Tcl Command **/
1273
Guido van Rossum00d93061998-05-28 23:06:38 +00001274/* Client data struct */
1275typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001276 PyObject *self;
1277 PyObject *func;
1278} PythonCmd_ClientData;
1279
1280static int
1281PythonCmd_Error(interp)
1282 Tcl_Interp *interp;
1283{
1284 errorInCmd = 1;
1285 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1286 LEAVE_PYTHON
1287 return TCL_ERROR;
1288}
1289
Guido van Rossum18468821994-06-20 07:49:28 +00001290/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 * function or method.
1292 */
Guido van Rossum18468821994-06-20 07:49:28 +00001293static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001294PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001295 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001296 Tcl_Interp *interp;
1297 int argc;
1298 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001299{
Guido van Rossum00d93061998-05-28 23:06:38 +00001300 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001301 PyObject *self, *func, *arg, *res, *tmp;
1302 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001303
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001304 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001305
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 /* TBD: no error checking here since we know, via the
1307 * Tkapp_CreateCommand() that the client data is a two-tuple
1308 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001309 self = data->self;
1310 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001311
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 /* Create argument list (argv1, ..., argvN) */
1313 if (!(arg = PyTuple_New(argc - 1)))
1314 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001315
Barry Warsawfa701a81997-01-16 00:15:11 +00001316 for (i = 0; i < (argc - 1); i++) {
1317 PyObject *s = PyString_FromString(argv[i + 1]);
1318 if (!s || PyTuple_SetItem(arg, i, s)) {
1319 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001320 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001321 }
1322 }
1323 res = PyEval_CallObject(func, arg);
1324 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001325
Barry Warsawfa701a81997-01-16 00:15:11 +00001326 if (res == NULL)
1327 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001328
Barry Warsawfa701a81997-01-16 00:15:11 +00001329 if (!(tmp = PyList_New(0))) {
1330 Py_DECREF(res);
1331 return PythonCmd_Error(interp);
1332 }
1333
1334 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1335 Py_DECREF(res);
1336 Py_DECREF(tmp);
1337
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 LEAVE_PYTHON
1339
Barry Warsawfa701a81997-01-16 00:15:11 +00001340 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001341}
1342
1343static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001344PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001345 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001346{
Guido van Rossum00d93061998-05-28 23:06:38 +00001347 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1348
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001349 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001350 Py_XDECREF(data->self);
1351 Py_XDECREF(data->func);
1352 PyMem_DEL(data);
1353 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001354}
1355
Barry Warsawfa701a81997-01-16 00:15:11 +00001356
1357
Guido van Rossum18468821994-06-20 07:49:28 +00001358static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001359Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001360 PyObject *self;
1361 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001362{
Guido van Rossum00d93061998-05-28 23:06:38 +00001363 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001364 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001365 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001366 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001367
Guido van Rossum43713e52000-02-29 13:59:29 +00001368 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001369 return NULL;
1370 if (!PyCallable_Check(func)) {
1371 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 return NULL;
1373 }
Guido van Rossum18468821994-06-20 07:49:28 +00001374
Guido van Rossum00d93061998-05-28 23:06:38 +00001375 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 if (!data)
1377 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001378 Py_XINCREF(self);
1379 Py_XINCREF(func);
1380 data->self = self;
1381 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001382
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 ENTER_TCL
1384 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1385 (ClientData)data, PythonCmdDelete);
1386 LEAVE_TCL
1387 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001388 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001389 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001390 return NULL;
1391 }
Guido van Rossum18468821994-06-20 07:49:28 +00001392
Barry Warsawfa701a81997-01-16 00:15:11 +00001393 Py_INCREF(Py_None);
1394 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001395}
1396
Barry Warsawfa701a81997-01-16 00:15:11 +00001397
1398
Guido van Rossum18468821994-06-20 07:49:28 +00001399static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001400Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001401 PyObject *self;
1402 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001403{
Barry Warsawfa701a81997-01-16 00:15:11 +00001404 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001405 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001406
Guido van Rossum43713e52000-02-29 13:59:29 +00001407 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001409 ENTER_TCL
1410 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1411 LEAVE_TCL
1412 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1414 return NULL;
1415 }
1416 Py_INCREF(Py_None);
1417 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001418}
1419
Barry Warsawfa701a81997-01-16 00:15:11 +00001420
1421
Guido van Rossum00d93061998-05-28 23:06:38 +00001422#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001423/** File Handler **/
1424
Guido van Rossum00d93061998-05-28 23:06:38 +00001425typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001426 PyObject *func;
1427 PyObject *file;
1428 int id;
1429 struct _fhcdata *next;
1430} FileHandler_ClientData;
1431
1432static FileHandler_ClientData *HeadFHCD;
1433
1434static FileHandler_ClientData *
1435NewFHCD(func, file, id)
1436 PyObject *func;
1437 PyObject *file;
1438 int id;
1439{
1440 FileHandler_ClientData *p;
1441 p = PyMem_NEW(FileHandler_ClientData, 1);
1442 if (p != NULL) {
1443 Py_XINCREF(func);
1444 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001445 p->func = func;
1446 p->file = file;
1447 p->id = id;
1448 p->next = HeadFHCD;
1449 HeadFHCD = p;
1450 }
1451 return p;
1452}
1453
1454static void
1455DeleteFHCD(id)
1456 int id;
1457{
1458 FileHandler_ClientData *p, **pp;
1459
1460 pp = &HeadFHCD;
1461 while ((p = *pp) != NULL) {
1462 if (p->id == id) {
1463 *pp = p->next;
1464 Py_XDECREF(p->func);
1465 Py_XDECREF(p->file);
1466 PyMem_DEL(p);
1467 }
1468 else
1469 pp = &p->next;
1470 }
1471}
1472
Guido van Rossuma597dde1995-01-10 20:56:29 +00001473static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001474FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001475 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001477{
Guido van Rossum00d93061998-05-28 23:06:38 +00001478 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001480
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001481 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001482 func = data->func;
1483 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001484
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 arg = Py_BuildValue("(Oi)", file, (long) mask);
1486 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001487 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001488
1489 if (res == NULL) {
1490 errorInCmd = 1;
1491 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1492 }
1493 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001494 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001495}
1496
1497static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001498GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001499 /* Either an int >= 0 or an object with a
1500 *.fileno() method that returns an int >= 0
1501 */
1502 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001503{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001504 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001505 int id;
1506 if (PyInt_Check(file)) {
1507 id = PyInt_AsLong(file);
1508 if (id < 0)
1509 PyErr_SetString(PyExc_ValueError, "invalid file id");
1510 return id;
1511 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001512 args = PyTuple_New(0);
1513 if (args == NULL)
1514 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001515
1516 meth = PyObject_GetAttrString(file, "fileno");
1517 if (meth == NULL) {
1518 Py_DECREF(args);
1519 return -1;
1520 }
1521
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001522 res = PyEval_CallObject(meth, args);
1523 Py_DECREF(args);
1524 Py_DECREF(meth);
1525 if (res == NULL)
1526 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001527
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001528 if (PyInt_Check(res))
1529 id = PyInt_AsLong(res);
1530 else
1531 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001532
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001533 if (id < 0)
1534 PyErr_SetString(PyExc_ValueError,
1535 "invalid fileno() return value");
1536 Py_DECREF(res);
1537 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001538}
1539
1540static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001541Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 PyObject *self;
1543 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001544{
Guido van Rossum00d93061998-05-28 23:06:38 +00001545 FileHandler_ClientData *data;
1546 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001547 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001548
Guido van Rossum43713e52000-02-29 13:59:29 +00001549 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001551 tfile = GetFileNo(file);
1552 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 return NULL;
1554 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001555 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001556 return NULL;
1557 }
1558
Guido van Rossuma80649b2000-03-28 20:07:05 +00001559 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001560 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001561 return NULL;
1562
Barry Warsawfa701a81997-01-16 00:15:11 +00001563 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001564 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001566 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001567 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001569}
1570
1571static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001572Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001573 PyObject *self;
1574 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001575{
Barry Warsawfa701a81997-01-16 00:15:11 +00001576 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001577 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001578 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001579
Guido van Rossum43713e52000-02-29 13:59:29 +00001580 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001582 tfile = GetFileNo(file);
1583 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 return NULL;
1585
Guido van Rossuma80649b2000-03-28 20:07:05 +00001586 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001587
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001589 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001590 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001591 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001592 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001593 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001594}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001595#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001596
Barry Warsawfa701a81997-01-16 00:15:11 +00001597
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001598/**** Tktt Object (timer token) ****/
1599
1600staticforward PyTypeObject Tktt_Type;
1601
Guido van Rossum00d93061998-05-28 23:06:38 +00001602typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001603 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001604 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001605 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001606} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001607
1608static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001609Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001610 PyObject *self;
1611 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001612{
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001614 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001615
Guido van Rossum43713e52000-02-29 13:59:29 +00001616 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001617 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001618 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001619 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001620 v->token = NULL;
1621 }
1622 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001623 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001624 Py_DECREF(func);
1625 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001626 }
1627 Py_INCREF(Py_None);
1628 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001629}
1630
1631static PyMethodDef Tktt_methods[] =
1632{
Guido van Rossum35d43371997-08-02 00:09:09 +00001633 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001634 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001635};
1636
1637static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001638Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001639 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640{
Barry Warsawfa701a81997-01-16 00:15:11 +00001641 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001642
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 v = PyObject_NEW(TkttObject, &Tktt_Type);
1644 if (v == NULL)
1645 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001646
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 Py_INCREF(func);
1648 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001650
1651 /* Extra reference, deleted when called or when handler is deleted */
1652 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001654}
1655
1656static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001657Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001658 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001659{
Guido van Rossum00d93061998-05-28 23:06:38 +00001660 TkttObject *v = (TkttObject *)self;
1661 PyObject *func = v->func;
1662
1663 Py_XDECREF(func);
1664
Guido van Rossum35d43371997-08-02 00:09:09 +00001665 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001666}
1667
Guido van Rossum597ac201998-05-12 14:36:19 +00001668static PyObject *
1669Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001671{
Barry Warsawfa701a81997-01-16 00:15:11 +00001672 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001673 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001674
Guido van Rossum597ac201998-05-12 14:36:19 +00001675 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001677 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001678}
1679
1680static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001681Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001682 PyObject *self;
1683 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001684{
Barry Warsawfa701a81997-01-16 00:15:11 +00001685 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001686}
1687
1688static PyTypeObject Tktt_Type =
1689{
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001691 0, /*ob_size */
1692 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001693 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 0, /*tp_itemsize */
1695 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001696 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001697 Tktt_GetAttr, /*tp_getattr */
1698 0, /*tp_setattr */
1699 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001700 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 0, /*tp_as_number */
1702 0, /*tp_as_sequence */
1703 0, /*tp_as_mapping */
1704 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001705};
1706
Barry Warsawfa701a81997-01-16 00:15:11 +00001707
1708
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001709/** Timer Handler **/
1710
1711static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001712TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001714{
Guido van Rossum00d93061998-05-28 23:06:38 +00001715 TkttObject *v = (TkttObject *)clientData;
1716 PyObject *func = v->func;
1717 PyObject *res;
1718
1719 if (func == NULL)
1720 return;
1721
1722 v->func = NULL;
1723
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001724 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001725
1726 res = PyEval_CallObject(func, NULL);
1727 Py_DECREF(func);
1728 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001729
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 if (res == NULL) {
1731 errorInCmd = 1;
1732 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1733 }
1734 else
1735 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001736
1737 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001738}
1739
1740static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001741Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001742 PyObject *self;
1743 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001744{
Barry Warsawfa701a81997-01-16 00:15:11 +00001745 int milliseconds;
1746 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001747 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001748
Guido van Rossum43713e52000-02-29 13:59:29 +00001749 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001750 return NULL;
1751 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001752 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001753 return NULL;
1754 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001755 v = Tktt_New(func);
1756 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1757 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001758
Guido van Rossum00d93061998-05-28 23:06:38 +00001759 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001760}
1761
Barry Warsawfa701a81997-01-16 00:15:11 +00001762
Guido van Rossum18468821994-06-20 07:49:28 +00001763/** Event Loop **/
1764
Guido van Rossum18468821994-06-20 07:49:28 +00001765static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001766Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001767 PyObject *self;
1768 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001769{
Barry Warsawfa701a81997-01-16 00:15:11 +00001770 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001771#ifdef WITH_THREAD
1772 PyThreadState *tstate = PyThreadState_Get();
1773#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001774
Guido van Rossum43713e52000-02-29 13:59:29 +00001775 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001776 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001777
Barry Warsawfa701a81997-01-16 00:15:11 +00001778 quitMainLoop = 0;
1779 while (Tk_GetNumMainWindows() > threshold &&
1780 !quitMainLoop &&
1781 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001782 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001783 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001784
1785#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001786 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001787 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001788 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001789 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001790 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001791 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001792 if (result == 0)
1793 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001794 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001795#else
1796 result = Tcl_DoOneEvent(0);
1797#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001798
Guido van Rossum35d43371997-08-02 00:09:09 +00001799 if (PyErr_CheckSignals() != 0)
1800 return NULL;
1801 if (result < 0)
1802 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001803 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001805
Barry Warsawfa701a81997-01-16 00:15:11 +00001806 if (errorInCmd) {
1807 errorInCmd = 0;
1808 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1809 excInCmd = valInCmd = trbInCmd = NULL;
1810 return NULL;
1811 }
1812 Py_INCREF(Py_None);
1813 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001814}
1815
1816static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001817Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001818 PyObject *self;
1819 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001820{
Guido van Rossum35d43371997-08-02 00:09:09 +00001821 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001822 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001823
Guido van Rossum43713e52000-02-29 13:59:29 +00001824 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001825 return NULL;
1826
Guido van Rossum00d93061998-05-28 23:06:38 +00001827 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001828 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001829 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001830 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001831}
1832
1833static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001834Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001835 PyObject *self;
1836 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001837{
1838
Guido van Rossum43713e52000-02-29 13:59:29 +00001839 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001840 return NULL;
1841
1842 quitMainLoop = 1;
1843 Py_INCREF(Py_None);
1844 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001845}
1846
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001847static PyObject *
1848Tkapp_InterpAddr(self, args)
1849 PyObject *self;
1850 PyObject *args;
1851{
1852
Guido van Rossum43713e52000-02-29 13:59:29 +00001853 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001854 return NULL;
1855
1856 return PyInt_FromLong((long)Tkapp_Interp(self));
1857}
1858
Barry Warsawfa701a81997-01-16 00:15:11 +00001859
1860
Guido van Rossum18468821994-06-20 07:49:28 +00001861/**** Tkapp Method List ****/
1862
1863static PyMethodDef Tkapp_methods[] =
1864{
Guido van Rossum35d43371997-08-02 00:09:09 +00001865 {"call", Tkapp_Call, 0},
1866 {"globalcall", Tkapp_GlobalCall, 0},
1867 {"eval", Tkapp_Eval, 1},
1868 {"globaleval", Tkapp_GlobalEval, 1},
1869 {"evalfile", Tkapp_EvalFile, 1},
1870 {"record", Tkapp_Record, 1},
1871 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1872 {"setvar", Tkapp_SetVar, 1},
1873 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1874 {"getvar", Tkapp_GetVar, 1},
1875 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1876 {"unsetvar", Tkapp_UnsetVar, 1},
1877 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1878 {"getint", Tkapp_GetInt, 1},
1879 {"getdouble", Tkapp_GetDouble, 1},
1880 {"getboolean", Tkapp_GetBoolean, 1},
1881 {"exprstring", Tkapp_ExprString, 1},
1882 {"exprlong", Tkapp_ExprLong, 1},
1883 {"exprdouble", Tkapp_ExprDouble, 1},
1884 {"exprboolean", Tkapp_ExprBoolean, 1},
1885 {"splitlist", Tkapp_SplitList, 1},
1886 {"split", Tkapp_Split, 1},
1887 {"merge", Tkapp_Merge, 0},
1888 {"createcommand", Tkapp_CreateCommand, 1},
1889 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001890#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001891 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1892 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001893#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001894 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001895 {"mainloop", Tkapp_MainLoop, 1},
1896 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001897 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001898 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001899 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001900};
1901
Barry Warsawfa701a81997-01-16 00:15:11 +00001902
1903
Guido van Rossum18468821994-06-20 07:49:28 +00001904/**** Tkapp Type Methods ****/
1905
1906static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001907Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001908 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001909{
Guido van Rossum00d93061998-05-28 23:06:38 +00001910 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001911 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001912 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001913 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001914 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001915}
1916
1917static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001918Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001919 PyObject *self;
1920 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001921{
Guido van Rossum35d43371997-08-02 00:09:09 +00001922 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001923}
1924
1925static PyTypeObject Tkapp_Type =
1926{
Guido van Rossum35d43371997-08-02 00:09:09 +00001927 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 0, /*ob_size */
1929 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001930 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 0, /*tp_itemsize */
1932 Tkapp_Dealloc, /*tp_dealloc */
1933 0, /*tp_print */
1934 Tkapp_GetAttr, /*tp_getattr */
1935 0, /*tp_setattr */
1936 0, /*tp_compare */
1937 0, /*tp_repr */
1938 0, /*tp_as_number */
1939 0, /*tp_as_sequence */
1940 0, /*tp_as_mapping */
1941 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001942};
1943
Barry Warsawfa701a81997-01-16 00:15:11 +00001944
1945
Guido van Rossum18468821994-06-20 07:49:28 +00001946/**** Tkinter Module ****/
1947
1948static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001949Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001950 PyObject *self;
1951 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001952{
Barry Warsawfa701a81997-01-16 00:15:11 +00001953 char *screenName = NULL;
1954 char *baseName = NULL;
1955 char *className = NULL;
1956 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001957
Guido van Rossum35d43371997-08-02 00:09:09 +00001958 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001959 if (baseName != NULL)
1960 baseName++;
1961 else
1962 baseName = Py_GetProgramName();
1963 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001964
Guido van Rossum43713e52000-02-29 13:59:29 +00001965 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001966 &screenName, &baseName, &className,
1967 &interactive))
1968 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001969
Barry Warsawfa701a81997-01-16 00:15:11 +00001970 return (PyObject *) Tkapp_New(screenName, baseName, className,
1971 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001972}
1973
1974static PyMethodDef moduleMethods[] =
1975{
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001977#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001978 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1979 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001980#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001981 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001982 {"mainloop", Tkapp_MainLoop, 1},
1983 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001984 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001985 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001986};
1987
Guido van Rossum7bf15641998-05-22 18:28:17 +00001988#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001989
1990static int stdin_ready = 0;
1991
Guido van Rossumad4db171998-06-13 13:56:28 +00001992#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001993static void
1994MyFileProc(clientData, mask)
1995 void *clientData;
1996 int mask;
1997{
1998 stdin_ready = 1;
1999}
Guido van Rossumad4db171998-06-13 13:56:28 +00002000#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002001
Guido van Rossum00d93061998-05-28 23:06:38 +00002002static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002003
Guido van Rossum18468821994-06-20 07:49:28 +00002004static int
Guido van Rossum35d43371997-08-02 00:09:09 +00002005EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00002006{
Guido van Rossumad4db171998-06-13 13:56:28 +00002007#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002008 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002009#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002010#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002011 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002012#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002013 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002014 errorInCmd = 0;
2015#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002016 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002017 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002018#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002019 while (!errorInCmd && !stdin_ready) {
2020 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002021#ifdef MS_WINDOWS
2022 if (_kbhit()) {
2023 stdin_ready = 1;
2024 break;
2025 }
2026#endif
2027#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002028 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002029 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002030 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002031
Guido van Rossum00d93061998-05-28 23:06:38 +00002032 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002033
2034 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002035 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002036 if (result == 0)
2037 Sleep(20);
2038 Py_END_ALLOW_THREADS
2039#else
2040 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002041#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002042
2043 if (result < 0)
2044 break;
2045 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002046#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002047 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002048#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002049 if (errorInCmd) {
2050 errorInCmd = 0;
2051 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2052 excInCmd = valInCmd = trbInCmd = NULL;
2053 PyErr_Print();
2054 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002055#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002056 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002057#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002058 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002059}
Guido van Rossum18468821994-06-20 07:49:28 +00002060
Guido van Rossum00d93061998-05-28 23:06:38 +00002061#endif
2062
Guido van Rossum7bf15641998-05-22 18:28:17 +00002063static void
2064EnableEventHook()
2065{
Guido van Rossum00d93061998-05-28 23:06:38 +00002066#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002067 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002068#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002069 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002070#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002071 PyOS_InputHook = EventHook;
2072 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002073#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002074}
2075
2076static void
2077DisableEventHook()
2078{
Guido van Rossum00d93061998-05-28 23:06:38 +00002079#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002080 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2081 PyOS_InputHook = NULL;
2082 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002083#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002084}
2085
Barry Warsawfa701a81997-01-16 00:15:11 +00002086
2087/* all errors will be checked in one fell swoop in init_tkinter() */
2088static void
2089ins_long(d, name, val)
2090 PyObject *d;
2091 char *name;
2092 long val;
2093{
2094 PyObject *v = PyInt_FromLong(val);
2095 if (v) {
2096 PyDict_SetItemString(d, name, v);
2097 Py_DECREF(v);
2098 }
2099}
2100static void
2101ins_string(d, name, val)
2102 PyObject *d;
2103 char *name;
2104 char *val;
2105{
2106 PyObject *v = PyString_FromString(val);
2107 if (v) {
2108 PyDict_SetItemString(d, name, v);
2109 Py_DECREF(v);
2110 }
2111}
2112
2113
Guido van Rossum3886bb61998-12-04 18:50:17 +00002114DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002115init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002116{
Barry Warsawfa701a81997-01-16 00:15:11 +00002117 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002118
Barry Warsawfa701a81997-01-16 00:15:11 +00002119 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002120
2121#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002122 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002123#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002124
Barry Warsawfa701a81997-01-16 00:15:11 +00002125 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002126
Barry Warsawfa701a81997-01-16 00:15:11 +00002127 d = PyModule_GetDict(m);
2128 Tkinter_TclError = Py_BuildValue("s", "TclError");
2129 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002130
Guido van Rossum35d43371997-08-02 00:09:09 +00002131 ins_long(d, "READABLE", TCL_READABLE);
2132 ins_long(d, "WRITABLE", TCL_WRITABLE);
2133 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2134 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2135 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2136 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2137 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2138 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2139 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002140 ins_string(d, "TK_VERSION", TK_VERSION);
2141 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002142
Guido van Rossum83551bf1997-09-13 00:44:23 +00002143 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002144
2145 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002146 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2147
Guido van Rossume187b0e2000-03-27 21:46:29 +00002148 /* This helps the dynamic loader; in Unicode aware Tcl versions
2149 it also helps Tcl find its encodings. */
2150 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002151
Barry Warsawfa701a81997-01-16 00:15:11 +00002152 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002153 return;
2154
Guido van Rossum43ff8681998-07-14 18:02:13 +00002155#if 0
2156 /* This was not a good idea; through <Destroy> bindings,
2157 Tcl_Finalize() may invoke Python code but at that point the
2158 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002159 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002160#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002161
Jack Jansen34cc5c31995-10-31 16:15:12 +00002162#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002163 /*
2164 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2165 ** Most of the initializations in that routine (toolbox init calls and
2166 ** such) have already been done for us, so we only need these.
2167 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002168 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002169
2170 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002171#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002172 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002173#endif /* GENERATINGCFM */
2174#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002175}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002176
Guido van Rossumec22c921996-02-25 04:50:29 +00002177
Barry Warsawfa701a81997-01-16 00:15:11 +00002178
Guido van Rossum9722ad81995-09-22 23:49:28 +00002179#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002180
2181/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002182** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002183*/
2184
Guido van Rossum9722ad81995-09-22 23:49:28 +00002185void
2186panic(char * format, ...)
2187{
Barry Warsawfa701a81997-01-16 00:15:11 +00002188 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002189
Barry Warsawfa701a81997-01-16 00:15:11 +00002190 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002191
Guido van Rossum227cf761998-08-05 13:53:32 +00002192 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002193 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002194
Barry Warsawfa701a81997-01-16 00:15:11 +00002195 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002196
Barry Warsawfa701a81997-01-16 00:15:11 +00002197 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002198}
Jack Jansen40b546d1995-11-14 10:34:45 +00002199
Guido van Rossumec22c921996-02-25 04:50:29 +00002200/*
2201** Pass events to SIOUX before passing them to Tk.
2202*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002203
Guido van Rossumec22c921996-02-25 04:50:29 +00002204static int
2205PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002206 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002207{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002208 WindowPtr frontwin;
2209 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002210 ** Sioux eats too many events, so we don't pass it everything. We
2211 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002212 ** the Sioux window is frontmost. This means that Tk menus don't work
2213 ** in that case, but at least we can scroll the sioux window.
2214 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2215 ** part of the external interface of Sioux...
2216 */
2217 frontwin = FrontWindow();
2218 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2219 if (SIOUXHandleOneEvent(eventPtr))
2220 return 0; /* Nothing happened to the Tcl event queue */
2221 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002222 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002223}
2224
Guido van Rossumec22c921996-02-25 04:50:29 +00002225#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002226
2227/*
2228** Additional Mac specific code for dealing with shared libraries.
2229*/
2230
2231#include <Resources.h>
2232#include <CodeFragments.h>
2233
2234static int loaded_from_shlib = 0;
2235static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002236
Jack Jansen34cc5c31995-10-31 16:15:12 +00002237/*
2238** If this module is dynamically loaded the following routine should
2239** be the init routine. It takes care of adding the shared library to
2240** the resource-file chain, so that the tk routines can find their
2241** resources.
2242*/
2243OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002244init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002245{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002246 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002247 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002248 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002249 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2250 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002251 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002252 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2253 loaded_from_shlib = 1;
2254 }
2255 return noErr;
2256}
2257
2258/*
2259** Insert the library resources into the search path. Put them after
2260** the resources from the application. Again, we ignore errors.
2261*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002262static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002263mac_addlibresources()
2264{
2265 if ( !loaded_from_shlib )
2266 return;
2267 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2268}
2269
Guido van Rossumec22c921996-02-25 04:50:29 +00002270#endif /* GENERATINGCFM */
2271#endif /* macintosh */