blob: 3dface6a4e538de4c01d885bb634cbf10ce35398 [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
Martin v. Löwis71e25a02002-10-01 18:08:06 +000044/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
45 making _tkinter correct for this API means to break earlier
46 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
47 earlier versions. Once Tcl releases before 8.4 don't need to be supported
48 anymore, this should go. */
49#define USE_COMPAT_CONST
50
Jack Jansencb852442001-12-09 23:15:56 +000051#ifdef TK_FRAMEWORK
52#include <Tcl/tcl.h>
53#include <Tk/tk.h>
54#else
Guido van Rossum18468821994-06-20 07:49:28 +000055#include <tcl.h>
56#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000057#endif
Guido van Rossum18468821994-06-20 07:49:28 +000058
Guido van Rossum3e819a71997-08-01 19:29:02 +000059#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
60
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000061#if TKMAJORMINOR < 8002
62#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000063#endif
64
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000065/* Unicode conversion assumes that Tcl_UniChar is two bytes.
66 We cannot test this directly, so we test UTF-8 size instead,
67 expecting that TCL_UTF_MAX is changed if Tcl ever supports
68 either UTF-16 or UCS-4. */
69#if TCL_UTF_MAX != 3
70#error "unsupported Tcl configuration"
71#endif
72
Guido van Rossuma80649b2000-03-28 20:07:05 +000073#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000074/* Sigh, we have to include this to get at the tcl qd pointer */
75#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000076/* And this one we need to clear the menu bar */
77#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000078#endif
79
Jack Jansen84c10b12001-07-16 19:32:52 +000080#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
81/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000082#define HAVE_CREATEFILEHANDLER
83#endif
84
Guido van Rossum00d93061998-05-28 23:06:38 +000085#ifdef HAVE_CREATEFILEHANDLER
86
87/* Tcl_CreateFileHandler() changed several times; these macros deal with the
88 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
89 Unix, only because Jack added it back); when available on Windows, it only
90 applies to sockets. */
91
Guido van Rossum7bf15641998-05-22 18:28:17 +000092#ifdef MS_WINDOWS
93#define FHANDLETYPE TCL_WIN_SOCKET
94#else
95#define FHANDLETYPE TCL_UNIX_FD
96#endif
97
Guido van Rossum00d93061998-05-28 23:06:38 +000098/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
99 which uses this to handle Tcl events while the user is typing commands. */
100
101#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000102#define WAIT_FOR_STDIN
103#endif
104
Guido van Rossum00d93061998-05-28 23:06:38 +0000105#endif /* HAVE_CREATEFILEHANDLER */
106
Guido van Rossumad4db171998-06-13 13:56:28 +0000107#ifdef MS_WINDOWS
108#include <conio.h>
109#define WAIT_FOR_STDIN
110#endif
111
Guido van Rossum00d93061998-05-28 23:06:38 +0000112#ifdef WITH_THREAD
113
114/* The threading situation is complicated. Tcl is not thread-safe, except for
115 Tcl 8.1, which will probably remain in alpha status for another 6 months
116 (and the README says that Tk will probably remain thread-unsafe forever).
117 So we need to use a lock around all uses of Tcl. Previously, the Python
118 interpreter lock was used for this. However, this causes problems when
119 other Python threads need to run while Tcl is blocked waiting for events.
120
121 To solve this problem, a separate lock for Tcl is introduced. Holding it
122 is incompatible with holding Python's interpreter lock. The following four
123 macros manipulate both locks together.
124
125 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
126 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
127 that could call an event handler, or otherwise affect the state of a Tcl
128 interpreter. These assume that the surrounding code has the Python
129 interpreter lock; inside the brackets, the Python interpreter lock has been
130 released and the lock for Tcl has been acquired.
131
Guido van Rossum5e977831998-06-15 14:03:52 +0000132 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
133 (For example, when transferring data from the Tcl interpreter result to a
134 Python string object.) This can be done by using different macros to close
135 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
136 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
137 releases the Tcl lock.
138
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000139 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 handlers when the handler needs to use Python. Such event handlers are
141 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000142 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000143 the Python interpreter lock, restoring the appropriate thread state, and
144 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
145 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000146 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000147
148 These locks expand to several statements and brackets; they should not be
149 used in branches of if statements and the like.
150
151*/
152
Guido van Rossum65d5b571998-12-21 19:32:43 +0000153static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000154static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000155
156#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000157 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000158 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000159
160#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000161 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000162
Guido van Rossum62320c91998-06-15 04:36:09 +0000163#define ENTER_OVERLAP \
164 Py_END_ALLOW_THREADS
165
166#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000168
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169#define ENTER_PYTHON \
170 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000171 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000172
173#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000174 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000175 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000176
177#else
178
179#define ENTER_TCL
180#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000181#define ENTER_OVERLAP
182#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000184#define LEAVE_PYTHON
185
186#endif
187
Guido van Rossumec22c921996-02-25 04:50:29 +0000188#ifdef macintosh
189
190/*
191** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000192** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000193*/
194
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000195/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000196#define FREECAST (char *)
197
Guido van Rossumec22c921996-02-25 04:50:29 +0000198#include <Events.h> /* For EventRecord */
199
Fred Drake509d79a2000-07-08 04:04:38 +0000200typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000201void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
202int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000203
Jeremy Hylton938ace62002-07-17 16:30:39 +0000204static int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000205
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000206#include <SIOUX.h>
207extern int SIOUXIsAppWindow(WindowPtr);
208
Guido van Rossumec22c921996-02-25 04:50:29 +0000209#endif /* macintosh */
210
Guido van Rossum97867b21996-08-08 19:09:53 +0000211#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000212#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000213#endif
214
Guido van Rossum18468821994-06-20 07:49:28 +0000215/**** Tkapp Object Declaration ****/
216
Jeremy Hylton938ace62002-07-17 16:30:39 +0000217static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000218
Guido van Rossum00d93061998-05-28 23:06:38 +0000219typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000220 PyObject_HEAD
221 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000222} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000223
224#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000225#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000226#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000227
Guido van Rossum35d43371997-08-02 00:09:09 +0000228#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000229(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000230
Barry Warsawfa701a81997-01-16 00:15:11 +0000231
232
Guido van Rossum18468821994-06-20 07:49:28 +0000233/**** Error Handling ****/
234
235static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000236static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000237static int errorInCmd = 0;
238static PyObject *excInCmd;
239static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000241
Barry Warsawfa701a81997-01-16 00:15:11 +0000242
243
Guido van Rossum18468821994-06-20 07:49:28 +0000244static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000245Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000246{
Barry Warsawfa701a81997-01-16 00:15:11 +0000247 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
248 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000249}
250
Barry Warsawfa701a81997-01-16 00:15:11 +0000251
Barry Warsawfa701a81997-01-16 00:15:11 +0000252
Guido van Rossum18468821994-06-20 07:49:28 +0000253/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000254
255#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000256#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000257
Guido van Rossum00d93061998-05-28 23:06:38 +0000258/* Millisecond sleep() for Unix platforms. */
259
260static void
Fred Drake509d79a2000-07-08 04:04:38 +0000261Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000262{
263 /* XXX Too bad if you don't have select(). */
264 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000265 t.tv_sec = milli/1000;
266 t.tv_usec = (milli%1000) * 1000;
267 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
268}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000269#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000270#endif /* WITH_THREAD */
271
272
Guido van Rossum18468821994-06-20 07:49:28 +0000273static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000274AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000275{
Guido van Rossum35d43371997-08-02 00:09:09 +0000276 if (PyString_Check(value))
277 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000278#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000279 else if (PyUnicode_Check(value)) {
280 PyObject *v = PyUnicode_AsUTF8String(value);
281 if (v == NULL)
282 return NULL;
283 if (PyList_Append(tmp, v) != 0) {
284 Py_DECREF(v);
285 return NULL;
286 }
287 Py_DECREF(v);
288 return PyString_AsString(v);
289 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000290#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000291 else {
292 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000293 if (v == NULL)
294 return NULL;
295 if (PyList_Append(tmp, v) != 0) {
296 Py_DECREF(v);
297 return NULL;
298 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000299 Py_DECREF(v);
300 return PyString_AsString(v);
301 }
Guido van Rossum18468821994-06-20 07:49:28 +0000302}
303
Barry Warsawfa701a81997-01-16 00:15:11 +0000304
305
Guido van Rossum18468821994-06-20 07:49:28 +0000306#define ARGSZ 64
307
308static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000309Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000310{
Barry Warsawfa701a81997-01-16 00:15:11 +0000311 PyObject *tmp = NULL;
312 char *argvStore[ARGSZ];
313 char **argv = NULL;
314 int fvStore[ARGSZ];
315 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000316 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000318
Barry Warsawfa701a81997-01-16 00:15:11 +0000319 if (!(tmp = PyList_New(0)))
320 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000321
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 argv = argvStore;
323 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (args == NULL)
326 argc = 0;
327
328 else if (!PyTuple_Check(args)) {
329 argc = 1;
330 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000331 if (!(argv[0] = AsString(args, tmp)))
332 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000333 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000334 else {
335 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000336
Barry Warsawfa701a81997-01-16 00:15:11 +0000337 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000338 argv = (char **)ckalloc(argc * sizeof(char *));
339 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 if (argv == NULL || fv == NULL) {
341 PyErr_NoMemory();
342 goto finally;
343 }
344 }
345
346 for (i = 0; i < argc; i++) {
347 PyObject *v = PyTuple_GetItem(args, i);
348 if (PyTuple_Check(v)) {
349 fv[i] = 1;
350 if (!(argv[i] = Merge(v)))
351 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000352 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000353 }
354 else if (v == Py_None) {
355 argc = i;
356 break;
357 }
358 else {
359 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000360 if (!(argv[i] = AsString(v, tmp)))
361 goto finally;
362 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 }
364 }
Guido van Rossum18468821994-06-20 07:49:28 +0000365 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000366 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000367 if (res == NULL)
368 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000371 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000372 if (fv[i]) {
373 ckfree(argv[i]);
374 }
375 if (argv != argvStore)
376 ckfree(FREECAST argv);
377 if (fv != fvStore)
378 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 Py_DECREF(tmp);
381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000382}
383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384
385
Guido van Rossum18468821994-06-20 07:49:28 +0000386static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000387Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000388{
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 int argc;
390 char **argv;
391 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000392
Barry Warsawfa701a81997-01-16 00:15:11 +0000393 if (list == NULL) {
394 Py_INCREF(Py_None);
395 return Py_None;
396 }
Guido van Rossum18468821994-06-20 07:49:28 +0000397
Guido van Rossum00d93061998-05-28 23:06:38 +0000398 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 /* Not a list.
400 * Could be a quoted string containing funnies, e.g. {"}.
401 * Return the string itself.
402 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 return PyString_FromString(list);
404 }
Guido van Rossum18468821994-06-20 07:49:28 +0000405
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 if (argc == 0)
407 v = PyString_FromString("");
408 else if (argc == 1)
409 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000410 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000411 int i;
412 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000413
Barry Warsawfa701a81997-01-16 00:15:11 +0000414 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000415 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 Py_DECREF(v);
417 v = NULL;
418 break;
419 }
420 PyTuple_SetItem(v, i, w);
421 }
422 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000423 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000425}
426
Barry Warsawfa701a81997-01-16 00:15:11 +0000427
428
Guido van Rossum18468821994-06-20 07:49:28 +0000429/**** Tkapp Object ****/
430
431#ifndef WITH_APPINIT
432int
Fred Drake509d79a2000-07-08 04:04:38 +0000433Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000434{
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000436
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 main = Tk_MainWindow(interp);
438 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000439 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 return TCL_ERROR;
441 }
442 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000443 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000444 return TCL_ERROR;
445 }
446 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000447}
448#endif /* !WITH_APPINIT */
449
Guido van Rossum18468821994-06-20 07:49:28 +0000450
Barry Warsawfa701a81997-01-16 00:15:11 +0000451
452
453/* Initialize the Tk application; see the `main' function in
454 * `tkMain.c'.
455 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000456
Thomas Wouters58d05102000-07-24 14:43:35 +0000457static void EnableEventHook(void); /* Forward */
458static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000459
Barry Warsawfa701a81997-01-16 00:15:11 +0000460static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000461Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000462{
463 TkappObject *v;
464 char *argv0;
465
Guido van Rossumb18618d2000-05-03 23:44:39 +0000466 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000467 if (v == NULL)
468 return NULL;
469
470 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000471
Guido van Rossuma80649b2000-03-28 20:07:05 +0000472#if defined(macintosh)
473 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000474 ClearMenuBar();
475 TkMacInitMenus(v->interp);
476#endif
Jack Jansencb852442001-12-09 23:15:56 +0000477
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000478 /* Delete the 'exit' command, which can screw things up */
479 Tcl_DeleteCommand(v->interp, "exit");
480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 if (screenName != NULL)
482 Tcl_SetVar2(v->interp, "env", "DISPLAY",
483 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000484
Barry Warsawfa701a81997-01-16 00:15:11 +0000485 if (interactive)
486 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
487 else
488 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 /* This is used to get the application class for Tk 4.1 and up */
491 argv0 = (char*)ckalloc(strlen(className) + 1);
492 if (!argv0) {
493 PyErr_NoMemory();
494 Py_DECREF(v);
495 return NULL;
496 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000497
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000499 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000500 argv0[0] = tolower(argv0[0]);
501 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
502 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000503
Barry Warsawfa701a81997-01-16 00:15:11 +0000504 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000505 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000506
Guido van Rossum7bf15641998-05-22 18:28:17 +0000507 EnableEventHook();
508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000510}
511
Barry Warsawfa701a81997-01-16 00:15:11 +0000512
513
Guido van Rossum18468821994-06-20 07:49:28 +0000514/** Tcl Eval **/
515
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000516static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000517AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000518{
519 Tcl_Obj *result;
520
521 if (PyString_Check(value))
522 return Tcl_NewStringObj(PyString_AS_STRING(value),
523 PyString_GET_SIZE(value));
524 else if (PyInt_Check(value))
525 return Tcl_NewLongObj(PyInt_AS_LONG(value));
526 else if (PyFloat_Check(value))
527 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
528 else if (PyTuple_Check(value)) {
529 Tcl_Obj **argv = (Tcl_Obj**)
530 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
531 int i;
532 if(!argv)
533 return 0;
534 for(i=0;i<PyTuple_Size(value);i++)
535 argv[i] = AsObj(PyTuple_GetItem(value,i));
536 result = Tcl_NewListObj(PyTuple_Size(value), argv);
537 ckfree(FREECAST argv);
538 return result;
539 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000540#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000541 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000542 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
543 int size = PyUnicode_GET_SIZE(value);
544 /* This #ifdef assumes that Tcl uses UCS-2.
545 See TCL_UTF_MAX test above. */
546#ifdef Py_UNICODE_WIDE
547 Tcl_UniChar *outbuf;
548 int i;
549 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
550 if (!outbuf) {
551 PyErr_NoMemory();
552 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000553 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000554 for (i = 0; i < size; i++) {
555 if (inbuf[i] >= 0x10000) {
556 /* Tcl doesn't do UTF-16, yet. */
557 PyErr_SetString(PyExc_ValueError,
558 "unsupported character");
559 ckfree(FREECAST outbuf);
560 return NULL;
561 }
562 outbuf[i] = inbuf[i];
563 }
564 result = Tcl_NewUnicodeObj(outbuf, size);
565 ckfree(FREECAST outbuf);
566 return result;
567#else
568 return Tcl_NewUnicodeObj(inbuf, size);
569#endif
570
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000571 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000572#endif
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000573 else {
574 PyObject *v = PyObject_Str(value);
575 if (!v)
576 return 0;
577 result = AsObj(v);
578 Py_DECREF(v);
579 return result;
580 }
581}
582
Guido van Rossum18468821994-06-20 07:49:28 +0000583static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000584Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000585{
Guido van Rossum632de272000-03-29 00:19:50 +0000586 Tcl_Obj *objStore[ARGSZ];
587 Tcl_Obj **objv = NULL;
588 int objc = 0, i;
589 PyObject *res = NULL;
590 Tcl_Interp *interp = Tkapp_Interp(self);
591 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
592 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000593
Guido van Rossum632de272000-03-29 00:19:50 +0000594 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000595
Guido van Rossum212643f1998-04-29 16:22:14 +0000596 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000597 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000598
Guido van Rossum212643f1998-04-29 16:22:14 +0000599 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000600 objv[0] = AsObj(args);
601 if (objv[0] == 0)
602 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000603 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000604 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000605 }
606 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000607 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000608
Guido van Rossum632de272000-03-29 00:19:50 +0000609 if (objc > ARGSZ) {
610 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
611 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000612 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000613 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000614 goto finally;
615 }
616 }
617
Guido van Rossum632de272000-03-29 00:19:50 +0000618 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000619 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000620 if (v == Py_None) {
621 objc = i;
622 break;
623 }
Guido van Rossum632de272000-03-29 00:19:50 +0000624 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000625 if (!objv[i]) {
626 /* Reset objc, so it attempts to clear
627 objects only up to i. */
628 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000629 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000630 }
Guido van Rossum632de272000-03-29 00:19:50 +0000631 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000632 }
633 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000634
Guido van Rossum62320c91998-06-15 04:36:09 +0000635 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000636
637 i = Tcl_EvalObjv(interp, objc, objv, flags);
638
Guido van Rossum62320c91998-06-15 04:36:09 +0000639 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000640 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000641 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000642 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000643 /* We could request the object result here, but doing
644 so would confuse applications that expect a string. */
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000645 const char *s = Tcl_GetStringResult(interp);
646 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000647
Guido van Rossum990f5c62000-05-04 15:07:16 +0000648 /* If the result contains any bytes with the top bit set,
649 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000650#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000651 while (*p != '\0') {
652 if (*p & 0x80)
653 break;
654 p++;
655 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000656
Guido van Rossum990f5c62000-05-04 15:07:16 +0000657 if (*p == '\0')
658 res = PyString_FromStringAndSize(s, (int)(p-s));
659 else {
660 /* Convert UTF-8 to Unicode string */
661 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000662 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
663 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000664 PyErr_Clear();
665 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000666 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000667 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000668#else
669 p = strchr(p, '\0');
670 res = PyString_FromStringAndSize(s, (int)(p-s));
671#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000672 }
Guido van Rossum632de272000-03-29 00:19:50 +0000673
Guido van Rossum62320c91998-06-15 04:36:09 +0000674 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000675
Guido van Rossum212643f1998-04-29 16:22:14 +0000676 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000677 for (i = 0; i < objc; i++)
678 Tcl_DecrRefCount(objv[i]);
679 if (objv != objStore)
680 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000681 return res;
682}
683
684
685static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000686Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000687{
Guido van Rossum212643f1998-04-29 16:22:14 +0000688 /* Could do the same here as for Tkapp_Call(), but this is not used
689 much, so I can't be bothered. Unfortunately Tcl doesn't export a
690 way for the user to do what all its Global* variants do (save and
691 reset the scope pointer, call the local version, restore the saved
692 scope pointer). */
693
Guido van Rossum62320c91998-06-15 04:36:09 +0000694 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000696
Guido van Rossum62320c91998-06-15 04:36:09 +0000697 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000698 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000699 int err;
700 ENTER_TCL
701 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000702 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000703 if (err == TCL_ERROR)
704 res = Tkinter_Error(self);
705 else
706 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000707 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000708 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000709 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000710
711 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000712}
713
714static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000715Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000716{
Barry Warsawfa701a81997-01-16 00:15:11 +0000717 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000718 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000719 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000720
Guido van Rossum43713e52000-02-29 13:59:29 +0000721 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 return NULL;
723
Guido van Rossum00d93061998-05-28 23:06:38 +0000724 ENTER_TCL
725 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000726 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000727 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000728 res = Tkinter_Error(self);
729 else
730 res = PyString_FromString(Tkapp_Result(self));
731 LEAVE_OVERLAP_TCL
732 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000733}
734
735static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000736Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000737{
Barry Warsawfa701a81997-01-16 00:15:11 +0000738 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000739 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000740 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000741
Guido van Rossum43713e52000-02-29 13:59:29 +0000742 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000743 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000744
Guido van Rossum00d93061998-05-28 23:06:38 +0000745 ENTER_TCL
746 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000747 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000748 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000749 res = Tkinter_Error(self);
750 else
751 res = PyString_FromString(Tkapp_Result(self));
752 LEAVE_OVERLAP_TCL
753 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000754}
755
756static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000757Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000758{
Barry Warsawfa701a81997-01-16 00:15:11 +0000759 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000760 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000761 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000762
Guido van Rossum43713e52000-02-29 13:59:29 +0000763 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000764 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000765
Guido van Rossum00d93061998-05-28 23:06:38 +0000766 ENTER_TCL
767 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000768 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000769 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000770 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000771
Guido van Rossum62320c91998-06-15 04:36:09 +0000772 else
773 res = PyString_FromString(Tkapp_Result(self));
774 LEAVE_OVERLAP_TCL
775 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000776}
777
778static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000779Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000780{
Barry Warsawfa701a81997-01-16 00:15:11 +0000781 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000782 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000783 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000784
Guido van Rossum35d43371997-08-02 00:09:09 +0000785 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000786 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000787
Guido van Rossum00d93061998-05-28 23:06:38 +0000788 ENTER_TCL
789 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000790 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000791 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000792 res = Tkinter_Error(self);
793 else
794 res = PyString_FromString(Tkapp_Result(self));
795 LEAVE_OVERLAP_TCL
796 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000797}
798
799static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000800Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000801{
Barry Warsawfa701a81997-01-16 00:15:11 +0000802 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000803
Guido van Rossum43713e52000-02-29 13:59:29 +0000804 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000806 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000808 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000809
Barry Warsawfa701a81997-01-16 00:15:11 +0000810 Py_INCREF(Py_None);
811 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000812}
813
Barry Warsawfa701a81997-01-16 00:15:11 +0000814
815
Guido van Rossum18468821994-06-20 07:49:28 +0000816/** Tcl Variable **/
817
818static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000819SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000820{
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000821 char *name1, *name2, *s;
822 const char *ok;
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000824 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000825
Guido van Rossum62320c91998-06-15 04:36:09 +0000826 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 if (!tmp)
828 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000829
Guido van Rossum43713e52000-02-29 13:59:29 +0000830 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000832 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000833 if (s == NULL)
834 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000835 ENTER_TCL
836 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
837 LEAVE_TCL
838 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000840 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000841 if (PyArg_ParseTuple(args, "ssO:setvar",
842 &name1, &name2, &newValue)) {
843 s = AsString(newValue, tmp);
844 if (s == NULL)
845 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000846 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000847 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000848 s, flags);
849 LEAVE_TCL
850 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000851 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000852 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000853 return NULL;
854 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000855 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000856 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000857
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 if (!ok)
859 return Tkinter_Error(self);
860
861 Py_INCREF(Py_None);
862 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000863}
864
865static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000866Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000867{
Barry Warsawfa701a81997-01-16 00:15:11 +0000868 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000869}
870
871static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000872Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000873{
Barry Warsawfa701a81997-01-16 00:15:11 +0000874 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000875}
876
Barry Warsawfa701a81997-01-16 00:15:11 +0000877
878
Guido van Rossum18468821994-06-20 07:49:28 +0000879static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000880GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000881{
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000882 char *name1, *name2=NULL;
883 const char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000884 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000885
Guido van Rossum43713e52000-02-29 13:59:29 +0000886 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000887 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000888 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000889 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000890 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000891
Barry Warsawfa701a81997-01-16 00:15:11 +0000892 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000893 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000894 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000895
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000897 res = Tkinter_Error(self);
898 else
899 res = PyString_FromString(s);
900 LEAVE_OVERLAP_TCL
901 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000902}
903
904static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000905Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000906{
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000908}
909
910static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000911Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000912{
Barry Warsawfa701a81997-01-16 00:15:11 +0000913 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000914}
915
Barry Warsawfa701a81997-01-16 00:15:11 +0000916
917
Guido van Rossum18468821994-06-20 07:49:28 +0000918static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000919UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000920{
Guido van Rossum35d43371997-08-02 00:09:09 +0000921 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000922 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000924
Guido van Rossum43713e52000-02-29 13:59:29 +0000925 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000927 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000928 if (name2 == NULL)
929 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
930
931 else
932 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000933 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000934
Barry Warsawfa701a81997-01-16 00:15:11 +0000935 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000936 res = Tkinter_Error(self);
937 else {
938 Py_INCREF(Py_None);
939 res = Py_None;
940 }
941 LEAVE_OVERLAP_TCL
942 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000943}
944
945static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000946Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000947{
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000949}
950
951static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000952Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000953{
Barry Warsawfa701a81997-01-16 00:15:11 +0000954 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000955}
956
Barry Warsawfa701a81997-01-16 00:15:11 +0000957
958
Guido van Rossum18468821994-06-20 07:49:28 +0000959/** Tcl to Python **/
960
961static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000962Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000963{
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 char *s;
965 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000966
Guido van Rossum43713e52000-02-29 13:59:29 +0000967 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000969 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000970 return Tkinter_Error(self);
971 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000972}
973
974static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000975Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000976{
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 char *s;
978 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Guido van Rossum43713e52000-02-29 13:59:29 +0000980 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000981 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000982 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000983 return Tkinter_Error(self);
984 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000985}
986
987static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000988Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000989{
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 char *s;
991 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000992
Guido van Rossum43713e52000-02-29 13:59:29 +0000993 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000995 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
996 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000998}
999
1000static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001001Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001002{
Barry Warsawfa701a81997-01-16 00:15:11 +00001003 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001004 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001005 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001006
Guido van Rossum43713e52000-02-29 13:59:29 +00001007 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001009 ENTER_TCL
1010 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001011 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001012 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001013 res = Tkinter_Error(self);
1014 else
1015 res = Py_BuildValue("s", Tkapp_Result(self));
1016 LEAVE_OVERLAP_TCL
1017 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001018}
1019
1020static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001021Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001022{
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001024 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001025 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001026 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001027
Guido van Rossum43713e52000-02-29 13:59:29 +00001028 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001030 ENTER_TCL
1031 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001032 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001033 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001034 res = Tkinter_Error(self);
1035 else
1036 res = Py_BuildValue("l", v);
1037 LEAVE_OVERLAP_TCL
1038 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001039}
1040
1041static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001042Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001043{
Barry Warsawfa701a81997-01-16 00:15:11 +00001044 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001045 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001047 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001048
Guido van Rossum43713e52000-02-29 13:59:29 +00001049 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001051 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001052 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001053 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001054 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001055 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001056 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001057 res = Tkinter_Error(self);
1058 else
1059 res = Py_BuildValue("d", v);
1060 LEAVE_OVERLAP_TCL
1061 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001062}
1063
1064static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001065Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001066{
Barry Warsawfa701a81997-01-16 00:15:11 +00001067 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001068 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001069 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum43713e52000-02-29 13:59:29 +00001072 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001074 ENTER_TCL
1075 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001076 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001077 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001078 res = Tkinter_Error(self);
1079 else
1080 res = Py_BuildValue("i", v);
1081 LEAVE_OVERLAP_TCL
1082 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001083}
1084
Barry Warsawfa701a81997-01-16 00:15:11 +00001085
1086
Guido van Rossum18468821994-06-20 07:49:28 +00001087static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001088Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001089{
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 char *list;
1091 int argc;
1092 char **argv;
1093 PyObject *v;
1094 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001095
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001096 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001097 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001098
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1100 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001101
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 if (!(v = PyTuple_New(argc)))
1103 return NULL;
1104
1105 for (i = 0; i < argc; i++) {
1106 PyObject *s = PyString_FromString(argv[i]);
1107 if (!s || PyTuple_SetItem(v, i, s)) {
1108 Py_DECREF(v);
1109 v = NULL;
1110 goto finally;
1111 }
1112 }
Guido van Rossum18468821994-06-20 07:49:28 +00001113
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 finally:
1115 ckfree(FREECAST argv);
1116 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001117}
1118
1119static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001120Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001121{
Barry Warsawfa701a81997-01-16 00:15:11 +00001122 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001123
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001124 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001126 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001127}
1128
1129static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001130Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001131{
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 char *s = Merge(args);
1133 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001134
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 if (s) {
1136 res = PyString_FromString(s);
1137 ckfree(s);
1138 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001139
1140 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001141}
1142
Barry Warsawfa701a81997-01-16 00:15:11 +00001143
1144
Guido van Rossum18468821994-06-20 07:49:28 +00001145/** Tcl Command **/
1146
Guido van Rossum00d93061998-05-28 23:06:38 +00001147/* Client data struct */
1148typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001149 PyObject *self;
1150 PyObject *func;
1151} PythonCmd_ClientData;
1152
1153static int
Fred Drake509d79a2000-07-08 04:04:38 +00001154PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001155{
1156 errorInCmd = 1;
1157 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1158 LEAVE_PYTHON
1159 return TCL_ERROR;
1160}
1161
Guido van Rossum18468821994-06-20 07:49:28 +00001162/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 * function or method.
1164 */
Guido van Rossum18468821994-06-20 07:49:28 +00001165static int
Fred Drake509d79a2000-07-08 04:04:38 +00001166PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001167{
Guido van Rossum00d93061998-05-28 23:06:38 +00001168 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001170 int i, rv;
1171 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001172
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001173 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001174
Barry Warsawfa701a81997-01-16 00:15:11 +00001175 /* TBD: no error checking here since we know, via the
1176 * Tkapp_CreateCommand() that the client data is a two-tuple
1177 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001178 self = data->self;
1179 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001180
Barry Warsawfa701a81997-01-16 00:15:11 +00001181 /* Create argument list (argv1, ..., argvN) */
1182 if (!(arg = PyTuple_New(argc - 1)))
1183 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001184
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 for (i = 0; i < (argc - 1); i++) {
1186 PyObject *s = PyString_FromString(argv[i + 1]);
1187 if (!s || PyTuple_SetItem(arg, i, s)) {
1188 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001189 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 }
1191 }
1192 res = PyEval_CallObject(func, arg);
1193 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001194
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 if (res == NULL)
1196 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001197
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 if (!(tmp = PyList_New(0))) {
1199 Py_DECREF(res);
1200 return PythonCmd_Error(interp);
1201 }
1202
Guido van Rossum2834b972000-10-06 16:58:26 +00001203 s = AsString(res, tmp);
1204 if (s == NULL) {
1205 rv = PythonCmd_Error(interp);
1206 }
1207 else {
1208 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1209 rv = TCL_OK;
1210 }
1211
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 Py_DECREF(res);
1213 Py_DECREF(tmp);
1214
Guido van Rossum00d93061998-05-28 23:06:38 +00001215 LEAVE_PYTHON
1216
Guido van Rossum2834b972000-10-06 16:58:26 +00001217 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001218}
1219
1220static void
Fred Drake509d79a2000-07-08 04:04:38 +00001221PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001222{
Guido van Rossum00d93061998-05-28 23:06:38 +00001223 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1224
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001225 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001226 Py_XDECREF(data->self);
1227 Py_XDECREF(data->func);
1228 PyMem_DEL(data);
1229 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001230}
1231
Barry Warsawfa701a81997-01-16 00:15:11 +00001232
1233
Guido van Rossum18468821994-06-20 07:49:28 +00001234static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001235Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001236{
Guido van Rossum00d93061998-05-28 23:06:38 +00001237 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001240 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001241
Guido van Rossum43713e52000-02-29 13:59:29 +00001242 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001243 return NULL;
1244 if (!PyCallable_Check(func)) {
1245 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001246 return NULL;
1247 }
Guido van Rossum18468821994-06-20 07:49:28 +00001248
Guido van Rossum00d93061998-05-28 23:06:38 +00001249 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001250 if (!data)
1251 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001252 Py_XINCREF(self);
1253 Py_XINCREF(func);
1254 data->self = self;
1255 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001256
Guido van Rossum00d93061998-05-28 23:06:38 +00001257 ENTER_TCL
1258 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1259 (ClientData)data, PythonCmdDelete);
1260 LEAVE_TCL
1261 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001262 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001263 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001264 return NULL;
1265 }
Guido van Rossum18468821994-06-20 07:49:28 +00001266
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 Py_INCREF(Py_None);
1268 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001269}
1270
Barry Warsawfa701a81997-01-16 00:15:11 +00001271
1272
Guido van Rossum18468821994-06-20 07:49:28 +00001273static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001274Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001275{
Barry Warsawfa701a81997-01-16 00:15:11 +00001276 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001277 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001278
Guido van Rossum43713e52000-02-29 13:59:29 +00001279 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001280 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001281 ENTER_TCL
1282 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1283 LEAVE_TCL
1284 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1286 return NULL;
1287 }
1288 Py_INCREF(Py_None);
1289 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001290}
1291
Barry Warsawfa701a81997-01-16 00:15:11 +00001292
1293
Guido van Rossum00d93061998-05-28 23:06:38 +00001294#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001295/** File Handler **/
1296
Guido van Rossum00d93061998-05-28 23:06:38 +00001297typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001298 PyObject *func;
1299 PyObject *file;
1300 int id;
1301 struct _fhcdata *next;
1302} FileHandler_ClientData;
1303
1304static FileHandler_ClientData *HeadFHCD;
1305
1306static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001307NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001308{
1309 FileHandler_ClientData *p;
1310 p = PyMem_NEW(FileHandler_ClientData, 1);
1311 if (p != NULL) {
1312 Py_XINCREF(func);
1313 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001314 p->func = func;
1315 p->file = file;
1316 p->id = id;
1317 p->next = HeadFHCD;
1318 HeadFHCD = p;
1319 }
1320 return p;
1321}
1322
1323static void
Fred Drake509d79a2000-07-08 04:04:38 +00001324DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001325{
1326 FileHandler_ClientData *p, **pp;
1327
1328 pp = &HeadFHCD;
1329 while ((p = *pp) != NULL) {
1330 if (p->id == id) {
1331 *pp = p->next;
1332 Py_XDECREF(p->func);
1333 Py_XDECREF(p->file);
1334 PyMem_DEL(p);
1335 }
1336 else
1337 pp = &p->next;
1338 }
1339}
1340
Guido van Rossuma597dde1995-01-10 20:56:29 +00001341static void
Fred Drake509d79a2000-07-08 04:04:38 +00001342FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001343{
Guido van Rossum00d93061998-05-28 23:06:38 +00001344 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001345 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001346
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001347 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001348 func = data->func;
1349 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001350
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 arg = Py_BuildValue("(Oi)", file, (long) mask);
1352 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001353 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001354
1355 if (res == NULL) {
1356 errorInCmd = 1;
1357 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1358 }
1359 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001360 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001361}
1362
Guido van Rossum18468821994-06-20 07:49:28 +00001363static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001364Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1365 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001366{
Guido van Rossum00d93061998-05-28 23:06:38 +00001367 FileHandler_ClientData *data;
1368 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001369 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001370
Guido van Rossum2834b972000-10-06 16:58:26 +00001371 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1372 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001374 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001375 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 return NULL;
1377 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001378 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 return NULL;
1380 }
1381
Guido van Rossuma80649b2000-03-28 20:07:05 +00001382 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 return NULL;
1385
Barry Warsawfa701a81997-01-16 00:15:11 +00001386 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001387 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001388 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001389 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001390 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001391 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001392}
1393
1394static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001395Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001396{
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001398 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001399
Guido van Rossum43713e52000-02-29 13:59:29 +00001400 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001401 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001402 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001403 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001404 return NULL;
1405
Guido van Rossuma80649b2000-03-28 20:07:05 +00001406 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001407
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001409 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001411 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001412 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001414}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001415#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001416
Barry Warsawfa701a81997-01-16 00:15:11 +00001417
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001418/**** Tktt Object (timer token) ****/
1419
Jeremy Hylton938ace62002-07-17 16:30:39 +00001420static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001421
Guido van Rossum00d93061998-05-28 23:06:38 +00001422typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001423 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001424 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001425 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001426} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001427
1428static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001429Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001430{
Barry Warsawfa701a81997-01-16 00:15:11 +00001431 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001432 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001433
Guido van Rossum43713e52000-02-29 13:59:29 +00001434 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001437 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001438 v->token = NULL;
1439 }
1440 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001441 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 Py_DECREF(func);
1443 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 }
1445 Py_INCREF(Py_None);
1446 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001447}
1448
1449static PyMethodDef Tktt_methods[] =
1450{
Neal Norwitzb0493252002-03-31 14:44:22 +00001451 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001453};
1454
1455static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001456Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001457{
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001459
Guido van Rossumb18618d2000-05-03 23:44:39 +00001460 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 if (v == NULL)
1462 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001463
Guido van Rossum00d93061998-05-28 23:06:38 +00001464 Py_INCREF(func);
1465 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001467
1468 /* Extra reference, deleted when called or when handler is deleted */
1469 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001470 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001471}
1472
1473static void
Fred Drake509d79a2000-07-08 04:04:38 +00001474Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001475{
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 TkttObject *v = (TkttObject *)self;
1477 PyObject *func = v->func;
1478
1479 Py_XDECREF(func);
1480
Guido van Rossumb18618d2000-05-03 23:44:39 +00001481 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001482}
1483
Guido van Rossum597ac201998-05-12 14:36:19 +00001484static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001485Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001486{
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001488 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001489
Tim Peters885d4572001-11-28 20:27:42 +00001490 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00001491 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001492 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001493}
1494
1495static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001496Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001497{
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001499}
1500
1501static PyTypeObject Tktt_Type =
1502{
Guido van Rossum35d43371997-08-02 00:09:09 +00001503 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001504 0, /*ob_size */
1505 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001506 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001507 0, /*tp_itemsize */
1508 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001509 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 Tktt_GetAttr, /*tp_getattr */
1511 0, /*tp_setattr */
1512 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001513 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 0, /*tp_as_number */
1515 0, /*tp_as_sequence */
1516 0, /*tp_as_mapping */
1517 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001518};
1519
Barry Warsawfa701a81997-01-16 00:15:11 +00001520
1521
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001522/** Timer Handler **/
1523
1524static void
Fred Drake509d79a2000-07-08 04:04:38 +00001525TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001526{
Guido van Rossum00d93061998-05-28 23:06:38 +00001527 TkttObject *v = (TkttObject *)clientData;
1528 PyObject *func = v->func;
1529 PyObject *res;
1530
1531 if (func == NULL)
1532 return;
1533
1534 v->func = NULL;
1535
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001536 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001537
1538 res = PyEval_CallObject(func, NULL);
1539 Py_DECREF(func);
1540 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001541
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 if (res == NULL) {
1543 errorInCmd = 1;
1544 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1545 }
1546 else
1547 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001548
1549 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001550}
1551
1552static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001553Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001554{
Barry Warsawfa701a81997-01-16 00:15:11 +00001555 int milliseconds;
1556 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001557 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001558
Guido van Rossum2834b972000-10-06 16:58:26 +00001559 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1560 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001561 return NULL;
1562 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001563 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001564 return NULL;
1565 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001566 v = Tktt_New(func);
1567 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1568 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001569
Guido van Rossum00d93061998-05-28 23:06:38 +00001570 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001571}
1572
Barry Warsawfa701a81997-01-16 00:15:11 +00001573
Guido van Rossum18468821994-06-20 07:49:28 +00001574/** Event Loop **/
1575
Guido van Rossum18468821994-06-20 07:49:28 +00001576static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001577Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001578{
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001580#ifdef WITH_THREAD
1581 PyThreadState *tstate = PyThreadState_Get();
1582#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001583
Guido van Rossum43713e52000-02-29 13:59:29 +00001584 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001586
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 quitMainLoop = 0;
1588 while (Tk_GetNumMainWindows() > threshold &&
1589 !quitMainLoop &&
1590 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001591 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001592 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001593
1594#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001595 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001596 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001597 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001598 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001599 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001600 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001601 if (result == 0)
1602 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001603 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001604#else
1605 result = Tcl_DoOneEvent(0);
1606#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001607
Guido van Rossum35d43371997-08-02 00:09:09 +00001608 if (PyErr_CheckSignals() != 0)
1609 return NULL;
1610 if (result < 0)
1611 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001612 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001614
Barry Warsawfa701a81997-01-16 00:15:11 +00001615 if (errorInCmd) {
1616 errorInCmd = 0;
1617 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1618 excInCmd = valInCmd = trbInCmd = NULL;
1619 return NULL;
1620 }
1621 Py_INCREF(Py_None);
1622 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001623}
1624
1625static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001626Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001627{
Guido van Rossum35d43371997-08-02 00:09:09 +00001628 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001629 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001630
Guido van Rossum43713e52000-02-29 13:59:29 +00001631 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001632 return NULL;
1633
Guido van Rossum00d93061998-05-28 23:06:38 +00001634 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001635 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001636 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001638}
1639
1640static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001641Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001642{
1643
Guido van Rossum43713e52000-02-29 13:59:29 +00001644 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 return NULL;
1646
1647 quitMainLoop = 1;
1648 Py_INCREF(Py_None);
1649 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001650}
1651
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001652static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001653Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001654{
1655
Guido van Rossum43713e52000-02-29 13:59:29 +00001656 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001657 return NULL;
1658
1659 return PyInt_FromLong((long)Tkapp_Interp(self));
1660}
1661
Barry Warsawfa701a81997-01-16 00:15:11 +00001662
1663
Guido van Rossum18468821994-06-20 07:49:28 +00001664/**** Tkapp Method List ****/
1665
1666static PyMethodDef Tkapp_methods[] =
1667{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001668 {"call", Tkapp_Call, METH_OLDARGS},
1669 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
1670 {"eval", Tkapp_Eval, METH_VARARGS},
1671 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
1672 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
1673 {"record", Tkapp_Record, METH_VARARGS},
1674 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
1675 {"setvar", Tkapp_SetVar, METH_VARARGS},
1676 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
1677 {"getvar", Tkapp_GetVar, METH_VARARGS},
1678 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
1679 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
1680 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
1681 {"getint", Tkapp_GetInt, METH_VARARGS},
1682 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
1683 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
1684 {"exprstring", Tkapp_ExprString, METH_VARARGS},
1685 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
1686 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
1687 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
1688 {"splitlist", Tkapp_SplitList, METH_VARARGS},
1689 {"split", Tkapp_Split, METH_VARARGS},
1690 {"merge", Tkapp_Merge, METH_OLDARGS},
1691 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
1692 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001693#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001694 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
1695 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00001696#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001697 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
1698 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
1699 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
1700 {"quit", Tkapp_Quit, METH_VARARGS},
1701 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001702 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001703};
1704
Barry Warsawfa701a81997-01-16 00:15:11 +00001705
1706
Guido van Rossum18468821994-06-20 07:49:28 +00001707/**** Tkapp Type Methods ****/
1708
1709static void
Fred Drake509d79a2000-07-08 04:04:38 +00001710Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001711{
Guido van Rossum00d93061998-05-28 23:06:38 +00001712 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001713 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001714 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001715 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001716 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001717}
1718
1719static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001720Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001721{
Guido van Rossum35d43371997-08-02 00:09:09 +00001722 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001723}
1724
1725static PyTypeObject Tkapp_Type =
1726{
Guido van Rossum35d43371997-08-02 00:09:09 +00001727 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 0, /*ob_size */
1729 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001730 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001731 0, /*tp_itemsize */
1732 Tkapp_Dealloc, /*tp_dealloc */
1733 0, /*tp_print */
1734 Tkapp_GetAttr, /*tp_getattr */
1735 0, /*tp_setattr */
1736 0, /*tp_compare */
1737 0, /*tp_repr */
1738 0, /*tp_as_number */
1739 0, /*tp_as_sequence */
1740 0, /*tp_as_mapping */
1741 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001742};
1743
Barry Warsawfa701a81997-01-16 00:15:11 +00001744
1745
Guido van Rossum18468821994-06-20 07:49:28 +00001746/**** Tkinter Module ****/
1747
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001748typedef struct {
1749 PyObject* tuple;
1750 int size; /* current size */
1751 int maxsize; /* allocated size */
1752} FlattenContext;
1753
1754static int
1755_bump(FlattenContext* context, int size)
1756{
Guido van Rossum2834b972000-10-06 16:58:26 +00001757 /* expand tuple to hold (at least) size new items.
1758 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001759
1760 int maxsize = context->maxsize * 2;
1761
1762 if (maxsize < context->size + size)
1763 maxsize = context->size + size;
1764
1765 context->maxsize = maxsize;
1766
Tim Peters4324aa32001-05-28 22:30:08 +00001767 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001768}
1769
1770static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001771_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001772{
1773 /* add tuple or list to argument tuple (recursively) */
1774
1775 int i, size;
1776
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001777 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001778 PyErr_SetString(PyExc_ValueError,
1779 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001780 return 0;
1781 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001782 size = PyList_GET_SIZE(item);
1783 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001784 if (context->size + size > context->maxsize &&
1785 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001786 return 0;
1787 /* copy items to output tuple */
1788 for (i = 0; i < size; i++) {
1789 PyObject *o = PyList_GET_ITEM(item, i);
1790 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001791 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001792 return 0;
1793 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001794 if (context->size + 1 > context->maxsize &&
1795 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001796 return 0;
1797 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001798 PyTuple_SET_ITEM(context->tuple,
1799 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001800 }
1801 }
1802 } else if (PyTuple_Check(item)) {
1803 /* same, for tuples */
1804 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001805 if (context->size + size > context->maxsize &&
1806 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001807 return 0;
1808 for (i = 0; i < size; i++) {
1809 PyObject *o = PyTuple_GET_ITEM(item, i);
1810 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001811 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001812 return 0;
1813 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001814 if (context->size + 1 > context->maxsize &&
1815 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001816 return 0;
1817 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001818 PyTuple_SET_ITEM(context->tuple,
1819 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001820 }
1821 }
1822 } else {
1823 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1824 return 0;
1825 }
1826 return 1;
1827}
1828
1829static PyObject *
1830Tkinter_Flatten(PyObject* self, PyObject* args)
1831{
1832 FlattenContext context;
1833 PyObject* item;
1834
1835 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1836 return NULL;
1837
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001838 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001839 if (context.maxsize <= 0)
1840 return PyTuple_New(0);
1841
1842 context.tuple = PyTuple_New(context.maxsize);
1843 if (!context.tuple)
1844 return NULL;
1845
1846 context.size = 0;
1847
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001848 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001849 return NULL;
1850
Tim Peters4324aa32001-05-28 22:30:08 +00001851 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001852 return NULL;
1853
1854 return context.tuple;
1855}
1856
Guido van Rossum18468821994-06-20 07:49:28 +00001857static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001858Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001859{
Barry Warsawfa701a81997-01-16 00:15:11 +00001860 char *screenName = NULL;
1861 char *baseName = NULL;
1862 char *className = NULL;
1863 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001864
Guido van Rossum35d43371997-08-02 00:09:09 +00001865 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 if (baseName != NULL)
1867 baseName++;
1868 else
1869 baseName = Py_GetProgramName();
1870 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001871
Guido van Rossum43713e52000-02-29 13:59:29 +00001872 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001873 &screenName, &baseName, &className,
1874 &interactive))
1875 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001876
Barry Warsawfa701a81997-01-16 00:15:11 +00001877 return (PyObject *) Tkapp_New(screenName, baseName, className,
1878 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001879}
1880
1881static PyMethodDef moduleMethods[] =
1882{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001883 {"_flatten", Tkinter_Flatten, METH_VARARGS},
1884 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001885#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001886 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
1887 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00001888#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001889 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
1890 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
1891 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
1892 {"quit", Tkapp_Quit, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001893 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001894};
1895
Guido van Rossum7bf15641998-05-22 18:28:17 +00001896#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001897
1898static int stdin_ready = 0;
1899
Guido van Rossumad4db171998-06-13 13:56:28 +00001900#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001901static void
Fred Drake509d79a2000-07-08 04:04:38 +00001902MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001903{
1904 stdin_ready = 1;
1905}
Guido van Rossumad4db171998-06-13 13:56:28 +00001906#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001907
Guido van Rossum00d93061998-05-28 23:06:38 +00001908static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001909
Guido van Rossum18468821994-06-20 07:49:28 +00001910static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001911EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00001912{
Guido van Rossumad4db171998-06-13 13:56:28 +00001913#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001914 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001915#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001916#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001917 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001918#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001919 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001920 errorInCmd = 0;
1921#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001922 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001923 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001924#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001925 while (!errorInCmd && !stdin_ready) {
1926 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001927#ifdef MS_WINDOWS
1928 if (_kbhit()) {
1929 stdin_ready = 1;
1930 break;
1931 }
1932#endif
1933#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001934 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001935 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001936 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001937
Guido van Rossum00d93061998-05-28 23:06:38 +00001938 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001939
1940 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001941 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001942 if (result == 0)
1943 Sleep(20);
1944 Py_END_ALLOW_THREADS
1945#else
1946 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001947#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001948
1949 if (result < 0)
1950 break;
1951 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001952#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001953 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001954#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001955 if (errorInCmd) {
1956 errorInCmd = 0;
1957 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1958 excInCmd = valInCmd = trbInCmd = NULL;
1959 PyErr_Print();
1960 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001961#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001962 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001963#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001965}
Guido van Rossum18468821994-06-20 07:49:28 +00001966
Guido van Rossum00d93061998-05-28 23:06:38 +00001967#endif
1968
Guido van Rossum7bf15641998-05-22 18:28:17 +00001969static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001970EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001971{
Guido van Rossum00d93061998-05-28 23:06:38 +00001972#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001973 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001974#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001975 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001976#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001977 PyOS_InputHook = EventHook;
1978 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001979#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001980}
1981
1982static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001983DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001984{
Guido van Rossum00d93061998-05-28 23:06:38 +00001985#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001986 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1987 PyOS_InputHook = NULL;
1988 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001989#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001990}
1991
Barry Warsawfa701a81997-01-16 00:15:11 +00001992
1993/* all errors will be checked in one fell swoop in init_tkinter() */
1994static void
Fred Drake509d79a2000-07-08 04:04:38 +00001995ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00001996{
1997 PyObject *v = PyInt_FromLong(val);
1998 if (v) {
1999 PyDict_SetItemString(d, name, v);
2000 Py_DECREF(v);
2001 }
2002}
2003static void
Fred Drake509d79a2000-07-08 04:04:38 +00002004ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002005{
2006 PyObject *v = PyString_FromString(val);
2007 if (v) {
2008 PyDict_SetItemString(d, name, v);
2009 Py_DECREF(v);
2010 }
2011}
2012
2013
Mark Hammond62b1ab12002-07-23 06:31:15 +00002014PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002015init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002016{
Barry Warsawfa701a81997-01-16 00:15:11 +00002017 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002018
Barry Warsawfa701a81997-01-16 00:15:11 +00002019 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002020
2021#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002022 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002023#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002024
Barry Warsawfa701a81997-01-16 00:15:11 +00002025 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002026
Barry Warsawfa701a81997-01-16 00:15:11 +00002027 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00002028 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00002029 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002030
Guido van Rossum35d43371997-08-02 00:09:09 +00002031 ins_long(d, "READABLE", TCL_READABLE);
2032 ins_long(d, "WRITABLE", TCL_WRITABLE);
2033 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2034 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2035 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2036 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2037 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2038 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2039 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002040 ins_string(d, "TK_VERSION", TK_VERSION);
2041 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002042
Guido van Rossum83551bf1997-09-13 00:44:23 +00002043 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002044
2045 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002046 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2047
Jack Jansencb852442001-12-09 23:15:56 +00002048
2049#ifdef TK_AQUA
2050 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
2051 * start waking up. Note that Tcl_FindExecutable will do this, this
2052 * code must be above it! The original warning from
2053 * tkMacOSXAppInit.c is copied below.
2054 *
2055 * NB - You have to swap in the Tk Notifier BEFORE you start up the
2056 * Tcl interpreter for now. It probably should work to do this
2057 * in the other order, but for now it doesn't seem to.
2058 *
2059 */
2060 Tk_MacOSXSetupTkNotifier();
2061#endif
2062
2063
Guido van Rossume187b0e2000-03-27 21:46:29 +00002064 /* This helps the dynamic loader; in Unicode aware Tcl versions
2065 it also helps Tcl find its encodings. */
2066 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002067
Barry Warsawfa701a81997-01-16 00:15:11 +00002068 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002069 return;
2070
Guido van Rossum43ff8681998-07-14 18:02:13 +00002071#if 0
2072 /* This was not a good idea; through <Destroy> bindings,
2073 Tcl_Finalize() may invoke Python code but at that point the
2074 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002075 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002076#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002077
Jack Jansen34cc5c31995-10-31 16:15:12 +00002078#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002079 /*
2080 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2081 ** Most of the initializations in that routine (toolbox init calls and
2082 ** such) have already been done for us, so we only need these.
2083 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002084 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002085
2086 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002087#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002088 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002089#endif /* GENERATINGCFM */
2090#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002091}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002092
Guido van Rossumec22c921996-02-25 04:50:29 +00002093
Barry Warsawfa701a81997-01-16 00:15:11 +00002094
Guido van Rossum9722ad81995-09-22 23:49:28 +00002095#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002096
2097/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002098** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002099*/
2100
Guido van Rossum9722ad81995-09-22 23:49:28 +00002101void
2102panic(char * format, ...)
2103{
Barry Warsawfa701a81997-01-16 00:15:11 +00002104 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002105
Barry Warsawfa701a81997-01-16 00:15:11 +00002106 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002107
Guido van Rossum227cf761998-08-05 13:53:32 +00002108 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002109 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002110
Barry Warsawfa701a81997-01-16 00:15:11 +00002111 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002112
Barry Warsawfa701a81997-01-16 00:15:11 +00002113 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002114}
Jack Jansen40b546d1995-11-14 10:34:45 +00002115
Guido van Rossumec22c921996-02-25 04:50:29 +00002116/*
2117** Pass events to SIOUX before passing them to Tk.
2118*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002119
Guido van Rossumec22c921996-02-25 04:50:29 +00002120static int
Fred Drake509d79a2000-07-08 04:04:38 +00002121PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002122{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002123 WindowPtr frontwin;
2124 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002125 ** Sioux eats too many events, so we don't pass it everything. We
2126 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002127 ** the Sioux window is frontmost. This means that Tk menus don't work
2128 ** in that case, but at least we can scroll the sioux window.
2129 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2130 ** part of the external interface of Sioux...
2131 */
2132 frontwin = FrontWindow();
2133 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2134 if (SIOUXHandleOneEvent(eventPtr))
2135 return 0; /* Nothing happened to the Tcl event queue */
2136 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002137 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002138}
2139
Guido van Rossumec22c921996-02-25 04:50:29 +00002140#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002141
2142/*
2143** Additional Mac specific code for dealing with shared libraries.
2144*/
2145
2146#include <Resources.h>
2147#include <CodeFragments.h>
2148
2149static int loaded_from_shlib = 0;
2150static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002151
Jack Jansen34cc5c31995-10-31 16:15:12 +00002152/*
2153** If this module is dynamically loaded the following routine should
2154** be the init routine. It takes care of adding the shared library to
2155** the resource-file chain, so that the tk routines can find their
2156** resources.
2157*/
2158OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002159init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002160{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002161 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002162 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002163 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002164 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2165 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002166 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002167 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2168 loaded_from_shlib = 1;
2169 }
2170 return noErr;
2171}
2172
2173/*
2174** Insert the library resources into the search path. Put them after
2175** the resources from the application. Again, we ignore errors.
2176*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002177static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002178mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002179{
2180 if ( !loaded_from_shlib )
2181 return;
2182 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2183}
2184
Guido van Rossumec22c921996-02-25 04:50:29 +00002185#endif /* GENERATINGCFM */
2186#endif /* macintosh */