blob: f20a1effdf2d2322de40f747a5cfc42b01f2e706 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Guido van Rossuma80649b2000-03-28 20:07:05 +000012 Only Tcl/Tk 8.0 and later are supported. Older versions are not
13 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
14 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
19 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
20 intelligent mappings between Python objects and Tcl objects (e.g. ints,
21 floats and Tcl window pointers could be handled specially).
22
23 - Register a new Tcl type, "Python callable", which can be called more
24 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
25
Guido van Rossum7ffa7611996-08-13 21:10:16 +000026*/
27
Guido van Rossum35d43371997-08-02 00:09:09 +000028
Guido van Rossum9722ad81995-09-22 23:49:28 +000029#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000030#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000031
Guido van Rossum00d93061998-05-28 23:06:38 +000032#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000033#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000034#endif
35
Guido van Rossum2a5119b1998-05-29 01:28:40 +000036#ifdef MS_WINDOWS
37#include <windows.h>
38#endif
39
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000040#ifdef macintosh
41#define MAC_TCL
Guido van Rossum49b56061998-10-01 20:42:43 +000042#endif
43
Guido van Rossum18468821994-06-20 07:49:28 +000044#include <tcl.h>
45#include <tk.h>
46
Guido van Rossum3e819a71997-08-01 19:29:02 +000047#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
48
Guido van Rossuma80649b2000-03-28 20:07:05 +000049#if TKMAJORMINOR < 8000
50#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000051#endif
52
Guido van Rossuma80649b2000-03-28 20:07:05 +000053#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000054/* Sigh, we have to include this to get at the tcl qd pointer */
55#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000056/* And this one we need to clear the menu bar */
57#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000058#endif
59
Jack Jansen84c10b12001-07-16 19:32:52 +000060#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
61/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000062#define HAVE_CREATEFILEHANDLER
63#endif
64
Guido van Rossum00d93061998-05-28 23:06:38 +000065#ifdef HAVE_CREATEFILEHANDLER
66
67/* Tcl_CreateFileHandler() changed several times; these macros deal with the
68 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
69 Unix, only because Jack added it back); when available on Windows, it only
70 applies to sockets. */
71
Guido van Rossum7bf15641998-05-22 18:28:17 +000072#ifdef MS_WINDOWS
73#define FHANDLETYPE TCL_WIN_SOCKET
74#else
75#define FHANDLETYPE TCL_UNIX_FD
76#endif
77
Guido van Rossum00d93061998-05-28 23:06:38 +000078/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
79 which uses this to handle Tcl events while the user is typing commands. */
80
81#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000082#define WAIT_FOR_STDIN
83#endif
84
Guido van Rossum00d93061998-05-28 23:06:38 +000085#endif /* HAVE_CREATEFILEHANDLER */
86
Guido van Rossumad4db171998-06-13 13:56:28 +000087#ifdef MS_WINDOWS
88#include <conio.h>
89#define WAIT_FOR_STDIN
90#endif
91
Guido van Rossum00d93061998-05-28 23:06:38 +000092#ifdef WITH_THREAD
93
94/* The threading situation is complicated. Tcl is not thread-safe, except for
95 Tcl 8.1, which will probably remain in alpha status for another 6 months
96 (and the README says that Tk will probably remain thread-unsafe forever).
97 So we need to use a lock around all uses of Tcl. Previously, the Python
98 interpreter lock was used for this. However, this causes problems when
99 other Python threads need to run while Tcl is blocked waiting for events.
100
101 To solve this problem, a separate lock for Tcl is introduced. Holding it
102 is incompatible with holding Python's interpreter lock. The following four
103 macros manipulate both locks together.
104
105 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
106 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
107 that could call an event handler, or otherwise affect the state of a Tcl
108 interpreter. These assume that the surrounding code has the Python
109 interpreter lock; inside the brackets, the Python interpreter lock has been
110 released and the lock for Tcl has been acquired.
111
Guido van Rossum5e977831998-06-15 14:03:52 +0000112 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
113 (For example, when transferring data from the Tcl interpreter result to a
114 Python string object.) This can be done by using different macros to close
115 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
116 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
117 releases the Tcl lock.
118
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000119 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000120 handlers when the handler needs to use Python. Such event handlers are
121 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000122 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000123 the Python interpreter lock, restoring the appropriate thread state, and
124 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
125 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000126 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000127
128 These locks expand to several statements and brackets; they should not be
129 used in branches of if statements and the like.
130
131*/
132
Guido van Rossum65d5b571998-12-21 19:32:43 +0000133static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000134static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000135
136#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000137 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000138 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000139
140#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000141 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000142
Guido van Rossum62320c91998-06-15 04:36:09 +0000143#define ENTER_OVERLAP \
144 Py_END_ALLOW_THREADS
145
146#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000147 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000148
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000149#define ENTER_PYTHON \
150 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000151 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000152
153#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000154 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157#else
158
159#define ENTER_TCL
160#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000161#define ENTER_OVERLAP
162#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000164#define LEAVE_PYTHON
165
166#endif
167
Guido van Rossumec22c921996-02-25 04:50:29 +0000168#ifdef macintosh
169
170/*
171** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000172** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000173*/
174
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000175/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000176#define FREECAST (char *)
177
Guido van Rossumec22c921996-02-25 04:50:29 +0000178#include <Events.h> /* For EventRecord */
179
Fred Drake509d79a2000-07-08 04:04:38 +0000180typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000181void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
182int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000183
Guido van Rossum2834b972000-10-06 16:58:26 +0000184staticforward int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000185
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000186#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
187 #pragma import on
188#endif
189
190#include <SIOUX.h>
191extern int SIOUXIsAppWindow(WindowPtr);
192
193#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
194 #pragma import reset
195#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000196#endif /* macintosh */
197
Guido van Rossum97867b21996-08-08 19:09:53 +0000198#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000199#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000200#endif
201
Guido van Rossum18468821994-06-20 07:49:28 +0000202/**** Tkapp Object Declaration ****/
203
204staticforward PyTypeObject Tkapp_Type;
205
Guido van Rossum00d93061998-05-28 23:06:38 +0000206typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000207 PyObject_HEAD
208 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000209} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000210
211#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000212#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000213#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000214
Guido van Rossum35d43371997-08-02 00:09:09 +0000215#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000216(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000217
Barry Warsawfa701a81997-01-16 00:15:11 +0000218
219
Guido van Rossum18468821994-06-20 07:49:28 +0000220/**** Error Handling ****/
221
222static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000223static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000224static int errorInCmd = 0;
225static PyObject *excInCmd;
226static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000228
Barry Warsawfa701a81997-01-16 00:15:11 +0000229
230
Guido van Rossum18468821994-06-20 07:49:28 +0000231static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000232Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000233{
Barry Warsawfa701a81997-01-16 00:15:11 +0000234 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
235 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000236}
237
Barry Warsawfa701a81997-01-16 00:15:11 +0000238
Barry Warsawfa701a81997-01-16 00:15:11 +0000239
Guido van Rossum18468821994-06-20 07:49:28 +0000240/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000241
242#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000243#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000244
Guido van Rossum00d93061998-05-28 23:06:38 +0000245/* Millisecond sleep() for Unix platforms. */
246
247static void
Fred Drake509d79a2000-07-08 04:04:38 +0000248Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000249{
250 /* XXX Too bad if you don't have select(). */
251 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000252 t.tv_sec = milli/1000;
253 t.tv_usec = (milli%1000) * 1000;
254 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
255}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000256#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000257#endif /* WITH_THREAD */
258
259
Guido van Rossum18468821994-06-20 07:49:28 +0000260static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000261AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000262{
Guido van Rossum35d43371997-08-02 00:09:09 +0000263 if (PyString_Check(value))
264 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000265 else if (PyUnicode_Check(value)) {
266 PyObject *v = PyUnicode_AsUTF8String(value);
267 if (v == NULL)
268 return NULL;
269 if (PyList_Append(tmp, v) != 0) {
270 Py_DECREF(v);
271 return NULL;
272 }
273 Py_DECREF(v);
274 return PyString_AsString(v);
275 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000276 else {
277 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000278 if (v == NULL)
279 return NULL;
280 if (PyList_Append(tmp, v) != 0) {
281 Py_DECREF(v);
282 return NULL;
283 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000284 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;
Guido van Rossum2834b972000-10-06 16:58:26 +0000301 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 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;
Guido van Rossum2834b972000-10-06 16:58:26 +0000316 if (!(argv[0] = AsString(args, tmp)))
317 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000318 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000319 else {
320 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000321
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000323 argv = (char **)ckalloc(argc * sizeof(char *));
324 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (argv == NULL || fv == NULL) {
326 PyErr_NoMemory();
327 goto finally;
328 }
329 }
330
331 for (i = 0; i < argc; i++) {
332 PyObject *v = PyTuple_GetItem(args, i);
333 if (PyTuple_Check(v)) {
334 fv[i] = 1;
335 if (!(argv[i] = Merge(v)))
336 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000337 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000338 }
339 else if (v == Py_None) {
340 argc = i;
341 break;
342 }
343 else {
344 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000345 if (!(argv[i] = AsString(v, tmp)))
346 goto finally;
347 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000348 }
349 }
Guido van Rossum18468821994-06-20 07:49:28 +0000350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000352 if (res == NULL)
353 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000356 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 if (fv[i]) {
358 ckfree(argv[i]);
359 }
360 if (argv != argvStore)
361 ckfree(FREECAST argv);
362 if (fv != fvStore)
363 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000364
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 Py_DECREF(tmp);
366 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000372Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000373{
Barry Warsawfa701a81997-01-16 00:15:11 +0000374 int argc;
375 char **argv;
376 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000377
Barry Warsawfa701a81997-01-16 00:15:11 +0000378 if (list == NULL) {
379 Py_INCREF(Py_None);
380 return Py_None;
381 }
Guido van Rossum18468821994-06-20 07:49:28 +0000382
Guido van Rossum00d93061998-05-28 23:06:38 +0000383 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 /* Not a list.
385 * Could be a quoted string containing funnies, e.g. {"}.
386 * Return the string itself.
387 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 return PyString_FromString(list);
389 }
Guido van Rossum18468821994-06-20 07:49:28 +0000390
Barry Warsawfa701a81997-01-16 00:15:11 +0000391 if (argc == 0)
392 v = PyString_FromString("");
393 else if (argc == 1)
394 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000395 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 int i;
397 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000400 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000401 Py_DECREF(v);
402 v = NULL;
403 break;
404 }
405 PyTuple_SetItem(v, i, w);
406 }
407 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000408 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000410}
411
Barry Warsawfa701a81997-01-16 00:15:11 +0000412
413
Guido van Rossum18468821994-06-20 07:49:28 +0000414/**** Tkapp Object ****/
415
416#ifndef WITH_APPINIT
417int
Fred Drake509d79a2000-07-08 04:04:38 +0000418Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000419{
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000421
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 main = Tk_MainWindow(interp);
423 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000424 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return TCL_ERROR;
426 }
427 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000428 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000429 return TCL_ERROR;
430 }
431 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000432}
433#endif /* !WITH_APPINIT */
434
Guido van Rossum18468821994-06-20 07:49:28 +0000435
Barry Warsawfa701a81997-01-16 00:15:11 +0000436
437
438/* Initialize the Tk application; see the `main' function in
439 * `tkMain.c'.
440 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000441
Thomas Wouters58d05102000-07-24 14:43:35 +0000442static void EnableEventHook(void); /* Forward */
443static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000444
Barry Warsawfa701a81997-01-16 00:15:11 +0000445static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000446Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000447{
448 TkappObject *v;
449 char *argv0;
450
Guido van Rossumb18618d2000-05-03 23:44:39 +0000451 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 if (v == NULL)
453 return NULL;
454
455 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000456
Guido van Rossuma80649b2000-03-28 20:07:05 +0000457#if defined(macintosh)
458 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000459 ClearMenuBar();
460 TkMacInitMenus(v->interp);
461#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000462 /* Delete the 'exit' command, which can screw things up */
463 Tcl_DeleteCommand(v->interp, "exit");
464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 if (screenName != NULL)
466 Tcl_SetVar2(v->interp, "env", "DISPLAY",
467 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 if (interactive)
470 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
471 else
472 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000473
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 /* This is used to get the application class for Tk 4.1 and up */
475 argv0 = (char*)ckalloc(strlen(className) + 1);
476 if (!argv0) {
477 PyErr_NoMemory();
478 Py_DECREF(v);
479 return NULL;
480 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000481
Barry Warsawfa701a81997-01-16 00:15:11 +0000482 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000483 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 argv0[0] = tolower(argv0[0]);
485 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
486 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000489 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000490
Guido van Rossum7bf15641998-05-22 18:28:17 +0000491 EnableEventHook();
492
Barry Warsawfa701a81997-01-16 00:15:11 +0000493 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000494}
495
Barry Warsawfa701a81997-01-16 00:15:11 +0000496
497
Guido van Rossum18468821994-06-20 07:49:28 +0000498/** Tcl Eval **/
499
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000500#if TKMAJORMINOR >= 8001
501#define USING_OBJECTS
502#endif
503
504#ifdef USING_OBJECTS
505
506static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000507AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000508{
509 Tcl_Obj *result;
510
511 if (PyString_Check(value))
512 return Tcl_NewStringObj(PyString_AS_STRING(value),
513 PyString_GET_SIZE(value));
514 else if (PyInt_Check(value))
515 return Tcl_NewLongObj(PyInt_AS_LONG(value));
516 else if (PyFloat_Check(value))
517 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
518 else if (PyTuple_Check(value)) {
519 Tcl_Obj **argv = (Tcl_Obj**)
520 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
521 int i;
522 if(!argv)
523 return 0;
524 for(i=0;i<PyTuple_Size(value);i++)
525 argv[i] = AsObj(PyTuple_GetItem(value,i));
526 result = Tcl_NewListObj(PyTuple_Size(value), argv);
527 ckfree(FREECAST argv);
528 return result;
529 }
530 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000531#if TKMAJORMINOR <= 8001
532 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000533 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000534 if (!utf8)
535 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000536 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
537 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000538 Py_DECREF(utf8);
539 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000540#else /* TKMAJORMINOR > 8001 */
541 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
542 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
543 /* XXX Should really test this at compile time */
544 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000545 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000546 return 0;
547 }
548 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
549 PyUnicode_GET_SIZE(value));
550#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000551 }
552 else {
553 PyObject *v = PyObject_Str(value);
554 if (!v)
555 return 0;
556 result = AsObj(v);
557 Py_DECREF(v);
558 return result;
559 }
560}
561
Guido van Rossum18468821994-06-20 07:49:28 +0000562static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000563Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000564{
Guido van Rossum632de272000-03-29 00:19:50 +0000565 Tcl_Obj *objStore[ARGSZ];
566 Tcl_Obj **objv = NULL;
567 int objc = 0, i;
568 PyObject *res = NULL;
569 Tcl_Interp *interp = Tkapp_Interp(self);
570 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
571 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000572
Guido van Rossum632de272000-03-29 00:19:50 +0000573 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000574
Guido van Rossum212643f1998-04-29 16:22:14 +0000575 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000576 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000577
Guido van Rossum212643f1998-04-29 16:22:14 +0000578 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000579 objv[0] = AsObj(args);
580 if (objv[0] == 0)
581 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000582 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000583 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 }
585 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000586 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000587
Guido van Rossum632de272000-03-29 00:19:50 +0000588 if (objc > ARGSZ) {
589 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
590 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000591 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000592 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 goto finally;
594 }
595 }
596
Guido van Rossum632de272000-03-29 00:19:50 +0000597 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000598 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000599 if (v == Py_None) {
600 objc = i;
601 break;
602 }
Guido van Rossum632de272000-03-29 00:19:50 +0000603 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000604 if (!objv[i]) {
605 /* Reset objc, so it attempts to clear
606 objects only up to i. */
607 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000608 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000609 }
Guido van Rossum632de272000-03-29 00:19:50 +0000610 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000611 }
612 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000613
Guido van Rossum62320c91998-06-15 04:36:09 +0000614 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000615
616 i = Tcl_EvalObjv(interp, objc, objv, flags);
617
Guido van Rossum62320c91998-06-15 04:36:09 +0000618 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000619 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000620 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000621 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000622 /* We could request the object result here, but doing
623 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000624 char *s = Tcl_GetStringResult(interp);
625 char *p = s;
626 /* If the result contains any bytes with the top bit set,
627 it's UTF-8 and we should decode it to Unicode */
628 while (*p != '\0') {
629 if (*p & 0x80)
630 break;
631 p++;
632 }
633 if (*p == '\0')
634 res = PyString_FromStringAndSize(s, (int)(p-s));
635 else {
636 /* Convert UTF-8 to Unicode string */
637 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000638 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
639 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000640 PyErr_Clear();
641 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000642 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000643 }
644 }
Guido van Rossum632de272000-03-29 00:19:50 +0000645
Guido van Rossum62320c91998-06-15 04:36:09 +0000646 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000647
Guido van Rossum212643f1998-04-29 16:22:14 +0000648 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000649 for (i = 0; i < objc; i++)
650 Tcl_DecrRefCount(objv[i]);
651 if (objv != objStore)
652 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000653 return res;
654}
655
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000656#else /* !USING_OBJECTS */
657
658static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000659Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000660{
661 /* This is copied from Merge() */
662 PyObject *tmp = NULL;
663 char *argvStore[ARGSZ];
664 char **argv = NULL;
665 int fvStore[ARGSZ];
666 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000667 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000668 PyObject *res = NULL; /* except this has a different type */
669 Tcl_CmdInfo info; /* and this is added */
670 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
671
672 if (!(tmp = PyList_New(0)))
673 return NULL;
674
675 argv = argvStore;
676 fv = fvStore;
677
678 if (args == NULL)
679 argc = 0;
680
681 else if (!PyTuple_Check(args)) {
682 argc = 1;
683 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000684 if (!(argv[0] = AsString(args, tmp)))
685 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000686 }
687 else {
688 argc = PyTuple_Size(args);
689
690 if (argc > ARGSZ) {
691 argv = (char **)ckalloc(argc * sizeof(char *));
692 fv = (int *)ckalloc(argc * sizeof(int));
693 if (argv == NULL || fv == NULL) {
694 PyErr_NoMemory();
695 goto finally;
696 }
697 }
698
699 for (i = 0; i < argc; i++) {
700 PyObject *v = PyTuple_GetItem(args, i);
701 if (PyTuple_Check(v)) {
702 fv[i] = 1;
703 if (!(argv[i] = Merge(v)))
704 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000705 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000706 }
707 else if (v == Py_None) {
708 argc = i;
709 break;
710 }
711 else {
712 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000713 if (!(argv[i] = AsString(v, tmp)))
714 goto finally;
715 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000716 }
717 }
718 }
719 /* End code copied from Merge() */
720
721 /* All this to avoid a call to Tcl_Merge() and the corresponding call
722 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
723 if (Py_VerboseFlag >= 2) {
724 for (i = 0; i < argc; i++)
725 PySys_WriteStderr("%s ", argv[i]);
726 }
727 ENTER_TCL
728 info.proc = NULL;
729 if (argc < 1 ||
730 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
731 info.proc == NULL)
732 {
733 char *cmd;
734 cmd = Tcl_Merge(argc, argv);
735 i = Tcl_Eval(interp, cmd);
736 ckfree(cmd);
737 }
738 else {
739 Tcl_ResetResult(interp);
740 i = (*info.proc)(info.clientData, interp, argc, argv);
741 }
742 ENTER_OVERLAP
743 if (info.proc == NULL && Py_VerboseFlag >= 2)
744 PySys_WriteStderr("... use TclEval ");
745 if (i == TCL_ERROR) {
746 if (Py_VerboseFlag >= 2)
747 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000748 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000749 Tkinter_Error(self);
750 }
751 else {
752 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000753 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
754 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000755 }
756 LEAVE_OVERLAP_TCL
757
758 /* Copied from Merge() again */
759 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000760 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000761 if (fv[i]) {
762 ckfree(argv[i]);
763 }
764 if (argv != argvStore)
765 ckfree(FREECAST argv);
766 if (fv != fvStore)
767 ckfree(FREECAST fv);
768
769 Py_DECREF(tmp);
770 return res;
771}
772
773#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000774
775static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000776Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000777{
Guido van Rossum212643f1998-04-29 16:22:14 +0000778 /* Could do the same here as for Tkapp_Call(), but this is not used
779 much, so I can't be bothered. Unfortunately Tcl doesn't export a
780 way for the user to do what all its Global* variants do (save and
781 reset the scope pointer, call the local version, restore the saved
782 scope pointer). */
783
Guido van Rossum62320c91998-06-15 04:36:09 +0000784 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000786
Guido van Rossum62320c91998-06-15 04:36:09 +0000787 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000788 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000789 int err;
790 ENTER_TCL
791 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000792 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000793 if (err == TCL_ERROR)
794 res = Tkinter_Error(self);
795 else
796 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000797 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000798 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000799 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000800
801 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000802}
803
804static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000805Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000806{
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000808 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000809 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000810
Guido van Rossum43713e52000-02-29 13:59:29 +0000811 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 return NULL;
813
Guido van Rossum00d93061998-05-28 23:06:38 +0000814 ENTER_TCL
815 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000816 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000817 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000818 res = Tkinter_Error(self);
819 else
820 res = PyString_FromString(Tkapp_Result(self));
821 LEAVE_OVERLAP_TCL
822 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000823}
824
825static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000826Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000827{
Barry Warsawfa701a81997-01-16 00:15:11 +0000828 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000829 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000830 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000831
Guido van Rossum43713e52000-02-29 13:59:29 +0000832 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000833 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000834
Guido van Rossum00d93061998-05-28 23:06:38 +0000835 ENTER_TCL
836 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000837 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000838 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000839 res = Tkinter_Error(self);
840 else
841 res = PyString_FromString(Tkapp_Result(self));
842 LEAVE_OVERLAP_TCL
843 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000844}
845
846static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000847Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000848{
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000850 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000851 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000852
Guido van Rossum43713e52000-02-29 13:59:29 +0000853 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000855
Guido van Rossum00d93061998-05-28 23:06:38 +0000856 ENTER_TCL
857 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000858 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000859 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000860 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000861
Guido van Rossum62320c91998-06-15 04:36:09 +0000862 else
863 res = PyString_FromString(Tkapp_Result(self));
864 LEAVE_OVERLAP_TCL
865 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000866}
867
868static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000869Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000870{
Barry Warsawfa701a81997-01-16 00:15:11 +0000871 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000872 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000873 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000874
Guido van Rossum35d43371997-08-02 00:09:09 +0000875 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000877
Guido van Rossum00d93061998-05-28 23:06:38 +0000878 ENTER_TCL
879 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000880 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000881 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000882 res = Tkinter_Error(self);
883 else
884 res = PyString_FromString(Tkapp_Result(self));
885 LEAVE_OVERLAP_TCL
886 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000887}
888
889static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000890Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000891{
Barry Warsawfa701a81997-01-16 00:15:11 +0000892 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000893
Guido van Rossum43713e52000-02-29 13:59:29 +0000894 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000896 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000897 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000898 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000899
Barry Warsawfa701a81997-01-16 00:15:11 +0000900 Py_INCREF(Py_None);
901 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000902}
903
Barry Warsawfa701a81997-01-16 00:15:11 +0000904
905
Guido van Rossum18468821994-06-20 07:49:28 +0000906/** Tcl Variable **/
907
908static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000909SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000910{
Guido van Rossum00d93061998-05-28 23:06:38 +0000911 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000912 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000913 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000914
Guido van Rossum62320c91998-06-15 04:36:09 +0000915 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 if (!tmp)
917 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000918
Guido van Rossum43713e52000-02-29 13:59:29 +0000919 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000921 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000922 if (s == NULL)
923 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000924 ENTER_TCL
925 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
926 LEAVE_TCL
927 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000929 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000930 if (PyArg_ParseTuple(args, "ssO:setvar",
931 &name1, &name2, &newValue)) {
932 s = AsString(newValue, tmp);
933 if (s == NULL)
934 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000935 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000936 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000937 s, flags);
938 LEAVE_TCL
939 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000940 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000941 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000942 return NULL;
943 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000945 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000946
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 if (!ok)
948 return Tkinter_Error(self);
949
950 Py_INCREF(Py_None);
951 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000952}
953
954static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000955Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000956{
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000958}
959
960static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000961Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000962{
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000964}
965
Barry Warsawfa701a81997-01-16 00:15:11 +0000966
967
Guido van Rossum18468821994-06-20 07:49:28 +0000968static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000969GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000970{
Guido van Rossum35d43371997-08-02 00:09:09 +0000971 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000972 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000973
Guido van Rossum43713e52000-02-29 13:59:29 +0000974 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000975 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000976 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000978 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Barry Warsawfa701a81997-01-16 00:15:11 +0000980 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000982 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000983
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000985 res = Tkinter_Error(self);
986 else
987 res = PyString_FromString(s);
988 LEAVE_OVERLAP_TCL
989 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000990}
991
992static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000993Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000994{
Barry Warsawfa701a81997-01-16 00:15:11 +0000995 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000996}
997
998static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000999Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001000{
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001002}
1003
Barry Warsawfa701a81997-01-16 00:15:11 +00001004
1005
Guido van Rossum18468821994-06-20 07:49:28 +00001006static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001007UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001008{
Guido van Rossum35d43371997-08-02 00:09:09 +00001009 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001010 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001012
Guido van Rossum43713e52000-02-29 13:59:29 +00001013 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001015 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001016 if (name2 == NULL)
1017 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1018
1019 else
1020 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001021 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001022
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001024 res = Tkinter_Error(self);
1025 else {
1026 Py_INCREF(Py_None);
1027 res = Py_None;
1028 }
1029 LEAVE_OVERLAP_TCL
1030 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001031}
1032
1033static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001034Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001035{
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001037}
1038
1039static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001040Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001041{
Barry Warsawfa701a81997-01-16 00:15:11 +00001042 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001043}
1044
Barry Warsawfa701a81997-01-16 00:15:11 +00001045
1046
Guido van Rossum18468821994-06-20 07:49:28 +00001047/** Tcl to Python **/
1048
1049static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001050Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001051{
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 char *s;
1053 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001054
Guido van Rossum43713e52000-02-29 13:59:29 +00001055 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001057 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 return Tkinter_Error(self);
1059 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001060}
1061
1062static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001063Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001064{
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 char *s;
1066 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001067
Guido van Rossum43713e52000-02-29 13:59:29 +00001068 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001070 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 return Tkinter_Error(self);
1072 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001073}
1074
1075static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001076Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001077{
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 char *s;
1079 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001080
Guido van Rossum43713e52000-02-29 13:59:29 +00001081 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001082 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001083 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1084 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001085 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001086}
1087
1088static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001089Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001090{
Barry Warsawfa701a81997-01-16 00:15:11 +00001091 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001092 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001093 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001094
Guido van Rossum43713e52000-02-29 13:59:29 +00001095 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001097 ENTER_TCL
1098 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001099 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001100 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001101 res = Tkinter_Error(self);
1102 else
1103 res = Py_BuildValue("s", Tkapp_Result(self));
1104 LEAVE_OVERLAP_TCL
1105 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001106}
1107
1108static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001109Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001110{
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001112 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001113 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001115
Guido van Rossum43713e52000-02-29 13:59:29 +00001116 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001117 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001118 ENTER_TCL
1119 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001120 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001121 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001122 res = Tkinter_Error(self);
1123 else
1124 res = Py_BuildValue("l", v);
1125 LEAVE_OVERLAP_TCL
1126 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001127}
1128
1129static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001130Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001131{
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001133 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001135 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Guido van Rossum43713e52000-02-29 13:59:29 +00001137 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001139 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001140 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001141 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001142 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001143 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001144 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001145 res = Tkinter_Error(self);
1146 else
1147 res = Py_BuildValue("d", v);
1148 LEAVE_OVERLAP_TCL
1149 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001150}
1151
1152static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001153Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001154{
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001156 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001157 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001159
Guido van Rossum43713e52000-02-29 13:59:29 +00001160 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001162 ENTER_TCL
1163 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001164 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001165 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001166 res = Tkinter_Error(self);
1167 else
1168 res = Py_BuildValue("i", v);
1169 LEAVE_OVERLAP_TCL
1170 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001171}
1172
Barry Warsawfa701a81997-01-16 00:15:11 +00001173
1174
Guido van Rossum18468821994-06-20 07:49:28 +00001175static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001176Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001177{
Barry Warsawfa701a81997-01-16 00:15:11 +00001178 char *list;
1179 int argc;
1180 char **argv;
1181 PyObject *v;
1182 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001183
Guido van Rossum43713e52000-02-29 13:59:29 +00001184 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001186
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1188 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001189
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 if (!(v = PyTuple_New(argc)))
1191 return NULL;
1192
1193 for (i = 0; i < argc; i++) {
1194 PyObject *s = PyString_FromString(argv[i]);
1195 if (!s || PyTuple_SetItem(v, i, s)) {
1196 Py_DECREF(v);
1197 v = NULL;
1198 goto finally;
1199 }
1200 }
Guido van Rossum18468821994-06-20 07:49:28 +00001201
Barry Warsawfa701a81997-01-16 00:15:11 +00001202 finally:
1203 ckfree(FREECAST argv);
1204 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001205}
1206
1207static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001208Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001209{
Barry Warsawfa701a81997-01-16 00:15:11 +00001210 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001211
Guido van Rossum43713e52000-02-29 13:59:29 +00001212 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001213 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001214 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001215}
1216
1217static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001218Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001219{
Barry Warsawfa701a81997-01-16 00:15:11 +00001220 char *s = Merge(args);
1221 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001222
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 if (s) {
1224 res = PyString_FromString(s);
1225 ckfree(s);
1226 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001227
1228 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001229}
1230
Barry Warsawfa701a81997-01-16 00:15:11 +00001231
1232
Guido van Rossum18468821994-06-20 07:49:28 +00001233/** Tcl Command **/
1234
Guido van Rossum00d93061998-05-28 23:06:38 +00001235/* Client data struct */
1236typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001237 PyObject *self;
1238 PyObject *func;
1239} PythonCmd_ClientData;
1240
1241static int
Fred Drake509d79a2000-07-08 04:04:38 +00001242PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001243{
1244 errorInCmd = 1;
1245 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1246 LEAVE_PYTHON
1247 return TCL_ERROR;
1248}
1249
Guido van Rossum18468821994-06-20 07:49:28 +00001250/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 * function or method.
1252 */
Guido van Rossum18468821994-06-20 07:49:28 +00001253static int
Fred Drake509d79a2000-07-08 04:04:38 +00001254PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001255{
Guido van Rossum00d93061998-05-28 23:06:38 +00001256 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001258 int i, rv;
1259 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001260
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001261 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001262
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 /* TBD: no error checking here since we know, via the
1264 * Tkapp_CreateCommand() that the client data is a two-tuple
1265 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001266 self = data->self;
1267 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001268
Barry Warsawfa701a81997-01-16 00:15:11 +00001269 /* Create argument list (argv1, ..., argvN) */
1270 if (!(arg = PyTuple_New(argc - 1)))
1271 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001272
Barry Warsawfa701a81997-01-16 00:15:11 +00001273 for (i = 0; i < (argc - 1); i++) {
1274 PyObject *s = PyString_FromString(argv[i + 1]);
1275 if (!s || PyTuple_SetItem(arg, i, s)) {
1276 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001277 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001278 }
1279 }
1280 res = PyEval_CallObject(func, arg);
1281 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001282
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 if (res == NULL)
1284 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001285
Barry Warsawfa701a81997-01-16 00:15:11 +00001286 if (!(tmp = PyList_New(0))) {
1287 Py_DECREF(res);
1288 return PythonCmd_Error(interp);
1289 }
1290
Guido van Rossum2834b972000-10-06 16:58:26 +00001291 s = AsString(res, tmp);
1292 if (s == NULL) {
1293 rv = PythonCmd_Error(interp);
1294 }
1295 else {
1296 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1297 rv = TCL_OK;
1298 }
1299
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 Py_DECREF(res);
1301 Py_DECREF(tmp);
1302
Guido van Rossum00d93061998-05-28 23:06:38 +00001303 LEAVE_PYTHON
1304
Guido van Rossum2834b972000-10-06 16:58:26 +00001305 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001306}
1307
1308static void
Fred Drake509d79a2000-07-08 04:04:38 +00001309PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001310{
Guido van Rossum00d93061998-05-28 23:06:38 +00001311 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1312
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001313 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001314 Py_XDECREF(data->self);
1315 Py_XDECREF(data->func);
1316 PyMem_DEL(data);
1317 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001318}
1319
Barry Warsawfa701a81997-01-16 00:15:11 +00001320
1321
Guido van Rossum18468821994-06-20 07:49:28 +00001322static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001323Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001324{
Guido van Rossum00d93061998-05-28 23:06:38 +00001325 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001326 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001327 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001328 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001329
Guido van Rossum43713e52000-02-29 13:59:29 +00001330 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001331 return NULL;
1332 if (!PyCallable_Check(func)) {
1333 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 return NULL;
1335 }
Guido van Rossum18468821994-06-20 07:49:28 +00001336
Guido van Rossum00d93061998-05-28 23:06:38 +00001337 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 if (!data)
1339 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001340 Py_XINCREF(self);
1341 Py_XINCREF(func);
1342 data->self = self;
1343 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001344
Guido van Rossum00d93061998-05-28 23:06:38 +00001345 ENTER_TCL
1346 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1347 (ClientData)data, PythonCmdDelete);
1348 LEAVE_TCL
1349 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001350 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001351 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001352 return NULL;
1353 }
Guido van Rossum18468821994-06-20 07:49:28 +00001354
Barry Warsawfa701a81997-01-16 00:15:11 +00001355 Py_INCREF(Py_None);
1356 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001357}
1358
Barry Warsawfa701a81997-01-16 00:15:11 +00001359
1360
Guido van Rossum18468821994-06-20 07:49:28 +00001361static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001362Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001363{
Barry Warsawfa701a81997-01-16 00:15:11 +00001364 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001365 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001366
Guido van Rossum43713e52000-02-29 13:59:29 +00001367 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001369 ENTER_TCL
1370 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1371 LEAVE_TCL
1372 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1374 return NULL;
1375 }
1376 Py_INCREF(Py_None);
1377 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001378}
1379
Barry Warsawfa701a81997-01-16 00:15:11 +00001380
1381
Guido van Rossum00d93061998-05-28 23:06:38 +00001382#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001383/** File Handler **/
1384
Guido van Rossum00d93061998-05-28 23:06:38 +00001385typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001386 PyObject *func;
1387 PyObject *file;
1388 int id;
1389 struct _fhcdata *next;
1390} FileHandler_ClientData;
1391
1392static FileHandler_ClientData *HeadFHCD;
1393
1394static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001395NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001396{
1397 FileHandler_ClientData *p;
1398 p = PyMem_NEW(FileHandler_ClientData, 1);
1399 if (p != NULL) {
1400 Py_XINCREF(func);
1401 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001402 p->func = func;
1403 p->file = file;
1404 p->id = id;
1405 p->next = HeadFHCD;
1406 HeadFHCD = p;
1407 }
1408 return p;
1409}
1410
1411static void
Fred Drake509d79a2000-07-08 04:04:38 +00001412DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001413{
1414 FileHandler_ClientData *p, **pp;
1415
1416 pp = &HeadFHCD;
1417 while ((p = *pp) != NULL) {
1418 if (p->id == id) {
1419 *pp = p->next;
1420 Py_XDECREF(p->func);
1421 Py_XDECREF(p->file);
1422 PyMem_DEL(p);
1423 }
1424 else
1425 pp = &p->next;
1426 }
1427}
1428
Guido van Rossuma597dde1995-01-10 20:56:29 +00001429static void
Fred Drake509d79a2000-07-08 04:04:38 +00001430FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001431{
Guido van Rossum00d93061998-05-28 23:06:38 +00001432 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001434
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001435 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 func = data->func;
1437 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 arg = Py_BuildValue("(Oi)", file, (long) mask);
1440 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001441 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001442
1443 if (res == NULL) {
1444 errorInCmd = 1;
1445 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1446 }
1447 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001449}
1450
Guido van Rossum18468821994-06-20 07:49:28 +00001451static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001452Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1453 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001454{
Guido van Rossum00d93061998-05-28 23:06:38 +00001455 FileHandler_ClientData *data;
1456 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001457 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001458
Guido van Rossum2834b972000-10-06 16:58:26 +00001459 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1460 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001462 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001463 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 return NULL;
1465 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001466 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001467 return NULL;
1468 }
1469
Guido van Rossuma80649b2000-03-28 20:07:05 +00001470 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001471 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 return NULL;
1473
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001475 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001477 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001478 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001480}
1481
1482static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001483Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001484{
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001486 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001487
Guido van Rossum43713e52000-02-29 13:59:29 +00001488 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001490 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001491 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001492 return NULL;
1493
Guido van Rossuma80649b2000-03-28 20:07:05 +00001494 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001495
Barry Warsawfa701a81997-01-16 00:15:11 +00001496 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001497 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001499 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001500 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001501 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001502}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001503#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001504
Barry Warsawfa701a81997-01-16 00:15:11 +00001505
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001506/**** Tktt Object (timer token) ****/
1507
1508staticforward PyTypeObject Tktt_Type;
1509
Guido van Rossum00d93061998-05-28 23:06:38 +00001510typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001512 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001514} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001515
1516static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001517Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001518{
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001520 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001521
Guido van Rossum43713e52000-02-29 13:59:29 +00001522 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001524 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001525 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001526 v->token = NULL;
1527 }
1528 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001530 Py_DECREF(func);
1531 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 }
1533 Py_INCREF(Py_None);
1534 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001535}
1536
1537static PyMethodDef Tktt_methods[] =
1538{
Guido van Rossum35d43371997-08-02 00:09:09 +00001539 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001540 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001541};
1542
1543static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001544Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001545{
Barry Warsawfa701a81997-01-16 00:15:11 +00001546 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001547
Guido van Rossumb18618d2000-05-03 23:44:39 +00001548 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 if (v == NULL)
1550 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001551
Guido van Rossum00d93061998-05-28 23:06:38 +00001552 Py_INCREF(func);
1553 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001554 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001555
1556 /* Extra reference, deleted when called or when handler is deleted */
1557 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001559}
1560
1561static void
Fred Drake509d79a2000-07-08 04:04:38 +00001562Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001563{
Guido van Rossum00d93061998-05-28 23:06:38 +00001564 TkttObject *v = (TkttObject *)self;
1565 PyObject *func = v->func;
1566
1567 Py_XDECREF(func);
1568
Guido van Rossumb18618d2000-05-03 23:44:39 +00001569 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001570}
1571
Guido van Rossum597ac201998-05-12 14:36:19 +00001572static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001573Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001574{
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001576 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001577
Fred Drakea44d3532000-06-30 15:01:00 +00001578 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001580 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001581}
1582
1583static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001584Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001585{
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001587}
1588
1589static PyTypeObject Tktt_Type =
1590{
Guido van Rossum35d43371997-08-02 00:09:09 +00001591 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 0, /*ob_size */
1593 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001594 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001595 0, /*tp_itemsize */
1596 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001597 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001598 Tktt_GetAttr, /*tp_getattr */
1599 0, /*tp_setattr */
1600 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001601 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001602 0, /*tp_as_number */
1603 0, /*tp_as_sequence */
1604 0, /*tp_as_mapping */
1605 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001606};
1607
Barry Warsawfa701a81997-01-16 00:15:11 +00001608
1609
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001610/** Timer Handler **/
1611
1612static void
Fred Drake509d79a2000-07-08 04:04:38 +00001613TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001614{
Guido van Rossum00d93061998-05-28 23:06:38 +00001615 TkttObject *v = (TkttObject *)clientData;
1616 PyObject *func = v->func;
1617 PyObject *res;
1618
1619 if (func == NULL)
1620 return;
1621
1622 v->func = NULL;
1623
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001624 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001625
1626 res = PyEval_CallObject(func, NULL);
1627 Py_DECREF(func);
1628 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001629
Barry Warsawfa701a81997-01-16 00:15:11 +00001630 if (res == NULL) {
1631 errorInCmd = 1;
1632 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1633 }
1634 else
1635 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001636
1637 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001638}
1639
1640static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001641Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001642{
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 int milliseconds;
1644 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001645 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001646
Guido van Rossum2834b972000-10-06 16:58:26 +00001647 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1648 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 return NULL;
1650 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001651 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001652 return NULL;
1653 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001654 v = Tktt_New(func);
1655 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1656 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001657
Guido van Rossum00d93061998-05-28 23:06:38 +00001658 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001659}
1660
Barry Warsawfa701a81997-01-16 00:15:11 +00001661
Guido van Rossum18468821994-06-20 07:49:28 +00001662/** Event Loop **/
1663
Guido van Rossum18468821994-06-20 07:49:28 +00001664static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001665Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001666{
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001668#ifdef WITH_THREAD
1669 PyThreadState *tstate = PyThreadState_Get();
1670#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001671
Guido van Rossum43713e52000-02-29 13:59:29 +00001672 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001673 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001674
Barry Warsawfa701a81997-01-16 00:15:11 +00001675 quitMainLoop = 0;
1676 while (Tk_GetNumMainWindows() > threshold &&
1677 !quitMainLoop &&
1678 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001679 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001680 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001681
1682#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001683 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001684 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001685 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001686 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001687 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001688 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001689 if (result == 0)
1690 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001691 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001692#else
1693 result = Tcl_DoOneEvent(0);
1694#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001695
Guido van Rossum35d43371997-08-02 00:09:09 +00001696 if (PyErr_CheckSignals() != 0)
1697 return NULL;
1698 if (result < 0)
1699 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001700 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001702
Barry Warsawfa701a81997-01-16 00:15:11 +00001703 if (errorInCmd) {
1704 errorInCmd = 0;
1705 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1706 excInCmd = valInCmd = trbInCmd = NULL;
1707 return NULL;
1708 }
1709 Py_INCREF(Py_None);
1710 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001711}
1712
1713static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001714Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001715{
Guido van Rossum35d43371997-08-02 00:09:09 +00001716 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001717 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001718
Guido van Rossum43713e52000-02-29 13:59:29 +00001719 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001720 return NULL;
1721
Guido van Rossum00d93061998-05-28 23:06:38 +00001722 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001723 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001724 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001725 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001726}
1727
1728static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001729Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001730{
1731
Guido van Rossum43713e52000-02-29 13:59:29 +00001732 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001733 return NULL;
1734
1735 quitMainLoop = 1;
1736 Py_INCREF(Py_None);
1737 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001738}
1739
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001740static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001741Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001742{
1743
Guido van Rossum43713e52000-02-29 13:59:29 +00001744 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001745 return NULL;
1746
1747 return PyInt_FromLong((long)Tkapp_Interp(self));
1748}
1749
Barry Warsawfa701a81997-01-16 00:15:11 +00001750
1751
Guido van Rossum18468821994-06-20 07:49:28 +00001752/**** Tkapp Method List ****/
1753
1754static PyMethodDef Tkapp_methods[] =
1755{
Guido van Rossum35d43371997-08-02 00:09:09 +00001756 {"call", Tkapp_Call, 0},
1757 {"globalcall", Tkapp_GlobalCall, 0},
1758 {"eval", Tkapp_Eval, 1},
1759 {"globaleval", Tkapp_GlobalEval, 1},
1760 {"evalfile", Tkapp_EvalFile, 1},
1761 {"record", Tkapp_Record, 1},
1762 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1763 {"setvar", Tkapp_SetVar, 1},
1764 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1765 {"getvar", Tkapp_GetVar, 1},
1766 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1767 {"unsetvar", Tkapp_UnsetVar, 1},
1768 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1769 {"getint", Tkapp_GetInt, 1},
1770 {"getdouble", Tkapp_GetDouble, 1},
1771 {"getboolean", Tkapp_GetBoolean, 1},
1772 {"exprstring", Tkapp_ExprString, 1},
1773 {"exprlong", Tkapp_ExprLong, 1},
1774 {"exprdouble", Tkapp_ExprDouble, 1},
1775 {"exprboolean", Tkapp_ExprBoolean, 1},
1776 {"splitlist", Tkapp_SplitList, 1},
1777 {"split", Tkapp_Split, 1},
1778 {"merge", Tkapp_Merge, 0},
1779 {"createcommand", Tkapp_CreateCommand, 1},
1780 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001781#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001782 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1783 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001784#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001785 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001786 {"mainloop", Tkapp_MainLoop, 1},
1787 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001788 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001789 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001791};
1792
Barry Warsawfa701a81997-01-16 00:15:11 +00001793
1794
Guido van Rossum18468821994-06-20 07:49:28 +00001795/**** Tkapp Type Methods ****/
1796
1797static void
Fred Drake509d79a2000-07-08 04:04:38 +00001798Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001799{
Guido van Rossum00d93061998-05-28 23:06:38 +00001800 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001801 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001802 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001803 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001804 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001805}
1806
1807static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001808Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001809{
Guido van Rossum35d43371997-08-02 00:09:09 +00001810 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001811}
1812
1813static PyTypeObject Tkapp_Type =
1814{
Guido van Rossum35d43371997-08-02 00:09:09 +00001815 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001816 0, /*ob_size */
1817 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001818 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 0, /*tp_itemsize */
1820 Tkapp_Dealloc, /*tp_dealloc */
1821 0, /*tp_print */
1822 Tkapp_GetAttr, /*tp_getattr */
1823 0, /*tp_setattr */
1824 0, /*tp_compare */
1825 0, /*tp_repr */
1826 0, /*tp_as_number */
1827 0, /*tp_as_sequence */
1828 0, /*tp_as_mapping */
1829 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001830};
1831
Barry Warsawfa701a81997-01-16 00:15:11 +00001832
1833
Guido van Rossum18468821994-06-20 07:49:28 +00001834/**** Tkinter Module ****/
1835
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001836typedef struct {
1837 PyObject* tuple;
1838 int size; /* current size */
1839 int maxsize; /* allocated size */
1840} FlattenContext;
1841
1842static int
1843_bump(FlattenContext* context, int size)
1844{
Guido van Rossum2834b972000-10-06 16:58:26 +00001845 /* expand tuple to hold (at least) size new items.
1846 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001847
1848 int maxsize = context->maxsize * 2;
1849
1850 if (maxsize < context->size + size)
1851 maxsize = context->size + size;
1852
1853 context->maxsize = maxsize;
1854
Tim Peters4324aa32001-05-28 22:30:08 +00001855 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001856}
1857
1858static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001859_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001860{
1861 /* add tuple or list to argument tuple (recursively) */
1862
1863 int i, size;
1864
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001865 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001866 PyErr_SetString(PyExc_ValueError,
1867 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001868 return 0;
1869 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001870 size = PyList_GET_SIZE(item);
1871 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001872 if (context->size + size > context->maxsize &&
1873 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001874 return 0;
1875 /* copy items to output tuple */
1876 for (i = 0; i < size; i++) {
1877 PyObject *o = PyList_GET_ITEM(item, i);
1878 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001879 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001880 return 0;
1881 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001882 if (context->size + 1 > context->maxsize &&
1883 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001884 return 0;
1885 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001886 PyTuple_SET_ITEM(context->tuple,
1887 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001888 }
1889 }
1890 } else if (PyTuple_Check(item)) {
1891 /* same, for tuples */
1892 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001893 if (context->size + size > context->maxsize &&
1894 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001895 return 0;
1896 for (i = 0; i < size; i++) {
1897 PyObject *o = PyTuple_GET_ITEM(item, i);
1898 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001899 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001900 return 0;
1901 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001902 if (context->size + 1 > context->maxsize &&
1903 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001904 return 0;
1905 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001906 PyTuple_SET_ITEM(context->tuple,
1907 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001908 }
1909 }
1910 } else {
1911 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1912 return 0;
1913 }
1914 return 1;
1915}
1916
1917static PyObject *
1918Tkinter_Flatten(PyObject* self, PyObject* args)
1919{
1920 FlattenContext context;
1921 PyObject* item;
1922
1923 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1924 return NULL;
1925
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001926 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001927 if (context.maxsize <= 0)
1928 return PyTuple_New(0);
1929
1930 context.tuple = PyTuple_New(context.maxsize);
1931 if (!context.tuple)
1932 return NULL;
1933
1934 context.size = 0;
1935
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001936 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001937 return NULL;
1938
Tim Peters4324aa32001-05-28 22:30:08 +00001939 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001940 return NULL;
1941
1942 return context.tuple;
1943}
1944
Guido van Rossum18468821994-06-20 07:49:28 +00001945static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001946Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001947{
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 char *screenName = NULL;
1949 char *baseName = NULL;
1950 char *className = NULL;
1951 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001952
Guido van Rossum35d43371997-08-02 00:09:09 +00001953 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 if (baseName != NULL)
1955 baseName++;
1956 else
1957 baseName = Py_GetProgramName();
1958 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001959
Guido van Rossum43713e52000-02-29 13:59:29 +00001960 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001961 &screenName, &baseName, &className,
1962 &interactive))
1963 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001964
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 return (PyObject *) Tkapp_New(screenName, baseName, className,
1966 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001967}
1968
1969static PyMethodDef moduleMethods[] =
1970{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001971 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001972 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001973#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001974 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1975 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001976#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001977 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001978 {"mainloop", Tkapp_MainLoop, 1},
1979 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001980 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001981 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001982};
1983
Guido van Rossum7bf15641998-05-22 18:28:17 +00001984#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001985
1986static int stdin_ready = 0;
1987
Guido van Rossumad4db171998-06-13 13:56:28 +00001988#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001989static void
Fred Drake509d79a2000-07-08 04:04:38 +00001990MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001991{
1992 stdin_ready = 1;
1993}
Guido van Rossumad4db171998-06-13 13:56:28 +00001994#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001995
Guido van Rossum00d93061998-05-28 23:06:38 +00001996static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001997
Guido van Rossum18468821994-06-20 07:49:28 +00001998static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001999EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002000{
Guido van Rossumad4db171998-06-13 13:56:28 +00002001#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002002 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002003#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002004#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002005 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002006#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002007 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002008 errorInCmd = 0;
2009#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002010 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002011 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002012#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002013 while (!errorInCmd && !stdin_ready) {
2014 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002015#ifdef MS_WINDOWS
2016 if (_kbhit()) {
2017 stdin_ready = 1;
2018 break;
2019 }
2020#endif
2021#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002022 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002023 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002024 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002025
Guido van Rossum00d93061998-05-28 23:06:38 +00002026 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002027
2028 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002029 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002030 if (result == 0)
2031 Sleep(20);
2032 Py_END_ALLOW_THREADS
2033#else
2034 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002035#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002036
2037 if (result < 0)
2038 break;
2039 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002040#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002041 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002042#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002043 if (errorInCmd) {
2044 errorInCmd = 0;
2045 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2046 excInCmd = valInCmd = trbInCmd = NULL;
2047 PyErr_Print();
2048 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002049#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002050 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002051#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002052 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002053}
Guido van Rossum18468821994-06-20 07:49:28 +00002054
Guido van Rossum00d93061998-05-28 23:06:38 +00002055#endif
2056
Guido van Rossum7bf15641998-05-22 18:28:17 +00002057static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002058EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002059{
Guido van Rossum00d93061998-05-28 23:06:38 +00002060#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002061 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002062#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002063 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002064#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002065 PyOS_InputHook = EventHook;
2066 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002067#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002068}
2069
2070static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002071DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002072{
Guido van Rossum00d93061998-05-28 23:06:38 +00002073#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002074 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2075 PyOS_InputHook = NULL;
2076 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002077#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002078}
2079
Barry Warsawfa701a81997-01-16 00:15:11 +00002080
2081/* all errors will be checked in one fell swoop in init_tkinter() */
2082static void
Fred Drake509d79a2000-07-08 04:04:38 +00002083ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002084{
2085 PyObject *v = PyInt_FromLong(val);
2086 if (v) {
2087 PyDict_SetItemString(d, name, v);
2088 Py_DECREF(v);
2089 }
2090}
2091static void
Fred Drake509d79a2000-07-08 04:04:38 +00002092ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002093{
2094 PyObject *v = PyString_FromString(val);
2095 if (v) {
2096 PyDict_SetItemString(d, name, v);
2097 Py_DECREF(v);
2098 }
2099}
2100
2101
Guido van Rossum3886bb61998-12-04 18:50:17 +00002102DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002103init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002104{
Barry Warsawfa701a81997-01-16 00:15:11 +00002105 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002106
Barry Warsawfa701a81997-01-16 00:15:11 +00002107 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002108
2109#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002110 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002111#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002112
Barry Warsawfa701a81997-01-16 00:15:11 +00002113 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002114
Barry Warsawfa701a81997-01-16 00:15:11 +00002115 d = PyModule_GetDict(m);
2116 Tkinter_TclError = Py_BuildValue("s", "TclError");
2117 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002118
Guido van Rossum35d43371997-08-02 00:09:09 +00002119 ins_long(d, "READABLE", TCL_READABLE);
2120 ins_long(d, "WRITABLE", TCL_WRITABLE);
2121 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2122 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2123 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2124 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2125 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2126 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2127 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002128 ins_string(d, "TK_VERSION", TK_VERSION);
2129 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002130
Guido van Rossum83551bf1997-09-13 00:44:23 +00002131 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002132
2133 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002134 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2135
Guido van Rossume187b0e2000-03-27 21:46:29 +00002136 /* This helps the dynamic loader; in Unicode aware Tcl versions
2137 it also helps Tcl find its encodings. */
2138 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002139
Barry Warsawfa701a81997-01-16 00:15:11 +00002140 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002141 return;
2142
Guido van Rossum43ff8681998-07-14 18:02:13 +00002143#if 0
2144 /* This was not a good idea; through <Destroy> bindings,
2145 Tcl_Finalize() may invoke Python code but at that point the
2146 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002147 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002148#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002149
Jack Jansen34cc5c31995-10-31 16:15:12 +00002150#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002151 /*
2152 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2153 ** Most of the initializations in that routine (toolbox init calls and
2154 ** such) have already been done for us, so we only need these.
2155 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002156 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002157
2158 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002159#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002160 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002161#endif /* GENERATINGCFM */
2162#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002163}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002164
Guido van Rossumec22c921996-02-25 04:50:29 +00002165
Barry Warsawfa701a81997-01-16 00:15:11 +00002166
Guido van Rossum9722ad81995-09-22 23:49:28 +00002167#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002168
2169/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002170** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002171*/
2172
Guido van Rossum9722ad81995-09-22 23:49:28 +00002173void
2174panic(char * format, ...)
2175{
Barry Warsawfa701a81997-01-16 00:15:11 +00002176 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002177
Barry Warsawfa701a81997-01-16 00:15:11 +00002178 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002179
Guido van Rossum227cf761998-08-05 13:53:32 +00002180 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002181 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002182
Barry Warsawfa701a81997-01-16 00:15:11 +00002183 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002184
Barry Warsawfa701a81997-01-16 00:15:11 +00002185 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002186}
Jack Jansen40b546d1995-11-14 10:34:45 +00002187
Guido van Rossumec22c921996-02-25 04:50:29 +00002188/*
2189** Pass events to SIOUX before passing them to Tk.
2190*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002191
Guido van Rossumec22c921996-02-25 04:50:29 +00002192static int
Fred Drake509d79a2000-07-08 04:04:38 +00002193PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002194{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002195 WindowPtr frontwin;
2196 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002197 ** Sioux eats too many events, so we don't pass it everything. We
2198 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002199 ** the Sioux window is frontmost. This means that Tk menus don't work
2200 ** in that case, but at least we can scroll the sioux window.
2201 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2202 ** part of the external interface of Sioux...
2203 */
2204 frontwin = FrontWindow();
2205 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2206 if (SIOUXHandleOneEvent(eventPtr))
2207 return 0; /* Nothing happened to the Tcl event queue */
2208 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002209 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002210}
2211
Guido van Rossumec22c921996-02-25 04:50:29 +00002212#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002213
2214/*
2215** Additional Mac specific code for dealing with shared libraries.
2216*/
2217
2218#include <Resources.h>
2219#include <CodeFragments.h>
2220
2221static int loaded_from_shlib = 0;
2222static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002223
Jack Jansen34cc5c31995-10-31 16:15:12 +00002224/*
2225** If this module is dynamically loaded the following routine should
2226** be the init routine. It takes care of adding the shared library to
2227** the resource-file chain, so that the tk routines can find their
2228** resources.
2229*/
2230OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002231init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002232{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002233 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002234 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002235 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002236 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2237 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002238 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002239 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2240 loaded_from_shlib = 1;
2241 }
2242 return noErr;
2243}
2244
2245/*
2246** Insert the library resources into the search path. Put them after
2247** the resources from the application. Again, we ignore errors.
2248*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002249static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002250mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002251{
2252 if ( !loaded_from_shlib )
2253 return;
2254 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2255}
2256
Guido van Rossumec22c921996-02-25 04:50:29 +00002257#endif /* GENERATINGCFM */
2258#endif /* macintosh */