blob: 6e99359204f22d2fa37c6172e4970a942c5e4a41 [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
Jack Jansencb852442001-12-09 23:15:56 +000044#ifdef TK_FRAMEWORK
45#include <Tcl/tcl.h>
46#include <Tk/tk.h>
47#else
Guido van Rossum18468821994-06-20 07:49:28 +000048#include <tcl.h>
49#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000050#endif
Guido van Rossum18468821994-06-20 07:49:28 +000051
Guido van Rossum3e819a71997-08-01 19:29:02 +000052#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
53
Guido van Rossuma80649b2000-03-28 20:07:05 +000054#if TKMAJORMINOR < 8000
55#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000056#endif
57
Guido van Rossuma80649b2000-03-28 20:07:05 +000058#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000059/* Sigh, we have to include this to get at the tcl qd pointer */
60#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000061/* And this one we need to clear the menu bar */
62#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000063#endif
64
Jack Jansen84c10b12001-07-16 19:32:52 +000065#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
66/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000067#define HAVE_CREATEFILEHANDLER
68#endif
69
Guido van Rossum00d93061998-05-28 23:06:38 +000070#ifdef HAVE_CREATEFILEHANDLER
71
72/* Tcl_CreateFileHandler() changed several times; these macros deal with the
73 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
74 Unix, only because Jack added it back); when available on Windows, it only
75 applies to sockets. */
76
Guido van Rossum7bf15641998-05-22 18:28:17 +000077#ifdef MS_WINDOWS
78#define FHANDLETYPE TCL_WIN_SOCKET
79#else
80#define FHANDLETYPE TCL_UNIX_FD
81#endif
82
Guido van Rossum00d93061998-05-28 23:06:38 +000083/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
84 which uses this to handle Tcl events while the user is typing commands. */
85
86#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000087#define WAIT_FOR_STDIN
88#endif
89
Guido van Rossum00d93061998-05-28 23:06:38 +000090#endif /* HAVE_CREATEFILEHANDLER */
91
Guido van Rossumad4db171998-06-13 13:56:28 +000092#ifdef MS_WINDOWS
93#include <conio.h>
94#define WAIT_FOR_STDIN
95#endif
96
Guido van Rossum00d93061998-05-28 23:06:38 +000097#ifdef WITH_THREAD
98
99/* The threading situation is complicated. Tcl is not thread-safe, except for
100 Tcl 8.1, which will probably remain in alpha status for another 6 months
101 (and the README says that Tk will probably remain thread-unsafe forever).
102 So we need to use a lock around all uses of Tcl. Previously, the Python
103 interpreter lock was used for this. However, this causes problems when
104 other Python threads need to run while Tcl is blocked waiting for events.
105
106 To solve this problem, a separate lock for Tcl is introduced. Holding it
107 is incompatible with holding Python's interpreter lock. The following four
108 macros manipulate both locks together.
109
110 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
111 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
112 that could call an event handler, or otherwise affect the state of a Tcl
113 interpreter. These assume that the surrounding code has the Python
114 interpreter lock; inside the brackets, the Python interpreter lock has been
115 released and the lock for Tcl has been acquired.
116
Guido van Rossum5e977831998-06-15 14:03:52 +0000117 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
118 (For example, when transferring data from the Tcl interpreter result to a
119 Python string object.) This can be done by using different macros to close
120 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
121 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
122 releases the Tcl lock.
123
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000124 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000125 handlers when the handler needs to use Python. Such event handlers are
126 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000127 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000128 the Python interpreter lock, restoring the appropriate thread state, and
129 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
130 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000131 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000132
133 These locks expand to several statements and brackets; they should not be
134 used in branches of if statements and the like.
135
136*/
137
Guido van Rossum65d5b571998-12-21 19:32:43 +0000138static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000139static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000140
141#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000142 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000143 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000144
145#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000146 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000147
Guido van Rossum62320c91998-06-15 04:36:09 +0000148#define ENTER_OVERLAP \
149 Py_END_ALLOW_THREADS
150
151#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000152 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000153
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000154#define ENTER_PYTHON \
155 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000156 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000157
158#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000159 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000160 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000161
162#else
163
164#define ENTER_TCL
165#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000166#define ENTER_OVERLAP
167#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000168#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000169#define LEAVE_PYTHON
170
171#endif
172
Guido van Rossumec22c921996-02-25 04:50:29 +0000173#ifdef macintosh
174
175/*
176** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000177** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000178*/
179
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000180/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000181#define FREECAST (char *)
182
Guido van Rossumec22c921996-02-25 04:50:29 +0000183#include <Events.h> /* For EventRecord */
184
Fred Drake509d79a2000-07-08 04:04:38 +0000185typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000186void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
187int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000188
Guido van Rossum2834b972000-10-06 16:58:26 +0000189staticforward int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000190
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000191#include <SIOUX.h>
192extern int SIOUXIsAppWindow(WindowPtr);
193
Guido van Rossumec22c921996-02-25 04:50:29 +0000194#endif /* macintosh */
195
Guido van Rossum97867b21996-08-08 19:09:53 +0000196#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000197#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000198#endif
199
Guido van Rossum18468821994-06-20 07:49:28 +0000200/**** Tkapp Object Declaration ****/
201
202staticforward PyTypeObject Tkapp_Type;
203
Guido van Rossum00d93061998-05-28 23:06:38 +0000204typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000205 PyObject_HEAD
206 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000207} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000208
209#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000210#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000211#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000212
Guido van Rossum35d43371997-08-02 00:09:09 +0000213#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000214(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000215
Barry Warsawfa701a81997-01-16 00:15:11 +0000216
217
Guido van Rossum18468821994-06-20 07:49:28 +0000218/**** Error Handling ****/
219
220static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000221static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000222static int errorInCmd = 0;
223static PyObject *excInCmd;
224static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000226
Barry Warsawfa701a81997-01-16 00:15:11 +0000227
228
Guido van Rossum18468821994-06-20 07:49:28 +0000229static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000230Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000231{
Barry Warsawfa701a81997-01-16 00:15:11 +0000232 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
233 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000234}
235
Barry Warsawfa701a81997-01-16 00:15:11 +0000236
Barry Warsawfa701a81997-01-16 00:15:11 +0000237
Guido van Rossum18468821994-06-20 07:49:28 +0000238/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000239
240#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000241#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000242
Guido van Rossum00d93061998-05-28 23:06:38 +0000243/* Millisecond sleep() for Unix platforms. */
244
245static void
Fred Drake509d79a2000-07-08 04:04:38 +0000246Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000247{
248 /* XXX Too bad if you don't have select(). */
249 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000250 t.tv_sec = milli/1000;
251 t.tv_usec = (milli%1000) * 1000;
252 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
253}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000254#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000255#endif /* WITH_THREAD */
256
257
Guido van Rossum18468821994-06-20 07:49:28 +0000258static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000259AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000260{
Guido van Rossum35d43371997-08-02 00:09:09 +0000261 if (PyString_Check(value))
262 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000263#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000264 else if (PyUnicode_Check(value)) {
265 PyObject *v = PyUnicode_AsUTF8String(value);
266 if (v == NULL)
267 return NULL;
268 if (PyList_Append(tmp, v) != 0) {
269 Py_DECREF(v);
270 return NULL;
271 }
272 Py_DECREF(v);
273 return PyString_AsString(v);
274 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000275#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000276 else {
277 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000278 if (v == NULL)
279 return NULL;
280 if (PyList_Append(tmp, v) != 0) {
281 Py_DECREF(v);
282 return NULL;
283 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000284 Py_DECREF(v);
285 return PyString_AsString(v);
286 }
Guido van Rossum18468821994-06-20 07:49:28 +0000287}
288
Barry Warsawfa701a81997-01-16 00:15:11 +0000289
290
Guido van Rossum18468821994-06-20 07:49:28 +0000291#define ARGSZ 64
292
293static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000294Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000295{
Barry Warsawfa701a81997-01-16 00:15:11 +0000296 PyObject *tmp = NULL;
297 char *argvStore[ARGSZ];
298 char **argv = NULL;
299 int fvStore[ARGSZ];
300 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000301 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000303
Barry Warsawfa701a81997-01-16 00:15:11 +0000304 if (!(tmp = PyList_New(0)))
305 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000306
Barry Warsawfa701a81997-01-16 00:15:11 +0000307 argv = argvStore;
308 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000309
Barry Warsawfa701a81997-01-16 00:15:11 +0000310 if (args == NULL)
311 argc = 0;
312
313 else if (!PyTuple_Check(args)) {
314 argc = 1;
315 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000316 if (!(argv[0] = AsString(args, tmp)))
317 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000318 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000319 else {
320 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000321
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000323 argv = (char **)ckalloc(argc * sizeof(char *));
324 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (argv == NULL || fv == NULL) {
326 PyErr_NoMemory();
327 goto finally;
328 }
329 }
330
331 for (i = 0; i < argc; i++) {
332 PyObject *v = PyTuple_GetItem(args, i);
333 if (PyTuple_Check(v)) {
334 fv[i] = 1;
335 if (!(argv[i] = Merge(v)))
336 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000337 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000338 }
339 else if (v == Py_None) {
340 argc = i;
341 break;
342 }
343 else {
344 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000345 if (!(argv[i] = AsString(v, tmp)))
346 goto finally;
347 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000348 }
349 }
Guido van Rossum18468821994-06-20 07:49:28 +0000350 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000352 if (res == NULL)
353 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000356 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 if (fv[i]) {
358 ckfree(argv[i]);
359 }
360 if (argv != argvStore)
361 ckfree(FREECAST argv);
362 if (fv != fvStore)
363 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000364
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 Py_DECREF(tmp);
366 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000372Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000373{
Barry Warsawfa701a81997-01-16 00:15:11 +0000374 int argc;
375 char **argv;
376 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000377
Barry Warsawfa701a81997-01-16 00:15:11 +0000378 if (list == NULL) {
379 Py_INCREF(Py_None);
380 return Py_None;
381 }
Guido van Rossum18468821994-06-20 07:49:28 +0000382
Guido van Rossum00d93061998-05-28 23:06:38 +0000383 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 /* Not a list.
385 * Could be a quoted string containing funnies, e.g. {"}.
386 * Return the string itself.
387 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 return PyString_FromString(list);
389 }
Guido van Rossum18468821994-06-20 07:49:28 +0000390
Barry Warsawfa701a81997-01-16 00:15:11 +0000391 if (argc == 0)
392 v = PyString_FromString("");
393 else if (argc == 1)
394 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000395 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 int i;
397 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000400 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000401 Py_DECREF(v);
402 v = NULL;
403 break;
404 }
405 PyTuple_SetItem(v, i, w);
406 }
407 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000408 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000410}
411
Barry Warsawfa701a81997-01-16 00:15:11 +0000412
413
Guido van Rossum18468821994-06-20 07:49:28 +0000414/**** Tkapp Object ****/
415
416#ifndef WITH_APPINIT
417int
Fred Drake509d79a2000-07-08 04:04:38 +0000418Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000419{
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000421
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 main = Tk_MainWindow(interp);
423 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000424 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return TCL_ERROR;
426 }
427 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000428 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000429 return TCL_ERROR;
430 }
431 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000432}
433#endif /* !WITH_APPINIT */
434
Guido van Rossum18468821994-06-20 07:49:28 +0000435
Barry Warsawfa701a81997-01-16 00:15:11 +0000436
437
438/* Initialize the Tk application; see the `main' function in
439 * `tkMain.c'.
440 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000441
Thomas Wouters58d05102000-07-24 14:43:35 +0000442static void EnableEventHook(void); /* Forward */
443static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000444
Barry Warsawfa701a81997-01-16 00:15:11 +0000445static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000446Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000447{
448 TkappObject *v;
449 char *argv0;
450
Guido van Rossumb18618d2000-05-03 23:44:39 +0000451 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 if (v == NULL)
453 return NULL;
454
455 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000456
Guido van Rossuma80649b2000-03-28 20:07:05 +0000457#if defined(macintosh)
458 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000459 ClearMenuBar();
460 TkMacInitMenus(v->interp);
461#endif
Jack Jansencb852442001-12-09 23:15:56 +0000462
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000463 /* Delete the 'exit' command, which can screw things up */
464 Tcl_DeleteCommand(v->interp, "exit");
465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (screenName != NULL)
467 Tcl_SetVar2(v->interp, "env", "DISPLAY",
468 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000469
Barry Warsawfa701a81997-01-16 00:15:11 +0000470 if (interactive)
471 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
472 else
473 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000474
Barry Warsawfa701a81997-01-16 00:15:11 +0000475 /* This is used to get the application class for Tk 4.1 and up */
476 argv0 = (char*)ckalloc(strlen(className) + 1);
477 if (!argv0) {
478 PyErr_NoMemory();
479 Py_DECREF(v);
480 return NULL;
481 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000482
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000484 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000485 argv0[0] = tolower(argv0[0]);
486 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
487 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000488
Barry Warsawfa701a81997-01-16 00:15:11 +0000489 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000490 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000491
Guido van Rossum7bf15641998-05-22 18:28:17 +0000492 EnableEventHook();
493
Barry Warsawfa701a81997-01-16 00:15:11 +0000494 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000495}
496
Barry Warsawfa701a81997-01-16 00:15:11 +0000497
498
Guido van Rossum18468821994-06-20 07:49:28 +0000499/** Tcl Eval **/
500
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000501#if TKMAJORMINOR >= 8001
502#define USING_OBJECTS
503#endif
504
505#ifdef USING_OBJECTS
506
507static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000508AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000509{
510 Tcl_Obj *result;
511
512 if (PyString_Check(value))
513 return Tcl_NewStringObj(PyString_AS_STRING(value),
514 PyString_GET_SIZE(value));
515 else if (PyInt_Check(value))
516 return Tcl_NewLongObj(PyInt_AS_LONG(value));
517 else if (PyFloat_Check(value))
518 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
519 else if (PyTuple_Check(value)) {
520 Tcl_Obj **argv = (Tcl_Obj**)
521 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
522 int i;
523 if(!argv)
524 return 0;
525 for(i=0;i<PyTuple_Size(value);i++)
526 argv[i] = AsObj(PyTuple_GetItem(value,i));
527 result = Tcl_NewListObj(PyTuple_Size(value), argv);
528 ckfree(FREECAST argv);
529 return result;
530 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000531#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000532 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000533#if TKMAJORMINOR <= 8001
534 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000535 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000536 if (!utf8)
537 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000538 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
539 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000540 Py_DECREF(utf8);
541 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000542#else /* TKMAJORMINOR > 8001 */
543 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
544 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
545 /* XXX Should really test this at compile time */
546 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000547 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000548 return 0;
549 }
550 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
551 PyUnicode_GET_SIZE(value));
552#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000553 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000554#endif
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000555 else {
556 PyObject *v = PyObject_Str(value);
557 if (!v)
558 return 0;
559 result = AsObj(v);
560 Py_DECREF(v);
561 return result;
562 }
563}
564
Guido van Rossum18468821994-06-20 07:49:28 +0000565static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000566Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000567{
Guido van Rossum632de272000-03-29 00:19:50 +0000568 Tcl_Obj *objStore[ARGSZ];
569 Tcl_Obj **objv = NULL;
570 int objc = 0, i;
571 PyObject *res = NULL;
572 Tcl_Interp *interp = Tkapp_Interp(self);
573 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
574 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000575
Guido van Rossum632de272000-03-29 00:19:50 +0000576 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000577
Guido van Rossum212643f1998-04-29 16:22:14 +0000578 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000579 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000580
Guido van Rossum212643f1998-04-29 16:22:14 +0000581 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000582 objv[0] = AsObj(args);
583 if (objv[0] == 0)
584 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000585 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000586 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000587 }
588 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000589 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000590
Guido van Rossum632de272000-03-29 00:19:50 +0000591 if (objc > ARGSZ) {
592 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
593 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000594 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000595 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000596 goto finally;
597 }
598 }
599
Guido van Rossum632de272000-03-29 00:19:50 +0000600 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000601 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000602 if (v == Py_None) {
603 objc = i;
604 break;
605 }
Guido van Rossum632de272000-03-29 00:19:50 +0000606 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000607 if (!objv[i]) {
608 /* Reset objc, so it attempts to clear
609 objects only up to i. */
610 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000611 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000612 }
Guido van Rossum632de272000-03-29 00:19:50 +0000613 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000614 }
615 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000616
Guido van Rossum62320c91998-06-15 04:36:09 +0000617 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000618
619 i = Tcl_EvalObjv(interp, objc, objv, flags);
620
Guido van Rossum62320c91998-06-15 04:36:09 +0000621 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000622 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000623 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000624 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000625 /* We could request the object result here, but doing
626 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000627 char *s = Tcl_GetStringResult(interp);
628 char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000629
Guido van Rossum990f5c62000-05-04 15:07:16 +0000630 /* If the result contains any bytes with the top bit set,
631 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000632#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000633 while (*p != '\0') {
634 if (*p & 0x80)
635 break;
636 p++;
637 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000638
Guido van Rossum990f5c62000-05-04 15:07:16 +0000639 if (*p == '\0')
640 res = PyString_FromStringAndSize(s, (int)(p-s));
641 else {
642 /* Convert UTF-8 to Unicode string */
643 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000644 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
645 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000646 PyErr_Clear();
647 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000648 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000649 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000650#else
651 p = strchr(p, '\0');
652 res = PyString_FromStringAndSize(s, (int)(p-s));
653#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000654 }
Guido van Rossum632de272000-03-29 00:19:50 +0000655
Guido van Rossum62320c91998-06-15 04:36:09 +0000656 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000657
Guido van Rossum212643f1998-04-29 16:22:14 +0000658 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000659 for (i = 0; i < objc; i++)
660 Tcl_DecrRefCount(objv[i]);
661 if (objv != objStore)
662 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 return res;
664}
665
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000666#else /* !USING_OBJECTS */
667
668static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000669Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000670{
671 /* This is copied from Merge() */
672 PyObject *tmp = NULL;
673 char *argvStore[ARGSZ];
674 char **argv = NULL;
675 int fvStore[ARGSZ];
676 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000677 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000678 PyObject *res = NULL; /* except this has a different type */
679 Tcl_CmdInfo info; /* and this is added */
680 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
681
682 if (!(tmp = PyList_New(0)))
683 return NULL;
684
685 argv = argvStore;
686 fv = fvStore;
687
688 if (args == NULL)
689 argc = 0;
690
691 else if (!PyTuple_Check(args)) {
692 argc = 1;
693 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000694 if (!(argv[0] = AsString(args, tmp)))
695 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000696 }
697 else {
698 argc = PyTuple_Size(args);
699
700 if (argc > ARGSZ) {
701 argv = (char **)ckalloc(argc * sizeof(char *));
702 fv = (int *)ckalloc(argc * sizeof(int));
703 if (argv == NULL || fv == NULL) {
704 PyErr_NoMemory();
705 goto finally;
706 }
707 }
708
709 for (i = 0; i < argc; i++) {
710 PyObject *v = PyTuple_GetItem(args, i);
711 if (PyTuple_Check(v)) {
712 fv[i] = 1;
713 if (!(argv[i] = Merge(v)))
714 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000715 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000716 }
717 else if (v == Py_None) {
718 argc = i;
719 break;
720 }
721 else {
722 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000723 if (!(argv[i] = AsString(v, tmp)))
724 goto finally;
725 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000726 }
727 }
728 }
729 /* End code copied from Merge() */
730
731 /* All this to avoid a call to Tcl_Merge() and the corresponding call
732 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
733 if (Py_VerboseFlag >= 2) {
734 for (i = 0; i < argc; i++)
735 PySys_WriteStderr("%s ", argv[i]);
736 }
737 ENTER_TCL
738 info.proc = NULL;
739 if (argc < 1 ||
740 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
741 info.proc == NULL)
742 {
743 char *cmd;
744 cmd = Tcl_Merge(argc, argv);
745 i = Tcl_Eval(interp, cmd);
746 ckfree(cmd);
747 }
748 else {
749 Tcl_ResetResult(interp);
750 i = (*info.proc)(info.clientData, interp, argc, argv);
751 }
752 ENTER_OVERLAP
753 if (info.proc == NULL && Py_VerboseFlag >= 2)
754 PySys_WriteStderr("... use TclEval ");
755 if (i == TCL_ERROR) {
756 if (Py_VerboseFlag >= 2)
757 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000758 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000759 Tkinter_Error(self);
760 }
761 else {
762 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000763 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
764 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000765 }
766 LEAVE_OVERLAP_TCL
767
768 /* Copied from Merge() again */
769 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000770 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000771 if (fv[i]) {
772 ckfree(argv[i]);
773 }
774 if (argv != argvStore)
775 ckfree(FREECAST argv);
776 if (fv != fvStore)
777 ckfree(FREECAST fv);
778
779 Py_DECREF(tmp);
780 return res;
781}
782
783#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000784
785static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000786Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000787{
Guido van Rossum212643f1998-04-29 16:22:14 +0000788 /* Could do the same here as for Tkapp_Call(), but this is not used
789 much, so I can't be bothered. Unfortunately Tcl doesn't export a
790 way for the user to do what all its Global* variants do (save and
791 reset the scope pointer, call the local version, restore the saved
792 scope pointer). */
793
Guido van Rossum62320c91998-06-15 04:36:09 +0000794 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000795 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000796
Guido van Rossum62320c91998-06-15 04:36:09 +0000797 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000798 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000799 int err;
800 ENTER_TCL
801 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000802 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000803 if (err == TCL_ERROR)
804 res = Tkinter_Error(self);
805 else
806 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000807 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000808 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000809 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000810
811 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000812}
813
814static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000815Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000816{
Barry Warsawfa701a81997-01-16 00:15:11 +0000817 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000818 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000819 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000820
Guido van Rossum43713e52000-02-29 13:59:29 +0000821 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 return NULL;
823
Guido van Rossum00d93061998-05-28 23:06:38 +0000824 ENTER_TCL
825 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000826 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000827 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000828 res = Tkinter_Error(self);
829 else
830 res = PyString_FromString(Tkapp_Result(self));
831 LEAVE_OVERLAP_TCL
832 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000833}
834
835static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000836Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000837{
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000839 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000840 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000841
Guido van Rossum43713e52000-02-29 13:59:29 +0000842 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000844
Guido van Rossum00d93061998-05-28 23:06:38 +0000845 ENTER_TCL
846 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000847 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000848 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000849 res = Tkinter_Error(self);
850 else
851 res = PyString_FromString(Tkapp_Result(self));
852 LEAVE_OVERLAP_TCL
853 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000854}
855
856static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000857Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000858{
Barry Warsawfa701a81997-01-16 00:15:11 +0000859 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000860 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000861 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000862
Guido van Rossum43713e52000-02-29 13:59:29 +0000863 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000865
Guido van Rossum00d93061998-05-28 23:06:38 +0000866 ENTER_TCL
867 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000868 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000869 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000870 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum62320c91998-06-15 04:36:09 +0000872 else
873 res = PyString_FromString(Tkapp_Result(self));
874 LEAVE_OVERLAP_TCL
875 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000876}
877
878static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000879Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000880{
Barry Warsawfa701a81997-01-16 00:15:11 +0000881 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000882 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000883 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000884
Guido van Rossum35d43371997-08-02 00:09:09 +0000885 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000887
Guido van Rossum00d93061998-05-28 23:06:38 +0000888 ENTER_TCL
889 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000890 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000891 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000892 res = Tkinter_Error(self);
893 else
894 res = PyString_FromString(Tkapp_Result(self));
895 LEAVE_OVERLAP_TCL
896 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000897}
898
899static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000900Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000901{
Barry Warsawfa701a81997-01-16 00:15:11 +0000902 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000903
Guido van Rossum43713e52000-02-29 13:59:29 +0000904 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000905 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000906 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000908 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000909
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 Py_INCREF(Py_None);
911 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000912}
913
Barry Warsawfa701a81997-01-16 00:15:11 +0000914
915
Guido van Rossum18468821994-06-20 07:49:28 +0000916/** Tcl Variable **/
917
918static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000919SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000920{
Guido van Rossum00d93061998-05-28 23:06:38 +0000921 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000923 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000924
Guido van Rossum62320c91998-06-15 04:36:09 +0000925 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 if (!tmp)
927 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000928
Guido van Rossum43713e52000-02-29 13:59:29 +0000929 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000930 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000931 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000932 if (s == NULL)
933 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000934 ENTER_TCL
935 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
936 LEAVE_TCL
937 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000938 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000940 if (PyArg_ParseTuple(args, "ssO:setvar",
941 &name1, &name2, &newValue)) {
942 s = AsString(newValue, tmp);
943 if (s == NULL)
944 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000945 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000946 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000947 s, flags);
948 LEAVE_TCL
949 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000950 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000951 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000952 return NULL;
953 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000954 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000955 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000956
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 if (!ok)
958 return Tkinter_Error(self);
959
960 Py_INCREF(Py_None);
961 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000962}
963
964static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000965Tkapp_SetVar(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);
Guido van Rossum18468821994-06-20 07:49:28 +0000968}
969
970static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000971Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000972{
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000974}
975
Barry Warsawfa701a81997-01-16 00:15:11 +0000976
977
Guido van Rossum18468821994-06-20 07:49:28 +0000978static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000979GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000980{
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000982 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000983
Guido van Rossum43713e52000-02-29 13:59:29 +0000984 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000985 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000986 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000987 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000988 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000989
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000991 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000992 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000993
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000995 res = Tkinter_Error(self);
996 else
997 res = PyString_FromString(s);
998 LEAVE_OVERLAP_TCL
999 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001000}
1001
1002static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001003Tkapp_GetVar(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);
Guido van Rossum18468821994-06-20 07:49:28 +00001006}
1007
1008static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001009Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001010{
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001012}
1013
Barry Warsawfa701a81997-01-16 00:15:11 +00001014
1015
Guido van Rossum18468821994-06-20 07:49:28 +00001016static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001017UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001018{
Guido van Rossum35d43371997-08-02 00:09:09 +00001019 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001020 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001022
Guido van Rossum43713e52000-02-29 13:59:29 +00001023 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001025 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001026 if (name2 == NULL)
1027 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1028
1029 else
1030 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001031 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001032
Barry Warsawfa701a81997-01-16 00:15:11 +00001033 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001034 res = Tkinter_Error(self);
1035 else {
1036 Py_INCREF(Py_None);
1037 res = Py_None;
1038 }
1039 LEAVE_OVERLAP_TCL
1040 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001041}
1042
1043static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001044Tkapp_UnsetVar(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);
Guido van Rossum18468821994-06-20 07:49:28 +00001047}
1048
1049static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001050Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001051{
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001053}
1054
Barry Warsawfa701a81997-01-16 00:15:11 +00001055
1056
Guido van Rossum18468821994-06-20 07:49:28 +00001057/** Tcl to Python **/
1058
1059static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001060Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001061{
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 char *s;
1063 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001064
Guido van Rossum43713e52000-02-29 13:59:29 +00001065 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001066 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001067 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 return Tkinter_Error(self);
1069 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001070}
1071
1072static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001073Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001074{
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 char *s;
1076 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001077
Guido van Rossum43713e52000-02-29 13:59:29 +00001078 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001079 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001080 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 return Tkinter_Error(self);
1082 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001083}
1084
1085static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001086Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001087{
Barry Warsawfa701a81997-01-16 00:15:11 +00001088 char *s;
1089 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001090
Guido van Rossum43713e52000-02-29 13:59:29 +00001091 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001092 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001093 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1094 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001096}
1097
1098static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001099Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001100{
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001102 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001103 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001104
Guido van Rossum43713e52000-02-29 13:59:29 +00001105 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001107 ENTER_TCL
1108 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001109 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001110 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001111 res = Tkinter_Error(self);
1112 else
1113 res = Py_BuildValue("s", Tkapp_Result(self));
1114 LEAVE_OVERLAP_TCL
1115 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001116}
1117
1118static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001119Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001120{
Barry Warsawfa701a81997-01-16 00:15:11 +00001121 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001122 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001123 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001124 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001125
Guido van Rossum43713e52000-02-29 13:59:29 +00001126 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001127 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001128 ENTER_TCL
1129 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001130 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001131 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001132 res = Tkinter_Error(self);
1133 else
1134 res = Py_BuildValue("l", v);
1135 LEAVE_OVERLAP_TCL
1136 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001137}
1138
1139static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001140Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001141{
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001143 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001144 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001145 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001146
Guido van Rossum43713e52000-02-29 13:59:29 +00001147 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001149 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001150 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001151 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001152 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001153 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001154 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001155 res = Tkinter_Error(self);
1156 else
1157 res = Py_BuildValue("d", v);
1158 LEAVE_OVERLAP_TCL
1159 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001160}
1161
1162static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001163Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001164{
Barry Warsawfa701a81997-01-16 00:15:11 +00001165 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001166 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001167 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001168 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001169
Guido van Rossum43713e52000-02-29 13:59:29 +00001170 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001172 ENTER_TCL
1173 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001174 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001175 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001176 res = Tkinter_Error(self);
1177 else
1178 res = Py_BuildValue("i", v);
1179 LEAVE_OVERLAP_TCL
1180 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001181}
1182
Barry Warsawfa701a81997-01-16 00:15:11 +00001183
1184
Guido van Rossum18468821994-06-20 07:49:28 +00001185static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001186Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001187{
Barry Warsawfa701a81997-01-16 00:15:11 +00001188 char *list;
1189 int argc;
1190 char **argv;
1191 PyObject *v;
1192 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001193
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001194 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001196
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1198 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001199
Barry Warsawfa701a81997-01-16 00:15:11 +00001200 if (!(v = PyTuple_New(argc)))
1201 return NULL;
1202
1203 for (i = 0; i < argc; i++) {
1204 PyObject *s = PyString_FromString(argv[i]);
1205 if (!s || PyTuple_SetItem(v, i, s)) {
1206 Py_DECREF(v);
1207 v = NULL;
1208 goto finally;
1209 }
1210 }
Guido van Rossum18468821994-06-20 07:49:28 +00001211
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 finally:
1213 ckfree(FREECAST argv);
1214 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001215}
1216
1217static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001218Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001219{
Barry Warsawfa701a81997-01-16 00:15:11 +00001220 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001221
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001222 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001224 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001225}
1226
1227static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001228Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001229{
Barry Warsawfa701a81997-01-16 00:15:11 +00001230 char *s = Merge(args);
1231 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001232
Barry Warsawfa701a81997-01-16 00:15:11 +00001233 if (s) {
1234 res = PyString_FromString(s);
1235 ckfree(s);
1236 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001237
1238 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001239}
1240
Barry Warsawfa701a81997-01-16 00:15:11 +00001241
1242
Guido van Rossum18468821994-06-20 07:49:28 +00001243/** Tcl Command **/
1244
Guido van Rossum00d93061998-05-28 23:06:38 +00001245/* Client data struct */
1246typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001247 PyObject *self;
1248 PyObject *func;
1249} PythonCmd_ClientData;
1250
1251static int
Fred Drake509d79a2000-07-08 04:04:38 +00001252PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001253{
1254 errorInCmd = 1;
1255 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1256 LEAVE_PYTHON
1257 return TCL_ERROR;
1258}
1259
Guido van Rossum18468821994-06-20 07:49:28 +00001260/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001261 * function or method.
1262 */
Guido van Rossum18468821994-06-20 07:49:28 +00001263static int
Fred Drake509d79a2000-07-08 04:04:38 +00001264PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001265{
Guido van Rossum00d93061998-05-28 23:06:38 +00001266 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001268 int i, rv;
1269 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001270
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001271 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001272
Barry Warsawfa701a81997-01-16 00:15:11 +00001273 /* TBD: no error checking here since we know, via the
1274 * Tkapp_CreateCommand() that the client data is a two-tuple
1275 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001276 self = data->self;
1277 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001278
Barry Warsawfa701a81997-01-16 00:15:11 +00001279 /* Create argument list (argv1, ..., argvN) */
1280 if (!(arg = PyTuple_New(argc - 1)))
1281 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001282
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 for (i = 0; i < (argc - 1); i++) {
1284 PyObject *s = PyString_FromString(argv[i + 1]);
1285 if (!s || PyTuple_SetItem(arg, i, s)) {
1286 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001287 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001288 }
1289 }
1290 res = PyEval_CallObject(func, arg);
1291 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001292
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 if (res == NULL)
1294 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001295
Barry Warsawfa701a81997-01-16 00:15:11 +00001296 if (!(tmp = PyList_New(0))) {
1297 Py_DECREF(res);
1298 return PythonCmd_Error(interp);
1299 }
1300
Guido van Rossum2834b972000-10-06 16:58:26 +00001301 s = AsString(res, tmp);
1302 if (s == NULL) {
1303 rv = PythonCmd_Error(interp);
1304 }
1305 else {
1306 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1307 rv = TCL_OK;
1308 }
1309
Barry Warsawfa701a81997-01-16 00:15:11 +00001310 Py_DECREF(res);
1311 Py_DECREF(tmp);
1312
Guido van Rossum00d93061998-05-28 23:06:38 +00001313 LEAVE_PYTHON
1314
Guido van Rossum2834b972000-10-06 16:58:26 +00001315 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001316}
1317
1318static void
Fred Drake509d79a2000-07-08 04:04:38 +00001319PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001320{
Guido van Rossum00d93061998-05-28 23:06:38 +00001321 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1322
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001323 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001324 Py_XDECREF(data->self);
1325 Py_XDECREF(data->func);
1326 PyMem_DEL(data);
1327 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001328}
1329
Barry Warsawfa701a81997-01-16 00:15:11 +00001330
1331
Guido van Rossum18468821994-06-20 07:49:28 +00001332static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001333Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001334{
Guido van Rossum00d93061998-05-28 23:06:38 +00001335 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001336 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001339
Guido van Rossum43713e52000-02-29 13:59:29 +00001340 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001341 return NULL;
1342 if (!PyCallable_Check(func)) {
1343 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001344 return NULL;
1345 }
Guido van Rossum18468821994-06-20 07:49:28 +00001346
Guido van Rossum00d93061998-05-28 23:06:38 +00001347 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001348 if (!data)
1349 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001350 Py_XINCREF(self);
1351 Py_XINCREF(func);
1352 data->self = self;
1353 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001354
Guido van Rossum00d93061998-05-28 23:06:38 +00001355 ENTER_TCL
1356 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1357 (ClientData)data, PythonCmdDelete);
1358 LEAVE_TCL
1359 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001360 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001361 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001362 return NULL;
1363 }
Guido van Rossum18468821994-06-20 07:49:28 +00001364
Barry Warsawfa701a81997-01-16 00:15:11 +00001365 Py_INCREF(Py_None);
1366 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001367}
1368
Barry Warsawfa701a81997-01-16 00:15:11 +00001369
1370
Guido van Rossum18468821994-06-20 07:49:28 +00001371static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001372Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001373{
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001375 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001376
Guido van Rossum43713e52000-02-29 13:59:29 +00001377 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001379 ENTER_TCL
1380 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1381 LEAVE_TCL
1382 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1384 return NULL;
1385 }
1386 Py_INCREF(Py_None);
1387 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001388}
1389
Barry Warsawfa701a81997-01-16 00:15:11 +00001390
1391
Guido van Rossum00d93061998-05-28 23:06:38 +00001392#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001393/** File Handler **/
1394
Guido van Rossum00d93061998-05-28 23:06:38 +00001395typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 PyObject *func;
1397 PyObject *file;
1398 int id;
1399 struct _fhcdata *next;
1400} FileHandler_ClientData;
1401
1402static FileHandler_ClientData *HeadFHCD;
1403
1404static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001405NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001406{
1407 FileHandler_ClientData *p;
1408 p = PyMem_NEW(FileHandler_ClientData, 1);
1409 if (p != NULL) {
1410 Py_XINCREF(func);
1411 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001412 p->func = func;
1413 p->file = file;
1414 p->id = id;
1415 p->next = HeadFHCD;
1416 HeadFHCD = p;
1417 }
1418 return p;
1419}
1420
1421static void
Fred Drake509d79a2000-07-08 04:04:38 +00001422DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001423{
1424 FileHandler_ClientData *p, **pp;
1425
1426 pp = &HeadFHCD;
1427 while ((p = *pp) != NULL) {
1428 if (p->id == id) {
1429 *pp = p->next;
1430 Py_XDECREF(p->func);
1431 Py_XDECREF(p->file);
1432 PyMem_DEL(p);
1433 }
1434 else
1435 pp = &p->next;
1436 }
1437}
1438
Guido van Rossuma597dde1995-01-10 20:56:29 +00001439static void
Fred Drake509d79a2000-07-08 04:04:38 +00001440FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001441{
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001443 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001444
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001445 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001446 func = data->func;
1447 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001448
Barry Warsawfa701a81997-01-16 00:15:11 +00001449 arg = Py_BuildValue("(Oi)", file, (long) mask);
1450 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001451 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001452
1453 if (res == NULL) {
1454 errorInCmd = 1;
1455 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1456 }
1457 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001458 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001459}
1460
Guido van Rossum18468821994-06-20 07:49:28 +00001461static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001462Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1463 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001464{
Guido van Rossum00d93061998-05-28 23:06:38 +00001465 FileHandler_ClientData *data;
1466 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001467 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001468
Guido van Rossum2834b972000-10-06 16:58:26 +00001469 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1470 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001472 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001473 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 return NULL;
1475 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001476 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 return NULL;
1478 }
1479
Guido van Rossuma80649b2000-03-28 20:07:05 +00001480 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 return NULL;
1483
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001486 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001487 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001488 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001490}
1491
1492static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001493Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001494{
Barry Warsawfa701a81997-01-16 00:15:11 +00001495 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001496 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001497
Guido van Rossum43713e52000-02-29 13:59:29 +00001498 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001499 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001500 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001501 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 return NULL;
1503
Guido van Rossuma80649b2000-03-28 20:07:05 +00001504 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001505
Barry Warsawfa701a81997-01-16 00:15:11 +00001506 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001507 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001508 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001509 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001510 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001512}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001513#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001514
Barry Warsawfa701a81997-01-16 00:15:11 +00001515
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001516/**** Tktt Object (timer token) ****/
1517
1518staticforward PyTypeObject Tktt_Type;
1519
Guido van Rossum00d93061998-05-28 23:06:38 +00001520typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001522 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001524} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001525
1526static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001527Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001528{
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001530 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001531
Guido van Rossum43713e52000-02-29 13:59:29 +00001532 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001534 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001535 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001536 v->token = NULL;
1537 }
1538 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001540 Py_DECREF(func);
1541 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 }
1543 Py_INCREF(Py_None);
1544 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001545}
1546
1547static PyMethodDef Tktt_methods[] =
1548{
Guido van Rossum35d43371997-08-02 00:09:09 +00001549 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001551};
1552
1553static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001554Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001555{
Barry Warsawfa701a81997-01-16 00:15:11 +00001556 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001557
Guido van Rossumb18618d2000-05-03 23:44:39 +00001558 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001559 if (v == NULL)
1560 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001561
Guido van Rossum00d93061998-05-28 23:06:38 +00001562 Py_INCREF(func);
1563 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001564 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001565
1566 /* Extra reference, deleted when called or when handler is deleted */
1567 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001569}
1570
1571static void
Fred Drake509d79a2000-07-08 04:04:38 +00001572Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001573{
Guido van Rossum00d93061998-05-28 23:06:38 +00001574 TkttObject *v = (TkttObject *)self;
1575 PyObject *func = v->func;
1576
1577 Py_XDECREF(func);
1578
Guido van Rossumb18618d2000-05-03 23:44:39 +00001579 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001580}
1581
Guido van Rossum597ac201998-05-12 14:36:19 +00001582static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001583Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001584{
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001586 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001587
Tim Peters885d4572001-11-28 20:27:42 +00001588 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00001589 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001590 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001591}
1592
1593static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001594Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001595{
Barry Warsawfa701a81997-01-16 00:15:11 +00001596 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001597}
1598
1599static PyTypeObject Tktt_Type =
1600{
Guido van Rossum35d43371997-08-02 00:09:09 +00001601 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001602 0, /*ob_size */
1603 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001604 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001605 0, /*tp_itemsize */
1606 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001607 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001608 Tktt_GetAttr, /*tp_getattr */
1609 0, /*tp_setattr */
1610 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001611 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001612 0, /*tp_as_number */
1613 0, /*tp_as_sequence */
1614 0, /*tp_as_mapping */
1615 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001616};
1617
Barry Warsawfa701a81997-01-16 00:15:11 +00001618
1619
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001620/** Timer Handler **/
1621
1622static void
Fred Drake509d79a2000-07-08 04:04:38 +00001623TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001624{
Guido van Rossum00d93061998-05-28 23:06:38 +00001625 TkttObject *v = (TkttObject *)clientData;
1626 PyObject *func = v->func;
1627 PyObject *res;
1628
1629 if (func == NULL)
1630 return;
1631
1632 v->func = NULL;
1633
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001634 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001635
1636 res = PyEval_CallObject(func, NULL);
1637 Py_DECREF(func);
1638 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001639
Barry Warsawfa701a81997-01-16 00:15:11 +00001640 if (res == NULL) {
1641 errorInCmd = 1;
1642 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1643 }
1644 else
1645 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001646
1647 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001648}
1649
1650static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001651Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001652{
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 int milliseconds;
1654 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001655 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001656
Guido van Rossum2834b972000-10-06 16:58:26 +00001657 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1658 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001659 return NULL;
1660 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001661 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001662 return NULL;
1663 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001664 v = Tktt_New(func);
1665 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1666 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001667
Guido van Rossum00d93061998-05-28 23:06:38 +00001668 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001669}
1670
Barry Warsawfa701a81997-01-16 00:15:11 +00001671
Guido van Rossum18468821994-06-20 07:49:28 +00001672/** Event Loop **/
1673
Guido van Rossum18468821994-06-20 07:49:28 +00001674static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001675Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001676{
Barry Warsawfa701a81997-01-16 00:15:11 +00001677 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001678#ifdef WITH_THREAD
1679 PyThreadState *tstate = PyThreadState_Get();
1680#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001681
Guido van Rossum43713e52000-02-29 13:59:29 +00001682 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001683 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001684
Barry Warsawfa701a81997-01-16 00:15:11 +00001685 quitMainLoop = 0;
1686 while (Tk_GetNumMainWindows() > threshold &&
1687 !quitMainLoop &&
1688 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001689 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001691
1692#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001693 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001694 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001695 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001696 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001697 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001698 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001699 if (result == 0)
1700 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001701 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001702#else
1703 result = Tcl_DoOneEvent(0);
1704#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001705
Guido van Rossum35d43371997-08-02 00:09:09 +00001706 if (PyErr_CheckSignals() != 0)
1707 return NULL;
1708 if (result < 0)
1709 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001710 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001712
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 if (errorInCmd) {
1714 errorInCmd = 0;
1715 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1716 excInCmd = valInCmd = trbInCmd = NULL;
1717 return NULL;
1718 }
1719 Py_INCREF(Py_None);
1720 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001721}
1722
1723static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001724Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001725{
Guido van Rossum35d43371997-08-02 00:09:09 +00001726 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001727 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001728
Guido van Rossum43713e52000-02-29 13:59:29 +00001729 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 return NULL;
1731
Guido van Rossum00d93061998-05-28 23:06:38 +00001732 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001733 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001734 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001735 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001736}
1737
1738static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001739Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001740{
1741
Guido van Rossum43713e52000-02-29 13:59:29 +00001742 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001743 return NULL;
1744
1745 quitMainLoop = 1;
1746 Py_INCREF(Py_None);
1747 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001748}
1749
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001750static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001751Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001752{
1753
Guido van Rossum43713e52000-02-29 13:59:29 +00001754 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001755 return NULL;
1756
1757 return PyInt_FromLong((long)Tkapp_Interp(self));
1758}
1759
Barry Warsawfa701a81997-01-16 00:15:11 +00001760
1761
Guido van Rossum18468821994-06-20 07:49:28 +00001762/**** Tkapp Method List ****/
1763
1764static PyMethodDef Tkapp_methods[] =
1765{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001766 {"call", Tkapp_Call, METH_OLDARGS},
1767 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
1768 {"eval", Tkapp_Eval, METH_VARARGS},
1769 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
1770 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
1771 {"record", Tkapp_Record, METH_VARARGS},
1772 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
1773 {"setvar", Tkapp_SetVar, METH_VARARGS},
1774 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
1775 {"getvar", Tkapp_GetVar, METH_VARARGS},
1776 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
1777 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
1778 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
1779 {"getint", Tkapp_GetInt, METH_VARARGS},
1780 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
1781 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
1782 {"exprstring", Tkapp_ExprString, METH_VARARGS},
1783 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
1784 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
1785 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
1786 {"splitlist", Tkapp_SplitList, METH_VARARGS},
1787 {"split", Tkapp_Split, METH_VARARGS},
1788 {"merge", Tkapp_Merge, METH_OLDARGS},
1789 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
1790 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001791#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001792 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
1793 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00001794#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001795 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
1796 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
1797 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
1798 {"quit", Tkapp_Quit, METH_VARARGS},
1799 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001800 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001801};
1802
Barry Warsawfa701a81997-01-16 00:15:11 +00001803
1804
Guido van Rossum18468821994-06-20 07:49:28 +00001805/**** Tkapp Type Methods ****/
1806
1807static void
Fred Drake509d79a2000-07-08 04:04:38 +00001808Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001809{
Guido van Rossum00d93061998-05-28 23:06:38 +00001810 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001811 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001812 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001813 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001814 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001815}
1816
1817static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001818Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001819{
Guido van Rossum35d43371997-08-02 00:09:09 +00001820 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001821}
1822
1823static PyTypeObject Tkapp_Type =
1824{
Guido van Rossum35d43371997-08-02 00:09:09 +00001825 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001826 0, /*ob_size */
1827 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001828 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001829 0, /*tp_itemsize */
1830 Tkapp_Dealloc, /*tp_dealloc */
1831 0, /*tp_print */
1832 Tkapp_GetAttr, /*tp_getattr */
1833 0, /*tp_setattr */
1834 0, /*tp_compare */
1835 0, /*tp_repr */
1836 0, /*tp_as_number */
1837 0, /*tp_as_sequence */
1838 0, /*tp_as_mapping */
1839 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001840};
1841
Barry Warsawfa701a81997-01-16 00:15:11 +00001842
1843
Guido van Rossum18468821994-06-20 07:49:28 +00001844/**** Tkinter Module ****/
1845
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001846typedef struct {
1847 PyObject* tuple;
1848 int size; /* current size */
1849 int maxsize; /* allocated size */
1850} FlattenContext;
1851
1852static int
1853_bump(FlattenContext* context, int size)
1854{
Guido van Rossum2834b972000-10-06 16:58:26 +00001855 /* expand tuple to hold (at least) size new items.
1856 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001857
1858 int maxsize = context->maxsize * 2;
1859
1860 if (maxsize < context->size + size)
1861 maxsize = context->size + size;
1862
1863 context->maxsize = maxsize;
1864
Tim Peters4324aa32001-05-28 22:30:08 +00001865 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001866}
1867
1868static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001869_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001870{
1871 /* add tuple or list to argument tuple (recursively) */
1872
1873 int i, size;
1874
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001875 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001876 PyErr_SetString(PyExc_ValueError,
1877 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001878 return 0;
1879 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001880 size = PyList_GET_SIZE(item);
1881 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001882 if (context->size + size > context->maxsize &&
1883 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001884 return 0;
1885 /* copy items to output tuple */
1886 for (i = 0; i < size; i++) {
1887 PyObject *o = PyList_GET_ITEM(item, i);
1888 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001889 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001890 return 0;
1891 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001892 if (context->size + 1 > context->maxsize &&
1893 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001894 return 0;
1895 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001896 PyTuple_SET_ITEM(context->tuple,
1897 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001898 }
1899 }
1900 } else if (PyTuple_Check(item)) {
1901 /* same, for tuples */
1902 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001903 if (context->size + size > context->maxsize &&
1904 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001905 return 0;
1906 for (i = 0; i < size; i++) {
1907 PyObject *o = PyTuple_GET_ITEM(item, i);
1908 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001909 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001910 return 0;
1911 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001912 if (context->size + 1 > context->maxsize &&
1913 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001914 return 0;
1915 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001916 PyTuple_SET_ITEM(context->tuple,
1917 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001918 }
1919 }
1920 } else {
1921 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1922 return 0;
1923 }
1924 return 1;
1925}
1926
1927static PyObject *
1928Tkinter_Flatten(PyObject* self, PyObject* args)
1929{
1930 FlattenContext context;
1931 PyObject* item;
1932
1933 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1934 return NULL;
1935
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001936 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001937 if (context.maxsize <= 0)
1938 return PyTuple_New(0);
1939
1940 context.tuple = PyTuple_New(context.maxsize);
1941 if (!context.tuple)
1942 return NULL;
1943
1944 context.size = 0;
1945
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001946 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001947 return NULL;
1948
Tim Peters4324aa32001-05-28 22:30:08 +00001949 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001950 return NULL;
1951
1952 return context.tuple;
1953}
1954
Guido van Rossum18468821994-06-20 07:49:28 +00001955static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001956Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001957{
Barry Warsawfa701a81997-01-16 00:15:11 +00001958 char *screenName = NULL;
1959 char *baseName = NULL;
1960 char *className = NULL;
1961 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001962
Guido van Rossum35d43371997-08-02 00:09:09 +00001963 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 if (baseName != NULL)
1965 baseName++;
1966 else
1967 baseName = Py_GetProgramName();
1968 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001969
Guido van Rossum43713e52000-02-29 13:59:29 +00001970 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 &screenName, &baseName, &className,
1972 &interactive))
1973 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001974
Barry Warsawfa701a81997-01-16 00:15:11 +00001975 return (PyObject *) Tkapp_New(screenName, baseName, className,
1976 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001977}
1978
1979static PyMethodDef moduleMethods[] =
1980{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001981 {"_flatten", Tkinter_Flatten, METH_VARARGS},
1982 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001983#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001984 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
1985 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00001986#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001987 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
1988 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
1989 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
1990 {"quit", Tkapp_Quit, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001991 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001992};
1993
Guido van Rossum7bf15641998-05-22 18:28:17 +00001994#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001995
1996static int stdin_ready = 0;
1997
Guido van Rossumad4db171998-06-13 13:56:28 +00001998#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001999static void
Fred Drake509d79a2000-07-08 04:04:38 +00002000MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002001{
2002 stdin_ready = 1;
2003}
Guido van Rossumad4db171998-06-13 13:56:28 +00002004#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002005
Guido van Rossum00d93061998-05-28 23:06:38 +00002006static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002007
Guido van Rossum18468821994-06-20 07:49:28 +00002008static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002009EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002010{
Guido van Rossumad4db171998-06-13 13:56:28 +00002011#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002012 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002013#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002014#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002015 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002016#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002017 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002018 errorInCmd = 0;
2019#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002020 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002021 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002022#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002023 while (!errorInCmd && !stdin_ready) {
2024 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002025#ifdef MS_WINDOWS
2026 if (_kbhit()) {
2027 stdin_ready = 1;
2028 break;
2029 }
2030#endif
2031#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002032 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002033 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002034 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002035
Guido van Rossum00d93061998-05-28 23:06:38 +00002036 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002037
2038 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002039 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002040 if (result == 0)
2041 Sleep(20);
2042 Py_END_ALLOW_THREADS
2043#else
2044 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002045#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002046
2047 if (result < 0)
2048 break;
2049 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002050#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002051 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002052#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002053 if (errorInCmd) {
2054 errorInCmd = 0;
2055 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2056 excInCmd = valInCmd = trbInCmd = NULL;
2057 PyErr_Print();
2058 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002059#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002060 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002061#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002062 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002063}
Guido van Rossum18468821994-06-20 07:49:28 +00002064
Guido van Rossum00d93061998-05-28 23:06:38 +00002065#endif
2066
Guido van Rossum7bf15641998-05-22 18:28:17 +00002067static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002068EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002069{
Guido van Rossum00d93061998-05-28 23:06:38 +00002070#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002071 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002072#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002073 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002074#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002075 PyOS_InputHook = EventHook;
2076 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002077#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002078}
2079
2080static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002081DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002082{
Guido van Rossum00d93061998-05-28 23:06:38 +00002083#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002084 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2085 PyOS_InputHook = NULL;
2086 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002087#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002088}
2089
Barry Warsawfa701a81997-01-16 00:15:11 +00002090
2091/* all errors will be checked in one fell swoop in init_tkinter() */
2092static void
Fred Drake509d79a2000-07-08 04:04:38 +00002093ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002094{
2095 PyObject *v = PyInt_FromLong(val);
2096 if (v) {
2097 PyDict_SetItemString(d, name, v);
2098 Py_DECREF(v);
2099 }
2100}
2101static void
Fred Drake509d79a2000-07-08 04:04:38 +00002102ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002103{
2104 PyObject *v = PyString_FromString(val);
2105 if (v) {
2106 PyDict_SetItemString(d, name, v);
2107 Py_DECREF(v);
2108 }
2109}
2110
2111
Guido van Rossum3886bb61998-12-04 18:50:17 +00002112DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002113init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002114{
Barry Warsawfa701a81997-01-16 00:15:11 +00002115 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002116
Barry Warsawfa701a81997-01-16 00:15:11 +00002117 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002118
2119#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002120 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002121#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002122
Barry Warsawfa701a81997-01-16 00:15:11 +00002123 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002124
Barry Warsawfa701a81997-01-16 00:15:11 +00002125 d = PyModule_GetDict(m);
2126 Tkinter_TclError = Py_BuildValue("s", "TclError");
2127 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002128
Guido van Rossum35d43371997-08-02 00:09:09 +00002129 ins_long(d, "READABLE", TCL_READABLE);
2130 ins_long(d, "WRITABLE", TCL_WRITABLE);
2131 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2132 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2133 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2134 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2135 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2136 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2137 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002138 ins_string(d, "TK_VERSION", TK_VERSION);
2139 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002140
Guido van Rossum83551bf1997-09-13 00:44:23 +00002141 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002142
2143 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002144 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2145
Jack Jansencb852442001-12-09 23:15:56 +00002146
2147#ifdef TK_AQUA
2148 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
2149 * start waking up. Note that Tcl_FindExecutable will do this, this
2150 * code must be above it! The original warning from
2151 * tkMacOSXAppInit.c is copied below.
2152 *
2153 * NB - You have to swap in the Tk Notifier BEFORE you start up the
2154 * Tcl interpreter for now. It probably should work to do this
2155 * in the other order, but for now it doesn't seem to.
2156 *
2157 */
2158 Tk_MacOSXSetupTkNotifier();
2159#endif
2160
2161
Guido van Rossume187b0e2000-03-27 21:46:29 +00002162 /* This helps the dynamic loader; in Unicode aware Tcl versions
2163 it also helps Tcl find its encodings. */
2164 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002165
Barry Warsawfa701a81997-01-16 00:15:11 +00002166 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002167 return;
2168
Guido van Rossum43ff8681998-07-14 18:02:13 +00002169#if 0
2170 /* This was not a good idea; through <Destroy> bindings,
2171 Tcl_Finalize() may invoke Python code but at that point the
2172 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002173 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002174#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002175
Jack Jansen34cc5c31995-10-31 16:15:12 +00002176#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002177 /*
2178 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2179 ** Most of the initializations in that routine (toolbox init calls and
2180 ** such) have already been done for us, so we only need these.
2181 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002182 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002183
2184 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002185#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002186 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002187#endif /* GENERATINGCFM */
2188#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002189}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002190
Guido van Rossumec22c921996-02-25 04:50:29 +00002191
Barry Warsawfa701a81997-01-16 00:15:11 +00002192
Guido van Rossum9722ad81995-09-22 23:49:28 +00002193#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002194
2195/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002196** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002197*/
2198
Guido van Rossum9722ad81995-09-22 23:49:28 +00002199void
2200panic(char * format, ...)
2201{
Barry Warsawfa701a81997-01-16 00:15:11 +00002202 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002203
Barry Warsawfa701a81997-01-16 00:15:11 +00002204 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002205
Guido van Rossum227cf761998-08-05 13:53:32 +00002206 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002207 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002208
Barry Warsawfa701a81997-01-16 00:15:11 +00002209 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002210
Barry Warsawfa701a81997-01-16 00:15:11 +00002211 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002212}
Jack Jansen40b546d1995-11-14 10:34:45 +00002213
Guido van Rossumec22c921996-02-25 04:50:29 +00002214/*
2215** Pass events to SIOUX before passing them to Tk.
2216*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002217
Guido van Rossumec22c921996-02-25 04:50:29 +00002218static int
Fred Drake509d79a2000-07-08 04:04:38 +00002219PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002220{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002221 WindowPtr frontwin;
2222 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002223 ** Sioux eats too many events, so we don't pass it everything. We
2224 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002225 ** the Sioux window is frontmost. This means that Tk menus don't work
2226 ** in that case, but at least we can scroll the sioux window.
2227 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2228 ** part of the external interface of Sioux...
2229 */
2230 frontwin = FrontWindow();
2231 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2232 if (SIOUXHandleOneEvent(eventPtr))
2233 return 0; /* Nothing happened to the Tcl event queue */
2234 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002235 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002236}
2237
Guido van Rossumec22c921996-02-25 04:50:29 +00002238#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002239
2240/*
2241** Additional Mac specific code for dealing with shared libraries.
2242*/
2243
2244#include <Resources.h>
2245#include <CodeFragments.h>
2246
2247static int loaded_from_shlib = 0;
2248static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002249
Jack Jansen34cc5c31995-10-31 16:15:12 +00002250/*
2251** If this module is dynamically loaded the following routine should
2252** be the init routine. It takes care of adding the shared library to
2253** the resource-file chain, so that the tk routines can find their
2254** resources.
2255*/
2256OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002257init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002258{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002259 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002260 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002261 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002262 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2263 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002264 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002265 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2266 loaded_from_shlib = 1;
2267 }
2268 return noErr;
2269}
2270
2271/*
2272** Insert the library resources into the search path. Put them after
2273** the resources from the application. Again, we ignore errors.
2274*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002275static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002276mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002277{
2278 if ( !loaded_from_shlib )
2279 return;
2280 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2281}
2282
Guido van Rossumec22c921996-02-25 04:50:29 +00002283#endif /* GENERATINGCFM */
2284#endif /* macintosh */