blob: f61b0ded1edf9340687124febba51307b1abce40 [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 Rossumfd71b9e2000-06-30 23:50:40 +00008Copyright (c) 2000, BeOpen.com.
9Copyright (c) 1995-2000, Corporation for National Research Initiatives.
10Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
11All rights reserved.
Guido van Rossum845547d1996-06-26 18:26:04 +000012
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000013See the file "Misc/COPYRIGHT" for information on usage and
14redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum845547d1996-06-26 18:26:04 +000015
16******************************************************************/
17
18/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000019
Guido van Rossum7ffa7611996-08-13 21:10:16 +000020/* TCL/TK VERSION INFO:
21
Guido van Rossuma80649b2000-03-28 20:07:05 +000022 Only Tcl/Tk 8.0 and later are supported. Older versions are not
23 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
24 libraries.)
25*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000026
Guido van Rossuma80649b2000-03-28 20:07:05 +000027/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000028
29 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
30 intelligent mappings between Python objects and Tcl objects (e.g. ints,
31 floats and Tcl window pointers could be handled specially).
32
33 - Register a new Tcl type, "Python callable", which can be called more
34 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
35
Guido van Rossum7ffa7611996-08-13 21:10:16 +000036*/
37
Guido van Rossum35d43371997-08-02 00:09:09 +000038
Guido van Rossum9722ad81995-09-22 23:49:28 +000039#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000040#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000041
Guido van Rossum00d93061998-05-28 23:06:38 +000042#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000043#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000044#endif
45
Guido van Rossum2a5119b1998-05-29 01:28:40 +000046#ifdef MS_WINDOWS
47#include <windows.h>
48#endif
49
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000050#ifdef macintosh
51#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000052#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000053#endif
54
Guido van Rossum49b56061998-10-01 20:42:43 +000055#ifdef PYOS_OS2
56#include "myselect.h"
57#endif
58
Guido van Rossum18468821994-06-20 07:49:28 +000059#include <tcl.h>
60#include <tk.h>
61
Guido van Rossum3e819a71997-08-01 19:29:02 +000062#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
63
Guido van Rossuma80649b2000-03-28 20:07:05 +000064#if TKMAJORMINOR < 8000
65#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000066#endif
67
Guido van Rossuma80649b2000-03-28 20:07:05 +000068#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000069/* Sigh, we have to include this to get at the tcl qd pointer */
70#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000071/* And this one we need to clear the menu bar */
72#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000073#endif
74
Guido van Rossuma80649b2000-03-28 20:07:05 +000075#if !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000076#define HAVE_CREATEFILEHANDLER
77#endif
78
Guido van Rossum00d93061998-05-28 23:06:38 +000079#ifdef HAVE_CREATEFILEHANDLER
80
81/* Tcl_CreateFileHandler() changed several times; these macros deal with the
82 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
83 Unix, only because Jack added it back); when available on Windows, it only
84 applies to sockets. */
85
Guido van Rossum7bf15641998-05-22 18:28:17 +000086#ifdef MS_WINDOWS
87#define FHANDLETYPE TCL_WIN_SOCKET
88#else
89#define FHANDLETYPE TCL_UNIX_FD
90#endif
91
Guido van Rossum00d93061998-05-28 23:06:38 +000092/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
93 which uses this to handle Tcl events while the user is typing commands. */
94
95#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000096#define WAIT_FOR_STDIN
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#endif /* HAVE_CREATEFILEHANDLER */
100
Guido van Rossumad4db171998-06-13 13:56:28 +0000101#ifdef MS_WINDOWS
102#include <conio.h>
103#define WAIT_FOR_STDIN
104#endif
105
Guido van Rossum00d93061998-05-28 23:06:38 +0000106#ifdef WITH_THREAD
107
108/* The threading situation is complicated. Tcl is not thread-safe, except for
109 Tcl 8.1, which will probably remain in alpha status for another 6 months
110 (and the README says that Tk will probably remain thread-unsafe forever).
111 So we need to use a lock around all uses of Tcl. Previously, the Python
112 interpreter lock was used for this. However, this causes problems when
113 other Python threads need to run while Tcl is blocked waiting for events.
114
115 To solve this problem, a separate lock for Tcl is introduced. Holding it
116 is incompatible with holding Python's interpreter lock. The following four
117 macros manipulate both locks together.
118
119 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
120 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
121 that could call an event handler, or otherwise affect the state of a Tcl
122 interpreter. These assume that the surrounding code has the Python
123 interpreter lock; inside the brackets, the Python interpreter lock has been
124 released and the lock for Tcl has been acquired.
125
Guido van Rossum5e977831998-06-15 14:03:52 +0000126 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
127 (For example, when transferring data from the Tcl interpreter result to a
128 Python string object.) This can be done by using different macros to close
129 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
130 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
131 releases the Tcl lock.
132
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000133 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000134 handlers when the handler needs to use Python. Such event handlers are
135 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000136 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000137 the Python interpreter lock, restoring the appropriate thread state, and
138 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
139 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000140 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000141
142 These locks expand to several statements and brackets; they should not be
143 used in branches of if statements and the like.
144
145*/
146
Guido van Rossum65d5b571998-12-21 19:32:43 +0000147static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000149
150#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000152 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000153
154#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
Guido van Rossum62320c91998-06-15 04:36:09 +0000157#define ENTER_OVERLAP \
158 Py_END_ALLOW_THREADS
159
160#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000161 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000162
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163#define ENTER_PYTHON \
164 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000165 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000166
167#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000168 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000169 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171#else
172
173#define ENTER_TCL
174#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000175#define ENTER_OVERLAP
176#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000177#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000178#define LEAVE_PYTHON
179
180#endif
181
Guido van Rossumec22c921996-02-25 04:50:29 +0000182#ifdef macintosh
183
184/*
185** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000186** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000187*/
188
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000189/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000190#define FREECAST (char *)
191
Guido van Rossumec22c921996-02-25 04:50:29 +0000192#include <Events.h> /* For EventRecord */
193
Fred Drake509d79a2000-07-08 04:04:38 +0000194typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
195void Tcl_MacSetEventProc (TclMacConvertEventPtr procPtr);
196int TkMacConvertEvent (EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000197
Fred Drake509d79a2000-07-08 04:04:38 +0000198staticforward int PyMacConvertEvent (EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000199
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000200#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
201 #pragma import on
202#endif
203
204#include <SIOUX.h>
205extern int SIOUXIsAppWindow(WindowPtr);
206
207#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
208 #pragma import reset
209#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000210#endif /* macintosh */
211
Guido van Rossum97867b21996-08-08 19:09:53 +0000212#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000213#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000214#endif
215
Guido van Rossum18468821994-06-20 07:49:28 +0000216/**** Tkapp Object Declaration ****/
217
218staticforward PyTypeObject Tkapp_Type;
219
Guido van Rossum00d93061998-05-28 23:06:38 +0000220typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000221 PyObject_HEAD
222 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000223} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000224
225#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000226#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
227#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
228
Guido van Rossum35d43371997-08-02 00:09:09 +0000229#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000230(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000231
Barry Warsawfa701a81997-01-16 00:15:11 +0000232
233
Guido van Rossum18468821994-06-20 07:49:28 +0000234/**** Error Handling ****/
235
236static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000237static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000238static int errorInCmd = 0;
239static PyObject *excInCmd;
240static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000242
Barry Warsawfa701a81997-01-16 00:15:11 +0000243
244
Guido van Rossum18468821994-06-20 07:49:28 +0000245static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000246Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000247{
Barry Warsawfa701a81997-01-16 00:15:11 +0000248 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
249 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000250}
251
Barry Warsawfa701a81997-01-16 00:15:11 +0000252
Barry Warsawfa701a81997-01-16 00:15:11 +0000253
Guido van Rossum18468821994-06-20 07:49:28 +0000254/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000255
256#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000257#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000258#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000259#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000260
Guido van Rossum00d93061998-05-28 23:06:38 +0000261/* Millisecond sleep() for Unix platforms. */
262
263static void
Fred Drake509d79a2000-07-08 04:04:38 +0000264Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000265{
266 /* XXX Too bad if you don't have select(). */
267 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000268 t.tv_sec = milli/1000;
269 t.tv_usec = (milli%1000) * 1000;
270 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
271}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000272#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000273#endif /* WITH_THREAD */
274
275
Guido van Rossum18468821994-06-20 07:49:28 +0000276static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000277AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000278{
Guido van Rossum35d43371997-08-02 00:09:09 +0000279 if (PyString_Check(value))
280 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000281 else {
282 PyObject *v = PyObject_Str(value);
283 PyList_Append(tmp, v);
284 Py_DECREF(v);
285 return PyString_AsString(v);
286 }
Guido van Rossum18468821994-06-20 07:49:28 +0000287}
288
Barry Warsawfa701a81997-01-16 00:15:11 +0000289
290
Guido van Rossum18468821994-06-20 07:49:28 +0000291#define ARGSZ 64
292
293static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000294Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000295{
Barry Warsawfa701a81997-01-16 00:15:11 +0000296 PyObject *tmp = NULL;
297 char *argvStore[ARGSZ];
298 char **argv = NULL;
299 int fvStore[ARGSZ];
300 int *fv = NULL;
301 int argc = 0, i;
302 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000303
Barry Warsawfa701a81997-01-16 00:15:11 +0000304 if (!(tmp = PyList_New(0)))
305 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000306
Barry Warsawfa701a81997-01-16 00:15:11 +0000307 argv = argvStore;
308 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000309
Barry Warsawfa701a81997-01-16 00:15:11 +0000310 if (args == NULL)
311 argc = 0;
312
313 else if (!PyTuple_Check(args)) {
314 argc = 1;
315 fv[0] = 0;
316 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000317 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000318 else {
319 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000320
Barry Warsawfa701a81997-01-16 00:15:11 +0000321 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000322 argv = (char **)ckalloc(argc * sizeof(char *));
323 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 if (argv == NULL || fv == NULL) {
325 PyErr_NoMemory();
326 goto finally;
327 }
328 }
329
330 for (i = 0; i < argc; i++) {
331 PyObject *v = PyTuple_GetItem(args, i);
332 if (PyTuple_Check(v)) {
333 fv[i] = 1;
334 if (!(argv[i] = Merge(v)))
335 goto finally;
336 }
337 else if (v == Py_None) {
338 argc = i;
339 break;
340 }
341 else {
342 fv[i] = 0;
343 argv[i] = AsString(v, tmp);
344 }
345 }
Guido van Rossum18468821994-06-20 07:49:28 +0000346 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000348
Barry Warsawfa701a81997-01-16 00:15:11 +0000349 finally:
350 for (i = 0; i < argc; i++)
351 if (fv[i]) {
352 ckfree(argv[i]);
353 }
354 if (argv != argvStore)
355 ckfree(FREECAST argv);
356 if (fv != fvStore)
357 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000358
Barry Warsawfa701a81997-01-16 00:15:11 +0000359 Py_DECREF(tmp);
360 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000361}
362
Barry Warsawfa701a81997-01-16 00:15:11 +0000363
364
Guido van Rossum18468821994-06-20 07:49:28 +0000365static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000366Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000367{
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 int argc;
369 char **argv;
370 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000371
Barry Warsawfa701a81997-01-16 00:15:11 +0000372 if (list == NULL) {
373 Py_INCREF(Py_None);
374 return Py_None;
375 }
Guido van Rossum18468821994-06-20 07:49:28 +0000376
Guido van Rossum00d93061998-05-28 23:06:38 +0000377 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000378 /* Not a list.
379 * Could be a quoted string containing funnies, e.g. {"}.
380 * Return the string itself.
381 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 return PyString_FromString(list);
383 }
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 if (argc == 0)
386 v = PyString_FromString("");
387 else if (argc == 1)
388 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000389 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 int i;
391 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000392
Barry Warsawfa701a81997-01-16 00:15:11 +0000393 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000394 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000395 Py_DECREF(v);
396 v = NULL;
397 break;
398 }
399 PyTuple_SetItem(v, i, w);
400 }
401 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000402 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000404}
405
Barry Warsawfa701a81997-01-16 00:15:11 +0000406
407
Guido van Rossum18468821994-06-20 07:49:28 +0000408/**** Tkapp Object ****/
409
410#ifndef WITH_APPINIT
411int
Fred Drake509d79a2000-07-08 04:04:38 +0000412Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000413{
Barry Warsawfa701a81997-01-16 00:15:11 +0000414 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000415
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 main = Tk_MainWindow(interp);
417 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000418 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 return TCL_ERROR;
420 }
421 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000422 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 return TCL_ERROR;
424 }
425 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427#endif /* !WITH_APPINIT */
428
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430
431
432/* Initialize the Tk application; see the `main' function in
433 * `tkMain.c'.
434 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000435
436static void EnableEventHook(); /* Forward */
437static void DisableEventHook(); /* Forward */
438
Barry Warsawfa701a81997-01-16 00:15:11 +0000439static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000440Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000441{
442 TkappObject *v;
443 char *argv0;
444
Guido van Rossumb18618d2000-05-03 23:44:39 +0000445 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000446 if (v == NULL)
447 return NULL;
448
449 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000450
Guido van Rossuma80649b2000-03-28 20:07:05 +0000451#if defined(macintosh)
452 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000453 ClearMenuBar();
454 TkMacInitMenus(v->interp);
455#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000456 /* Delete the 'exit' command, which can screw things up */
457 Tcl_DeleteCommand(v->interp, "exit");
458
Barry Warsawfa701a81997-01-16 00:15:11 +0000459 if (screenName != NULL)
460 Tcl_SetVar2(v->interp, "env", "DISPLAY",
461 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000462
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 if (interactive)
464 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
465 else
466 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 /* This is used to get the application class for Tk 4.1 and up */
469 argv0 = (char*)ckalloc(strlen(className) + 1);
470 if (!argv0) {
471 PyErr_NoMemory();
472 Py_DECREF(v);
473 return NULL;
474 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000475
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000477 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 argv0[0] = tolower(argv0[0]);
479 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
480 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000481
Barry Warsawfa701a81997-01-16 00:15:11 +0000482 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000483 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000484
Guido van Rossum7bf15641998-05-22 18:28:17 +0000485 EnableEventHook();
486
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000488}
489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490
491
Guido van Rossum18468821994-06-20 07:49:28 +0000492/** Tcl Eval **/
493
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000494#if TKMAJORMINOR >= 8001
495#define USING_OBJECTS
496#endif
497
498#ifdef USING_OBJECTS
499
500static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000501AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000502{
503 Tcl_Obj *result;
504
505 if (PyString_Check(value))
506 return Tcl_NewStringObj(PyString_AS_STRING(value),
507 PyString_GET_SIZE(value));
508 else if (PyInt_Check(value))
509 return Tcl_NewLongObj(PyInt_AS_LONG(value));
510 else if (PyFloat_Check(value))
511 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
512 else if (PyTuple_Check(value)) {
513 Tcl_Obj **argv = (Tcl_Obj**)
514 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
515 int i;
516 if(!argv)
517 return 0;
518 for(i=0;i<PyTuple_Size(value);i++)
519 argv[i] = AsObj(PyTuple_GetItem(value,i));
520 result = Tcl_NewListObj(PyTuple_Size(value), argv);
521 ckfree(FREECAST argv);
522 return result;
523 }
524 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000525#if TKMAJORMINOR <= 8001
526 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000527 PyObject* utf8 = PyUnicode_AsUTF8String (value);
528 if (!utf8)
529 return 0;
Guido van Rossum8823acc2000-04-27 20:14:31 +0000530 result = Tcl_NewStringObj (PyString_AS_STRING (utf8),
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000531 PyString_GET_SIZE (utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000532 Py_DECREF(utf8);
533 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000534#else /* TKMAJORMINOR > 8001 */
535 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
536 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
537 /* XXX Should really test this at compile time */
538 PyErr_SetString(PyExc_SystemError,
539 "Py_UNICODE and Tcl_UniChar differ in size");
540 return 0;
541 }
542 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
543 PyUnicode_GET_SIZE(value));
544#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000545 }
546 else {
547 PyObject *v = PyObject_Str(value);
548 if (!v)
549 return 0;
550 result = AsObj(v);
551 Py_DECREF(v);
552 return result;
553 }
554}
555
Guido van Rossum18468821994-06-20 07:49:28 +0000556static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000557Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000558{
Guido van Rossum632de272000-03-29 00:19:50 +0000559 Tcl_Obj *objStore[ARGSZ];
560 Tcl_Obj **objv = NULL;
561 int objc = 0, i;
562 PyObject *res = NULL;
563 Tcl_Interp *interp = Tkapp_Interp(self);
564 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
565 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000566
Guido van Rossum632de272000-03-29 00:19:50 +0000567 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000568
Guido van Rossum212643f1998-04-29 16:22:14 +0000569 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000570 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000571
Guido van Rossum212643f1998-04-29 16:22:14 +0000572 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000573 objc = 1;
574 objv[0] = AsObj(args);
575 if (objv[0] == 0)
576 goto finally;
577 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000578 }
579 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000580 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000581
Guido van Rossum632de272000-03-29 00:19:50 +0000582 if (objc > ARGSZ) {
583 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
584 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000585 PyErr_NoMemory();
586 goto finally;
587 }
588 }
589
Guido van Rossum632de272000-03-29 00:19:50 +0000590 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000591 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000592 if (v == Py_None) {
593 objc = i;
594 break;
595 }
Guido van Rossum632de272000-03-29 00:19:50 +0000596 objv[i] = AsObj(v);
597 if (!objv[i])
598 goto finally;
599 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000600 }
601 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000602
Guido van Rossum62320c91998-06-15 04:36:09 +0000603 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000604
605 i = Tcl_EvalObjv(interp, objc, objv, flags);
606
Guido van Rossum62320c91998-06-15 04:36:09 +0000607 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000608 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000609 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000610 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000611 /* We could request the object result here, but doing
612 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000613 char *s = Tcl_GetStringResult(interp);
614 char *p = s;
615 /* If the result contains any bytes with the top bit set,
616 it's UTF-8 and we should decode it to Unicode */
617 while (*p != '\0') {
618 if (*p & 0x80)
619 break;
620 p++;
621 }
622 if (*p == '\0')
623 res = PyString_FromStringAndSize(s, (int)(p-s));
624 else {
625 /* Convert UTF-8 to Unicode string */
626 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000627 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
628 if (res == NULL) {
629 PyErr_Clear();
630 res = PyString_FromStringAndSize(s, (int)(p-s));
631 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000632 }
633 }
Guido van Rossum632de272000-03-29 00:19:50 +0000634
Guido van Rossum62320c91998-06-15 04:36:09 +0000635 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000636
Guido van Rossum212643f1998-04-29 16:22:14 +0000637 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000638 for (i = 0; i < objc; i++)
639 Tcl_DecrRefCount(objv[i]);
640 if (objv != objStore)
641 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000642 return res;
643}
644
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000645#else /* !USING_OBJECTS */
646
647static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000648Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000649{
650 /* This is copied from Merge() */
651 PyObject *tmp = NULL;
652 char *argvStore[ARGSZ];
653 char **argv = NULL;
654 int fvStore[ARGSZ];
655 int *fv = NULL;
656 int argc = 0, i;
657 PyObject *res = NULL; /* except this has a different type */
658 Tcl_CmdInfo info; /* and this is added */
659 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
660
661 if (!(tmp = PyList_New(0)))
662 return NULL;
663
664 argv = argvStore;
665 fv = fvStore;
666
667 if (args == NULL)
668 argc = 0;
669
670 else if (!PyTuple_Check(args)) {
671 argc = 1;
672 fv[0] = 0;
673 argv[0] = AsString(args, tmp);
674 }
675 else {
676 argc = PyTuple_Size(args);
677
678 if (argc > ARGSZ) {
679 argv = (char **)ckalloc(argc * sizeof(char *));
680 fv = (int *)ckalloc(argc * sizeof(int));
681 if (argv == NULL || fv == NULL) {
682 PyErr_NoMemory();
683 goto finally;
684 }
685 }
686
687 for (i = 0; i < argc; i++) {
688 PyObject *v = PyTuple_GetItem(args, i);
689 if (PyTuple_Check(v)) {
690 fv[i] = 1;
691 if (!(argv[i] = Merge(v)))
692 goto finally;
693 }
694 else if (v == Py_None) {
695 argc = i;
696 break;
697 }
698 else {
699 fv[i] = 0;
700 argv[i] = AsString(v, tmp);
701 }
702 }
703 }
704 /* End code copied from Merge() */
705
706 /* All this to avoid a call to Tcl_Merge() and the corresponding call
707 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
708 if (Py_VerboseFlag >= 2) {
709 for (i = 0; i < argc; i++)
710 PySys_WriteStderr("%s ", argv[i]);
711 }
712 ENTER_TCL
713 info.proc = NULL;
714 if (argc < 1 ||
715 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
716 info.proc == NULL)
717 {
718 char *cmd;
719 cmd = Tcl_Merge(argc, argv);
720 i = Tcl_Eval(interp, cmd);
721 ckfree(cmd);
722 }
723 else {
724 Tcl_ResetResult(interp);
725 i = (*info.proc)(info.clientData, interp, argc, argv);
726 }
727 ENTER_OVERLAP
728 if (info.proc == NULL && Py_VerboseFlag >= 2)
729 PySys_WriteStderr("... use TclEval ");
730 if (i == TCL_ERROR) {
731 if (Py_VerboseFlag >= 2)
732 PySys_WriteStderr("... error: '%s'\n",
733 interp->result);
734 Tkinter_Error(self);
735 }
736 else {
737 if (Py_VerboseFlag >= 2)
738 PySys_WriteStderr("-> '%s'\n", interp->result);
739 res = PyString_FromString(interp->result);
740 }
741 LEAVE_OVERLAP_TCL
742
743 /* Copied from Merge() again */
744 finally:
745 for (i = 0; i < argc; i++)
746 if (fv[i]) {
747 ckfree(argv[i]);
748 }
749 if (argv != argvStore)
750 ckfree(FREECAST argv);
751 if (fv != fvStore)
752 ckfree(FREECAST fv);
753
754 Py_DECREF(tmp);
755 return res;
756}
757
758#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000759
760static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000761Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000762{
Guido van Rossum212643f1998-04-29 16:22:14 +0000763 /* Could do the same here as for Tkapp_Call(), but this is not used
764 much, so I can't be bothered. Unfortunately Tcl doesn't export a
765 way for the user to do what all its Global* variants do (save and
766 reset the scope pointer, call the local version, restore the saved
767 scope pointer). */
768
Guido van Rossum62320c91998-06-15 04:36:09 +0000769 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000771
Guido van Rossum62320c91998-06-15 04:36:09 +0000772 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000773 if (!cmd)
774 PyErr_SetString(Tkinter_TclError, "merge failed");
775
Guido van Rossum00d93061998-05-28 23:06:38 +0000776 else {
777 int err;
778 ENTER_TCL
779 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000780 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000781 if (err == TCL_ERROR)
782 res = Tkinter_Error(self);
783 else
784 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000785 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000786 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000787
788 if (cmd)
789 ckfree(cmd);
790
791 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000792}
793
794static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000795Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000796{
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000798 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000799 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000800
Guido van Rossum43713e52000-02-29 13:59:29 +0000801 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000802 return NULL;
803
Guido van Rossum00d93061998-05-28 23:06:38 +0000804 ENTER_TCL
805 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000806 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000807 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000808 res = Tkinter_Error(self);
809 else
810 res = PyString_FromString(Tkapp_Result(self));
811 LEAVE_OVERLAP_TCL
812 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000813}
814
815static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000816Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000817{
Barry Warsawfa701a81997-01-16 00:15:11 +0000818 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000819 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000820 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000821
Guido van Rossum43713e52000-02-29 13:59:29 +0000822 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000824
Guido van Rossum00d93061998-05-28 23:06:38 +0000825 ENTER_TCL
826 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000827 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000828 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000829 res = Tkinter_Error(self);
830 else
831 res = PyString_FromString(Tkapp_Result(self));
832 LEAVE_OVERLAP_TCL
833 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000834}
835
836static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000837Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000838{
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000840 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000841 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000842
Guido van Rossum43713e52000-02-29 13:59:29 +0000843 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000845
Guido van Rossum00d93061998-05-28 23:06:38 +0000846 ENTER_TCL
847 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000848 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000849 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000850 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000851
Guido van Rossum62320c91998-06-15 04:36:09 +0000852 else
853 res = PyString_FromString(Tkapp_Result(self));
854 LEAVE_OVERLAP_TCL
855 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000856}
857
858static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000859Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000860{
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000862 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000863 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000864
Guido van Rossum35d43371997-08-02 00:09:09 +0000865 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000866 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000867
Guido van Rossum00d93061998-05-28 23:06:38 +0000868 ENTER_TCL
869 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000870 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000871 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000872 res = Tkinter_Error(self);
873 else
874 res = PyString_FromString(Tkapp_Result(self));
875 LEAVE_OVERLAP_TCL
876 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000877}
878
879static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000880Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000881{
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000883
Guido van Rossum43713e52000-02-29 13:59:29 +0000884 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000885 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000886 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000888 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000889
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 Py_INCREF(Py_None);
891 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000892}
893
Barry Warsawfa701a81997-01-16 00:15:11 +0000894
895
Guido van Rossum18468821994-06-20 07:49:28 +0000896/** Tcl Variable **/
897
898static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000899SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000900{
Guido van Rossum00d93061998-05-28 23:06:38 +0000901 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000902 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000903 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000904
Guido van Rossum62320c91998-06-15 04:36:09 +0000905 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000906 if (!tmp)
907 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Guido van Rossum43713e52000-02-29 13:59:29 +0000909 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000911 s = AsString(newValue, tmp);
912 ENTER_TCL
913 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
914 LEAVE_TCL
915 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000917 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000918 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000919 s = AsString (newValue, tmp);
920 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000921 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000922 s, flags);
923 LEAVE_TCL
924 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000925 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000926 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000927 return NULL;
928 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000930 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000931
Barry Warsawfa701a81997-01-16 00:15:11 +0000932 if (!ok)
933 return Tkinter_Error(self);
934
935 Py_INCREF(Py_None);
936 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000937}
938
939static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000940Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000941{
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000943}
944
945static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000946Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000947{
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000949}
950
Barry Warsawfa701a81997-01-16 00:15:11 +0000951
952
Guido van Rossum18468821994-06-20 07:49:28 +0000953static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000954GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000955{
Guido van Rossum35d43371997-08-02 00:09:09 +0000956 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000957 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000958
Guido van Rossum43713e52000-02-29 13:59:29 +0000959 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000960 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000961 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000962 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000963 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000964
Barry Warsawfa701a81997-01-16 00:15:11 +0000965 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000966 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000967 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000968
Barry Warsawfa701a81997-01-16 00:15:11 +0000969 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000970 res = Tkinter_Error(self);
971 else
972 res = PyString_FromString(s);
973 LEAVE_OVERLAP_TCL
974 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000975}
976
977static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000978Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000979{
Barry Warsawfa701a81997-01-16 00:15:11 +0000980 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000981}
982
983static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000984Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000985{
Barry Warsawfa701a81997-01-16 00:15:11 +0000986 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000987}
988
Barry Warsawfa701a81997-01-16 00:15:11 +0000989
990
Guido van Rossum18468821994-06-20 07:49:28 +0000991static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000992UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000993{
Guido van Rossum35d43371997-08-02 00:09:09 +0000994 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000995 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000996 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000997
Guido van Rossum43713e52000-02-29 13:59:29 +0000998 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000999 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001000 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001001 if (name2 == NULL)
1002 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1003
1004 else
1005 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001006 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001007
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001009 res = Tkinter_Error(self);
1010 else {
1011 Py_INCREF(Py_None);
1012 res = Py_None;
1013 }
1014 LEAVE_OVERLAP_TCL
1015 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001016}
1017
1018static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001019Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001020{
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001022}
1023
1024static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001025Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001026{
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001028}
1029
Barry Warsawfa701a81997-01-16 00:15:11 +00001030
1031
Guido van Rossum18468821994-06-20 07:49:28 +00001032/** Tcl to Python **/
1033
1034static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001035Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001036{
Barry Warsawfa701a81997-01-16 00:15:11 +00001037 char *s;
1038 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001039
Guido van Rossum43713e52000-02-29 13:59:29 +00001040 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001042 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 return Tkinter_Error(self);
1044 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001045}
1046
1047static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001048Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001049{
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 char *s;
1051 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001052
Guido van Rossum43713e52000-02-29 13:59:29 +00001053 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001055 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 return Tkinter_Error(self);
1057 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001058}
1059
1060static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001061Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001062{
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 char *s;
1064 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001065
Guido van Rossum43713e52000-02-29 13:59:29 +00001066 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001067 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001068 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1069 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001071}
1072
1073static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001074Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001075{
Barry Warsawfa701a81997-01-16 00:15:11 +00001076 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001077 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001078 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001079
Guido van Rossum43713e52000-02-29 13:59:29 +00001080 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001082 ENTER_TCL
1083 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001084 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001085 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001086 res = Tkinter_Error(self);
1087 else
1088 res = Py_BuildValue("s", Tkapp_Result(self));
1089 LEAVE_OVERLAP_TCL
1090 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001091}
1092
1093static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001094Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001095{
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001097 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001098 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001100
Guido van Rossum43713e52000-02-29 13:59:29 +00001101 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001103 ENTER_TCL
1104 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001105 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001106 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001107 res = Tkinter_Error(self);
1108 else
1109 res = Py_BuildValue("l", v);
1110 LEAVE_OVERLAP_TCL
1111 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001112}
1113
1114static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001115Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001116{
Barry Warsawfa701a81997-01-16 00:15:11 +00001117 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001118 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001120 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001121
Guido van Rossum43713e52000-02-29 13:59:29 +00001122 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001124 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001125 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001126 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001127 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001128 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001129 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001130 res = Tkinter_Error(self);
1131 else
1132 res = Py_BuildValue("d", v);
1133 LEAVE_OVERLAP_TCL
1134 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001135}
1136
1137static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001138Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001139{
Barry Warsawfa701a81997-01-16 00:15:11 +00001140 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001141 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001142 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001143 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001144
Guido van Rossum43713e52000-02-29 13:59:29 +00001145 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001146 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001147 ENTER_TCL
1148 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001149 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001150 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001151 res = Tkinter_Error(self);
1152 else
1153 res = Py_BuildValue("i", v);
1154 LEAVE_OVERLAP_TCL
1155 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001156}
1157
Barry Warsawfa701a81997-01-16 00:15:11 +00001158
1159
Guido van Rossum18468821994-06-20 07:49:28 +00001160static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001161Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001162{
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 char *list;
1164 int argc;
1165 char **argv;
1166 PyObject *v;
1167 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001168
Guido van Rossum43713e52000-02-29 13:59:29 +00001169 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001170 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001171
Barry Warsawfa701a81997-01-16 00:15:11 +00001172 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1173 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001174
Barry Warsawfa701a81997-01-16 00:15:11 +00001175 if (!(v = PyTuple_New(argc)))
1176 return NULL;
1177
1178 for (i = 0; i < argc; i++) {
1179 PyObject *s = PyString_FromString(argv[i]);
1180 if (!s || PyTuple_SetItem(v, i, s)) {
1181 Py_DECREF(v);
1182 v = NULL;
1183 goto finally;
1184 }
1185 }
Guido van Rossum18468821994-06-20 07:49:28 +00001186
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 finally:
1188 ckfree(FREECAST argv);
1189 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001190}
1191
1192static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001193Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001194{
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001196
Guido van Rossum43713e52000-02-29 13:59:29 +00001197 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001199 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001200}
1201
1202static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001203Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001204{
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 char *s = Merge(args);
1206 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001207
Barry Warsawfa701a81997-01-16 00:15:11 +00001208 if (s) {
1209 res = PyString_FromString(s);
1210 ckfree(s);
1211 }
1212 else
1213 PyErr_SetString(Tkinter_TclError, "merge failed");
1214
1215 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001216}
1217
Barry Warsawfa701a81997-01-16 00:15:11 +00001218
1219
Guido van Rossum18468821994-06-20 07:49:28 +00001220/** Tcl Command **/
1221
Guido van Rossum00d93061998-05-28 23:06:38 +00001222/* Client data struct */
1223typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001224 PyObject *self;
1225 PyObject *func;
1226} PythonCmd_ClientData;
1227
1228static int
Fred Drake509d79a2000-07-08 04:04:38 +00001229PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001230{
1231 errorInCmd = 1;
1232 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1233 LEAVE_PYTHON
1234 return TCL_ERROR;
1235}
1236
Guido van Rossum18468821994-06-20 07:49:28 +00001237/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 * function or method.
1239 */
Guido van Rossum18468821994-06-20 07:49:28 +00001240static int
Fred Drake509d79a2000-07-08 04:04:38 +00001241PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001242{
Guido van Rossum00d93061998-05-28 23:06:38 +00001243 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 PyObject *self, *func, *arg, *res, *tmp;
1245 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001246
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001247 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001248
Barry Warsawfa701a81997-01-16 00:15:11 +00001249 /* TBD: no error checking here since we know, via the
1250 * Tkapp_CreateCommand() that the client data is a two-tuple
1251 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001252 self = data->self;
1253 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001254
Barry Warsawfa701a81997-01-16 00:15:11 +00001255 /* Create argument list (argv1, ..., argvN) */
1256 if (!(arg = PyTuple_New(argc - 1)))
1257 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001258
Barry Warsawfa701a81997-01-16 00:15:11 +00001259 for (i = 0; i < (argc - 1); i++) {
1260 PyObject *s = PyString_FromString(argv[i + 1]);
1261 if (!s || PyTuple_SetItem(arg, i, s)) {
1262 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001263 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001264 }
1265 }
1266 res = PyEval_CallObject(func, arg);
1267 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001268
Barry Warsawfa701a81997-01-16 00:15:11 +00001269 if (res == NULL)
1270 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001271
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 if (!(tmp = PyList_New(0))) {
1273 Py_DECREF(res);
1274 return PythonCmd_Error(interp);
1275 }
1276
1277 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1278 Py_DECREF(res);
1279 Py_DECREF(tmp);
1280
Guido van Rossum00d93061998-05-28 23:06:38 +00001281 LEAVE_PYTHON
1282
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001284}
1285
1286static void
Fred Drake509d79a2000-07-08 04:04:38 +00001287PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001288{
Guido van Rossum00d93061998-05-28 23:06:38 +00001289 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1290
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001291 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001292 Py_XDECREF(data->self);
1293 Py_XDECREF(data->func);
1294 PyMem_DEL(data);
1295 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001296}
1297
Barry Warsawfa701a81997-01-16 00:15:11 +00001298
1299
Guido van Rossum18468821994-06-20 07:49:28 +00001300static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001301Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001302{
Guido van Rossum00d93061998-05-28 23:06:38 +00001303 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001305 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001306 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001307
Guido van Rossum43713e52000-02-29 13:59:29 +00001308 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001309 return NULL;
1310 if (!PyCallable_Check(func)) {
1311 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 return NULL;
1313 }
Guido van Rossum18468821994-06-20 07:49:28 +00001314
Guido van Rossum00d93061998-05-28 23:06:38 +00001315 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001316 if (!data)
1317 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 Py_XINCREF(self);
1319 Py_XINCREF(func);
1320 data->self = self;
1321 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001322
Guido van Rossum00d93061998-05-28 23:06:38 +00001323 ENTER_TCL
1324 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1325 (ClientData)data, PythonCmdDelete);
1326 LEAVE_TCL
1327 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001328 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001329 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001330 return NULL;
1331 }
Guido van Rossum18468821994-06-20 07:49:28 +00001332
Barry Warsawfa701a81997-01-16 00:15:11 +00001333 Py_INCREF(Py_None);
1334 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001335}
1336
Barry Warsawfa701a81997-01-16 00:15:11 +00001337
1338
Guido van Rossum18468821994-06-20 07:49:28 +00001339static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001340Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001341{
Barry Warsawfa701a81997-01-16 00:15:11 +00001342 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001343 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001344
Guido van Rossum43713e52000-02-29 13:59:29 +00001345 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001346 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001347 ENTER_TCL
1348 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1349 LEAVE_TCL
1350 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1352 return NULL;
1353 }
1354 Py_INCREF(Py_None);
1355 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001356}
1357
Barry Warsawfa701a81997-01-16 00:15:11 +00001358
1359
Guido van Rossum00d93061998-05-28 23:06:38 +00001360#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001361/** File Handler **/
1362
Guido van Rossum00d93061998-05-28 23:06:38 +00001363typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 PyObject *func;
1365 PyObject *file;
1366 int id;
1367 struct _fhcdata *next;
1368} FileHandler_ClientData;
1369
1370static FileHandler_ClientData *HeadFHCD;
1371
1372static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001373NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001374{
1375 FileHandler_ClientData *p;
1376 p = PyMem_NEW(FileHandler_ClientData, 1);
1377 if (p != NULL) {
1378 Py_XINCREF(func);
1379 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001380 p->func = func;
1381 p->file = file;
1382 p->id = id;
1383 p->next = HeadFHCD;
1384 HeadFHCD = p;
1385 }
1386 return p;
1387}
1388
1389static void
Fred Drake509d79a2000-07-08 04:04:38 +00001390DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001391{
1392 FileHandler_ClientData *p, **pp;
1393
1394 pp = &HeadFHCD;
1395 while ((p = *pp) != NULL) {
1396 if (p->id == id) {
1397 *pp = p->next;
1398 Py_XDECREF(p->func);
1399 Py_XDECREF(p->file);
1400 PyMem_DEL(p);
1401 }
1402 else
1403 pp = &p->next;
1404 }
1405}
1406
Guido van Rossuma597dde1995-01-10 20:56:29 +00001407static void
Fred Drake509d79a2000-07-08 04:04:38 +00001408FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001409{
Guido van Rossum00d93061998-05-28 23:06:38 +00001410 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001412
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001413 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001414 func = data->func;
1415 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001416
Barry Warsawfa701a81997-01-16 00:15:11 +00001417 arg = Py_BuildValue("(Oi)", file, (long) mask);
1418 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001419 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001420
1421 if (res == NULL) {
1422 errorInCmd = 1;
1423 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1424 }
1425 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001426 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001427}
1428
Guido van Rossum18468821994-06-20 07:49:28 +00001429static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001430Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1431 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001432{
Guido van Rossum00d93061998-05-28 23:06:38 +00001433 FileHandler_ClientData *data;
1434 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001435 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001436
Guido van Rossum43713e52000-02-29 13:59:29 +00001437 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001439 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001440 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001441 return NULL;
1442 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001443 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return NULL;
1445 }
1446
Guido van Rossuma80649b2000-03-28 20:07:05 +00001447 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001449 return NULL;
1450
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001454 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001455 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001456 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001457}
1458
1459static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001460Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001461{
Barry Warsawfa701a81997-01-16 00:15:11 +00001462 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001463 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001464
Guido van Rossum43713e52000-02-29 13:59:29 +00001465 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001467 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001468 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 return NULL;
1470
Guido van Rossuma80649b2000-03-28 20:07:05 +00001471 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001472
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001474 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001477 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001479}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001480#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001481
Barry Warsawfa701a81997-01-16 00:15:11 +00001482
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001483/**** Tktt Object (timer token) ****/
1484
1485staticforward PyTypeObject Tktt_Type;
1486
Guido van Rossum00d93061998-05-28 23:06:38 +00001487typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001489 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001490 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001491} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001492
1493static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001494Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001495{
Barry Warsawfa701a81997-01-16 00:15:11 +00001496 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001497 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001498
Guido van Rossum43713e52000-02-29 13:59:29 +00001499 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001501 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001502 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001503 v->token = NULL;
1504 }
1505 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001506 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001507 Py_DECREF(func);
1508 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 }
1510 Py_INCREF(Py_None);
1511 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001512}
1513
1514static PyMethodDef Tktt_methods[] =
1515{
Guido van Rossum35d43371997-08-02 00:09:09 +00001516 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001518};
1519
1520static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001521Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001522{
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001524
Guido van Rossumb18618d2000-05-03 23:44:39 +00001525 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 if (v == NULL)
1527 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001528
Guido van Rossum00d93061998-05-28 23:06:38 +00001529 Py_INCREF(func);
1530 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001531 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001532
1533 /* Extra reference, deleted when called or when handler is deleted */
1534 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001535 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001536}
1537
1538static void
Fred Drake509d79a2000-07-08 04:04:38 +00001539Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001540{
Guido van Rossum00d93061998-05-28 23:06:38 +00001541 TkttObject *v = (TkttObject *)self;
1542 PyObject *func = v->func;
1543
1544 Py_XDECREF(func);
1545
Guido van Rossumb18618d2000-05-03 23:44:39 +00001546 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001547}
1548
Guido van Rossum597ac201998-05-12 14:36:19 +00001549static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001550Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001551{
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001553 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001554
Fred Drakea44d3532000-06-30 15:01:00 +00001555 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001556 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001557 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001558}
1559
1560static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001561Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001562{
Barry Warsawfa701a81997-01-16 00:15:11 +00001563 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001564}
1565
1566static PyTypeObject Tktt_Type =
1567{
Guido van Rossum35d43371997-08-02 00:09:09 +00001568 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 0, /*ob_size */
1570 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001571 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 0, /*tp_itemsize */
1573 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001574 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 Tktt_GetAttr, /*tp_getattr */
1576 0, /*tp_setattr */
1577 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001578 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 0, /*tp_as_number */
1580 0, /*tp_as_sequence */
1581 0, /*tp_as_mapping */
1582 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001583};
1584
Barry Warsawfa701a81997-01-16 00:15:11 +00001585
1586
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001587/** Timer Handler **/
1588
1589static void
Fred Drake509d79a2000-07-08 04:04:38 +00001590TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001591{
Guido van Rossum00d93061998-05-28 23:06:38 +00001592 TkttObject *v = (TkttObject *)clientData;
1593 PyObject *func = v->func;
1594 PyObject *res;
1595
1596 if (func == NULL)
1597 return;
1598
1599 v->func = NULL;
1600
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001601 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001602
1603 res = PyEval_CallObject(func, NULL);
1604 Py_DECREF(func);
1605 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001606
Barry Warsawfa701a81997-01-16 00:15:11 +00001607 if (res == NULL) {
1608 errorInCmd = 1;
1609 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1610 }
1611 else
1612 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001613
1614 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001615}
1616
1617static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001618Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001619{
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 int milliseconds;
1621 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001622 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001623
Guido van Rossum43713e52000-02-29 13:59:29 +00001624 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001625 return NULL;
1626 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001627 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001628 return NULL;
1629 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001630 v = Tktt_New(func);
1631 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1632 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001633
Guido van Rossum00d93061998-05-28 23:06:38 +00001634 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001635}
1636
Barry Warsawfa701a81997-01-16 00:15:11 +00001637
Guido van Rossum18468821994-06-20 07:49:28 +00001638/** Event Loop **/
1639
Guido van Rossum18468821994-06-20 07:49:28 +00001640static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001641Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001642{
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001644#ifdef WITH_THREAD
1645 PyThreadState *tstate = PyThreadState_Get();
1646#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001647
Guido van Rossum43713e52000-02-29 13:59:29 +00001648 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001650
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 quitMainLoop = 0;
1652 while (Tk_GetNumMainWindows() > threshold &&
1653 !quitMainLoop &&
1654 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001655 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001656 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001657
1658#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001659 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001660 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001661 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001662 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001663 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001664 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001665 if (result == 0)
1666 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001667 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001668#else
1669 result = Tcl_DoOneEvent(0);
1670#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001671
Guido van Rossum35d43371997-08-02 00:09:09 +00001672 if (PyErr_CheckSignals() != 0)
1673 return NULL;
1674 if (result < 0)
1675 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001676 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001677 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001678
Barry Warsawfa701a81997-01-16 00:15:11 +00001679 if (errorInCmd) {
1680 errorInCmd = 0;
1681 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1682 excInCmd = valInCmd = trbInCmd = NULL;
1683 return NULL;
1684 }
1685 Py_INCREF(Py_None);
1686 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001687}
1688
1689static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001690Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001691{
Guido van Rossum35d43371997-08-02 00:09:09 +00001692 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001693 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001694
Guido van Rossum43713e52000-02-29 13:59:29 +00001695 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001696 return NULL;
1697
Guido van Rossum00d93061998-05-28 23:06:38 +00001698 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001699 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001700 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001702}
1703
1704static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001705Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001706{
1707
Guido van Rossum43713e52000-02-29 13:59:29 +00001708 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001709 return NULL;
1710
1711 quitMainLoop = 1;
1712 Py_INCREF(Py_None);
1713 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001714}
1715
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001716static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001717Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001718{
1719
Guido van Rossum43713e52000-02-29 13:59:29 +00001720 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001721 return NULL;
1722
1723 return PyInt_FromLong((long)Tkapp_Interp(self));
1724}
1725
Barry Warsawfa701a81997-01-16 00:15:11 +00001726
1727
Guido van Rossum18468821994-06-20 07:49:28 +00001728/**** Tkapp Method List ****/
1729
1730static PyMethodDef Tkapp_methods[] =
1731{
Guido van Rossum35d43371997-08-02 00:09:09 +00001732 {"call", Tkapp_Call, 0},
1733 {"globalcall", Tkapp_GlobalCall, 0},
1734 {"eval", Tkapp_Eval, 1},
1735 {"globaleval", Tkapp_GlobalEval, 1},
1736 {"evalfile", Tkapp_EvalFile, 1},
1737 {"record", Tkapp_Record, 1},
1738 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1739 {"setvar", Tkapp_SetVar, 1},
1740 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1741 {"getvar", Tkapp_GetVar, 1},
1742 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1743 {"unsetvar", Tkapp_UnsetVar, 1},
1744 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1745 {"getint", Tkapp_GetInt, 1},
1746 {"getdouble", Tkapp_GetDouble, 1},
1747 {"getboolean", Tkapp_GetBoolean, 1},
1748 {"exprstring", Tkapp_ExprString, 1},
1749 {"exprlong", Tkapp_ExprLong, 1},
1750 {"exprdouble", Tkapp_ExprDouble, 1},
1751 {"exprboolean", Tkapp_ExprBoolean, 1},
1752 {"splitlist", Tkapp_SplitList, 1},
1753 {"split", Tkapp_Split, 1},
1754 {"merge", Tkapp_Merge, 0},
1755 {"createcommand", Tkapp_CreateCommand, 1},
1756 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001757#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001758 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1759 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001760#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001761 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001762 {"mainloop", Tkapp_MainLoop, 1},
1763 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001764 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001765 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001766 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001767};
1768
Barry Warsawfa701a81997-01-16 00:15:11 +00001769
1770
Guido van Rossum18468821994-06-20 07:49:28 +00001771/**** Tkapp Type Methods ****/
1772
1773static void
Fred Drake509d79a2000-07-08 04:04:38 +00001774Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001775{
Guido van Rossum00d93061998-05-28 23:06:38 +00001776 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001777 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001778 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001779 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001780 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001781}
1782
1783static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001784Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001785{
Guido van Rossum35d43371997-08-02 00:09:09 +00001786 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001787}
1788
1789static PyTypeObject Tkapp_Type =
1790{
Guido van Rossum35d43371997-08-02 00:09:09 +00001791 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001792 0, /*ob_size */
1793 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001794 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001795 0, /*tp_itemsize */
1796 Tkapp_Dealloc, /*tp_dealloc */
1797 0, /*tp_print */
1798 Tkapp_GetAttr, /*tp_getattr */
1799 0, /*tp_setattr */
1800 0, /*tp_compare */
1801 0, /*tp_repr */
1802 0, /*tp_as_number */
1803 0, /*tp_as_sequence */
1804 0, /*tp_as_mapping */
1805 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001806};
1807
Barry Warsawfa701a81997-01-16 00:15:11 +00001808
1809
Guido van Rossum18468821994-06-20 07:49:28 +00001810/**** Tkinter Module ****/
1811
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001812typedef struct {
1813 PyObject* tuple;
1814 int size; /* current size */
1815 int maxsize; /* allocated size */
1816} FlattenContext;
1817
1818static int
1819_bump(FlattenContext* context, int size)
1820{
1821 /* expand tuple to hold (at least) size new items. return true if
1822 successful, false if an exception was raised*/
1823
1824 int maxsize = context->maxsize * 2;
1825
1826 if (maxsize < context->size + size)
1827 maxsize = context->size + size;
1828
1829 context->maxsize = maxsize;
1830
1831 return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0;
1832}
1833
1834static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001835_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001836{
1837 /* add tuple or list to argument tuple (recursively) */
1838
1839 int i, size;
1840
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001841 if (depth > 1000) {
1842 PyErr_SetString(PyExc_ValueError,"nesting too deep in _flatten");
1843 return 0;
1844 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001845 size = PyList_GET_SIZE(item);
1846 /* preallocate (assume no nesting) */
1847 if (context->size + size > context->maxsize && !_bump(context, size))
1848 return 0;
1849 /* copy items to output tuple */
1850 for (i = 0; i < size; i++) {
1851 PyObject *o = PyList_GET_ITEM(item, i);
1852 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001853 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001854 return 0;
1855 } else if (o != Py_None) {
1856 if (context->size + 1 > context->maxsize && !_bump(context, 1))
1857 return 0;
1858 Py_INCREF(o);
1859 PyTuple_SET_ITEM(context->tuple, context->size++, o);
1860 }
1861 }
1862 } else if (PyTuple_Check(item)) {
1863 /* same, for tuples */
1864 size = PyTuple_GET_SIZE(item);
1865 if (context->size + size > context->maxsize && !_bump(context, size))
1866 return 0;
1867 for (i = 0; i < size; i++) {
1868 PyObject *o = PyTuple_GET_ITEM(item, i);
1869 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001870 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001871 return 0;
1872 } else if (o != Py_None) {
1873 if (context->size + 1 > context->maxsize && !_bump(context, 1))
1874 return 0;
1875 Py_INCREF(o);
1876 PyTuple_SET_ITEM(context->tuple, context->size++, o);
1877 }
1878 }
1879 } else {
1880 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1881 return 0;
1882 }
1883 return 1;
1884}
1885
1886static PyObject *
1887Tkinter_Flatten(PyObject* self, PyObject* args)
1888{
1889 FlattenContext context;
1890 PyObject* item;
1891
1892 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1893 return NULL;
1894
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001895 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001896 if (context.maxsize <= 0)
1897 return PyTuple_New(0);
1898
1899 context.tuple = PyTuple_New(context.maxsize);
1900 if (!context.tuple)
1901 return NULL;
1902
1903 context.size = 0;
1904
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001905 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001906 return NULL;
1907
1908 if (_PyTuple_Resize(&context.tuple, context.size, 0))
1909 return NULL;
1910
1911 return context.tuple;
1912}
1913
Guido van Rossum18468821994-06-20 07:49:28 +00001914static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001915Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001916{
Barry Warsawfa701a81997-01-16 00:15:11 +00001917 char *screenName = NULL;
1918 char *baseName = NULL;
1919 char *className = NULL;
1920 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001921
Guido van Rossum35d43371997-08-02 00:09:09 +00001922 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001923 if (baseName != NULL)
1924 baseName++;
1925 else
1926 baseName = Py_GetProgramName();
1927 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001928
Guido van Rossum43713e52000-02-29 13:59:29 +00001929 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001930 &screenName, &baseName, &className,
1931 &interactive))
1932 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001933
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 return (PyObject *) Tkapp_New(screenName, baseName, className,
1935 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001936}
1937
1938static PyMethodDef moduleMethods[] =
1939{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001940 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001941 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001942#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001943 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1944 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001945#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001946 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001947 {"mainloop", Tkapp_MainLoop, 1},
1948 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001949 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001950 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001951};
1952
Guido van Rossum7bf15641998-05-22 18:28:17 +00001953#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001954
1955static int stdin_ready = 0;
1956
Guido van Rossumad4db171998-06-13 13:56:28 +00001957#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001958static void
Fred Drake509d79a2000-07-08 04:04:38 +00001959MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001960{
1961 stdin_ready = 1;
1962}
Guido van Rossumad4db171998-06-13 13:56:28 +00001963#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001964
Guido van Rossum00d93061998-05-28 23:06:38 +00001965static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001966
Guido van Rossum18468821994-06-20 07:49:28 +00001967static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001968EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00001969{
Guido van Rossumad4db171998-06-13 13:56:28 +00001970#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001971 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001972#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001973#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001974 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001975#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001976 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001977 errorInCmd = 0;
1978#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001979 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001980 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001981#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001982 while (!errorInCmd && !stdin_ready) {
1983 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001984#ifdef MS_WINDOWS
1985 if (_kbhit()) {
1986 stdin_ready = 1;
1987 break;
1988 }
1989#endif
1990#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001991 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001992 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001993 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001994
Guido van Rossum00d93061998-05-28 23:06:38 +00001995 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001996
1997 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001998 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001999 if (result == 0)
2000 Sleep(20);
2001 Py_END_ALLOW_THREADS
2002#else
2003 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002004#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002005
2006 if (result < 0)
2007 break;
2008 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002009#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002010 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002011#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002012 if (errorInCmd) {
2013 errorInCmd = 0;
2014 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2015 excInCmd = valInCmd = trbInCmd = NULL;
2016 PyErr_Print();
2017 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002018#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002019 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002020#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002021 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002022}
Guido van Rossum18468821994-06-20 07:49:28 +00002023
Guido van Rossum00d93061998-05-28 23:06:38 +00002024#endif
2025
Guido van Rossum7bf15641998-05-22 18:28:17 +00002026static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002027EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002028{
Guido van Rossum00d93061998-05-28 23:06:38 +00002029#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002030 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002031#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002032 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002033#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002034 PyOS_InputHook = EventHook;
2035 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002036#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002037}
2038
2039static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002040DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002041{
Guido van Rossum00d93061998-05-28 23:06:38 +00002042#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002043 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2044 PyOS_InputHook = NULL;
2045 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002046#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002047}
2048
Barry Warsawfa701a81997-01-16 00:15:11 +00002049
2050/* all errors will be checked in one fell swoop in init_tkinter() */
2051static void
Fred Drake509d79a2000-07-08 04:04:38 +00002052ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002053{
2054 PyObject *v = PyInt_FromLong(val);
2055 if (v) {
2056 PyDict_SetItemString(d, name, v);
2057 Py_DECREF(v);
2058 }
2059}
2060static void
Fred Drake509d79a2000-07-08 04:04:38 +00002061ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002062{
2063 PyObject *v = PyString_FromString(val);
2064 if (v) {
2065 PyDict_SetItemString(d, name, v);
2066 Py_DECREF(v);
2067 }
2068}
2069
2070
Guido van Rossum3886bb61998-12-04 18:50:17 +00002071DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002072init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002073{
Barry Warsawfa701a81997-01-16 00:15:11 +00002074 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002075
Barry Warsawfa701a81997-01-16 00:15:11 +00002076 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002077
2078#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002079 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002080#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002081
Barry Warsawfa701a81997-01-16 00:15:11 +00002082 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002083
Barry Warsawfa701a81997-01-16 00:15:11 +00002084 d = PyModule_GetDict(m);
2085 Tkinter_TclError = Py_BuildValue("s", "TclError");
2086 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002087
Guido van Rossum35d43371997-08-02 00:09:09 +00002088 ins_long(d, "READABLE", TCL_READABLE);
2089 ins_long(d, "WRITABLE", TCL_WRITABLE);
2090 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2091 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2092 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2093 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2094 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2095 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2096 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002097 ins_string(d, "TK_VERSION", TK_VERSION);
2098 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002099
Guido van Rossum83551bf1997-09-13 00:44:23 +00002100 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002101
2102 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002103 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2104
Guido van Rossume187b0e2000-03-27 21:46:29 +00002105 /* This helps the dynamic loader; in Unicode aware Tcl versions
2106 it also helps Tcl find its encodings. */
2107 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002108
Barry Warsawfa701a81997-01-16 00:15:11 +00002109 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002110 return;
2111
Guido van Rossum43ff8681998-07-14 18:02:13 +00002112#if 0
2113 /* This was not a good idea; through <Destroy> bindings,
2114 Tcl_Finalize() may invoke Python code but at that point the
2115 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002116 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002117#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002118
Jack Jansen34cc5c31995-10-31 16:15:12 +00002119#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002120 /*
2121 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2122 ** Most of the initializations in that routine (toolbox init calls and
2123 ** such) have already been done for us, so we only need these.
2124 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002125 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002126
2127 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002128#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002129 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002130#endif /* GENERATINGCFM */
2131#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002132}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002133
Guido van Rossumec22c921996-02-25 04:50:29 +00002134
Barry Warsawfa701a81997-01-16 00:15:11 +00002135
Guido van Rossum9722ad81995-09-22 23:49:28 +00002136#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002137
2138/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002139** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002140*/
2141
Guido van Rossum9722ad81995-09-22 23:49:28 +00002142void
2143panic(char * format, ...)
2144{
Barry Warsawfa701a81997-01-16 00:15:11 +00002145 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002146
Barry Warsawfa701a81997-01-16 00:15:11 +00002147 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002148
Guido van Rossum227cf761998-08-05 13:53:32 +00002149 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002150 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002151
Barry Warsawfa701a81997-01-16 00:15:11 +00002152 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002153
Barry Warsawfa701a81997-01-16 00:15:11 +00002154 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002155}
Jack Jansen40b546d1995-11-14 10:34:45 +00002156
Guido van Rossumec22c921996-02-25 04:50:29 +00002157/*
2158** Pass events to SIOUX before passing them to Tk.
2159*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002160
Guido van Rossumec22c921996-02-25 04:50:29 +00002161static int
Fred Drake509d79a2000-07-08 04:04:38 +00002162PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002163{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002164 WindowPtr frontwin;
2165 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002166 ** Sioux eats too many events, so we don't pass it everything. We
2167 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002168 ** the Sioux window is frontmost. This means that Tk menus don't work
2169 ** in that case, but at least we can scroll the sioux window.
2170 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2171 ** part of the external interface of Sioux...
2172 */
2173 frontwin = FrontWindow();
2174 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2175 if (SIOUXHandleOneEvent(eventPtr))
2176 return 0; /* Nothing happened to the Tcl event queue */
2177 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002178 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002179}
2180
Guido van Rossumec22c921996-02-25 04:50:29 +00002181#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002182
2183/*
2184** Additional Mac specific code for dealing with shared libraries.
2185*/
2186
2187#include <Resources.h>
2188#include <CodeFragments.h>
2189
2190static int loaded_from_shlib = 0;
2191static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002192
Jack Jansen34cc5c31995-10-31 16:15:12 +00002193/*
2194** If this module is dynamically loaded the following routine should
2195** be the init routine. It takes care of adding the shared library to
2196** the resource-file chain, so that the tk routines can find their
2197** resources.
2198*/
2199OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002200init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002201{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002202 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002203 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002204 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002205 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2206 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002207 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002208 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2209 loaded_from_shlib = 1;
2210 }
2211 return noErr;
2212}
2213
2214/*
2215** Insert the library resources into the search path. Put them after
2216** the resources from the application. Again, we ignore errors.
2217*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002218static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002219mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002220{
2221 if ( !loaded_from_shlib )
2222 return;
2223 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2224}
2225
Guido van Rossumec22c921996-02-25 04:50:29 +00002226#endif /* GENERATINGCFM */
2227#endif /* macintosh */