blob: eedb0c1008c8814d5fa99a2024018f727fa1803f [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#include <SIOUX.h>
187extern int SIOUXIsAppWindow(WindowPtr);
188
Guido van Rossumec22c921996-02-25 04:50:29 +0000189#endif /* macintosh */
190
Guido van Rossum97867b21996-08-08 19:09:53 +0000191#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000192#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000193#endif
194
Guido van Rossum18468821994-06-20 07:49:28 +0000195/**** Tkapp Object Declaration ****/
196
197staticforward PyTypeObject Tkapp_Type;
198
Guido van Rossum00d93061998-05-28 23:06:38 +0000199typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000200 PyObject_HEAD
201 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000203
204#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000205#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000206#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000207
Guido van Rossum35d43371997-08-02 00:09:09 +0000208#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000209(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000210
Barry Warsawfa701a81997-01-16 00:15:11 +0000211
212
Guido van Rossum18468821994-06-20 07:49:28 +0000213/**** Error Handling ****/
214
215static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000216static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000217static int errorInCmd = 0;
218static PyObject *excInCmd;
219static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000220static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000221
Barry Warsawfa701a81997-01-16 00:15:11 +0000222
223
Guido van Rossum18468821994-06-20 07:49:28 +0000224static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000225Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000226{
Barry Warsawfa701a81997-01-16 00:15:11 +0000227 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
228 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000229}
230
Barry Warsawfa701a81997-01-16 00:15:11 +0000231
Barry Warsawfa701a81997-01-16 00:15:11 +0000232
Guido van Rossum18468821994-06-20 07:49:28 +0000233/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000234
235#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000236#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000237
Guido van Rossum00d93061998-05-28 23:06:38 +0000238/* Millisecond sleep() for Unix platforms. */
239
240static void
Fred Drake509d79a2000-07-08 04:04:38 +0000241Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000242{
243 /* XXX Too bad if you don't have select(). */
244 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000245 t.tv_sec = milli/1000;
246 t.tv_usec = (milli%1000) * 1000;
247 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
248}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000249#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000250#endif /* WITH_THREAD */
251
252
Guido van Rossum18468821994-06-20 07:49:28 +0000253static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000254AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000255{
Guido van Rossum35d43371997-08-02 00:09:09 +0000256 if (PyString_Check(value))
257 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000258#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000259 else if (PyUnicode_Check(value)) {
260 PyObject *v = PyUnicode_AsUTF8String(value);
261 if (v == NULL)
262 return NULL;
263 if (PyList_Append(tmp, v) != 0) {
264 Py_DECREF(v);
265 return NULL;
266 }
267 Py_DECREF(v);
268 return PyString_AsString(v);
269 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000270#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000271 else {
272 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000273 if (v == NULL)
274 return NULL;
275 if (PyList_Append(tmp, v) != 0) {
276 Py_DECREF(v);
277 return NULL;
278 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000279 Py_DECREF(v);
280 return PyString_AsString(v);
281 }
Guido van Rossum18468821994-06-20 07:49:28 +0000282}
283
Barry Warsawfa701a81997-01-16 00:15:11 +0000284
285
Guido van Rossum18468821994-06-20 07:49:28 +0000286#define ARGSZ 64
287
288static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000289Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000290{
Barry Warsawfa701a81997-01-16 00:15:11 +0000291 PyObject *tmp = NULL;
292 char *argvStore[ARGSZ];
293 char **argv = NULL;
294 int fvStore[ARGSZ];
295 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000296 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000297 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000298
Barry Warsawfa701a81997-01-16 00:15:11 +0000299 if (!(tmp = PyList_New(0)))
300 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000301
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 argv = argvStore;
303 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000304
Barry Warsawfa701a81997-01-16 00:15:11 +0000305 if (args == NULL)
306 argc = 0;
307
308 else if (!PyTuple_Check(args)) {
309 argc = 1;
310 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000311 if (!(argv[0] = AsString(args, tmp)))
312 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000313 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000314 else {
315 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000316
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000318 argv = (char **)ckalloc(argc * sizeof(char *));
319 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000320 if (argv == NULL || fv == NULL) {
321 PyErr_NoMemory();
322 goto finally;
323 }
324 }
325
326 for (i = 0; i < argc; i++) {
327 PyObject *v = PyTuple_GetItem(args, i);
328 if (PyTuple_Check(v)) {
329 fv[i] = 1;
330 if (!(argv[i] = Merge(v)))
331 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000332 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000333 }
334 else if (v == Py_None) {
335 argc = i;
336 break;
337 }
338 else {
339 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000340 if (!(argv[i] = AsString(v, tmp)))
341 goto finally;
342 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 }
344 }
Guido van Rossum18468821994-06-20 07:49:28 +0000345 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000346 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000347 if (res == NULL)
348 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000349
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000351 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000352 if (fv[i]) {
353 ckfree(argv[i]);
354 }
355 if (argv != argvStore)
356 ckfree(FREECAST argv);
357 if (fv != fvStore)
358 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000359
Barry Warsawfa701a81997-01-16 00:15:11 +0000360 Py_DECREF(tmp);
361 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000362}
363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364
365
Guido van Rossum18468821994-06-20 07:49:28 +0000366static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000367Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000368{
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 int argc;
370 char **argv;
371 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000372
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 if (list == NULL) {
374 Py_INCREF(Py_None);
375 return Py_None;
376 }
Guido van Rossum18468821994-06-20 07:49:28 +0000377
Guido van Rossum00d93061998-05-28 23:06:38 +0000378 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 /* Not a list.
380 * Could be a quoted string containing funnies, e.g. {"}.
381 * Return the string itself.
382 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 return PyString_FromString(list);
384 }
Guido van Rossum18468821994-06-20 07:49:28 +0000385
Barry Warsawfa701a81997-01-16 00:15:11 +0000386 if (argc == 0)
387 v = PyString_FromString("");
388 else if (argc == 1)
389 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000390 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000391 int i;
392 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000395 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 Py_DECREF(v);
397 v = NULL;
398 break;
399 }
400 PyTuple_SetItem(v, i, w);
401 }
402 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000403 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000405}
406
Barry Warsawfa701a81997-01-16 00:15:11 +0000407
408
Guido van Rossum18468821994-06-20 07:49:28 +0000409/**** Tkapp Object ****/
410
411#ifndef WITH_APPINIT
412int
Fred Drake509d79a2000-07-08 04:04:38 +0000413Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000414{
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000416
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 main = Tk_MainWindow(interp);
418 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000419 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 return TCL_ERROR;
421 }
422 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000423 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 return TCL_ERROR;
425 }
426 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000427}
428#endif /* !WITH_APPINIT */
429
Guido van Rossum18468821994-06-20 07:49:28 +0000430
Barry Warsawfa701a81997-01-16 00:15:11 +0000431
432
433/* Initialize the Tk application; see the `main' function in
434 * `tkMain.c'.
435 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000436
Thomas Wouters58d05102000-07-24 14:43:35 +0000437static void EnableEventHook(void); /* Forward */
438static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000439
Barry Warsawfa701a81997-01-16 00:15:11 +0000440static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000441Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000442{
443 TkappObject *v;
444 char *argv0;
445
Guido van Rossumb18618d2000-05-03 23:44:39 +0000446 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000447 if (v == NULL)
448 return NULL;
449
450 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000451
Guido van Rossuma80649b2000-03-28 20:07:05 +0000452#if defined(macintosh)
453 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000454 ClearMenuBar();
455 TkMacInitMenus(v->interp);
456#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000457 /* Delete the 'exit' command, which can screw things up */
458 Tcl_DeleteCommand(v->interp, "exit");
459
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 if (screenName != NULL)
461 Tcl_SetVar2(v->interp, "env", "DISPLAY",
462 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000463
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 if (interactive)
465 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
466 else
467 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 /* This is used to get the application class for Tk 4.1 and up */
470 argv0 = (char*)ckalloc(strlen(className) + 1);
471 if (!argv0) {
472 PyErr_NoMemory();
473 Py_DECREF(v);
474 return NULL;
475 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000476
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000478 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 argv0[0] = tolower(argv0[0]);
480 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
481 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000482
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000484 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000485
Guido van Rossum7bf15641998-05-22 18:28:17 +0000486 EnableEventHook();
487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000489}
490
Barry Warsawfa701a81997-01-16 00:15:11 +0000491
492
Guido van Rossum18468821994-06-20 07:49:28 +0000493/** Tcl Eval **/
494
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000495#if TKMAJORMINOR >= 8001
496#define USING_OBJECTS
497#endif
498
499#ifdef USING_OBJECTS
500
501static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000502AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000503{
504 Tcl_Obj *result;
505
506 if (PyString_Check(value))
507 return Tcl_NewStringObj(PyString_AS_STRING(value),
508 PyString_GET_SIZE(value));
509 else if (PyInt_Check(value))
510 return Tcl_NewLongObj(PyInt_AS_LONG(value));
511 else if (PyFloat_Check(value))
512 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
513 else if (PyTuple_Check(value)) {
514 Tcl_Obj **argv = (Tcl_Obj**)
515 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
516 int i;
517 if(!argv)
518 return 0;
519 for(i=0;i<PyTuple_Size(value);i++)
520 argv[i] = AsObj(PyTuple_GetItem(value,i));
521 result = Tcl_NewListObj(PyTuple_Size(value), argv);
522 ckfree(FREECAST argv);
523 return result;
524 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000525#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000526 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000527#if TKMAJORMINOR <= 8001
528 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000529 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000530 if (!utf8)
531 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000532 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
533 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000534 Py_DECREF(utf8);
535 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000536#else /* TKMAJORMINOR > 8001 */
537 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
538 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
539 /* XXX Should really test this at compile time */
540 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000541 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000542 return 0;
543 }
544 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
545 PyUnicode_GET_SIZE(value));
546#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000547 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000548#endif
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000549 else {
550 PyObject *v = PyObject_Str(value);
551 if (!v)
552 return 0;
553 result = AsObj(v);
554 Py_DECREF(v);
555 return result;
556 }
557}
558
Guido van Rossum18468821994-06-20 07:49:28 +0000559static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000560Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000561{
Guido van Rossum632de272000-03-29 00:19:50 +0000562 Tcl_Obj *objStore[ARGSZ];
563 Tcl_Obj **objv = NULL;
564 int objc = 0, i;
565 PyObject *res = NULL;
566 Tcl_Interp *interp = Tkapp_Interp(self);
567 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
568 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Guido van Rossum632de272000-03-29 00:19:50 +0000570 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000571
Guido van Rossum212643f1998-04-29 16:22:14 +0000572 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000573 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000574
Guido van Rossum212643f1998-04-29 16:22:14 +0000575 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000576 objv[0] = AsObj(args);
577 if (objv[0] == 0)
578 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000579 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000580 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000581 }
582 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000583 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000584
Guido van Rossum632de272000-03-29 00:19:50 +0000585 if (objc > ARGSZ) {
586 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
587 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000588 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000589 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000590 goto finally;
591 }
592 }
593
Guido van Rossum632de272000-03-29 00:19:50 +0000594 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000595 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000596 if (v == Py_None) {
597 objc = i;
598 break;
599 }
Guido van Rossum632de272000-03-29 00:19:50 +0000600 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000601 if (!objv[i]) {
602 /* Reset objc, so it attempts to clear
603 objects only up to i. */
604 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000605 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000606 }
Guido van Rossum632de272000-03-29 00:19:50 +0000607 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000608 }
609 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000610
Guido van Rossum62320c91998-06-15 04:36:09 +0000611 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000612
613 i = Tcl_EvalObjv(interp, objc, objv, flags);
614
Guido van Rossum62320c91998-06-15 04:36:09 +0000615 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000616 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000617 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000618 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000619 /* We could request the object result here, but doing
620 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000621 char *s = Tcl_GetStringResult(interp);
622 char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000623
Guido van Rossum990f5c62000-05-04 15:07:16 +0000624 /* If the result contains any bytes with the top bit set,
625 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000626#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000627 while (*p != '\0') {
628 if (*p & 0x80)
629 break;
630 p++;
631 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000632
Guido van Rossum990f5c62000-05-04 15:07:16 +0000633 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 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000644#else
645 p = strchr(p, '\0');
646 res = PyString_FromStringAndSize(s, (int)(p-s));
647#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000648 }
Guido van Rossum632de272000-03-29 00:19:50 +0000649
Guido van Rossum62320c91998-06-15 04:36:09 +0000650 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000651
Guido van Rossum212643f1998-04-29 16:22:14 +0000652 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000653 for (i = 0; i < objc; i++)
654 Tcl_DecrRefCount(objv[i]);
655 if (objv != objStore)
656 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000657 return res;
658}
659
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000660#else /* !USING_OBJECTS */
661
662static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000663Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000664{
665 /* This is copied from Merge() */
666 PyObject *tmp = NULL;
667 char *argvStore[ARGSZ];
668 char **argv = NULL;
669 int fvStore[ARGSZ];
670 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000671 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000672 PyObject *res = NULL; /* except this has a different type */
673 Tcl_CmdInfo info; /* and this is added */
674 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
675
676 if (!(tmp = PyList_New(0)))
677 return NULL;
678
679 argv = argvStore;
680 fv = fvStore;
681
682 if (args == NULL)
683 argc = 0;
684
685 else if (!PyTuple_Check(args)) {
686 argc = 1;
687 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000688 if (!(argv[0] = AsString(args, tmp)))
689 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000690 }
691 else {
692 argc = PyTuple_Size(args);
693
694 if (argc > ARGSZ) {
695 argv = (char **)ckalloc(argc * sizeof(char *));
696 fv = (int *)ckalloc(argc * sizeof(int));
697 if (argv == NULL || fv == NULL) {
698 PyErr_NoMemory();
699 goto finally;
700 }
701 }
702
703 for (i = 0; i < argc; i++) {
704 PyObject *v = PyTuple_GetItem(args, i);
705 if (PyTuple_Check(v)) {
706 fv[i] = 1;
707 if (!(argv[i] = Merge(v)))
708 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000709 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000710 }
711 else if (v == Py_None) {
712 argc = i;
713 break;
714 }
715 else {
716 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000717 if (!(argv[i] = AsString(v, tmp)))
718 goto finally;
719 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000720 }
721 }
722 }
723 /* End code copied from Merge() */
724
725 /* All this to avoid a call to Tcl_Merge() and the corresponding call
726 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
727 if (Py_VerboseFlag >= 2) {
728 for (i = 0; i < argc; i++)
729 PySys_WriteStderr("%s ", argv[i]);
730 }
731 ENTER_TCL
732 info.proc = NULL;
733 if (argc < 1 ||
734 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
735 info.proc == NULL)
736 {
737 char *cmd;
738 cmd = Tcl_Merge(argc, argv);
739 i = Tcl_Eval(interp, cmd);
740 ckfree(cmd);
741 }
742 else {
743 Tcl_ResetResult(interp);
744 i = (*info.proc)(info.clientData, interp, argc, argv);
745 }
746 ENTER_OVERLAP
747 if (info.proc == NULL && Py_VerboseFlag >= 2)
748 PySys_WriteStderr("... use TclEval ");
749 if (i == TCL_ERROR) {
750 if (Py_VerboseFlag >= 2)
751 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000752 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000753 Tkinter_Error(self);
754 }
755 else {
756 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000757 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
758 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000759 }
760 LEAVE_OVERLAP_TCL
761
762 /* Copied from Merge() again */
763 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000764 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000765 if (fv[i]) {
766 ckfree(argv[i]);
767 }
768 if (argv != argvStore)
769 ckfree(FREECAST argv);
770 if (fv != fvStore)
771 ckfree(FREECAST fv);
772
773 Py_DECREF(tmp);
774 return res;
775}
776
777#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000778
779static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000780Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000781{
Guido van Rossum212643f1998-04-29 16:22:14 +0000782 /* Could do the same here as for Tkapp_Call(), but this is not used
783 much, so I can't be bothered. Unfortunately Tcl doesn't export a
784 way for the user to do what all its Global* variants do (save and
785 reset the scope pointer, call the local version, restore the saved
786 scope pointer). */
787
Guido van Rossum62320c91998-06-15 04:36:09 +0000788 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000790
Guido van Rossum62320c91998-06-15 04:36:09 +0000791 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000792 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000793 int err;
794 ENTER_TCL
795 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000796 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000797 if (err == TCL_ERROR)
798 res = Tkinter_Error(self);
799 else
800 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000801 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000802 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000803 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000804
805 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000806}
807
808static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000809Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000810{
Barry Warsawfa701a81997-01-16 00:15:11 +0000811 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000812 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000813 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000814
Guido van Rossum43713e52000-02-29 13:59:29 +0000815 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000816 return NULL;
817
Guido van Rossum00d93061998-05-28 23:06:38 +0000818 ENTER_TCL
819 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000820 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000821 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000822 res = Tkinter_Error(self);
823 else
824 res = PyString_FromString(Tkapp_Result(self));
825 LEAVE_OVERLAP_TCL
826 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000827}
828
829static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000830Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000831{
Barry Warsawfa701a81997-01-16 00:15:11 +0000832 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000833 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000834 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000835
Guido van Rossum43713e52000-02-29 13:59:29 +0000836 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000838
Guido van Rossum00d93061998-05-28 23:06:38 +0000839 ENTER_TCL
840 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000841 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000842 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000843 res = Tkinter_Error(self);
844 else
845 res = PyString_FromString(Tkapp_Result(self));
846 LEAVE_OVERLAP_TCL
847 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000848}
849
850static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000851Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000852{
Barry Warsawfa701a81997-01-16 00:15:11 +0000853 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000854 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000855 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Guido van Rossum43713e52000-02-29 13:59:29 +0000857 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000859
Guido van Rossum00d93061998-05-28 23:06:38 +0000860 ENTER_TCL
861 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000862 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000863 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000864 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000865
Guido van Rossum62320c91998-06-15 04:36:09 +0000866 else
867 res = PyString_FromString(Tkapp_Result(self));
868 LEAVE_OVERLAP_TCL
869 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000870}
871
872static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000873Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000874{
Barry Warsawfa701a81997-01-16 00:15:11 +0000875 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000876 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000877 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000878
Guido van Rossum35d43371997-08-02 00:09:09 +0000879 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000880 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000881
Guido van Rossum00d93061998-05-28 23:06:38 +0000882 ENTER_TCL
883 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000884 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000885 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000886 res = Tkinter_Error(self);
887 else
888 res = PyString_FromString(Tkapp_Result(self));
889 LEAVE_OVERLAP_TCL
890 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000891}
892
893static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000894Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000895{
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000897
Guido van Rossum43713e52000-02-29 13:59:29 +0000898 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000900 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000901 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000902 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000903
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 Py_INCREF(Py_None);
905 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000906}
907
Barry Warsawfa701a81997-01-16 00:15:11 +0000908
909
Guido van Rossum18468821994-06-20 07:49:28 +0000910/** Tcl Variable **/
911
912static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000913SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000914{
Guido van Rossum00d93061998-05-28 23:06:38 +0000915 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000917 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000918
Guido van Rossum62320c91998-06-15 04:36:09 +0000919 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 if (!tmp)
921 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000922
Guido van Rossum43713e52000-02-29 13:59:29 +0000923 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000924 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000925 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000926 if (s == NULL)
927 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000928 ENTER_TCL
929 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
930 LEAVE_TCL
931 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000932 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000934 if (PyArg_ParseTuple(args, "ssO:setvar",
935 &name1, &name2, &newValue)) {
936 s = AsString(newValue, tmp);
937 if (s == NULL)
938 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000939 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000940 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000941 s, flags);
942 LEAVE_TCL
943 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000944 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000945 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000946 return NULL;
947 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000949 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000950
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 if (!ok)
952 return Tkinter_Error(self);
953
954 Py_INCREF(Py_None);
955 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000956}
957
958static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000959Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000960{
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000962}
963
964static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000965Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000966{
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000968}
969
Barry Warsawfa701a81997-01-16 00:15:11 +0000970
971
Guido van Rossum18468821994-06-20 07:49:28 +0000972static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000973GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000974{
Guido van Rossum35d43371997-08-02 00:09:09 +0000975 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000976 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000977
Guido van Rossum43713e52000-02-29 13:59:29 +0000978 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000979 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000980 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000982 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000983
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000985 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000986 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000987
Barry Warsawfa701a81997-01-16 00:15:11 +0000988 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000989 res = Tkinter_Error(self);
990 else
991 res = PyString_FromString(s);
992 LEAVE_OVERLAP_TCL
993 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000994}
995
996static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000997Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000998{
Barry Warsawfa701a81997-01-16 00:15:11 +0000999 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001000}
1001
1002static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001003Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001004{
Barry Warsawfa701a81997-01-16 00:15:11 +00001005 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001006}
1007
Barry Warsawfa701a81997-01-16 00:15:11 +00001008
1009
Guido van Rossum18468821994-06-20 07:49:28 +00001010static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001011UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001012{
Guido van Rossum35d43371997-08-02 00:09:09 +00001013 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001014 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001015 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001016
Guido van Rossum43713e52000-02-29 13:59:29 +00001017 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001019 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001020 if (name2 == NULL)
1021 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1022
1023 else
1024 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001025 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001026
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001028 res = Tkinter_Error(self);
1029 else {
1030 Py_INCREF(Py_None);
1031 res = Py_None;
1032 }
1033 LEAVE_OVERLAP_TCL
1034 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001035}
1036
1037static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001038Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001039{
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001041}
1042
1043static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001044Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001045{
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001047}
1048
Barry Warsawfa701a81997-01-16 00:15:11 +00001049
1050
Guido van Rossum18468821994-06-20 07:49:28 +00001051/** Tcl to Python **/
1052
1053static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001054Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001055{
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 char *s;
1057 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001058
Guido van Rossum43713e52000-02-29 13:59:29 +00001059 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001061 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 return Tkinter_Error(self);
1063 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001064}
1065
1066static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001067Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001068{
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 char *s;
1070 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum43713e52000-02-29 13:59:29 +00001072 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001074 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return Tkinter_Error(self);
1076 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001077}
1078
1079static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001080Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001081{
Barry Warsawfa701a81997-01-16 00:15:11 +00001082 char *s;
1083 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001084
Guido van Rossum43713e52000-02-29 13:59:29 +00001085 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001087 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1088 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001090}
1091
1092static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001093Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001094{
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001096 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001097 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001098
Guido van Rossum43713e52000-02-29 13:59:29 +00001099 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001100 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001101 ENTER_TCL
1102 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001103 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001104 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001105 res = Tkinter_Error(self);
1106 else
1107 res = Py_BuildValue("s", Tkapp_Result(self));
1108 LEAVE_OVERLAP_TCL
1109 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001110}
1111
1112static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001113Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001114{
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001116 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001117 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001118 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001119
Guido van Rossum43713e52000-02-29 13:59:29 +00001120 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001121 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001122 ENTER_TCL
1123 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001124 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001125 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001126 res = Tkinter_Error(self);
1127 else
1128 res = Py_BuildValue("l", v);
1129 LEAVE_OVERLAP_TCL
1130 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001131}
1132
1133static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001134Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001135{
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001137 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001139 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001140
Guido van Rossum43713e52000-02-29 13:59:29 +00001141 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001143 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001144 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001145 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001146 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001147 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001148 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001149 res = Tkinter_Error(self);
1150 else
1151 res = Py_BuildValue("d", v);
1152 LEAVE_OVERLAP_TCL
1153 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001154}
1155
1156static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001157Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001158{
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001160 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001161 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001162 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001163
Guido van Rossum43713e52000-02-29 13:59:29 +00001164 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001165 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001166 ENTER_TCL
1167 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001168 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001169 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001170 res = Tkinter_Error(self);
1171 else
1172 res = Py_BuildValue("i", v);
1173 LEAVE_OVERLAP_TCL
1174 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001175}
1176
Barry Warsawfa701a81997-01-16 00:15:11 +00001177
1178
Guido van Rossum18468821994-06-20 07:49:28 +00001179static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001180Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001181{
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 char *list;
1183 int argc;
1184 char **argv;
1185 PyObject *v;
1186 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001187
Guido van Rossum43713e52000-02-29 13:59:29 +00001188 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001190
Barry Warsawfa701a81997-01-16 00:15:11 +00001191 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1192 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001193
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 if (!(v = PyTuple_New(argc)))
1195 return NULL;
1196
1197 for (i = 0; i < argc; i++) {
1198 PyObject *s = PyString_FromString(argv[i]);
1199 if (!s || PyTuple_SetItem(v, i, s)) {
1200 Py_DECREF(v);
1201 v = NULL;
1202 goto finally;
1203 }
1204 }
Guido van Rossum18468821994-06-20 07:49:28 +00001205
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 finally:
1207 ckfree(FREECAST argv);
1208 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001209}
1210
1211static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001212Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001213{
Barry Warsawfa701a81997-01-16 00:15:11 +00001214 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001215
Guido van Rossum43713e52000-02-29 13:59:29 +00001216 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001218 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001219}
1220
1221static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001222Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001223{
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 char *s = Merge(args);
1225 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001226
Barry Warsawfa701a81997-01-16 00:15:11 +00001227 if (s) {
1228 res = PyString_FromString(s);
1229 ckfree(s);
1230 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001231
1232 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001233}
1234
Barry Warsawfa701a81997-01-16 00:15:11 +00001235
1236
Guido van Rossum18468821994-06-20 07:49:28 +00001237/** Tcl Command **/
1238
Guido van Rossum00d93061998-05-28 23:06:38 +00001239/* Client data struct */
1240typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001241 PyObject *self;
1242 PyObject *func;
1243} PythonCmd_ClientData;
1244
1245static int
Fred Drake509d79a2000-07-08 04:04:38 +00001246PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001247{
1248 errorInCmd = 1;
1249 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1250 LEAVE_PYTHON
1251 return TCL_ERROR;
1252}
1253
Guido van Rossum18468821994-06-20 07:49:28 +00001254/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001255 * function or method.
1256 */
Guido van Rossum18468821994-06-20 07:49:28 +00001257static int
Fred Drake509d79a2000-07-08 04:04:38 +00001258PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001259{
Guido van Rossum00d93061998-05-28 23:06:38 +00001260 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001261 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001262 int i, rv;
1263 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001264
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001265 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001266
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 /* TBD: no error checking here since we know, via the
1268 * Tkapp_CreateCommand() that the client data is a two-tuple
1269 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001270 self = data->self;
1271 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001272
Barry Warsawfa701a81997-01-16 00:15:11 +00001273 /* Create argument list (argv1, ..., argvN) */
1274 if (!(arg = PyTuple_New(argc - 1)))
1275 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001276
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 for (i = 0; i < (argc - 1); i++) {
1278 PyObject *s = PyString_FromString(argv[i + 1]);
1279 if (!s || PyTuple_SetItem(arg, i, s)) {
1280 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001281 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001282 }
1283 }
1284 res = PyEval_CallObject(func, arg);
1285 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001286
Barry Warsawfa701a81997-01-16 00:15:11 +00001287 if (res == NULL)
1288 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001289
Barry Warsawfa701a81997-01-16 00:15:11 +00001290 if (!(tmp = PyList_New(0))) {
1291 Py_DECREF(res);
1292 return PythonCmd_Error(interp);
1293 }
1294
Guido van Rossum2834b972000-10-06 16:58:26 +00001295 s = AsString(res, tmp);
1296 if (s == NULL) {
1297 rv = PythonCmd_Error(interp);
1298 }
1299 else {
1300 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1301 rv = TCL_OK;
1302 }
1303
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 Py_DECREF(res);
1305 Py_DECREF(tmp);
1306
Guido van Rossum00d93061998-05-28 23:06:38 +00001307 LEAVE_PYTHON
1308
Guido van Rossum2834b972000-10-06 16:58:26 +00001309 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001310}
1311
1312static void
Fred Drake509d79a2000-07-08 04:04:38 +00001313PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001314{
Guido van Rossum00d93061998-05-28 23:06:38 +00001315 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1316
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001317 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 Py_XDECREF(data->self);
1319 Py_XDECREF(data->func);
1320 PyMem_DEL(data);
1321 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001322}
1323
Barry Warsawfa701a81997-01-16 00:15:11 +00001324
1325
Guido van Rossum18468821994-06-20 07:49:28 +00001326static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001327Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001328{
Guido van Rossum00d93061998-05-28 23:06:38 +00001329 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001330 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001331 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001332 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001333
Guido van Rossum43713e52000-02-29 13:59:29 +00001334 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001335 return NULL;
1336 if (!PyCallable_Check(func)) {
1337 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 return NULL;
1339 }
Guido van Rossum18468821994-06-20 07:49:28 +00001340
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001342 if (!data)
1343 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001344 Py_XINCREF(self);
1345 Py_XINCREF(func);
1346 data->self = self;
1347 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001348
Guido van Rossum00d93061998-05-28 23:06:38 +00001349 ENTER_TCL
1350 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1351 (ClientData)data, PythonCmdDelete);
1352 LEAVE_TCL
1353 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001354 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001355 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001356 return NULL;
1357 }
Guido van Rossum18468821994-06-20 07:49:28 +00001358
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 Py_INCREF(Py_None);
1360 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001361}
1362
Barry Warsawfa701a81997-01-16 00:15:11 +00001363
1364
Guido van Rossum18468821994-06-20 07:49:28 +00001365static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001366Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001367{
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001369 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001370
Guido van Rossum43713e52000-02-29 13:59:29 +00001371 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001373 ENTER_TCL
1374 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1375 LEAVE_TCL
1376 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001377 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1378 return NULL;
1379 }
1380 Py_INCREF(Py_None);
1381 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001382}
1383
Barry Warsawfa701a81997-01-16 00:15:11 +00001384
1385
Guido van Rossum00d93061998-05-28 23:06:38 +00001386#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001387/** File Handler **/
1388
Guido van Rossum00d93061998-05-28 23:06:38 +00001389typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001390 PyObject *func;
1391 PyObject *file;
1392 int id;
1393 struct _fhcdata *next;
1394} FileHandler_ClientData;
1395
1396static FileHandler_ClientData *HeadFHCD;
1397
1398static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001399NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001400{
1401 FileHandler_ClientData *p;
1402 p = PyMem_NEW(FileHandler_ClientData, 1);
1403 if (p != NULL) {
1404 Py_XINCREF(func);
1405 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001406 p->func = func;
1407 p->file = file;
1408 p->id = id;
1409 p->next = HeadFHCD;
1410 HeadFHCD = p;
1411 }
1412 return p;
1413}
1414
1415static void
Fred Drake509d79a2000-07-08 04:04:38 +00001416DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001417{
1418 FileHandler_ClientData *p, **pp;
1419
1420 pp = &HeadFHCD;
1421 while ((p = *pp) != NULL) {
1422 if (p->id == id) {
1423 *pp = p->next;
1424 Py_XDECREF(p->func);
1425 Py_XDECREF(p->file);
1426 PyMem_DEL(p);
1427 }
1428 else
1429 pp = &p->next;
1430 }
1431}
1432
Guido van Rossuma597dde1995-01-10 20:56:29 +00001433static void
Fred Drake509d79a2000-07-08 04:04:38 +00001434FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001435{
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001437 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001439 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001440 func = data->func;
1441 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001442
Barry Warsawfa701a81997-01-16 00:15:11 +00001443 arg = Py_BuildValue("(Oi)", file, (long) mask);
1444 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001445 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001446
1447 if (res == NULL) {
1448 errorInCmd = 1;
1449 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1450 }
1451 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001453}
1454
Guido van Rossum18468821994-06-20 07:49:28 +00001455static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001456Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1457 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001458{
Guido van Rossum00d93061998-05-28 23:06:38 +00001459 FileHandler_ClientData *data;
1460 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001461 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001462
Guido van Rossum2834b972000-10-06 16:58:26 +00001463 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1464 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001465 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001466 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001467 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 return NULL;
1469 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001470 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 return NULL;
1472 }
1473
Guido van Rossuma80649b2000-03-28 20:07:05 +00001474 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001475 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 return NULL;
1477
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001479 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001480 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001482 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001484}
1485
1486static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001487Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001488{
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001490 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001491
Guido van Rossum43713e52000-02-29 13:59:29 +00001492 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001494 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001495 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001496 return NULL;
1497
Guido van Rossuma80649b2000-03-28 20:07:05 +00001498 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001499
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001501 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001503 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001504 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001506}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001507#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001508
Barry Warsawfa701a81997-01-16 00:15:11 +00001509
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001510/**** Tktt Object (timer token) ****/
1511
1512staticforward PyTypeObject Tktt_Type;
1513
Guido van Rossum00d93061998-05-28 23:06:38 +00001514typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001516 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001518} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001519
1520static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001521Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001522{
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001524 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001525
Guido van Rossum43713e52000-02-29 13:59:29 +00001526 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001527 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001528 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001529 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001530 v->token = NULL;
1531 }
1532 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001534 Py_DECREF(func);
1535 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 }
1537 Py_INCREF(Py_None);
1538 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001539}
1540
1541static PyMethodDef Tktt_methods[] =
1542{
Guido van Rossum35d43371997-08-02 00:09:09 +00001543 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001544 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001545};
1546
1547static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001548Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001549{
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001551
Guido van Rossumb18618d2000-05-03 23:44:39 +00001552 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 if (v == NULL)
1554 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001555
Guido van Rossum00d93061998-05-28 23:06:38 +00001556 Py_INCREF(func);
1557 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001559
1560 /* Extra reference, deleted when called or when handler is deleted */
1561 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001562 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001563}
1564
1565static void
Fred Drake509d79a2000-07-08 04:04:38 +00001566Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001567{
Guido van Rossum00d93061998-05-28 23:06:38 +00001568 TkttObject *v = (TkttObject *)self;
1569 PyObject *func = v->func;
1570
1571 Py_XDECREF(func);
1572
Guido van Rossumb18618d2000-05-03 23:44:39 +00001573 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001574}
1575
Guido van Rossum597ac201998-05-12 14:36:19 +00001576static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001577Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001578{
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001580 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001581
Fred Drakea44d3532000-06-30 15:01:00 +00001582 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001584 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001585}
1586
1587static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001588Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001589{
Barry Warsawfa701a81997-01-16 00:15:11 +00001590 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001591}
1592
1593static PyTypeObject Tktt_Type =
1594{
Guido van Rossum35d43371997-08-02 00:09:09 +00001595 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001596 0, /*ob_size */
1597 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001598 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001599 0, /*tp_itemsize */
1600 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001601 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001602 Tktt_GetAttr, /*tp_getattr */
1603 0, /*tp_setattr */
1604 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001605 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001606 0, /*tp_as_number */
1607 0, /*tp_as_sequence */
1608 0, /*tp_as_mapping */
1609 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001610};
1611
Barry Warsawfa701a81997-01-16 00:15:11 +00001612
1613
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001614/** Timer Handler **/
1615
1616static void
Fred Drake509d79a2000-07-08 04:04:38 +00001617TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001618{
Guido van Rossum00d93061998-05-28 23:06:38 +00001619 TkttObject *v = (TkttObject *)clientData;
1620 PyObject *func = v->func;
1621 PyObject *res;
1622
1623 if (func == NULL)
1624 return;
1625
1626 v->func = NULL;
1627
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001628 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001629
1630 res = PyEval_CallObject(func, NULL);
1631 Py_DECREF(func);
1632 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001633
Barry Warsawfa701a81997-01-16 00:15:11 +00001634 if (res == NULL) {
1635 errorInCmd = 1;
1636 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1637 }
1638 else
1639 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001640
1641 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001642}
1643
1644static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001645Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001646{
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 int milliseconds;
1648 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001649 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001650
Guido van Rossum2834b972000-10-06 16:58:26 +00001651 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1652 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 return NULL;
1654 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001655 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001656 return NULL;
1657 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001658 v = Tktt_New(func);
1659 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1660 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001661
Guido van Rossum00d93061998-05-28 23:06:38 +00001662 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001663}
1664
Barry Warsawfa701a81997-01-16 00:15:11 +00001665
Guido van Rossum18468821994-06-20 07:49:28 +00001666/** Event Loop **/
1667
Guido van Rossum18468821994-06-20 07:49:28 +00001668static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001669Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001670{
Barry Warsawfa701a81997-01-16 00:15:11 +00001671 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001672#ifdef WITH_THREAD
1673 PyThreadState *tstate = PyThreadState_Get();
1674#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001675
Guido van Rossum43713e52000-02-29 13:59:29 +00001676 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001677 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001678
Barry Warsawfa701a81997-01-16 00:15:11 +00001679 quitMainLoop = 0;
1680 while (Tk_GetNumMainWindows() > threshold &&
1681 !quitMainLoop &&
1682 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001683 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001684 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001685
1686#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001687 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001688 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001689 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001691 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001692 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001693 if (result == 0)
1694 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001695 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001696#else
1697 result = Tcl_DoOneEvent(0);
1698#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001699
Guido van Rossum35d43371997-08-02 00:09:09 +00001700 if (PyErr_CheckSignals() != 0)
1701 return NULL;
1702 if (result < 0)
1703 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001704 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001706
Barry Warsawfa701a81997-01-16 00:15:11 +00001707 if (errorInCmd) {
1708 errorInCmd = 0;
1709 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1710 excInCmd = valInCmd = trbInCmd = NULL;
1711 return NULL;
1712 }
1713 Py_INCREF(Py_None);
1714 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001715}
1716
1717static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001718Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001719{
Guido van Rossum35d43371997-08-02 00:09:09 +00001720 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001721 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001722
Guido van Rossum43713e52000-02-29 13:59:29 +00001723 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001724 return NULL;
1725
Guido van Rossum00d93061998-05-28 23:06:38 +00001726 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001727 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001728 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001729 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001730}
1731
1732static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001733Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001734{
1735
Guido van Rossum43713e52000-02-29 13:59:29 +00001736 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001737 return NULL;
1738
1739 quitMainLoop = 1;
1740 Py_INCREF(Py_None);
1741 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001742}
1743
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001744static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001745Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001746{
1747
Guido van Rossum43713e52000-02-29 13:59:29 +00001748 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001749 return NULL;
1750
1751 return PyInt_FromLong((long)Tkapp_Interp(self));
1752}
1753
Barry Warsawfa701a81997-01-16 00:15:11 +00001754
1755
Guido van Rossum18468821994-06-20 07:49:28 +00001756/**** Tkapp Method List ****/
1757
1758static PyMethodDef Tkapp_methods[] =
1759{
Guido van Rossum35d43371997-08-02 00:09:09 +00001760 {"call", Tkapp_Call, 0},
1761 {"globalcall", Tkapp_GlobalCall, 0},
1762 {"eval", Tkapp_Eval, 1},
1763 {"globaleval", Tkapp_GlobalEval, 1},
1764 {"evalfile", Tkapp_EvalFile, 1},
1765 {"record", Tkapp_Record, 1},
1766 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1767 {"setvar", Tkapp_SetVar, 1},
1768 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1769 {"getvar", Tkapp_GetVar, 1},
1770 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1771 {"unsetvar", Tkapp_UnsetVar, 1},
1772 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1773 {"getint", Tkapp_GetInt, 1},
1774 {"getdouble", Tkapp_GetDouble, 1},
1775 {"getboolean", Tkapp_GetBoolean, 1},
1776 {"exprstring", Tkapp_ExprString, 1},
1777 {"exprlong", Tkapp_ExprLong, 1},
1778 {"exprdouble", Tkapp_ExprDouble, 1},
1779 {"exprboolean", Tkapp_ExprBoolean, 1},
1780 {"splitlist", Tkapp_SplitList, 1},
1781 {"split", Tkapp_Split, 1},
1782 {"merge", Tkapp_Merge, 0},
1783 {"createcommand", Tkapp_CreateCommand, 1},
1784 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001785#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001786 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1787 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001788#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001789 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 {"mainloop", Tkapp_MainLoop, 1},
1791 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001792 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001793 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001794 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001795};
1796
Barry Warsawfa701a81997-01-16 00:15:11 +00001797
1798
Guido van Rossum18468821994-06-20 07:49:28 +00001799/**** Tkapp Type Methods ****/
1800
1801static void
Fred Drake509d79a2000-07-08 04:04:38 +00001802Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001803{
Guido van Rossum00d93061998-05-28 23:06:38 +00001804 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001805 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001806 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001807 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001808 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001809}
1810
1811static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001812Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001813{
Guido van Rossum35d43371997-08-02 00:09:09 +00001814 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001815}
1816
1817static PyTypeObject Tkapp_Type =
1818{
Guido van Rossum35d43371997-08-02 00:09:09 +00001819 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001820 0, /*ob_size */
1821 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 0, /*tp_itemsize */
1824 Tkapp_Dealloc, /*tp_dealloc */
1825 0, /*tp_print */
1826 Tkapp_GetAttr, /*tp_getattr */
1827 0, /*tp_setattr */
1828 0, /*tp_compare */
1829 0, /*tp_repr */
1830 0, /*tp_as_number */
1831 0, /*tp_as_sequence */
1832 0, /*tp_as_mapping */
1833 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001834};
1835
Barry Warsawfa701a81997-01-16 00:15:11 +00001836
1837
Guido van Rossum18468821994-06-20 07:49:28 +00001838/**** Tkinter Module ****/
1839
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001840typedef struct {
1841 PyObject* tuple;
1842 int size; /* current size */
1843 int maxsize; /* allocated size */
1844} FlattenContext;
1845
1846static int
1847_bump(FlattenContext* context, int size)
1848{
Guido van Rossum2834b972000-10-06 16:58:26 +00001849 /* expand tuple to hold (at least) size new items.
1850 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001851
1852 int maxsize = context->maxsize * 2;
1853
1854 if (maxsize < context->size + size)
1855 maxsize = context->size + size;
1856
1857 context->maxsize = maxsize;
1858
Tim Peters4324aa32001-05-28 22:30:08 +00001859 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001860}
1861
1862static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001863_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001864{
1865 /* add tuple or list to argument tuple (recursively) */
1866
1867 int i, size;
1868
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001869 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001870 PyErr_SetString(PyExc_ValueError,
1871 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001872 return 0;
1873 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001874 size = PyList_GET_SIZE(item);
1875 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001876 if (context->size + size > context->maxsize &&
1877 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001878 return 0;
1879 /* copy items to output tuple */
1880 for (i = 0; i < size; i++) {
1881 PyObject *o = PyList_GET_ITEM(item, i);
1882 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001883 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001884 return 0;
1885 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001886 if (context->size + 1 > context->maxsize &&
1887 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001888 return 0;
1889 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001890 PyTuple_SET_ITEM(context->tuple,
1891 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001892 }
1893 }
1894 } else if (PyTuple_Check(item)) {
1895 /* same, for tuples */
1896 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001897 if (context->size + size > context->maxsize &&
1898 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001899 return 0;
1900 for (i = 0; i < size; i++) {
1901 PyObject *o = PyTuple_GET_ITEM(item, i);
1902 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001903 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001904 return 0;
1905 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001906 if (context->size + 1 > context->maxsize &&
1907 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001908 return 0;
1909 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001910 PyTuple_SET_ITEM(context->tuple,
1911 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001912 }
1913 }
1914 } else {
1915 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1916 return 0;
1917 }
1918 return 1;
1919}
1920
1921static PyObject *
1922Tkinter_Flatten(PyObject* self, PyObject* args)
1923{
1924 FlattenContext context;
1925 PyObject* item;
1926
1927 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1928 return NULL;
1929
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001930 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001931 if (context.maxsize <= 0)
1932 return PyTuple_New(0);
1933
1934 context.tuple = PyTuple_New(context.maxsize);
1935 if (!context.tuple)
1936 return NULL;
1937
1938 context.size = 0;
1939
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001940 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001941 return NULL;
1942
Tim Peters4324aa32001-05-28 22:30:08 +00001943 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001944 return NULL;
1945
1946 return context.tuple;
1947}
1948
Guido van Rossum18468821994-06-20 07:49:28 +00001949static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001950Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001951{
Barry Warsawfa701a81997-01-16 00:15:11 +00001952 char *screenName = NULL;
1953 char *baseName = NULL;
1954 char *className = NULL;
1955 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001956
Guido van Rossum35d43371997-08-02 00:09:09 +00001957 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001958 if (baseName != NULL)
1959 baseName++;
1960 else
1961 baseName = Py_GetProgramName();
1962 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001963
Guido van Rossum43713e52000-02-29 13:59:29 +00001964 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 &screenName, &baseName, &className,
1966 &interactive))
1967 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001968
Barry Warsawfa701a81997-01-16 00:15:11 +00001969 return (PyObject *) Tkapp_New(screenName, baseName, className,
1970 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001971}
1972
1973static PyMethodDef moduleMethods[] =
1974{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001975 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001977#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001978 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1979 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001980#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001981 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001982 {"mainloop", Tkapp_MainLoop, 1},
1983 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001984 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001985 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001986};
1987
Guido van Rossum7bf15641998-05-22 18:28:17 +00001988#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001989
1990static int stdin_ready = 0;
1991
Guido van Rossumad4db171998-06-13 13:56:28 +00001992#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001993static void
Fred Drake509d79a2000-07-08 04:04:38 +00001994MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001995{
1996 stdin_ready = 1;
1997}
Guido van Rossumad4db171998-06-13 13:56:28 +00001998#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001999
Guido van Rossum00d93061998-05-28 23:06:38 +00002000static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002001
Guido van Rossum18468821994-06-20 07:49:28 +00002002static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002003EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002004{
Guido van Rossumad4db171998-06-13 13:56:28 +00002005#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002006 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002007#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002008#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002009 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002010#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002011 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002012 errorInCmd = 0;
2013#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002014 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002015 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002016#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002017 while (!errorInCmd && !stdin_ready) {
2018 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002019#ifdef MS_WINDOWS
2020 if (_kbhit()) {
2021 stdin_ready = 1;
2022 break;
2023 }
2024#endif
2025#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002026 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002027 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002028 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002029
Guido van Rossum00d93061998-05-28 23:06:38 +00002030 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002031
2032 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002033 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002034 if (result == 0)
2035 Sleep(20);
2036 Py_END_ALLOW_THREADS
2037#else
2038 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002039#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002040
2041 if (result < 0)
2042 break;
2043 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002044#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002045 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002046#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002047 if (errorInCmd) {
2048 errorInCmd = 0;
2049 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2050 excInCmd = valInCmd = trbInCmd = NULL;
2051 PyErr_Print();
2052 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002053#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002054 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002055#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002056 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002057}
Guido van Rossum18468821994-06-20 07:49:28 +00002058
Guido van Rossum00d93061998-05-28 23:06:38 +00002059#endif
2060
Guido van Rossum7bf15641998-05-22 18:28:17 +00002061static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002062EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002063{
Guido van Rossum00d93061998-05-28 23:06:38 +00002064#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002065 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002066#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002067 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002068#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002069 PyOS_InputHook = EventHook;
2070 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002071#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002072}
2073
2074static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002075DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002076{
Guido van Rossum00d93061998-05-28 23:06:38 +00002077#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002078 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2079 PyOS_InputHook = NULL;
2080 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002081#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002082}
2083
Barry Warsawfa701a81997-01-16 00:15:11 +00002084
2085/* all errors will be checked in one fell swoop in init_tkinter() */
2086static void
Fred Drake509d79a2000-07-08 04:04:38 +00002087ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002088{
2089 PyObject *v = PyInt_FromLong(val);
2090 if (v) {
2091 PyDict_SetItemString(d, name, v);
2092 Py_DECREF(v);
2093 }
2094}
2095static void
Fred Drake509d79a2000-07-08 04:04:38 +00002096ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002097{
2098 PyObject *v = PyString_FromString(val);
2099 if (v) {
2100 PyDict_SetItemString(d, name, v);
2101 Py_DECREF(v);
2102 }
2103}
2104
2105
Guido van Rossum3886bb61998-12-04 18:50:17 +00002106DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002107init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002108{
Barry Warsawfa701a81997-01-16 00:15:11 +00002109 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002110
Barry Warsawfa701a81997-01-16 00:15:11 +00002111 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002112
2113#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002114 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002115#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002116
Barry Warsawfa701a81997-01-16 00:15:11 +00002117 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002118
Barry Warsawfa701a81997-01-16 00:15:11 +00002119 d = PyModule_GetDict(m);
2120 Tkinter_TclError = Py_BuildValue("s", "TclError");
2121 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002122
Guido van Rossum35d43371997-08-02 00:09:09 +00002123 ins_long(d, "READABLE", TCL_READABLE);
2124 ins_long(d, "WRITABLE", TCL_WRITABLE);
2125 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2126 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2127 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2128 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2129 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2130 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2131 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002132 ins_string(d, "TK_VERSION", TK_VERSION);
2133 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002134
Guido van Rossum83551bf1997-09-13 00:44:23 +00002135 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002136
2137 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002138 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2139
Guido van Rossume187b0e2000-03-27 21:46:29 +00002140 /* This helps the dynamic loader; in Unicode aware Tcl versions
2141 it also helps Tcl find its encodings. */
2142 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002143
Barry Warsawfa701a81997-01-16 00:15:11 +00002144 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002145 return;
2146
Guido van Rossum43ff8681998-07-14 18:02:13 +00002147#if 0
2148 /* This was not a good idea; through <Destroy> bindings,
2149 Tcl_Finalize() may invoke Python code but at that point the
2150 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002151 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002152#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002153
Jack Jansen34cc5c31995-10-31 16:15:12 +00002154#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002155 /*
2156 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2157 ** Most of the initializations in that routine (toolbox init calls and
2158 ** such) have already been done for us, so we only need these.
2159 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002160 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002161
2162 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002163#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002164 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002165#endif /* GENERATINGCFM */
2166#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002167}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002168
Guido van Rossumec22c921996-02-25 04:50:29 +00002169
Barry Warsawfa701a81997-01-16 00:15:11 +00002170
Guido van Rossum9722ad81995-09-22 23:49:28 +00002171#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002172
2173/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002174** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002175*/
2176
Guido van Rossum9722ad81995-09-22 23:49:28 +00002177void
2178panic(char * format, ...)
2179{
Barry Warsawfa701a81997-01-16 00:15:11 +00002180 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002181
Barry Warsawfa701a81997-01-16 00:15:11 +00002182 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002183
Guido van Rossum227cf761998-08-05 13:53:32 +00002184 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002185 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002186
Barry Warsawfa701a81997-01-16 00:15:11 +00002187 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002188
Barry Warsawfa701a81997-01-16 00:15:11 +00002189 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002190}
Jack Jansen40b546d1995-11-14 10:34:45 +00002191
Guido van Rossumec22c921996-02-25 04:50:29 +00002192/*
2193** Pass events to SIOUX before passing them to Tk.
2194*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002195
Guido van Rossumec22c921996-02-25 04:50:29 +00002196static int
Fred Drake509d79a2000-07-08 04:04:38 +00002197PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002198{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002199 WindowPtr frontwin;
2200 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002201 ** Sioux eats too many events, so we don't pass it everything. We
2202 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002203 ** the Sioux window is frontmost. This means that Tk menus don't work
2204 ** in that case, but at least we can scroll the sioux window.
2205 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2206 ** part of the external interface of Sioux...
2207 */
2208 frontwin = FrontWindow();
2209 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2210 if (SIOUXHandleOneEvent(eventPtr))
2211 return 0; /* Nothing happened to the Tcl event queue */
2212 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002213 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002214}
2215
Guido van Rossumec22c921996-02-25 04:50:29 +00002216#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002217
2218/*
2219** Additional Mac specific code for dealing with shared libraries.
2220*/
2221
2222#include <Resources.h>
2223#include <CodeFragments.h>
2224
2225static int loaded_from_shlib = 0;
2226static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002227
Jack Jansen34cc5c31995-10-31 16:15:12 +00002228/*
2229** If this module is dynamically loaded the following routine should
2230** be the init routine. It takes care of adding the shared library to
2231** the resource-file chain, so that the tk routines can find their
2232** resources.
2233*/
2234OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002235init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002236{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002237 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002238 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002239 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002240 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2241 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002242 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002243 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2244 loaded_from_shlib = 1;
2245 }
2246 return noErr;
2247}
2248
2249/*
2250** Insert the library resources into the search path. Put them after
2251** the resources from the application. Again, we ignore errors.
2252*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002253static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002254mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002255{
2256 if ( !loaded_from_shlib )
2257 return;
2258 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2259}
2260
Guido van Rossumec22c921996-02-25 04:50:29 +00002261#endif /* GENERATINGCFM */
2262#endif /* macintosh */