blob: 47edf626ebad071596f609e8d3e8933620bc7a18 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
Guido van Rossuma80649b2000-03-28 20:07:05 +000037 Only Tcl/Tk 8.0 and later are supported. Older versions are not
38 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
39 libraries.)
40*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
Guido van Rossuma80649b2000-03-28 20:07:05 +000042/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000043
44 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
45 intelligent mappings between Python objects and Tcl objects (e.g. ints,
46 floats and Tcl window pointers could be handled specially).
47
48 - Register a new Tcl type, "Python callable", which can be called more
49 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
50
Guido van Rossum7ffa7611996-08-13 21:10:16 +000051*/
52
Guido van Rossum35d43371997-08-02 00:09:09 +000053
Guido van Rossum9722ad81995-09-22 23:49:28 +000054#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000055#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000056
Guido van Rossum00d93061998-05-28 23:06:38 +000057#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000058#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000059#endif
60
Guido van Rossum2a5119b1998-05-29 01:28:40 +000061#ifdef MS_WINDOWS
62#include <windows.h>
63#endif
64
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000065#ifdef macintosh
66#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000067#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000068#endif
69
Guido van Rossum49b56061998-10-01 20:42:43 +000070#ifdef PYOS_OS2
71#include "myselect.h"
72#endif
73
Guido van Rossum18468821994-06-20 07:49:28 +000074#include <tcl.h>
75#include <tk.h>
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Guido van Rossuma80649b2000-03-28 20:07:05 +000079#if TKMAJORMINOR < 8000
80#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Guido van Rossuma80649b2000-03-28 20:07:05 +000083#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084/* Sigh, we have to include this to get at the tcl qd pointer */
85#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000086/* And this one we need to clear the menu bar */
87#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000088#endif
89
Guido van Rossuma80649b2000-03-28 20:07:05 +000090#if !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000091#define HAVE_CREATEFILEHANDLER
92#endif
93
Guido van Rossum00d93061998-05-28 23:06:38 +000094#ifdef HAVE_CREATEFILEHANDLER
95
96/* Tcl_CreateFileHandler() changed several times; these macros deal with the
97 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
98 Unix, only because Jack added it back); when available on Windows, it only
99 applies to sockets. */
100
Guido van Rossum7bf15641998-05-22 18:28:17 +0000101#ifdef MS_WINDOWS
102#define FHANDLETYPE TCL_WIN_SOCKET
103#else
104#define FHANDLETYPE TCL_UNIX_FD
105#endif
106
Guido van Rossum00d93061998-05-28 23:06:38 +0000107/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
108 which uses this to handle Tcl events while the user is typing commands. */
109
110#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000111#define WAIT_FOR_STDIN
112#endif
113
Guido van Rossum00d93061998-05-28 23:06:38 +0000114#endif /* HAVE_CREATEFILEHANDLER */
115
Guido van Rossumad4db171998-06-13 13:56:28 +0000116#ifdef MS_WINDOWS
117#include <conio.h>
118#define WAIT_FOR_STDIN
119#endif
120
Guido van Rossum00d93061998-05-28 23:06:38 +0000121#ifdef WITH_THREAD
122
123/* The threading situation is complicated. Tcl is not thread-safe, except for
124 Tcl 8.1, which will probably remain in alpha status for another 6 months
125 (and the README says that Tk will probably remain thread-unsafe forever).
126 So we need to use a lock around all uses of Tcl. Previously, the Python
127 interpreter lock was used for this. However, this causes problems when
128 other Python threads need to run while Tcl is blocked waiting for events.
129
130 To solve this problem, a separate lock for Tcl is introduced. Holding it
131 is incompatible with holding Python's interpreter lock. The following four
132 macros manipulate both locks together.
133
134 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
135 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
136 that could call an event handler, or otherwise affect the state of a Tcl
137 interpreter. These assume that the surrounding code has the Python
138 interpreter lock; inside the brackets, the Python interpreter lock has been
139 released and the lock for Tcl has been acquired.
140
Guido van Rossum5e977831998-06-15 14:03:52 +0000141 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
142 (For example, when transferring data from the Tcl interpreter result to a
143 Python string object.) This can be done by using different macros to close
144 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
145 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
146 releases the Tcl lock.
147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000149 handlers when the handler needs to use Python. Such event handlers are
150 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000152 the Python interpreter lock, restoring the appropriate thread state, and
153 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
154 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000155 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157 These locks expand to several statements and brackets; they should not be
158 used in branches of if statements and the like.
159
160*/
161
Guido van Rossum65d5b571998-12-21 19:32:43 +0000162static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000164
165#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000166 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000170 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000171
Guido van Rossum62320c91998-06-15 04:36:09 +0000172#define ENTER_OVERLAP \
173 Py_END_ALLOW_THREADS
174
175#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000176 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000177
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178#define ENTER_PYTHON \
179 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000181
182#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000184 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000185
186#else
187
188#define ENTER_TCL
189#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000190#define ENTER_OVERLAP
191#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000192#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000193#define LEAVE_PYTHON
194
195#endif
196
Guido van Rossumec22c921996-02-25 04:50:29 +0000197#ifdef macintosh
198
199/*
200** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000201** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000202*/
203
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000204/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000205#define FREECAST (char *)
206
Guido van Rossumec22c921996-02-25 04:50:29 +0000207#include <Events.h> /* For EventRecord */
208
209typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000210void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000211int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
212
213staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
214
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000215#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
216 #pragma import on
217#endif
218
219#include <SIOUX.h>
220extern int SIOUXIsAppWindow(WindowPtr);
221
222#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
223 #pragma import reset
224#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000225#endif /* macintosh */
226
Guido van Rossum97867b21996-08-08 19:09:53 +0000227#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000228#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000229#endif
230
Guido van Rossum18468821994-06-20 07:49:28 +0000231/**** Tkapp Object Declaration ****/
232
233staticforward PyTypeObject Tkapp_Type;
234
Guido van Rossum00d93061998-05-28 23:06:38 +0000235typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000236 PyObject_HEAD
237 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000238} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000239
240#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000241#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
242#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
243
Guido van Rossum35d43371997-08-02 00:09:09 +0000244#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000245(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Barry Warsawfa701a81997-01-16 00:15:11 +0000247
248
Guido van Rossum18468821994-06-20 07:49:28 +0000249/**** Error Handling ****/
250
251static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000252static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000253static int errorInCmd = 0;
254static PyObject *excInCmd;
255static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000257
Barry Warsawfa701a81997-01-16 00:15:11 +0000258
259
Guido van Rossum18468821994-06-20 07:49:28 +0000260static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000261Tkinter_Error(v)
262 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000263{
Barry Warsawfa701a81997-01-16 00:15:11 +0000264 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
265 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000266}
267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268
Barry Warsawfa701a81997-01-16 00:15:11 +0000269
Guido van Rossum18468821994-06-20 07:49:28 +0000270/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000271
272#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000273#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000274#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000275#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000276
Guido van Rossum00d93061998-05-28 23:06:38 +0000277/* Millisecond sleep() for Unix platforms. */
278
279static void
280Sleep(milli)
281 int milli;
282{
283 /* XXX Too bad if you don't have select(). */
284 struct timeval t;
285 double frac;
286 t.tv_sec = milli/1000;
287 t.tv_usec = (milli%1000) * 1000;
288 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
289}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000290#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000291#endif /* WITH_THREAD */
292
293
Guido van Rossum18468821994-06-20 07:49:28 +0000294static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000295AsString(value, tmp)
296 PyObject *value;
297 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000298{
Guido van Rossum35d43371997-08-02 00:09:09 +0000299 if (PyString_Check(value))
300 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 else {
302 PyObject *v = PyObject_Str(value);
303 PyList_Append(tmp, v);
304 Py_DECREF(v);
305 return PyString_AsString(v);
306 }
Guido van Rossum18468821994-06-20 07:49:28 +0000307}
308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309
310
Guido van Rossum18468821994-06-20 07:49:28 +0000311#define ARGSZ 64
312
313static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000314Merge(args)
315 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000316{
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 PyObject *tmp = NULL;
318 char *argvStore[ARGSZ];
319 char **argv = NULL;
320 int fvStore[ARGSZ];
321 int *fv = NULL;
322 int argc = 0, i;
323 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (!(tmp = PyList_New(0)))
326 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000327
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 argv = argvStore;
329 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (args == NULL)
332 argc = 0;
333
334 else if (!PyTuple_Check(args)) {
335 argc = 1;
336 fv[0] = 0;
337 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000338 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 else {
340 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000341
Barry Warsawfa701a81997-01-16 00:15:11 +0000342 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000343 argv = (char **)ckalloc(argc * sizeof(char *));
344 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000345 if (argv == NULL || fv == NULL) {
346 PyErr_NoMemory();
347 goto finally;
348 }
349 }
350
351 for (i = 0; i < argc; i++) {
352 PyObject *v = PyTuple_GetItem(args, i);
353 if (PyTuple_Check(v)) {
354 fv[i] = 1;
355 if (!(argv[i] = Merge(v)))
356 goto finally;
357 }
358 else if (v == Py_None) {
359 argc = i;
360 break;
361 }
362 else {
363 fv[i] = 0;
364 argv[i] = AsString(v, tmp);
365 }
366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 finally:
371 for (i = 0; i < argc; i++)
372 if (fv[i]) {
373 ckfree(argv[i]);
374 }
375 if (argv != argvStore)
376 ckfree(FREECAST argv);
377 if (fv != fvStore)
378 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 Py_DECREF(tmp);
381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000382}
383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384
385
Guido van Rossum18468821994-06-20 07:49:28 +0000386static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000387Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000389{
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 int argc;
391 char **argv;
392 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 if (list == NULL) {
395 Py_INCREF(Py_None);
396 return Py_None;
397 }
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 /* Not a list.
401 * Could be a quoted string containing funnies, e.g. {"}.
402 * Return the string itself.
403 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 return PyString_FromString(list);
405 }
Guido van Rossum18468821994-06-20 07:49:28 +0000406
Barry Warsawfa701a81997-01-16 00:15:11 +0000407 if (argc == 0)
408 v = PyString_FromString("");
409 else if (argc == 1)
410 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000411 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 int i;
413 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000416 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 Py_DECREF(v);
418 v = NULL;
419 break;
420 }
421 PyTuple_SetItem(v, i, w);
422 }
423 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000424 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427
Barry Warsawfa701a81997-01-16 00:15:11 +0000428
429
Guido van Rossum18468821994-06-20 07:49:28 +0000430/**** Tkapp Object ****/
431
432#ifndef WITH_APPINIT
433int
Guido van Rossum35d43371997-08-02 00:09:09 +0000434Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000436{
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000438
Barry Warsawfa701a81997-01-16 00:15:11 +0000439 main = Tk_MainWindow(interp);
440 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000441 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000442 return TCL_ERROR;
443 }
444 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000445 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000446 return TCL_ERROR;
447 }
448 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000449}
450#endif /* !WITH_APPINIT */
451
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453
454
455/* Initialize the Tk application; see the `main' function in
456 * `tkMain.c'.
457 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000458
459static void EnableEventHook(); /* Forward */
460static void DisableEventHook(); /* Forward */
461
Barry Warsawfa701a81997-01-16 00:15:11 +0000462static TkappObject *
463Tkapp_New(screenName, baseName, className, interactive)
464 char *screenName;
465 char *baseName;
466 char *className;
467 int interactive;
468{
469 TkappObject *v;
470 char *argv0;
471
472 v = PyObject_NEW(TkappObject, &Tkapp_Type);
473 if (v == NULL)
474 return NULL;
475
476 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000477
Guido van Rossuma80649b2000-03-28 20:07:05 +0000478#if defined(macintosh)
479 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000480 ClearMenuBar();
481 TkMacInitMenus(v->interp);
482#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000483 /* Delete the 'exit' command, which can screw things up */
484 Tcl_DeleteCommand(v->interp, "exit");
485
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 if (screenName != NULL)
487 Tcl_SetVar2(v->interp, "env", "DISPLAY",
488 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 if (interactive)
491 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
492 else
493 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000494
Barry Warsawfa701a81997-01-16 00:15:11 +0000495 /* This is used to get the application class for Tk 4.1 and up */
496 argv0 = (char*)ckalloc(strlen(className) + 1);
497 if (!argv0) {
498 PyErr_NoMemory();
499 Py_DECREF(v);
500 return NULL;
501 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000504 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 argv0[0] = tolower(argv0[0]);
506 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
507 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000510 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000511
Guido van Rossum7bf15641998-05-22 18:28:17 +0000512 EnableEventHook();
513
Barry Warsawfa701a81997-01-16 00:15:11 +0000514 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000515}
516
Barry Warsawfa701a81997-01-16 00:15:11 +0000517
518
Guido van Rossum18468821994-06-20 07:49:28 +0000519/** Tcl Eval **/
520
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000521#if TKMAJORMINOR >= 8001
522#define USING_OBJECTS
523#endif
524
525#ifdef USING_OBJECTS
526
527static Tcl_Obj*
528AsObj(value)
529 PyObject *value;
530{
531 Tcl_Obj *result;
532
533 if (PyString_Check(value))
534 return Tcl_NewStringObj(PyString_AS_STRING(value),
535 PyString_GET_SIZE(value));
536 else if (PyInt_Check(value))
537 return Tcl_NewLongObj(PyInt_AS_LONG(value));
538 else if (PyFloat_Check(value))
539 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
540 else if (PyTuple_Check(value)) {
541 Tcl_Obj **argv = (Tcl_Obj**)
542 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
543 int i;
544 if(!argv)
545 return 0;
546 for(i=0;i<PyTuple_Size(value);i++)
547 argv[i] = AsObj(PyTuple_GetItem(value,i));
548 result = Tcl_NewListObj(PyTuple_Size(value), argv);
549 ckfree(FREECAST argv);
550 return result;
551 }
552 else if (PyUnicode_Check(value)) {
553 PyObject* utf8 = PyUnicode_AsUTF8String (value);
554 if (!utf8)
555 return 0;
556 return Tcl_NewStringObj (PyString_AS_STRING (utf8),
557 PyString_GET_SIZE (utf8));
558 }
559 else {
560 PyObject *v = PyObject_Str(value);
561 if (!v)
562 return 0;
563 result = AsObj(v);
564 Py_DECREF(v);
565 return result;
566 }
567}
568
Guido van Rossum18468821994-06-20 07:49:28 +0000569static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000570Tkapp_Call(self, args)
571 PyObject *self;
572 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000573{
Guido van Rossum632de272000-03-29 00:19:50 +0000574 Tcl_Obj *objStore[ARGSZ];
575 Tcl_Obj **objv = NULL;
576 int objc = 0, i;
577 PyObject *res = NULL;
578 Tcl_Interp *interp = Tkapp_Interp(self);
579 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
580 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000581
Guido van Rossum632de272000-03-29 00:19:50 +0000582 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000583
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000585 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000586
Guido van Rossum212643f1998-04-29 16:22:14 +0000587 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000588 objc = 1;
589 objv[0] = AsObj(args);
590 if (objv[0] == 0)
591 goto finally;
592 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 }
594 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000595 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000596
Guido van Rossum632de272000-03-29 00:19:50 +0000597 if (objc > ARGSZ) {
598 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
599 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000600 PyErr_NoMemory();
601 goto finally;
602 }
603 }
604
Guido van Rossum632de272000-03-29 00:19:50 +0000605 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000606 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum632de272000-03-29 00:19:50 +0000607 objv[i] = AsObj(v);
608 if (!objv[i])
609 goto finally;
610 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000611 }
612 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000613
Guido van Rossum62320c91998-06-15 04:36:09 +0000614 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000615
616 i = Tcl_EvalObjv(interp, objc, objv, flags);
617
Guido van Rossum62320c91998-06-15 04:36:09 +0000618 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000619 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000620 Tkinter_Error(self);
Guido van Rossum632de272000-03-29 00:19:50 +0000621 else
622 /* We could request the object result here, but doing
623 so would confuse applications that expect a string. */
624 res = PyString_FromString(Tcl_GetStringResult(interp));
625
Guido van Rossum62320c91998-06-15 04:36:09 +0000626 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000627
Guido van Rossum212643f1998-04-29 16:22:14 +0000628 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000629 for (i = 0; i < objc; i++)
630 Tcl_DecrRefCount(objv[i]);
631 if (objv != objStore)
632 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 return res;
634}
635
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000636#else /* !USING_OBJECTS */
637
638static PyObject *
639Tkapp_Call(self, args)
640 PyObject *self;
641 PyObject *args;
642{
643 /* This is copied from Merge() */
644 PyObject *tmp = NULL;
645 char *argvStore[ARGSZ];
646 char **argv = NULL;
647 int fvStore[ARGSZ];
648 int *fv = NULL;
649 int argc = 0, i;
650 PyObject *res = NULL; /* except this has a different type */
651 Tcl_CmdInfo info; /* and this is added */
652 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
653
654 if (!(tmp = PyList_New(0)))
655 return NULL;
656
657 argv = argvStore;
658 fv = fvStore;
659
660 if (args == NULL)
661 argc = 0;
662
663 else if (!PyTuple_Check(args)) {
664 argc = 1;
665 fv[0] = 0;
666 argv[0] = AsString(args, tmp);
667 }
668 else {
669 argc = PyTuple_Size(args);
670
671 if (argc > ARGSZ) {
672 argv = (char **)ckalloc(argc * sizeof(char *));
673 fv = (int *)ckalloc(argc * sizeof(int));
674 if (argv == NULL || fv == NULL) {
675 PyErr_NoMemory();
676 goto finally;
677 }
678 }
679
680 for (i = 0; i < argc; i++) {
681 PyObject *v = PyTuple_GetItem(args, i);
682 if (PyTuple_Check(v)) {
683 fv[i] = 1;
684 if (!(argv[i] = Merge(v)))
685 goto finally;
686 }
687 else if (v == Py_None) {
688 argc = i;
689 break;
690 }
691 else {
692 fv[i] = 0;
693 argv[i] = AsString(v, tmp);
694 }
695 }
696 }
697 /* End code copied from Merge() */
698
699 /* All this to avoid a call to Tcl_Merge() and the corresponding call
700 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
701 if (Py_VerboseFlag >= 2) {
702 for (i = 0; i < argc; i++)
703 PySys_WriteStderr("%s ", argv[i]);
704 }
705 ENTER_TCL
706 info.proc = NULL;
707 if (argc < 1 ||
708 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
709 info.proc == NULL)
710 {
711 char *cmd;
712 cmd = Tcl_Merge(argc, argv);
713 i = Tcl_Eval(interp, cmd);
714 ckfree(cmd);
715 }
716 else {
717 Tcl_ResetResult(interp);
718 i = (*info.proc)(info.clientData, interp, argc, argv);
719 }
720 ENTER_OVERLAP
721 if (info.proc == NULL && Py_VerboseFlag >= 2)
722 PySys_WriteStderr("... use TclEval ");
723 if (i == TCL_ERROR) {
724 if (Py_VerboseFlag >= 2)
725 PySys_WriteStderr("... error: '%s'\n",
726 interp->result);
727 Tkinter_Error(self);
728 }
729 else {
730 if (Py_VerboseFlag >= 2)
731 PySys_WriteStderr("-> '%s'\n", interp->result);
732 res = PyString_FromString(interp->result);
733 }
734 LEAVE_OVERLAP_TCL
735
736 /* Copied from Merge() again */
737 finally:
738 for (i = 0; i < argc; i++)
739 if (fv[i]) {
740 ckfree(argv[i]);
741 }
742 if (argv != argvStore)
743 ckfree(FREECAST argv);
744 if (fv != fvStore)
745 ckfree(FREECAST fv);
746
747 Py_DECREF(tmp);
748 return res;
749}
750
751#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000752
753static PyObject *
754Tkapp_GlobalCall(self, args)
755 PyObject *self;
756 PyObject *args;
757{
Guido van Rossum212643f1998-04-29 16:22:14 +0000758 /* Could do the same here as for Tkapp_Call(), but this is not used
759 much, so I can't be bothered. Unfortunately Tcl doesn't export a
760 way for the user to do what all its Global* variants do (save and
761 reset the scope pointer, call the local version, restore the saved
762 scope pointer). */
763
Guido van Rossum62320c91998-06-15 04:36:09 +0000764 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000765 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000766
Guido van Rossum62320c91998-06-15 04:36:09 +0000767 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000768 if (!cmd)
769 PyErr_SetString(Tkinter_TclError, "merge failed");
770
Guido van Rossum00d93061998-05-28 23:06:38 +0000771 else {
772 int err;
773 ENTER_TCL
774 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000775 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000776 if (err == TCL_ERROR)
777 res = Tkinter_Error(self);
778 else
779 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000780 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000781 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000782
783 if (cmd)
784 ckfree(cmd);
785
786 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000787}
788
789static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000790Tkapp_Eval(self, args)
791 PyObject *self;
792 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000793{
Barry Warsawfa701a81997-01-16 00:15:11 +0000794 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000795 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000796 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000797
Guido van Rossum43713e52000-02-29 13:59:29 +0000798 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000799 return NULL;
800
Guido van Rossum00d93061998-05-28 23:06:38 +0000801 ENTER_TCL
802 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000803 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000804 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000805 res = Tkinter_Error(self);
806 else
807 res = PyString_FromString(Tkapp_Result(self));
808 LEAVE_OVERLAP_TCL
809 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000810}
811
812static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000813Tkapp_GlobalEval(self, args)
814 PyObject *self;
815 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000816{
Barry Warsawfa701a81997-01-16 00:15:11 +0000817 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000818 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000819 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000820
Guido van Rossum43713e52000-02-29 13:59:29 +0000821 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000823
Guido van Rossum00d93061998-05-28 23:06:38 +0000824 ENTER_TCL
825 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000826 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000827 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000828 res = Tkinter_Error(self);
829 else
830 res = PyString_FromString(Tkapp_Result(self));
831 LEAVE_OVERLAP_TCL
832 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000833}
834
835static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000836Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 PyObject *self;
838 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000839{
Barry Warsawfa701a81997-01-16 00:15:11 +0000840 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000841 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000842 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000843
Guido van Rossum43713e52000-02-29 13:59:29 +0000844 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000845 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000846
Guido van Rossum00d93061998-05-28 23:06:38 +0000847 ENTER_TCL
848 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000849 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000850 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000851 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000852
Guido van Rossum62320c91998-06-15 04:36:09 +0000853 else
854 res = PyString_FromString(Tkapp_Result(self));
855 LEAVE_OVERLAP_TCL
856 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000857}
858
859static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000860Tkapp_Record(self, args)
861 PyObject *self;
862 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000863{
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000865 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000866 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000867
Guido van Rossum35d43371997-08-02 00:09:09 +0000868 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000869 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000870
Guido van Rossum00d93061998-05-28 23:06:38 +0000871 ENTER_TCL
872 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000873 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000874 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000875 res = Tkinter_Error(self);
876 else
877 res = PyString_FromString(Tkapp_Result(self));
878 LEAVE_OVERLAP_TCL
879 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000880}
881
882static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000883Tkapp_AddErrorInfo(self, args)
884 PyObject *self;
885 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000886{
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000888
Guido van Rossum43713e52000-02-29 13:59:29 +0000889 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000891 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000892 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000893 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000894
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 Py_INCREF(Py_None);
896 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000897}
898
Barry Warsawfa701a81997-01-16 00:15:11 +0000899
900
Guido van Rossum18468821994-06-20 07:49:28 +0000901/** Tcl Variable **/
902
903static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000904SetVar(self, args, flags)
905 PyObject *self;
906 PyObject *args;
907 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000908{
Guido van Rossum00d93061998-05-28 23:06:38 +0000909 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000911 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000912
Guido van Rossum62320c91998-06-15 04:36:09 +0000913 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 if (!tmp)
915 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000916
Guido van Rossum43713e52000-02-29 13:59:29 +0000917 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000918 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000919 s = AsString(newValue, tmp);
920 ENTER_TCL
921 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
922 LEAVE_TCL
923 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000924 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000925 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000926 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000927 s = AsString (newValue, tmp);
928 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000929 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000930 s, flags);
931 LEAVE_TCL
932 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000934 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000935 return NULL;
936 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000937 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000938 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000939
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 if (!ok)
941 return Tkinter_Error(self);
942
943 Py_INCREF(Py_None);
944 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000945}
946
947static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000948Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 PyObject *self;
950 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000951{
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000953}
954
955static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000956Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 PyObject *self;
958 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000959{
Barry Warsawfa701a81997-01-16 00:15:11 +0000960 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000961}
962
Barry Warsawfa701a81997-01-16 00:15:11 +0000963
964
Guido van Rossum18468821994-06-20 07:49:28 +0000965static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000966GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 PyObject *self;
968 PyObject *args;
969 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000970{
Guido van Rossum35d43371997-08-02 00:09:09 +0000971 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000972 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000973
Guido van Rossum43713e52000-02-29 13:59:29 +0000974 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000975 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000976 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000978 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Barry Warsawfa701a81997-01-16 00:15:11 +0000980 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000982 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000983
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000985 res = Tkinter_Error(self);
986 else
987 res = PyString_FromString(s);
988 LEAVE_OVERLAP_TCL
989 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000990}
991
992static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000993Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 PyObject *self;
995 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000996{
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000998}
999
1000static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001001Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001002 PyObject *self;
1003 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001004{
Barry Warsawfa701a81997-01-16 00:15:11 +00001005 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001006}
1007
Barry Warsawfa701a81997-01-16 00:15:11 +00001008
1009
Guido van Rossum18468821994-06-20 07:49:28 +00001010static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001011UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 PyObject *self;
1013 PyObject *args;
1014 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001015{
Guido van Rossum35d43371997-08-02 00:09:09 +00001016 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001017 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001019
Guido van Rossum43713e52000-02-29 13:59:29 +00001020 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001022 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001023 if (name2 == NULL)
1024 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1025
1026 else
1027 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001028 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001029
Barry Warsawfa701a81997-01-16 00:15:11 +00001030 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001031 res = Tkinter_Error(self);
1032 else {
1033 Py_INCREF(Py_None);
1034 res = Py_None;
1035 }
1036 LEAVE_OVERLAP_TCL
1037 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001038}
1039
1040static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001041Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001042 PyObject *self;
1043 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001044{
Barry Warsawfa701a81997-01-16 00:15:11 +00001045 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001046}
1047
1048static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001049Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 PyObject *self;
1051 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001052{
Barry Warsawfa701a81997-01-16 00:15:11 +00001053 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001054}
1055
Barry Warsawfa701a81997-01-16 00:15:11 +00001056
1057
Guido van Rossum18468821994-06-20 07:49:28 +00001058/** Tcl to Python **/
1059
1060static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001061Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 PyObject *self;
1063 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001064{
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 char *s;
1066 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001067
Guido van Rossum43713e52000-02-29 13:59:29 +00001068 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001070 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 return Tkinter_Error(self);
1072 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001073}
1074
1075static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001076Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 PyObject *self;
1078 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001079{
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 char *s;
1081 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001082
Guido van Rossum43713e52000-02-29 13:59:29 +00001083 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001085 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 return Tkinter_Error(self);
1087 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001088}
1089
1090static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001091Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001092 PyObject *self;
1093 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001094{
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 char *s;
1096 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001097
Guido van Rossum43713e52000-02-29 13:59:29 +00001098 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001100 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1101 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001103}
1104
1105static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001106Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 PyObject *self;
1108 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001109{
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001111 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001112 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001113
Guido van Rossum43713e52000-02-29 13:59:29 +00001114 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001116 ENTER_TCL
1117 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001118 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001119 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001120 res = Tkinter_Error(self);
1121 else
1122 res = Py_BuildValue("s", Tkapp_Result(self));
1123 LEAVE_OVERLAP_TCL
1124 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001125}
1126
1127static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001128Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001129 PyObject *self;
1130 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001131{
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001133 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001134 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Guido van Rossum43713e52000-02-29 13:59:29 +00001137 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001139 ENTER_TCL
1140 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001141 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001142 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001143 res = Tkinter_Error(self);
1144 else
1145 res = Py_BuildValue("l", v);
1146 LEAVE_OVERLAP_TCL
1147 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001148}
1149
1150static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001151Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 PyObject *self;
1153 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001154{
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001156 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001157 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001158 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001159
Guido van Rossum43713e52000-02-29 13:59:29 +00001160 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001162 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001163 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001164 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001165 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001166 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001167 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001168 res = Tkinter_Error(self);
1169 else
1170 res = Py_BuildValue("d", v);
1171 LEAVE_OVERLAP_TCL
1172 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001173}
1174
1175static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001176Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 PyObject *self;
1178 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001179{
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001181 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001182 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001184
Guido van Rossum43713e52000-02-29 13:59:29 +00001185 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001187 ENTER_TCL
1188 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001189 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001190 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001191 res = Tkinter_Error(self);
1192 else
1193 res = Py_BuildValue("i", v);
1194 LEAVE_OVERLAP_TCL
1195 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001196}
1197
Barry Warsawfa701a81997-01-16 00:15:11 +00001198
1199
Guido van Rossum18468821994-06-20 07:49:28 +00001200static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001201Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001202 PyObject *self;
1203 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001204{
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 char *list;
1206 int argc;
1207 char **argv;
1208 PyObject *v;
1209 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001210
Guido van Rossum43713e52000-02-29 13:59:29 +00001211 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001213
Barry Warsawfa701a81997-01-16 00:15:11 +00001214 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1215 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001216
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 if (!(v = PyTuple_New(argc)))
1218 return NULL;
1219
1220 for (i = 0; i < argc; i++) {
1221 PyObject *s = PyString_FromString(argv[i]);
1222 if (!s || PyTuple_SetItem(v, i, s)) {
1223 Py_DECREF(v);
1224 v = NULL;
1225 goto finally;
1226 }
1227 }
Guido van Rossum18468821994-06-20 07:49:28 +00001228
Barry Warsawfa701a81997-01-16 00:15:11 +00001229 finally:
1230 ckfree(FREECAST argv);
1231 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001232}
1233
1234static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001235Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 PyObject *self;
1237 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001238{
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001240
Guido van Rossum43713e52000-02-29 13:59:29 +00001241 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001242 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001243 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001244}
1245
1246static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001247Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 PyObject *self;
1249 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001250{
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 char *s = Merge(args);
1252 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001253
Barry Warsawfa701a81997-01-16 00:15:11 +00001254 if (s) {
1255 res = PyString_FromString(s);
1256 ckfree(s);
1257 }
1258 else
1259 PyErr_SetString(Tkinter_TclError, "merge failed");
1260
1261 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001262}
1263
Barry Warsawfa701a81997-01-16 00:15:11 +00001264
1265
Guido van Rossum18468821994-06-20 07:49:28 +00001266/** Tcl Command **/
1267
Guido van Rossum00d93061998-05-28 23:06:38 +00001268/* Client data struct */
1269typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001270 PyObject *self;
1271 PyObject *func;
1272} PythonCmd_ClientData;
1273
1274static int
1275PythonCmd_Error(interp)
1276 Tcl_Interp *interp;
1277{
1278 errorInCmd = 1;
1279 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1280 LEAVE_PYTHON
1281 return TCL_ERROR;
1282}
1283
Guido van Rossum18468821994-06-20 07:49:28 +00001284/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 * function or method.
1286 */
Guido van Rossum18468821994-06-20 07:49:28 +00001287static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001288PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001289 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001290 Tcl_Interp *interp;
1291 int argc;
1292 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001293{
Guido van Rossum00d93061998-05-28 23:06:38 +00001294 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 PyObject *self, *func, *arg, *res, *tmp;
1296 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001297
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001298 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001299
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 /* TBD: no error checking here since we know, via the
1301 * Tkapp_CreateCommand() that the client data is a two-tuple
1302 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001303 self = data->self;
1304 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001305
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 /* Create argument list (argv1, ..., argvN) */
1307 if (!(arg = PyTuple_New(argc - 1)))
1308 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001309
Barry Warsawfa701a81997-01-16 00:15:11 +00001310 for (i = 0; i < (argc - 1); i++) {
1311 PyObject *s = PyString_FromString(argv[i + 1]);
1312 if (!s || PyTuple_SetItem(arg, i, s)) {
1313 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001314 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 }
1316 }
1317 res = PyEval_CallObject(func, arg);
1318 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001319
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 if (res == NULL)
1321 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001322
Barry Warsawfa701a81997-01-16 00:15:11 +00001323 if (!(tmp = PyList_New(0))) {
1324 Py_DECREF(res);
1325 return PythonCmd_Error(interp);
1326 }
1327
1328 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1329 Py_DECREF(res);
1330 Py_DECREF(tmp);
1331
Guido van Rossum00d93061998-05-28 23:06:38 +00001332 LEAVE_PYTHON
1333
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001335}
1336
1337static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001338PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001339 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001340{
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1342
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001343 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001344 Py_XDECREF(data->self);
1345 Py_XDECREF(data->func);
1346 PyMem_DEL(data);
1347 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001348}
1349
Barry Warsawfa701a81997-01-16 00:15:11 +00001350
1351
Guido van Rossum18468821994-06-20 07:49:28 +00001352static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001353Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001354 PyObject *self;
1355 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001356{
Guido van Rossum00d93061998-05-28 23:06:38 +00001357 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001360 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001361
Guido van Rossum43713e52000-02-29 13:59:29 +00001362 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001363 return NULL;
1364 if (!PyCallable_Check(func)) {
1365 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001366 return NULL;
1367 }
Guido van Rossum18468821994-06-20 07:49:28 +00001368
Guido van Rossum00d93061998-05-28 23:06:38 +00001369 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 if (!data)
1371 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001372 Py_XINCREF(self);
1373 Py_XINCREF(func);
1374 data->self = self;
1375 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001376
Guido van Rossum00d93061998-05-28 23:06:38 +00001377 ENTER_TCL
1378 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1379 (ClientData)data, PythonCmdDelete);
1380 LEAVE_TCL
1381 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001382 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001384 return NULL;
1385 }
Guido van Rossum18468821994-06-20 07:49:28 +00001386
Barry Warsawfa701a81997-01-16 00:15:11 +00001387 Py_INCREF(Py_None);
1388 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001389}
1390
Barry Warsawfa701a81997-01-16 00:15:11 +00001391
1392
Guido van Rossum18468821994-06-20 07:49:28 +00001393static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001394Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 PyObject *self;
1396 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001397{
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001399 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001400
Guido van Rossum43713e52000-02-29 13:59:29 +00001401 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001402 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001403 ENTER_TCL
1404 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1405 LEAVE_TCL
1406 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001407 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1408 return NULL;
1409 }
1410 Py_INCREF(Py_None);
1411 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001412}
1413
Barry Warsawfa701a81997-01-16 00:15:11 +00001414
1415
Guido van Rossum00d93061998-05-28 23:06:38 +00001416#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001417/** File Handler **/
1418
Guido van Rossum00d93061998-05-28 23:06:38 +00001419typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001420 PyObject *func;
1421 PyObject *file;
1422 int id;
1423 struct _fhcdata *next;
1424} FileHandler_ClientData;
1425
1426static FileHandler_ClientData *HeadFHCD;
1427
1428static FileHandler_ClientData *
1429NewFHCD(func, file, id)
1430 PyObject *func;
1431 PyObject *file;
1432 int id;
1433{
1434 FileHandler_ClientData *p;
1435 p = PyMem_NEW(FileHandler_ClientData, 1);
1436 if (p != NULL) {
1437 Py_XINCREF(func);
1438 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001439 p->func = func;
1440 p->file = file;
1441 p->id = id;
1442 p->next = HeadFHCD;
1443 HeadFHCD = p;
1444 }
1445 return p;
1446}
1447
1448static void
1449DeleteFHCD(id)
1450 int id;
1451{
1452 FileHandler_ClientData *p, **pp;
1453
1454 pp = &HeadFHCD;
1455 while ((p = *pp) != NULL) {
1456 if (p->id == id) {
1457 *pp = p->next;
1458 Py_XDECREF(p->func);
1459 Py_XDECREF(p->file);
1460 PyMem_DEL(p);
1461 }
1462 else
1463 pp = &p->next;
1464 }
1465}
1466
Guido van Rossuma597dde1995-01-10 20:56:29 +00001467static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001468FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001469 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001470 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001471{
Guido van Rossum00d93061998-05-28 23:06:38 +00001472 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001474
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001475 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 func = data->func;
1477 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001478
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 arg = Py_BuildValue("(Oi)", file, (long) mask);
1480 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001481 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001482
1483 if (res == NULL) {
1484 errorInCmd = 1;
1485 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1486 }
1487 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001488 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001489}
1490
1491static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001492GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 /* Either an int >= 0 or an object with a
1494 *.fileno() method that returns an int >= 0
1495 */
1496 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001497{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001498 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001499 int id;
1500 if (PyInt_Check(file)) {
1501 id = PyInt_AsLong(file);
1502 if (id < 0)
1503 PyErr_SetString(PyExc_ValueError, "invalid file id");
1504 return id;
1505 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001506 args = PyTuple_New(0);
1507 if (args == NULL)
1508 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001509
1510 meth = PyObject_GetAttrString(file, "fileno");
1511 if (meth == NULL) {
1512 Py_DECREF(args);
1513 return -1;
1514 }
1515
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001516 res = PyEval_CallObject(meth, args);
1517 Py_DECREF(args);
1518 Py_DECREF(meth);
1519 if (res == NULL)
1520 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001521
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001522 if (PyInt_Check(res))
1523 id = PyInt_AsLong(res);
1524 else
1525 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001526
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001527 if (id < 0)
1528 PyErr_SetString(PyExc_ValueError,
1529 "invalid fileno() return value");
1530 Py_DECREF(res);
1531 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001532}
1533
1534static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001535Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 PyObject *self;
1537 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001538{
Guido van Rossum00d93061998-05-28 23:06:38 +00001539 FileHandler_ClientData *data;
1540 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001541 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001542
Guido van Rossum43713e52000-02-29 13:59:29 +00001543 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001544 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001545 tfile = GetFileNo(file);
1546 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 return NULL;
1548 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001549 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 return NULL;
1551 }
1552
Guido van Rossuma80649b2000-03-28 20:07:05 +00001553 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001554 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001555 return NULL;
1556
Barry Warsawfa701a81997-01-16 00:15:11 +00001557 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001558 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001559 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001560 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001561 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001562 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001563}
1564
1565static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001566Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 PyObject *self;
1568 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001569{
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001571 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001572 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001573
Guido van Rossum43713e52000-02-29 13:59:29 +00001574 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001576 tfile = GetFileNo(file);
1577 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 return NULL;
1579
Guido van Rossuma80649b2000-03-28 20:07:05 +00001580 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001581
Barry Warsawfa701a81997-01-16 00:15:11 +00001582 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001583 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001585 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001586 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001588}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001589#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001590
Barry Warsawfa701a81997-01-16 00:15:11 +00001591
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001592/**** Tktt Object (timer token) ****/
1593
1594staticforward PyTypeObject Tktt_Type;
1595
Guido van Rossum00d93061998-05-28 23:06:38 +00001596typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001598 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001599 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001600} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001601
1602static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001603Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001604 PyObject *self;
1605 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001606{
Barry Warsawfa701a81997-01-16 00:15:11 +00001607 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001608 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001609
Guido van Rossum43713e52000-02-29 13:59:29 +00001610 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001612 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001613 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001614 v->token = NULL;
1615 }
1616 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001617 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001618 Py_DECREF(func);
1619 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 }
1621 Py_INCREF(Py_None);
1622 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001623}
1624
1625static PyMethodDef Tktt_methods[] =
1626{
Guido van Rossum35d43371997-08-02 00:09:09 +00001627 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001628 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001629};
1630
1631static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001632Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001633 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001634{
Barry Warsawfa701a81997-01-16 00:15:11 +00001635 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001636
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 v = PyObject_NEW(TkttObject, &Tktt_Type);
1638 if (v == NULL)
1639 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640
Guido van Rossum00d93061998-05-28 23:06:38 +00001641 Py_INCREF(func);
1642 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001644
1645 /* Extra reference, deleted when called or when handler is deleted */
1646 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001648}
1649
1650static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001651Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001652 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001653{
Guido van Rossum00d93061998-05-28 23:06:38 +00001654 TkttObject *v = (TkttObject *)self;
1655 PyObject *func = v->func;
1656
1657 Py_XDECREF(func);
1658
Guido van Rossum35d43371997-08-02 00:09:09 +00001659 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001660}
1661
Guido van Rossum597ac201998-05-12 14:36:19 +00001662static PyObject *
1663Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001664 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001665{
Barry Warsawfa701a81997-01-16 00:15:11 +00001666 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001667 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001668
Guido van Rossum597ac201998-05-12 14:36:19 +00001669 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001671 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001672}
1673
1674static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001675Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 PyObject *self;
1677 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001678{
Barry Warsawfa701a81997-01-16 00:15:11 +00001679 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001680}
1681
1682static PyTypeObject Tktt_Type =
1683{
Guido van Rossum35d43371997-08-02 00:09:09 +00001684 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001685 0, /*ob_size */
1686 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001687 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001688 0, /*tp_itemsize */
1689 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001690 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001691 Tktt_GetAttr, /*tp_getattr */
1692 0, /*tp_setattr */
1693 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001694 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 0, /*tp_as_number */
1696 0, /*tp_as_sequence */
1697 0, /*tp_as_mapping */
1698 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001699};
1700
Barry Warsawfa701a81997-01-16 00:15:11 +00001701
1702
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001703/** Timer Handler **/
1704
1705static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001706TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001707 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001708{
Guido van Rossum00d93061998-05-28 23:06:38 +00001709 TkttObject *v = (TkttObject *)clientData;
1710 PyObject *func = v->func;
1711 PyObject *res;
1712
1713 if (func == NULL)
1714 return;
1715
1716 v->func = NULL;
1717
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001718 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001719
1720 res = PyEval_CallObject(func, NULL);
1721 Py_DECREF(func);
1722 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001723
Barry Warsawfa701a81997-01-16 00:15:11 +00001724 if (res == NULL) {
1725 errorInCmd = 1;
1726 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1727 }
1728 else
1729 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001730
1731 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001732}
1733
1734static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001735Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001736 PyObject *self;
1737 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001738{
Barry Warsawfa701a81997-01-16 00:15:11 +00001739 int milliseconds;
1740 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001741 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001742
Guido van Rossum43713e52000-02-29 13:59:29 +00001743 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001744 return NULL;
1745 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001746 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001747 return NULL;
1748 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001749 v = Tktt_New(func);
1750 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1751 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001752
Guido van Rossum00d93061998-05-28 23:06:38 +00001753 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001754}
1755
Barry Warsawfa701a81997-01-16 00:15:11 +00001756
Guido van Rossum18468821994-06-20 07:49:28 +00001757/** Event Loop **/
1758
Guido van Rossum18468821994-06-20 07:49:28 +00001759static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001760Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001761 PyObject *self;
1762 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001763{
Barry Warsawfa701a81997-01-16 00:15:11 +00001764 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001765#ifdef WITH_THREAD
1766 PyThreadState *tstate = PyThreadState_Get();
1767#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001768
Guido van Rossum43713e52000-02-29 13:59:29 +00001769 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001770 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001771
Barry Warsawfa701a81997-01-16 00:15:11 +00001772 quitMainLoop = 0;
1773 while (Tk_GetNumMainWindows() > threshold &&
1774 !quitMainLoop &&
1775 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001776 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001777 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001778
1779#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001780 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001781 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001782 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001783 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001784 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001785 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001786 if (result == 0)
1787 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001788 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001789#else
1790 result = Tcl_DoOneEvent(0);
1791#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001792
Guido van Rossum35d43371997-08-02 00:09:09 +00001793 if (PyErr_CheckSignals() != 0)
1794 return NULL;
1795 if (result < 0)
1796 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001797 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001798 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001799
Barry Warsawfa701a81997-01-16 00:15:11 +00001800 if (errorInCmd) {
1801 errorInCmd = 0;
1802 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1803 excInCmd = valInCmd = trbInCmd = NULL;
1804 return NULL;
1805 }
1806 Py_INCREF(Py_None);
1807 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001808}
1809
1810static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001811Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001812 PyObject *self;
1813 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001814{
Guido van Rossum35d43371997-08-02 00:09:09 +00001815 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001816 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001817
Guido van Rossum43713e52000-02-29 13:59:29 +00001818 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 return NULL;
1820
Guido van Rossum00d93061998-05-28 23:06:38 +00001821 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001823 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001824 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001825}
1826
1827static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001828Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001829 PyObject *self;
1830 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001831{
1832
Guido van Rossum43713e52000-02-29 13:59:29 +00001833 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001834 return NULL;
1835
1836 quitMainLoop = 1;
1837 Py_INCREF(Py_None);
1838 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001839}
1840
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001841static PyObject *
1842Tkapp_InterpAddr(self, args)
1843 PyObject *self;
1844 PyObject *args;
1845{
1846
Guido van Rossum43713e52000-02-29 13:59:29 +00001847 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001848 return NULL;
1849
1850 return PyInt_FromLong((long)Tkapp_Interp(self));
1851}
1852
Barry Warsawfa701a81997-01-16 00:15:11 +00001853
1854
Guido van Rossum18468821994-06-20 07:49:28 +00001855/**** Tkapp Method List ****/
1856
1857static PyMethodDef Tkapp_methods[] =
1858{
Guido van Rossum35d43371997-08-02 00:09:09 +00001859 {"call", Tkapp_Call, 0},
1860 {"globalcall", Tkapp_GlobalCall, 0},
1861 {"eval", Tkapp_Eval, 1},
1862 {"globaleval", Tkapp_GlobalEval, 1},
1863 {"evalfile", Tkapp_EvalFile, 1},
1864 {"record", Tkapp_Record, 1},
1865 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1866 {"setvar", Tkapp_SetVar, 1},
1867 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1868 {"getvar", Tkapp_GetVar, 1},
1869 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1870 {"unsetvar", Tkapp_UnsetVar, 1},
1871 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1872 {"getint", Tkapp_GetInt, 1},
1873 {"getdouble", Tkapp_GetDouble, 1},
1874 {"getboolean", Tkapp_GetBoolean, 1},
1875 {"exprstring", Tkapp_ExprString, 1},
1876 {"exprlong", Tkapp_ExprLong, 1},
1877 {"exprdouble", Tkapp_ExprDouble, 1},
1878 {"exprboolean", Tkapp_ExprBoolean, 1},
1879 {"splitlist", Tkapp_SplitList, 1},
1880 {"split", Tkapp_Split, 1},
1881 {"merge", Tkapp_Merge, 0},
1882 {"createcommand", Tkapp_CreateCommand, 1},
1883 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001884#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001885 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1886 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001887#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001888 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001889 {"mainloop", Tkapp_MainLoop, 1},
1890 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001891 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001892 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001893 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001894};
1895
Barry Warsawfa701a81997-01-16 00:15:11 +00001896
1897
Guido van Rossum18468821994-06-20 07:49:28 +00001898/**** Tkapp Type Methods ****/
1899
1900static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001901Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001902 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001903{
Guido van Rossum00d93061998-05-28 23:06:38 +00001904 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001905 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001906 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001907 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001908 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001909}
1910
1911static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001912Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001913 PyObject *self;
1914 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001915{
Guido van Rossum35d43371997-08-02 00:09:09 +00001916 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001917}
1918
1919static PyTypeObject Tkapp_Type =
1920{
Guido van Rossum35d43371997-08-02 00:09:09 +00001921 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001922 0, /*ob_size */
1923 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001924 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001925 0, /*tp_itemsize */
1926 Tkapp_Dealloc, /*tp_dealloc */
1927 0, /*tp_print */
1928 Tkapp_GetAttr, /*tp_getattr */
1929 0, /*tp_setattr */
1930 0, /*tp_compare */
1931 0, /*tp_repr */
1932 0, /*tp_as_number */
1933 0, /*tp_as_sequence */
1934 0, /*tp_as_mapping */
1935 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001936};
1937
Barry Warsawfa701a81997-01-16 00:15:11 +00001938
1939
Guido van Rossum18468821994-06-20 07:49:28 +00001940/**** Tkinter Module ****/
1941
1942static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001943Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001944 PyObject *self;
1945 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001946{
Barry Warsawfa701a81997-01-16 00:15:11 +00001947 char *screenName = NULL;
1948 char *baseName = NULL;
1949 char *className = NULL;
1950 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001951
Guido van Rossum35d43371997-08-02 00:09:09 +00001952 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001953 if (baseName != NULL)
1954 baseName++;
1955 else
1956 baseName = Py_GetProgramName();
1957 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001958
Guido van Rossum43713e52000-02-29 13:59:29 +00001959 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001960 &screenName, &baseName, &className,
1961 &interactive))
1962 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001963
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 return (PyObject *) Tkapp_New(screenName, baseName, className,
1965 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001966}
1967
1968static PyMethodDef moduleMethods[] =
1969{
Barry Warsawfa701a81997-01-16 00:15:11 +00001970 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001971#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001972 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1973 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001974#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001975 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 {"mainloop", Tkapp_MainLoop, 1},
1977 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001978 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001979 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001980};
1981
Guido van Rossum7bf15641998-05-22 18:28:17 +00001982#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001983
1984static int stdin_ready = 0;
1985
Guido van Rossumad4db171998-06-13 13:56:28 +00001986#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001987static void
1988MyFileProc(clientData, mask)
1989 void *clientData;
1990 int mask;
1991{
1992 stdin_ready = 1;
1993}
Guido van Rossumad4db171998-06-13 13:56:28 +00001994#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001995
Guido van Rossum00d93061998-05-28 23:06:38 +00001996static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001997
Guido van Rossum18468821994-06-20 07:49:28 +00001998static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001999EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00002000{
Guido van Rossumad4db171998-06-13 13:56:28 +00002001#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002002 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002003#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002004#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002005 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002006#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002007 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002008 errorInCmd = 0;
2009#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002010 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002011 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002012#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002013 while (!errorInCmd && !stdin_ready) {
2014 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002015#ifdef MS_WINDOWS
2016 if (_kbhit()) {
2017 stdin_ready = 1;
2018 break;
2019 }
2020#endif
2021#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002022 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002023 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002024 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002025
Guido van Rossum00d93061998-05-28 23:06:38 +00002026 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002027
2028 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002029 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002030 if (result == 0)
2031 Sleep(20);
2032 Py_END_ALLOW_THREADS
2033#else
2034 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002035#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002036
2037 if (result < 0)
2038 break;
2039 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002040#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002041 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002042#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002043 if (errorInCmd) {
2044 errorInCmd = 0;
2045 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2046 excInCmd = valInCmd = trbInCmd = NULL;
2047 PyErr_Print();
2048 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002049#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002050 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002051#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002052 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002053}
Guido van Rossum18468821994-06-20 07:49:28 +00002054
Guido van Rossum00d93061998-05-28 23:06:38 +00002055#endif
2056
Guido van Rossum7bf15641998-05-22 18:28:17 +00002057static void
2058EnableEventHook()
2059{
Guido van Rossum00d93061998-05-28 23:06:38 +00002060#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002061 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002062#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002063 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002064#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002065 PyOS_InputHook = EventHook;
2066 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002067#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002068}
2069
2070static void
2071DisableEventHook()
2072{
Guido van Rossum00d93061998-05-28 23:06:38 +00002073#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002074 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2075 PyOS_InputHook = NULL;
2076 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002077#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002078}
2079
Barry Warsawfa701a81997-01-16 00:15:11 +00002080
2081/* all errors will be checked in one fell swoop in init_tkinter() */
2082static void
2083ins_long(d, name, val)
2084 PyObject *d;
2085 char *name;
2086 long val;
2087{
2088 PyObject *v = PyInt_FromLong(val);
2089 if (v) {
2090 PyDict_SetItemString(d, name, v);
2091 Py_DECREF(v);
2092 }
2093}
2094static void
2095ins_string(d, name, val)
2096 PyObject *d;
2097 char *name;
2098 char *val;
2099{
2100 PyObject *v = PyString_FromString(val);
2101 if (v) {
2102 PyDict_SetItemString(d, name, v);
2103 Py_DECREF(v);
2104 }
2105}
2106
2107
Guido van Rossum3886bb61998-12-04 18:50:17 +00002108DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002109init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002110{
Barry Warsawfa701a81997-01-16 00:15:11 +00002111 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002112
Barry Warsawfa701a81997-01-16 00:15:11 +00002113 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002114
2115#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002116 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002117#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002118
Barry Warsawfa701a81997-01-16 00:15:11 +00002119 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002120
Barry Warsawfa701a81997-01-16 00:15:11 +00002121 d = PyModule_GetDict(m);
2122 Tkinter_TclError = Py_BuildValue("s", "TclError");
2123 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002124
Guido van Rossum35d43371997-08-02 00:09:09 +00002125 ins_long(d, "READABLE", TCL_READABLE);
2126 ins_long(d, "WRITABLE", TCL_WRITABLE);
2127 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2128 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2129 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2130 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2131 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2132 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2133 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002134 ins_string(d, "TK_VERSION", TK_VERSION);
2135 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002136
Guido van Rossum83551bf1997-09-13 00:44:23 +00002137 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002138
2139 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002140 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2141
Guido van Rossume187b0e2000-03-27 21:46:29 +00002142 /* This helps the dynamic loader; in Unicode aware Tcl versions
2143 it also helps Tcl find its encodings. */
2144 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002145
Barry Warsawfa701a81997-01-16 00:15:11 +00002146 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002147 return;
2148
Guido van Rossum43ff8681998-07-14 18:02:13 +00002149#if 0
2150 /* This was not a good idea; through <Destroy> bindings,
2151 Tcl_Finalize() may invoke Python code but at that point the
2152 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002153 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002154#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002155
Jack Jansen34cc5c31995-10-31 16:15:12 +00002156#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002157 /*
2158 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2159 ** Most of the initializations in that routine (toolbox init calls and
2160 ** such) have already been done for us, so we only need these.
2161 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002162 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002163
2164 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002165#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002166 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002167#endif /* GENERATINGCFM */
2168#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002169}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002170
Guido van Rossumec22c921996-02-25 04:50:29 +00002171
Barry Warsawfa701a81997-01-16 00:15:11 +00002172
Guido van Rossum9722ad81995-09-22 23:49:28 +00002173#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002174
2175/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002176** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002177*/
2178
Guido van Rossum9722ad81995-09-22 23:49:28 +00002179void
2180panic(char * format, ...)
2181{
Barry Warsawfa701a81997-01-16 00:15:11 +00002182 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002183
Barry Warsawfa701a81997-01-16 00:15:11 +00002184 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002185
Guido van Rossum227cf761998-08-05 13:53:32 +00002186 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002187 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002188
Barry Warsawfa701a81997-01-16 00:15:11 +00002189 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002190
Barry Warsawfa701a81997-01-16 00:15:11 +00002191 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002192}
Jack Jansen40b546d1995-11-14 10:34:45 +00002193
Guido van Rossumec22c921996-02-25 04:50:29 +00002194/*
2195** Pass events to SIOUX before passing them to Tk.
2196*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002197
Guido van Rossumec22c921996-02-25 04:50:29 +00002198static int
2199PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002200 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002201{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002202 WindowPtr frontwin;
2203 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002204 ** Sioux eats too many events, so we don't pass it everything. We
2205 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002206 ** the Sioux window is frontmost. This means that Tk menus don't work
2207 ** in that case, but at least we can scroll the sioux window.
2208 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2209 ** part of the external interface of Sioux...
2210 */
2211 frontwin = FrontWindow();
2212 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2213 if (SIOUXHandleOneEvent(eventPtr))
2214 return 0; /* Nothing happened to the Tcl event queue */
2215 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002216 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002217}
2218
Guido van Rossumec22c921996-02-25 04:50:29 +00002219#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002220
2221/*
2222** Additional Mac specific code for dealing with shared libraries.
2223*/
2224
2225#include <Resources.h>
2226#include <CodeFragments.h>
2227
2228static int loaded_from_shlib = 0;
2229static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002230
Jack Jansen34cc5c31995-10-31 16:15:12 +00002231/*
2232** If this module is dynamically loaded the following routine should
2233** be the init routine. It takes care of adding the shared library to
2234** the resource-file chain, so that the tk routines can find their
2235** resources.
2236*/
2237OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002238init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002239{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002240 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002241 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002242 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002243 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2244 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002245 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002246 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2247 loaded_from_shlib = 1;
2248 }
2249 return noErr;
2250}
2251
2252/*
2253** Insert the library resources into the search path. Put them after
2254** the resources from the application. Again, we ignore errors.
2255*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002256static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002257mac_addlibresources()
2258{
2259 if ( !loaded_from_shlib )
2260 return;
2261 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2262}
2263
Guido van Rossumec22c921996-02-25 04:50:29 +00002264#endif /* GENERATINGCFM */
2265#endif /* macintosh */