blob: da905596d9ae0d044a120a8f5b416a21424bb3c5 [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
Guido van Rossumb18618d2000-05-03 23:44:39 +0000472 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 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)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000553#if TKMAJORMINOR <= 8001
554 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000555 PyObject* utf8 = PyUnicode_AsUTF8String (value);
556 if (!utf8)
557 return 0;
Guido van Rossum8823acc2000-04-27 20:14:31 +0000558 result = Tcl_NewStringObj (PyString_AS_STRING (utf8),
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000559 PyString_GET_SIZE (utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000560 Py_DECREF(utf8);
561 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000562#else /* TKMAJORMINOR > 8001 */
563 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
564 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
565 /* XXX Should really test this at compile time */
566 PyErr_SetString(PyExc_SystemError,
567 "Py_UNICODE and Tcl_UniChar differ in size");
568 return 0;
569 }
570 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
571 PyUnicode_GET_SIZE(value));
572#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000573 }
574 else {
575 PyObject *v = PyObject_Str(value);
576 if (!v)
577 return 0;
578 result = AsObj(v);
579 Py_DECREF(v);
580 return result;
581 }
582}
583
Guido van Rossum18468821994-06-20 07:49:28 +0000584static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000585Tkapp_Call(self, args)
586 PyObject *self;
587 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000588{
Guido van Rossum632de272000-03-29 00:19:50 +0000589 Tcl_Obj *objStore[ARGSZ];
590 Tcl_Obj **objv = NULL;
591 int objc = 0, i;
592 PyObject *res = NULL;
593 Tcl_Interp *interp = Tkapp_Interp(self);
594 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
595 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000596
Guido van Rossum632de272000-03-29 00:19:50 +0000597 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000598
Guido van Rossum212643f1998-04-29 16:22:14 +0000599 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000600 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000601
Guido van Rossum212643f1998-04-29 16:22:14 +0000602 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000603 objc = 1;
604 objv[0] = AsObj(args);
605 if (objv[0] == 0)
606 goto finally;
607 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000608 }
609 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000610 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000611
Guido van Rossum632de272000-03-29 00:19:50 +0000612 if (objc > ARGSZ) {
613 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
614 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000615 PyErr_NoMemory();
616 goto finally;
617 }
618 }
619
Guido van Rossum632de272000-03-29 00:19:50 +0000620 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000621 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000622 if (v == Py_None) {
623 objc = i;
624 break;
625 }
Guido van Rossum632de272000-03-29 00:19:50 +0000626 objv[i] = AsObj(v);
627 if (!objv[i])
628 goto finally;
629 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000630 }
631 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000632
Guido van Rossum62320c91998-06-15 04:36:09 +0000633 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000634
635 i = Tcl_EvalObjv(interp, objc, objv, flags);
636
Guido van Rossum62320c91998-06-15 04:36:09 +0000637 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000638 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000639 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000640 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000641 /* We could request the object result here, but doing
642 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000643 char *s = Tcl_GetStringResult(interp);
644 char *p = s;
645 /* If the result contains any bytes with the top bit set,
646 it's UTF-8 and we should decode it to Unicode */
647 while (*p != '\0') {
648 if (*p & 0x80)
649 break;
650 p++;
651 }
652 if (*p == '\0')
653 res = PyString_FromStringAndSize(s, (int)(p-s));
654 else {
655 /* Convert UTF-8 to Unicode string */
656 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000657 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
658 if (res == NULL) {
659 PyErr_Clear();
660 res = PyString_FromStringAndSize(s, (int)(p-s));
661 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000662 }
663 }
Guido van Rossum632de272000-03-29 00:19:50 +0000664
Guido van Rossum62320c91998-06-15 04:36:09 +0000665 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000666
Guido van Rossum212643f1998-04-29 16:22:14 +0000667 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000668 for (i = 0; i < objc; i++)
669 Tcl_DecrRefCount(objv[i]);
670 if (objv != objStore)
671 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 return res;
673}
674
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000675#else /* !USING_OBJECTS */
676
677static PyObject *
678Tkapp_Call(self, args)
679 PyObject *self;
680 PyObject *args;
681{
682 /* This is copied from Merge() */
683 PyObject *tmp = NULL;
684 char *argvStore[ARGSZ];
685 char **argv = NULL;
686 int fvStore[ARGSZ];
687 int *fv = NULL;
688 int argc = 0, i;
689 PyObject *res = NULL; /* except this has a different type */
690 Tcl_CmdInfo info; /* and this is added */
691 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
692
693 if (!(tmp = PyList_New(0)))
694 return NULL;
695
696 argv = argvStore;
697 fv = fvStore;
698
699 if (args == NULL)
700 argc = 0;
701
702 else if (!PyTuple_Check(args)) {
703 argc = 1;
704 fv[0] = 0;
705 argv[0] = AsString(args, tmp);
706 }
707 else {
708 argc = PyTuple_Size(args);
709
710 if (argc > ARGSZ) {
711 argv = (char **)ckalloc(argc * sizeof(char *));
712 fv = (int *)ckalloc(argc * sizeof(int));
713 if (argv == NULL || fv == NULL) {
714 PyErr_NoMemory();
715 goto finally;
716 }
717 }
718
719 for (i = 0; i < argc; i++) {
720 PyObject *v = PyTuple_GetItem(args, i);
721 if (PyTuple_Check(v)) {
722 fv[i] = 1;
723 if (!(argv[i] = Merge(v)))
724 goto finally;
725 }
726 else if (v == Py_None) {
727 argc = i;
728 break;
729 }
730 else {
731 fv[i] = 0;
732 argv[i] = AsString(v, tmp);
733 }
734 }
735 }
736 /* End code copied from Merge() */
737
738 /* All this to avoid a call to Tcl_Merge() and the corresponding call
739 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
740 if (Py_VerboseFlag >= 2) {
741 for (i = 0; i < argc; i++)
742 PySys_WriteStderr("%s ", argv[i]);
743 }
744 ENTER_TCL
745 info.proc = NULL;
746 if (argc < 1 ||
747 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
748 info.proc == NULL)
749 {
750 char *cmd;
751 cmd = Tcl_Merge(argc, argv);
752 i = Tcl_Eval(interp, cmd);
753 ckfree(cmd);
754 }
755 else {
756 Tcl_ResetResult(interp);
757 i = (*info.proc)(info.clientData, interp, argc, argv);
758 }
759 ENTER_OVERLAP
760 if (info.proc == NULL && Py_VerboseFlag >= 2)
761 PySys_WriteStderr("... use TclEval ");
762 if (i == TCL_ERROR) {
763 if (Py_VerboseFlag >= 2)
764 PySys_WriteStderr("... error: '%s'\n",
765 interp->result);
766 Tkinter_Error(self);
767 }
768 else {
769 if (Py_VerboseFlag >= 2)
770 PySys_WriteStderr("-> '%s'\n", interp->result);
771 res = PyString_FromString(interp->result);
772 }
773 LEAVE_OVERLAP_TCL
774
775 /* Copied from Merge() again */
776 finally:
777 for (i = 0; i < argc; i++)
778 if (fv[i]) {
779 ckfree(argv[i]);
780 }
781 if (argv != argvStore)
782 ckfree(FREECAST argv);
783 if (fv != fvStore)
784 ckfree(FREECAST fv);
785
786 Py_DECREF(tmp);
787 return res;
788}
789
790#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000791
792static PyObject *
793Tkapp_GlobalCall(self, args)
794 PyObject *self;
795 PyObject *args;
796{
Guido van Rossum212643f1998-04-29 16:22:14 +0000797 /* Could do the same here as for Tkapp_Call(), but this is not used
798 much, so I can't be bothered. Unfortunately Tcl doesn't export a
799 way for the user to do what all its Global* variants do (save and
800 reset the scope pointer, call the local version, restore the saved
801 scope pointer). */
802
Guido van Rossum62320c91998-06-15 04:36:09 +0000803 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000804 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000805
Guido van Rossum62320c91998-06-15 04:36:09 +0000806 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 if (!cmd)
808 PyErr_SetString(Tkinter_TclError, "merge failed");
809
Guido van Rossum00d93061998-05-28 23:06:38 +0000810 else {
811 int err;
812 ENTER_TCL
813 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000814 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000815 if (err == TCL_ERROR)
816 res = Tkinter_Error(self);
817 else
818 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000819 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000820 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000821
822 if (cmd)
823 ckfree(cmd);
824
825 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000826}
827
828static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000829Tkapp_Eval(self, args)
830 PyObject *self;
831 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000832{
Barry Warsawfa701a81997-01-16 00:15:11 +0000833 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000834 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000835 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000836
Guido van Rossum43713e52000-02-29 13:59:29 +0000837 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 return NULL;
839
Guido van Rossum00d93061998-05-28 23:06:38 +0000840 ENTER_TCL
841 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000842 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000843 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000844 res = Tkinter_Error(self);
845 else
846 res = PyString_FromString(Tkapp_Result(self));
847 LEAVE_OVERLAP_TCL
848 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000849}
850
851static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000852Tkapp_GlobalEval(self, args)
853 PyObject *self;
854 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000855{
Barry Warsawfa701a81997-01-16 00:15:11 +0000856 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000857 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000858 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000859
Guido van Rossum43713e52000-02-29 13:59:29 +0000860 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000862
Guido van Rossum00d93061998-05-28 23:06:38 +0000863 ENTER_TCL
864 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000865 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000866 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000867 res = Tkinter_Error(self);
868 else
869 res = PyString_FromString(Tkapp_Result(self));
870 LEAVE_OVERLAP_TCL
871 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000872}
873
874static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000875Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 PyObject *self;
877 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000878{
Barry Warsawfa701a81997-01-16 00:15:11 +0000879 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000880 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000881 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000882
Guido van Rossum43713e52000-02-29 13:59:29 +0000883 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000884 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000885
Guido van Rossum00d93061998-05-28 23:06:38 +0000886 ENTER_TCL
887 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000888 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000889 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000890 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000891
Guido van Rossum62320c91998-06-15 04:36:09 +0000892 else
893 res = PyString_FromString(Tkapp_Result(self));
894 LEAVE_OVERLAP_TCL
895 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000896}
897
898static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000899Tkapp_Record(self, args)
900 PyObject *self;
901 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000902{
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000904 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000905 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000906
Guido van Rossum35d43371997-08-02 00:09:09 +0000907 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000908 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000909
Guido van Rossum00d93061998-05-28 23:06:38 +0000910 ENTER_TCL
911 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000912 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000913 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000914 res = Tkinter_Error(self);
915 else
916 res = PyString_FromString(Tkapp_Result(self));
917 LEAVE_OVERLAP_TCL
918 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000919}
920
921static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000922Tkapp_AddErrorInfo(self, args)
923 PyObject *self;
924 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000925{
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Guido van Rossum43713e52000-02-29 13:59:29 +0000928 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000930 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000932 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000933
Barry Warsawfa701a81997-01-16 00:15:11 +0000934 Py_INCREF(Py_None);
935 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000936}
937
Barry Warsawfa701a81997-01-16 00:15:11 +0000938
939
Guido van Rossum18468821994-06-20 07:49:28 +0000940/** Tcl Variable **/
941
942static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000943SetVar(self, args, flags)
944 PyObject *self;
945 PyObject *args;
946 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000947{
Guido van Rossum00d93061998-05-28 23:06:38 +0000948 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000950 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000951
Guido van Rossum62320c91998-06-15 04:36:09 +0000952 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000953 if (!tmp)
954 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000955
Guido van Rossum43713e52000-02-29 13:59:29 +0000956 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000958 s = AsString(newValue, tmp);
959 ENTER_TCL
960 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
961 LEAVE_TCL
962 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000964 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000965 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000966 s = AsString (newValue, tmp);
967 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000968 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000969 s, flags);
970 LEAVE_TCL
971 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000972 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000973 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000974 return NULL;
975 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000976 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000978
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 if (!ok)
980 return Tkinter_Error(self);
981
982 Py_INCREF(Py_None);
983 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000984}
985
986static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000987Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000988 PyObject *self;
989 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000990{
Barry Warsawfa701a81997-01-16 00:15:11 +0000991 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000992}
993
994static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000995Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000996 PyObject *self;
997 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000998{
Barry Warsawfa701a81997-01-16 00:15:11 +0000999 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001000}
1001
Barry Warsawfa701a81997-01-16 00:15:11 +00001002
1003
Guido van Rossum18468821994-06-20 07:49:28 +00001004static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001005GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 PyObject *self;
1007 PyObject *args;
1008 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001009{
Guido van Rossum35d43371997-08-02 00:09:09 +00001010 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001011 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001012
Guido van Rossum43713e52000-02-29 13:59:29 +00001013 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001014 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001015 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001016 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001017 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +00001018
Barry Warsawfa701a81997-01-16 00:15:11 +00001019 else
Guido van Rossum35d43371997-08-02 00:09:09 +00001020 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001021 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001022
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001024 res = Tkinter_Error(self);
1025 else
1026 res = PyString_FromString(s);
1027 LEAVE_OVERLAP_TCL
1028 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001029}
1030
1031static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001032Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001033 PyObject *self;
1034 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001035{
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001037}
1038
1039static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001040Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 PyObject *self;
1042 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001043{
Barry Warsawfa701a81997-01-16 00:15:11 +00001044 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001045}
1046
Barry Warsawfa701a81997-01-16 00:15:11 +00001047
1048
Guido van Rossum18468821994-06-20 07:49:28 +00001049static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001050UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 PyObject *self;
1052 PyObject *args;
1053 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001054{
Guido van Rossum35d43371997-08-02 00:09:09 +00001055 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001056 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001058
Guido van Rossum43713e52000-02-29 13:59:29 +00001059 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001061 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001062 if (name2 == NULL)
1063 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1064
1065 else
1066 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001067 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001068
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001070 res = Tkinter_Error(self);
1071 else {
1072 Py_INCREF(Py_None);
1073 res = Py_None;
1074 }
1075 LEAVE_OVERLAP_TCL
1076 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001077}
1078
1079static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001080Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 PyObject *self;
1082 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001083{
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001085}
1086
1087static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001088Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 PyObject *self;
1090 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001091{
Barry Warsawfa701a81997-01-16 00:15:11 +00001092 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001093}
1094
Barry Warsawfa701a81997-01-16 00:15:11 +00001095
1096
Guido van Rossum18468821994-06-20 07:49:28 +00001097/** Tcl to Python **/
1098
1099static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001100Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 PyObject *self;
1102 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001103{
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 char *s;
1105 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001106
Guido van Rossum43713e52000-02-29 13:59:29 +00001107 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001108 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001109 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 return Tkinter_Error(self);
1111 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001112}
1113
1114static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001115Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 PyObject *self;
1117 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001118{
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 char *s;
1120 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001121
Guido van Rossum43713e52000-02-29 13:59:29 +00001122 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001124 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 return Tkinter_Error(self);
1126 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001127}
1128
1129static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001130Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 PyObject *self;
1132 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001133{
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 char *s;
1135 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Guido van Rossum43713e52000-02-29 13:59:29 +00001137 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001139 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1140 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001142}
1143
1144static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001145Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001146 PyObject *self;
1147 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001148{
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001150 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001151 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001152
Guido van Rossum43713e52000-02-29 13:59:29 +00001153 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001155 ENTER_TCL
1156 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001157 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001158 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001159 res = Tkinter_Error(self);
1160 else
1161 res = Py_BuildValue("s", Tkapp_Result(self));
1162 LEAVE_OVERLAP_TCL
1163 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001164}
1165
1166static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001167Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001168 PyObject *self;
1169 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001170{
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001172 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001173 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001175
Guido van Rossum43713e52000-02-29 13:59:29 +00001176 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001178 ENTER_TCL
1179 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001180 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001181 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001182 res = Tkinter_Error(self);
1183 else
1184 res = Py_BuildValue("l", v);
1185 LEAVE_OVERLAP_TCL
1186 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001187}
1188
1189static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001190Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001191 PyObject *self;
1192 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001193{
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001195 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001196 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001197 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001198
Guido van Rossum43713e52000-02-29 13:59:29 +00001199 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001200 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001201 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001202 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001203 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001204 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001205 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001206 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001207 res = Tkinter_Error(self);
1208 else
1209 res = Py_BuildValue("d", v);
1210 LEAVE_OVERLAP_TCL
1211 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001212}
1213
1214static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001215Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 PyObject *self;
1217 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001218{
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001220 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001221 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001223
Guido van Rossum43713e52000-02-29 13:59:29 +00001224 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001225 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001226 ENTER_TCL
1227 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001228 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001229 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001230 res = Tkinter_Error(self);
1231 else
1232 res = Py_BuildValue("i", v);
1233 LEAVE_OVERLAP_TCL
1234 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001235}
1236
Barry Warsawfa701a81997-01-16 00:15:11 +00001237
1238
Guido van Rossum18468821994-06-20 07:49:28 +00001239static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001240Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001241 PyObject *self;
1242 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001243{
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 char *list;
1245 int argc;
1246 char **argv;
1247 PyObject *v;
1248 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001249
Guido van Rossum43713e52000-02-29 13:59:29 +00001250 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001252
Barry Warsawfa701a81997-01-16 00:15:11 +00001253 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1254 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001255
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 if (!(v = PyTuple_New(argc)))
1257 return NULL;
1258
1259 for (i = 0; i < argc; i++) {
1260 PyObject *s = PyString_FromString(argv[i]);
1261 if (!s || PyTuple_SetItem(v, i, s)) {
1262 Py_DECREF(v);
1263 v = NULL;
1264 goto finally;
1265 }
1266 }
Guido van Rossum18468821994-06-20 07:49:28 +00001267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 finally:
1269 ckfree(FREECAST argv);
1270 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001271}
1272
1273static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001274Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001275 PyObject *self;
1276 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001277{
Barry Warsawfa701a81997-01-16 00:15:11 +00001278 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001279
Guido van Rossum43713e52000-02-29 13:59:29 +00001280 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001281 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001282 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001283}
1284
1285static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001286Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001287 PyObject *self;
1288 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001289{
Barry Warsawfa701a81997-01-16 00:15:11 +00001290 char *s = Merge(args);
1291 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001292
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 if (s) {
1294 res = PyString_FromString(s);
1295 ckfree(s);
1296 }
1297 else
1298 PyErr_SetString(Tkinter_TclError, "merge failed");
1299
1300 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001301}
1302
Barry Warsawfa701a81997-01-16 00:15:11 +00001303
1304
Guido van Rossum18468821994-06-20 07:49:28 +00001305/** Tcl Command **/
1306
Guido van Rossum00d93061998-05-28 23:06:38 +00001307/* Client data struct */
1308typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001309 PyObject *self;
1310 PyObject *func;
1311} PythonCmd_ClientData;
1312
1313static int
1314PythonCmd_Error(interp)
1315 Tcl_Interp *interp;
1316{
1317 errorInCmd = 1;
1318 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1319 LEAVE_PYTHON
1320 return TCL_ERROR;
1321}
1322
Guido van Rossum18468821994-06-20 07:49:28 +00001323/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 * function or method.
1325 */
Guido van Rossum18468821994-06-20 07:49:28 +00001326static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001327PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001328 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001329 Tcl_Interp *interp;
1330 int argc;
1331 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001332{
Guido van Rossum00d93061998-05-28 23:06:38 +00001333 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 PyObject *self, *func, *arg, *res, *tmp;
1335 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001336
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001337 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001338
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 /* TBD: no error checking here since we know, via the
1340 * Tkapp_CreateCommand() that the client data is a two-tuple
1341 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001342 self = data->self;
1343 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001344
Barry Warsawfa701a81997-01-16 00:15:11 +00001345 /* Create argument list (argv1, ..., argvN) */
1346 if (!(arg = PyTuple_New(argc - 1)))
1347 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001348
Barry Warsawfa701a81997-01-16 00:15:11 +00001349 for (i = 0; i < (argc - 1); i++) {
1350 PyObject *s = PyString_FromString(argv[i + 1]);
1351 if (!s || PyTuple_SetItem(arg, i, s)) {
1352 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001353 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001354 }
1355 }
1356 res = PyEval_CallObject(func, arg);
1357 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001358
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 if (res == NULL)
1360 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001361
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 if (!(tmp = PyList_New(0))) {
1363 Py_DECREF(res);
1364 return PythonCmd_Error(interp);
1365 }
1366
1367 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1368 Py_DECREF(res);
1369 Py_DECREF(tmp);
1370
Guido van Rossum00d93061998-05-28 23:06:38 +00001371 LEAVE_PYTHON
1372
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001374}
1375
1376static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001377PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001378 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001379{
Guido van Rossum00d93061998-05-28 23:06:38 +00001380 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1381
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001382 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 Py_XDECREF(data->self);
1384 Py_XDECREF(data->func);
1385 PyMem_DEL(data);
1386 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001387}
1388
Barry Warsawfa701a81997-01-16 00:15:11 +00001389
1390
Guido van Rossum18468821994-06-20 07:49:28 +00001391static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001392Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001393 PyObject *self;
1394 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001395{
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001399 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001400
Guido van Rossum43713e52000-02-29 13:59:29 +00001401 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001402 return NULL;
1403 if (!PyCallable_Check(func)) {
1404 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001405 return NULL;
1406 }
Guido van Rossum18468821994-06-20 07:49:28 +00001407
Guido van Rossum00d93061998-05-28 23:06:38 +00001408 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001409 if (!data)
1410 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001411 Py_XINCREF(self);
1412 Py_XINCREF(func);
1413 data->self = self;
1414 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001415
Guido van Rossum00d93061998-05-28 23:06:38 +00001416 ENTER_TCL
1417 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1418 (ClientData)data, PythonCmdDelete);
1419 LEAVE_TCL
1420 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001421 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001422 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001423 return NULL;
1424 }
Guido van Rossum18468821994-06-20 07:49:28 +00001425
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 Py_INCREF(Py_None);
1427 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001428}
1429
Barry Warsawfa701a81997-01-16 00:15:11 +00001430
1431
Guido van Rossum18468821994-06-20 07:49:28 +00001432static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001433Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 PyObject *self;
1435 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001436{
Barry Warsawfa701a81997-01-16 00:15:11 +00001437 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001438 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001439
Guido van Rossum43713e52000-02-29 13:59:29 +00001440 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001441 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 ENTER_TCL
1443 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1444 LEAVE_TCL
1445 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001446 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1447 return NULL;
1448 }
1449 Py_INCREF(Py_None);
1450 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001451}
1452
Barry Warsawfa701a81997-01-16 00:15:11 +00001453
1454
Guido van Rossum00d93061998-05-28 23:06:38 +00001455#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001456/** File Handler **/
1457
Guido van Rossum00d93061998-05-28 23:06:38 +00001458typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001459 PyObject *func;
1460 PyObject *file;
1461 int id;
1462 struct _fhcdata *next;
1463} FileHandler_ClientData;
1464
1465static FileHandler_ClientData *HeadFHCD;
1466
1467static FileHandler_ClientData *
1468NewFHCD(func, file, id)
1469 PyObject *func;
1470 PyObject *file;
1471 int id;
1472{
1473 FileHandler_ClientData *p;
1474 p = PyMem_NEW(FileHandler_ClientData, 1);
1475 if (p != NULL) {
1476 Py_XINCREF(func);
1477 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001478 p->func = func;
1479 p->file = file;
1480 p->id = id;
1481 p->next = HeadFHCD;
1482 HeadFHCD = p;
1483 }
1484 return p;
1485}
1486
1487static void
1488DeleteFHCD(id)
1489 int id;
1490{
1491 FileHandler_ClientData *p, **pp;
1492
1493 pp = &HeadFHCD;
1494 while ((p = *pp) != NULL) {
1495 if (p->id == id) {
1496 *pp = p->next;
1497 Py_XDECREF(p->func);
1498 Py_XDECREF(p->file);
1499 PyMem_DEL(p);
1500 }
1501 else
1502 pp = &p->next;
1503 }
1504}
1505
Guido van Rossuma597dde1995-01-10 20:56:29 +00001506static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001507FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001508 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001510{
Guido van Rossum00d93061998-05-28 23:06:38 +00001511 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001513
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001514 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001515 func = data->func;
1516 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001517
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 arg = Py_BuildValue("(Oi)", file, (long) mask);
1519 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001520 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001521
1522 if (res == NULL) {
1523 errorInCmd = 1;
1524 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1525 }
1526 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001527 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001528}
1529
1530static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001531GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 /* Either an int >= 0 or an object with a
1533 *.fileno() method that returns an int >= 0
1534 */
1535 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001536{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001537 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001538 int id;
1539 if (PyInt_Check(file)) {
1540 id = PyInt_AsLong(file);
1541 if (id < 0)
1542 PyErr_SetString(PyExc_ValueError, "invalid file id");
1543 return id;
1544 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001545 args = PyTuple_New(0);
1546 if (args == NULL)
1547 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001548
1549 meth = PyObject_GetAttrString(file, "fileno");
1550 if (meth == NULL) {
1551 Py_DECREF(args);
1552 return -1;
1553 }
1554
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001555 res = PyEval_CallObject(meth, args);
1556 Py_DECREF(args);
1557 Py_DECREF(meth);
1558 if (res == NULL)
1559 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001560
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001561 if (PyInt_Check(res))
1562 id = PyInt_AsLong(res);
1563 else
1564 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001565
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001566 if (id < 0)
1567 PyErr_SetString(PyExc_ValueError,
1568 "invalid fileno() return value");
1569 Py_DECREF(res);
1570 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001571}
1572
1573static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001574Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 PyObject *self;
1576 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001577{
Guido van Rossum00d93061998-05-28 23:06:38 +00001578 FileHandler_ClientData *data;
1579 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001580 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001581
Guido van Rossum43713e52000-02-29 13:59:29 +00001582 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001584 tfile = GetFileNo(file);
1585 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 return NULL;
1587 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001588 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 return NULL;
1590 }
1591
Guido van Rossuma80649b2000-03-28 20:07:05 +00001592 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001593 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 return NULL;
1595
Barry Warsawfa701a81997-01-16 00:15:11 +00001596 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001597 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001598 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001599 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001600 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001602}
1603
1604static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001605Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001606 PyObject *self;
1607 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001608{
Barry Warsawfa701a81997-01-16 00:15:11 +00001609 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001610 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001611 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001612
Guido van Rossum43713e52000-02-29 13:59:29 +00001613 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001614 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001615 tfile = GetFileNo(file);
1616 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001617 return NULL;
1618
Guido van Rossuma80649b2000-03-28 20:07:05 +00001619 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001620
Barry Warsawfa701a81997-01-16 00:15:11 +00001621 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001622 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001623 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001624 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001625 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001626 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001627}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001628#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001629
Barry Warsawfa701a81997-01-16 00:15:11 +00001630
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001631/**** Tktt Object (timer token) ****/
1632
1633staticforward PyTypeObject Tktt_Type;
1634
Guido van Rossum00d93061998-05-28 23:06:38 +00001635typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001636 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001637 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001638 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001639} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640
1641static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001642Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 PyObject *self;
1644 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001645{
Barry Warsawfa701a81997-01-16 00:15:11 +00001646 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001648
Guido van Rossum43713e52000-02-29 13:59:29 +00001649 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001650 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001651 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001652 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001653 v->token = NULL;
1654 }
1655 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001656 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001657 Py_DECREF(func);
1658 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001659 }
1660 Py_INCREF(Py_None);
1661 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001662}
1663
1664static PyMethodDef Tktt_methods[] =
1665{
Guido van Rossum35d43371997-08-02 00:09:09 +00001666 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001668};
1669
1670static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001671Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001672 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001673{
Barry Warsawfa701a81997-01-16 00:15:11 +00001674 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001675
Guido van Rossumb18618d2000-05-03 23:44:39 +00001676 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001677 if (v == NULL)
1678 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001679
Guido van Rossum00d93061998-05-28 23:06:38 +00001680 Py_INCREF(func);
1681 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001682 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001683
1684 /* Extra reference, deleted when called or when handler is deleted */
1685 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001686 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001687}
1688
1689static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001690Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001691 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001692{
Guido van Rossum00d93061998-05-28 23:06:38 +00001693 TkttObject *v = (TkttObject *)self;
1694 PyObject *func = v->func;
1695
1696 Py_XDECREF(func);
1697
Guido van Rossumb18618d2000-05-03 23:44:39 +00001698 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001699}
1700
Guido van Rossum597ac201998-05-12 14:36:19 +00001701static PyObject *
1702Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001703 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001704{
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001706 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001707
Guido van Rossum597ac201998-05-12 14:36:19 +00001708 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001709 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001710 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001711}
1712
1713static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001714Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001715 PyObject *self;
1716 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001717{
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001719}
1720
1721static PyTypeObject Tktt_Type =
1722{
Guido van Rossum35d43371997-08-02 00:09:09 +00001723 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001724 0, /*ob_size */
1725 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001726 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001727 0, /*tp_itemsize */
1728 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001729 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 Tktt_GetAttr, /*tp_getattr */
1731 0, /*tp_setattr */
1732 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001733 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001734 0, /*tp_as_number */
1735 0, /*tp_as_sequence */
1736 0, /*tp_as_mapping */
1737 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001738};
1739
Barry Warsawfa701a81997-01-16 00:15:11 +00001740
1741
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001742/** Timer Handler **/
1743
1744static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001745TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001746 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001747{
Guido van Rossum00d93061998-05-28 23:06:38 +00001748 TkttObject *v = (TkttObject *)clientData;
1749 PyObject *func = v->func;
1750 PyObject *res;
1751
1752 if (func == NULL)
1753 return;
1754
1755 v->func = NULL;
1756
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001757 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001758
1759 res = PyEval_CallObject(func, NULL);
1760 Py_DECREF(func);
1761 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001762
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 if (res == NULL) {
1764 errorInCmd = 1;
1765 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1766 }
1767 else
1768 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001769
1770 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001771}
1772
1773static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001774Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001775 PyObject *self;
1776 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001777{
Barry Warsawfa701a81997-01-16 00:15:11 +00001778 int milliseconds;
1779 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001780 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001781
Guido van Rossum43713e52000-02-29 13:59:29 +00001782 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001783 return NULL;
1784 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001785 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001786 return NULL;
1787 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001788 v = Tktt_New(func);
1789 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1790 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001791
Guido van Rossum00d93061998-05-28 23:06:38 +00001792 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001793}
1794
Barry Warsawfa701a81997-01-16 00:15:11 +00001795
Guido van Rossum18468821994-06-20 07:49:28 +00001796/** Event Loop **/
1797
Guido van Rossum18468821994-06-20 07:49:28 +00001798static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001799Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001800 PyObject *self;
1801 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001802{
Barry Warsawfa701a81997-01-16 00:15:11 +00001803 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001804#ifdef WITH_THREAD
1805 PyThreadState *tstate = PyThreadState_Get();
1806#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001807
Guido van Rossum43713e52000-02-29 13:59:29 +00001808 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001809 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001810
Barry Warsawfa701a81997-01-16 00:15:11 +00001811 quitMainLoop = 0;
1812 while (Tk_GetNumMainWindows() > threshold &&
1813 !quitMainLoop &&
1814 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001815 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001816 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001817
1818#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001819 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001820 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001821 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001823 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001824 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001825 if (result == 0)
1826 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001827 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001828#else
1829 result = Tcl_DoOneEvent(0);
1830#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001831
Guido van Rossum35d43371997-08-02 00:09:09 +00001832 if (PyErr_CheckSignals() != 0)
1833 return NULL;
1834 if (result < 0)
1835 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001836 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001838
Barry Warsawfa701a81997-01-16 00:15:11 +00001839 if (errorInCmd) {
1840 errorInCmd = 0;
1841 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1842 excInCmd = valInCmd = trbInCmd = NULL;
1843 return NULL;
1844 }
1845 Py_INCREF(Py_None);
1846 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001847}
1848
1849static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001850Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001851 PyObject *self;
1852 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001853{
Guido van Rossum35d43371997-08-02 00:09:09 +00001854 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001855 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001856
Guido van Rossum43713e52000-02-29 13:59:29 +00001857 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 return NULL;
1859
Guido van Rossum00d93061998-05-28 23:06:38 +00001860 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001861 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001862 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001863 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001864}
1865
1866static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001867Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001868 PyObject *self;
1869 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001870{
1871
Guido van Rossum43713e52000-02-29 13:59:29 +00001872 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001873 return NULL;
1874
1875 quitMainLoop = 1;
1876 Py_INCREF(Py_None);
1877 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001878}
1879
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001880static PyObject *
1881Tkapp_InterpAddr(self, args)
1882 PyObject *self;
1883 PyObject *args;
1884{
1885
Guido van Rossum43713e52000-02-29 13:59:29 +00001886 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001887 return NULL;
1888
1889 return PyInt_FromLong((long)Tkapp_Interp(self));
1890}
1891
Barry Warsawfa701a81997-01-16 00:15:11 +00001892
1893
Guido van Rossum18468821994-06-20 07:49:28 +00001894/**** Tkapp Method List ****/
1895
1896static PyMethodDef Tkapp_methods[] =
1897{
Guido van Rossum35d43371997-08-02 00:09:09 +00001898 {"call", Tkapp_Call, 0},
1899 {"globalcall", Tkapp_GlobalCall, 0},
1900 {"eval", Tkapp_Eval, 1},
1901 {"globaleval", Tkapp_GlobalEval, 1},
1902 {"evalfile", Tkapp_EvalFile, 1},
1903 {"record", Tkapp_Record, 1},
1904 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1905 {"setvar", Tkapp_SetVar, 1},
1906 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1907 {"getvar", Tkapp_GetVar, 1},
1908 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1909 {"unsetvar", Tkapp_UnsetVar, 1},
1910 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1911 {"getint", Tkapp_GetInt, 1},
1912 {"getdouble", Tkapp_GetDouble, 1},
1913 {"getboolean", Tkapp_GetBoolean, 1},
1914 {"exprstring", Tkapp_ExprString, 1},
1915 {"exprlong", Tkapp_ExprLong, 1},
1916 {"exprdouble", Tkapp_ExprDouble, 1},
1917 {"exprboolean", Tkapp_ExprBoolean, 1},
1918 {"splitlist", Tkapp_SplitList, 1},
1919 {"split", Tkapp_Split, 1},
1920 {"merge", Tkapp_Merge, 0},
1921 {"createcommand", Tkapp_CreateCommand, 1},
1922 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001923#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001924 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1925 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001926#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001927 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001928 {"mainloop", Tkapp_MainLoop, 1},
1929 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001930 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001931 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001932 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001933};
1934
Barry Warsawfa701a81997-01-16 00:15:11 +00001935
1936
Guido van Rossum18468821994-06-20 07:49:28 +00001937/**** Tkapp Type Methods ****/
1938
1939static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001940Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001941 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001942{
Guido van Rossum00d93061998-05-28 23:06:38 +00001943 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001944 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001945 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001946 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001947 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001948}
1949
1950static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001951Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 PyObject *self;
1953 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001954{
Guido van Rossum35d43371997-08-02 00:09:09 +00001955 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001956}
1957
1958static PyTypeObject Tkapp_Type =
1959{
Guido van Rossum35d43371997-08-02 00:09:09 +00001960 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001961 0, /*ob_size */
1962 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001963 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 0, /*tp_itemsize */
1965 Tkapp_Dealloc, /*tp_dealloc */
1966 0, /*tp_print */
1967 Tkapp_GetAttr, /*tp_getattr */
1968 0, /*tp_setattr */
1969 0, /*tp_compare */
1970 0, /*tp_repr */
1971 0, /*tp_as_number */
1972 0, /*tp_as_sequence */
1973 0, /*tp_as_mapping */
1974 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001975};
1976
Barry Warsawfa701a81997-01-16 00:15:11 +00001977
1978
Guido van Rossum18468821994-06-20 07:49:28 +00001979/**** Tkinter Module ****/
1980
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001981typedef struct {
1982 PyObject* tuple;
1983 int size; /* current size */
1984 int maxsize; /* allocated size */
1985} FlattenContext;
1986
1987static int
1988_bump(FlattenContext* context, int size)
1989{
1990 /* expand tuple to hold (at least) size new items. return true if
1991 successful, false if an exception was raised*/
1992
1993 int maxsize = context->maxsize * 2;
1994
1995 if (maxsize < context->size + size)
1996 maxsize = context->size + size;
1997
1998 context->maxsize = maxsize;
1999
2000 return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0;
2001}
2002
2003static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002004_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002005{
2006 /* add tuple or list to argument tuple (recursively) */
2007
2008 int i, size;
2009
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002010 if (depth > 1000) {
2011 PyErr_SetString(PyExc_ValueError,"nesting too deep in _flatten");
2012 return 0;
2013 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002014 size = PyList_GET_SIZE(item);
2015 /* preallocate (assume no nesting) */
2016 if (context->size + size > context->maxsize && !_bump(context, size))
2017 return 0;
2018 /* copy items to output tuple */
2019 for (i = 0; i < size; i++) {
2020 PyObject *o = PyList_GET_ITEM(item, i);
2021 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002022 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002023 return 0;
2024 } else if (o != Py_None) {
2025 if (context->size + 1 > context->maxsize && !_bump(context, 1))
2026 return 0;
2027 Py_INCREF(o);
2028 PyTuple_SET_ITEM(context->tuple, context->size++, o);
2029 }
2030 }
2031 } else if (PyTuple_Check(item)) {
2032 /* same, for tuples */
2033 size = PyTuple_GET_SIZE(item);
2034 if (context->size + size > context->maxsize && !_bump(context, size))
2035 return 0;
2036 for (i = 0; i < size; i++) {
2037 PyObject *o = PyTuple_GET_ITEM(item, i);
2038 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002039 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002040 return 0;
2041 } else if (o != Py_None) {
2042 if (context->size + 1 > context->maxsize && !_bump(context, 1))
2043 return 0;
2044 Py_INCREF(o);
2045 PyTuple_SET_ITEM(context->tuple, context->size++, o);
2046 }
2047 }
2048 } else {
2049 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2050 return 0;
2051 }
2052 return 1;
2053}
2054
2055static PyObject *
2056Tkinter_Flatten(PyObject* self, PyObject* args)
2057{
2058 FlattenContext context;
2059 PyObject* item;
2060
2061 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2062 return NULL;
2063
2064 context.maxsize = PySequence_Length(item);
2065 if (context.maxsize <= 0)
2066 return PyTuple_New(0);
2067
2068 context.tuple = PyTuple_New(context.maxsize);
2069 if (!context.tuple)
2070 return NULL;
2071
2072 context.size = 0;
2073
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002074 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002075 return NULL;
2076
2077 if (_PyTuple_Resize(&context.tuple, context.size, 0))
2078 return NULL;
2079
2080 return context.tuple;
2081}
2082
Guido van Rossum18468821994-06-20 07:49:28 +00002083static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00002084Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00002085 PyObject *self;
2086 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00002087{
Barry Warsawfa701a81997-01-16 00:15:11 +00002088 char *screenName = NULL;
2089 char *baseName = NULL;
2090 char *className = NULL;
2091 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002092
Guido van Rossum35d43371997-08-02 00:09:09 +00002093 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002094 if (baseName != NULL)
2095 baseName++;
2096 else
2097 baseName = Py_GetProgramName();
2098 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002099
Guido van Rossum43713e52000-02-29 13:59:29 +00002100 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002101 &screenName, &baseName, &className,
2102 &interactive))
2103 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002104
Barry Warsawfa701a81997-01-16 00:15:11 +00002105 return (PyObject *) Tkapp_New(screenName, baseName, className,
2106 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00002107}
2108
2109static PyMethodDef moduleMethods[] =
2110{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002111 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002112 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002113#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00002114 {"createfilehandler", Tkapp_CreateFileHandler, 1},
2115 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00002116#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00002117 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002118 {"mainloop", Tkapp_MainLoop, 1},
2119 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00002120 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002121 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002122};
2123
Guido van Rossum7bf15641998-05-22 18:28:17 +00002124#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002125
2126static int stdin_ready = 0;
2127
Guido van Rossumad4db171998-06-13 13:56:28 +00002128#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002129static void
2130MyFileProc(clientData, mask)
2131 void *clientData;
2132 int mask;
2133{
2134 stdin_ready = 1;
2135}
Guido van Rossumad4db171998-06-13 13:56:28 +00002136#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002137
Guido van Rossum00d93061998-05-28 23:06:38 +00002138static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002139
Guido van Rossum18468821994-06-20 07:49:28 +00002140static int
Guido van Rossum35d43371997-08-02 00:09:09 +00002141EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00002142{
Guido van Rossumad4db171998-06-13 13:56:28 +00002143#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002144 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002145#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002146#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002147 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002148#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002149 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002150 errorInCmd = 0;
2151#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002152 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002153 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002154#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002155 while (!errorInCmd && !stdin_ready) {
2156 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002157#ifdef MS_WINDOWS
2158 if (_kbhit()) {
2159 stdin_ready = 1;
2160 break;
2161 }
2162#endif
2163#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002164 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002165 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002166 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002167
Guido van Rossum00d93061998-05-28 23:06:38 +00002168 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002169
2170 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002171 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002172 if (result == 0)
2173 Sleep(20);
2174 Py_END_ALLOW_THREADS
2175#else
2176 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002177#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002178
2179 if (result < 0)
2180 break;
2181 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002182#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002183 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002184#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002185 if (errorInCmd) {
2186 errorInCmd = 0;
2187 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2188 excInCmd = valInCmd = trbInCmd = NULL;
2189 PyErr_Print();
2190 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002191#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002192 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002193#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002194 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002195}
Guido van Rossum18468821994-06-20 07:49:28 +00002196
Guido van Rossum00d93061998-05-28 23:06:38 +00002197#endif
2198
Guido van Rossum7bf15641998-05-22 18:28:17 +00002199static void
2200EnableEventHook()
2201{
Guido van Rossum00d93061998-05-28 23:06:38 +00002202#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002203 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002204#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002205 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002206#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002207 PyOS_InputHook = EventHook;
2208 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002209#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002210}
2211
2212static void
2213DisableEventHook()
2214{
Guido van Rossum00d93061998-05-28 23:06:38 +00002215#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002216 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2217 PyOS_InputHook = NULL;
2218 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002219#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002220}
2221
Barry Warsawfa701a81997-01-16 00:15:11 +00002222
2223/* all errors will be checked in one fell swoop in init_tkinter() */
2224static void
2225ins_long(d, name, val)
2226 PyObject *d;
2227 char *name;
2228 long val;
2229{
2230 PyObject *v = PyInt_FromLong(val);
2231 if (v) {
2232 PyDict_SetItemString(d, name, v);
2233 Py_DECREF(v);
2234 }
2235}
2236static void
2237ins_string(d, name, val)
2238 PyObject *d;
2239 char *name;
2240 char *val;
2241{
2242 PyObject *v = PyString_FromString(val);
2243 if (v) {
2244 PyDict_SetItemString(d, name, v);
2245 Py_DECREF(v);
2246 }
2247}
2248
2249
Guido van Rossum3886bb61998-12-04 18:50:17 +00002250DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002251init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002252{
Barry Warsawfa701a81997-01-16 00:15:11 +00002253 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002254
Barry Warsawfa701a81997-01-16 00:15:11 +00002255 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002256
2257#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002258 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002259#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002260
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002262
Barry Warsawfa701a81997-01-16 00:15:11 +00002263 d = PyModule_GetDict(m);
2264 Tkinter_TclError = Py_BuildValue("s", "TclError");
2265 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002266
Guido van Rossum35d43371997-08-02 00:09:09 +00002267 ins_long(d, "READABLE", TCL_READABLE);
2268 ins_long(d, "WRITABLE", TCL_WRITABLE);
2269 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2270 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2271 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2272 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2273 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2274 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2275 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002276 ins_string(d, "TK_VERSION", TK_VERSION);
2277 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002278
Guido van Rossum83551bf1997-09-13 00:44:23 +00002279 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002280
2281 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002282 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2283
Guido van Rossume187b0e2000-03-27 21:46:29 +00002284 /* This helps the dynamic loader; in Unicode aware Tcl versions
2285 it also helps Tcl find its encodings. */
2286 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002287
Barry Warsawfa701a81997-01-16 00:15:11 +00002288 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002289 return;
2290
Guido van Rossum43ff8681998-07-14 18:02:13 +00002291#if 0
2292 /* This was not a good idea; through <Destroy> bindings,
2293 Tcl_Finalize() may invoke Python code but at that point the
2294 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002295 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002296#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002297
Jack Jansen34cc5c31995-10-31 16:15:12 +00002298#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002299 /*
2300 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2301 ** Most of the initializations in that routine (toolbox init calls and
2302 ** such) have already been done for us, so we only need these.
2303 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002304 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002305
2306 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002307#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002308 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002309#endif /* GENERATINGCFM */
2310#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002311}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002312
Guido van Rossumec22c921996-02-25 04:50:29 +00002313
Barry Warsawfa701a81997-01-16 00:15:11 +00002314
Guido van Rossum9722ad81995-09-22 23:49:28 +00002315#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002316
2317/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002318** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002319*/
2320
Guido van Rossum9722ad81995-09-22 23:49:28 +00002321void
2322panic(char * format, ...)
2323{
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002325
Barry Warsawfa701a81997-01-16 00:15:11 +00002326 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002327
Guido van Rossum227cf761998-08-05 13:53:32 +00002328 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002329 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002330
Barry Warsawfa701a81997-01-16 00:15:11 +00002331 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002332
Barry Warsawfa701a81997-01-16 00:15:11 +00002333 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002334}
Jack Jansen40b546d1995-11-14 10:34:45 +00002335
Guido van Rossumec22c921996-02-25 04:50:29 +00002336/*
2337** Pass events to SIOUX before passing them to Tk.
2338*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002339
Guido van Rossumec22c921996-02-25 04:50:29 +00002340static int
2341PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002342 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002343{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002344 WindowPtr frontwin;
2345 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002346 ** Sioux eats too many events, so we don't pass it everything. We
2347 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002348 ** the Sioux window is frontmost. This means that Tk menus don't work
2349 ** in that case, but at least we can scroll the sioux window.
2350 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2351 ** part of the external interface of Sioux...
2352 */
2353 frontwin = FrontWindow();
2354 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2355 if (SIOUXHandleOneEvent(eventPtr))
2356 return 0; /* Nothing happened to the Tcl event queue */
2357 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002358 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002359}
2360
Guido van Rossumec22c921996-02-25 04:50:29 +00002361#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002362
2363/*
2364** Additional Mac specific code for dealing with shared libraries.
2365*/
2366
2367#include <Resources.h>
2368#include <CodeFragments.h>
2369
2370static int loaded_from_shlib = 0;
2371static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002372
Jack Jansen34cc5c31995-10-31 16:15:12 +00002373/*
2374** If this module is dynamically loaded the following routine should
2375** be the init routine. It takes care of adding the shared library to
2376** the resource-file chain, so that the tk routines can find their
2377** resources.
2378*/
2379OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002380init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002381{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002382 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002383 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002384 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002385 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2386 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002387 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002388 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2389 loaded_from_shlib = 1;
2390 }
2391 return noErr;
2392}
2393
2394/*
2395** Insert the library resources into the search path. Put them after
2396** the resources from the application. Again, we ignore errors.
2397*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002398static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002399mac_addlibresources()
2400{
2401 if ( !loaded_from_shlib )
2402 return;
2403 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2404}
2405
Guido van Rossumec22c921996-02-25 04:50:29 +00002406#endif /* GENERATINGCFM */
2407#endif /* macintosh */