blob: 528b04871983ff76adcbc8404d8bafadec285ac6 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Guido van Rossuma80649b2000-03-28 20:07:05 +000012 Only Tcl/Tk 8.0 and later are supported. Older versions are not
13 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
14 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
19 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
20 intelligent mappings between Python objects and Tcl objects (e.g. ints,
21 floats and Tcl window pointers could be handled specially).
22
23 - Register a new Tcl type, "Python callable", which can be called more
24 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
25
Guido van Rossum7ffa7611996-08-13 21:10:16 +000026*/
27
Guido van Rossum35d43371997-08-02 00:09:09 +000028
Guido van Rossum9722ad81995-09-22 23:49:28 +000029#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000030#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000031
Guido van Rossum00d93061998-05-28 23:06:38 +000032#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000033#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000034#endif
35
Guido van Rossum2a5119b1998-05-29 01:28:40 +000036#ifdef MS_WINDOWS
37#include <windows.h>
38#endif
39
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000040#ifdef macintosh
41#define MAC_TCL
Guido van Rossum49b56061998-10-01 20:42:43 +000042#endif
43
Guido van Rossum18468821994-06-20 07:49:28 +000044#include <tcl.h>
45#include <tk.h>
46
Guido van Rossum3e819a71997-08-01 19:29:02 +000047#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
48
Guido van Rossuma80649b2000-03-28 20:07:05 +000049#if TKMAJORMINOR < 8000
50#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000051#endif
52
Guido van Rossuma80649b2000-03-28 20:07:05 +000053#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000054/* Sigh, we have to include this to get at the tcl qd pointer */
55#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000056/* And this one we need to clear the menu bar */
57#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000058#endif
59
Tim Peters98dc0652000-10-05 19:24:26 +000060#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000061#define HAVE_CREATEFILEHANDLER
62#endif
63
Guido van Rossum00d93061998-05-28 23:06:38 +000064#ifdef HAVE_CREATEFILEHANDLER
65
66/* Tcl_CreateFileHandler() changed several times; these macros deal with the
67 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
68 Unix, only because Jack added it back); when available on Windows, it only
69 applies to sockets. */
70
Guido van Rossum7bf15641998-05-22 18:28:17 +000071#ifdef MS_WINDOWS
72#define FHANDLETYPE TCL_WIN_SOCKET
73#else
74#define FHANDLETYPE TCL_UNIX_FD
75#endif
76
Guido van Rossum00d93061998-05-28 23:06:38 +000077/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
78 which uses this to handle Tcl events while the user is typing commands. */
79
80#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000081#define WAIT_FOR_STDIN
82#endif
83
Guido van Rossum00d93061998-05-28 23:06:38 +000084#endif /* HAVE_CREATEFILEHANDLER */
85
Guido van Rossumad4db171998-06-13 13:56:28 +000086#ifdef MS_WINDOWS
87#include <conio.h>
88#define WAIT_FOR_STDIN
89#endif
90
Guido van Rossum00d93061998-05-28 23:06:38 +000091#ifdef WITH_THREAD
92
93/* The threading situation is complicated. Tcl is not thread-safe, except for
94 Tcl 8.1, which will probably remain in alpha status for another 6 months
95 (and the README says that Tk will probably remain thread-unsafe forever).
96 So we need to use a lock around all uses of Tcl. Previously, the Python
97 interpreter lock was used for this. However, this causes problems when
98 other Python threads need to run while Tcl is blocked waiting for events.
99
100 To solve this problem, a separate lock for Tcl is introduced. Holding it
101 is incompatible with holding Python's interpreter lock. The following four
102 macros manipulate both locks together.
103
104 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
105 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
106 that could call an event handler, or otherwise affect the state of a Tcl
107 interpreter. These assume that the surrounding code has the Python
108 interpreter lock; inside the brackets, the Python interpreter lock has been
109 released and the lock for Tcl has been acquired.
110
Guido van Rossum5e977831998-06-15 14:03:52 +0000111 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
112 (For example, when transferring data from the Tcl interpreter result to a
113 Python string object.) This can be done by using different macros to close
114 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
115 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
116 releases the Tcl lock.
117
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000118 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000119 handlers when the handler needs to use Python. Such event handlers are
120 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000121 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000122 the Python interpreter lock, restoring the appropriate thread state, and
123 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
124 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000125 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000126
127 These locks expand to several statements and brackets; they should not be
128 used in branches of if statements and the like.
129
130*/
131
Guido van Rossum65d5b571998-12-21 19:32:43 +0000132static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000133static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000134
135#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000136 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000137 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000138
139#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000140 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000141
Guido van Rossum62320c91998-06-15 04:36:09 +0000142#define ENTER_OVERLAP \
143 Py_END_ALLOW_THREADS
144
145#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000146 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148#define ENTER_PYTHON \
149 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000150 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000151
152#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000153 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000154 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000155
156#else
157
158#define ENTER_TCL
159#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000160#define ENTER_OVERLAP
161#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000163#define LEAVE_PYTHON
164
165#endif
166
Guido van Rossumec22c921996-02-25 04:50:29 +0000167#ifdef macintosh
168
169/*
170** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000171** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000172*/
173
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000174/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000175#define FREECAST (char *)
176
Guido van Rossumec22c921996-02-25 04:50:29 +0000177#include <Events.h> /* For EventRecord */
178
Fred Drake509d79a2000-07-08 04:04:38 +0000179typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000180void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
181int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000182
Guido van Rossum2834b972000-10-06 16:58:26 +0000183staticforward int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000184
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000185#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
186 #pragma import on
187#endif
188
189#include <SIOUX.h>
190extern int SIOUXIsAppWindow(WindowPtr);
191
192#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
193 #pragma import reset
194#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000195#endif /* macintosh */
196
Guido van Rossum97867b21996-08-08 19:09:53 +0000197#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000198#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000199#endif
200
Guido van Rossum18468821994-06-20 07:49:28 +0000201/**** Tkapp Object Declaration ****/
202
203staticforward PyTypeObject Tkapp_Type;
204
Guido van Rossum00d93061998-05-28 23:06:38 +0000205typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000206 PyObject_HEAD
207 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000208} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000209
210#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000211#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000212#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000213
Guido van Rossum35d43371997-08-02 00:09:09 +0000214#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000215(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000216
Barry Warsawfa701a81997-01-16 00:15:11 +0000217
218
Guido van Rossum18468821994-06-20 07:49:28 +0000219/**** Error Handling ****/
220
221static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000222static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000223static int errorInCmd = 0;
224static PyObject *excInCmd;
225static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000227
Barry Warsawfa701a81997-01-16 00:15:11 +0000228
229
Guido van Rossum18468821994-06-20 07:49:28 +0000230static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000231Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000232{
Barry Warsawfa701a81997-01-16 00:15:11 +0000233 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
234 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000235}
236
Barry Warsawfa701a81997-01-16 00:15:11 +0000237
Barry Warsawfa701a81997-01-16 00:15:11 +0000238
Guido van Rossum18468821994-06-20 07:49:28 +0000239/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000240
241#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000242#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000243
Guido van Rossum00d93061998-05-28 23:06:38 +0000244/* Millisecond sleep() for Unix platforms. */
245
246static void
Fred Drake509d79a2000-07-08 04:04:38 +0000247Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000248{
249 /* XXX Too bad if you don't have select(). */
250 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000251 t.tv_sec = milli/1000;
252 t.tv_usec = (milli%1000) * 1000;
253 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
254}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000255#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000256#endif /* WITH_THREAD */
257
258
Guido van Rossum18468821994-06-20 07:49:28 +0000259static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000260AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000261{
Guido van Rossum35d43371997-08-02 00:09:09 +0000262 if (PyString_Check(value))
263 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000264 else if (PyUnicode_Check(value)) {
265 PyObject *v = PyUnicode_AsUTF8String(value);
266 if (v == NULL)
267 return NULL;
268 if (PyList_Append(tmp, v) != 0) {
269 Py_DECREF(v);
270 return NULL;
271 }
272 Py_DECREF(v);
273 return PyString_AsString(v);
274 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000275 else {
276 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000277 if (v == NULL)
278 return NULL;
279 if (PyList_Append(tmp, v) != 0) {
280 Py_DECREF(v);
281 return NULL;
282 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000283 Py_DECREF(v);
284 return PyString_AsString(v);
285 }
Guido van Rossum18468821994-06-20 07:49:28 +0000286}
287
Barry Warsawfa701a81997-01-16 00:15:11 +0000288
289
Guido van Rossum18468821994-06-20 07:49:28 +0000290#define ARGSZ 64
291
292static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000293Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000294{
Barry Warsawfa701a81997-01-16 00:15:11 +0000295 PyObject *tmp = NULL;
296 char *argvStore[ARGSZ];
297 char **argv = NULL;
298 int fvStore[ARGSZ];
299 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000300 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000302
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 if (!(tmp = PyList_New(0)))
304 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000305
Barry Warsawfa701a81997-01-16 00:15:11 +0000306 argv = argvStore;
307 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309 if (args == NULL)
310 argc = 0;
311
312 else if (!PyTuple_Check(args)) {
313 argc = 1;
314 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000315 if (!(argv[0] = AsString(args, tmp)))
316 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000317 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000318 else {
319 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000320
Barry Warsawfa701a81997-01-16 00:15:11 +0000321 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000322 argv = (char **)ckalloc(argc * sizeof(char *));
323 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 if (argv == NULL || fv == NULL) {
325 PyErr_NoMemory();
326 goto finally;
327 }
328 }
329
330 for (i = 0; i < argc; i++) {
331 PyObject *v = PyTuple_GetItem(args, i);
332 if (PyTuple_Check(v)) {
333 fv[i] = 1;
334 if (!(argv[i] = Merge(v)))
335 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000336 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000337 }
338 else if (v == Py_None) {
339 argc = i;
340 break;
341 }
342 else {
343 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000344 if (!(argv[i] = AsString(v, tmp)))
345 goto finally;
346 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 }
348 }
Guido van Rossum18468821994-06-20 07:49:28 +0000349 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000351 if (res == NULL)
352 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000353
Barry Warsawfa701a81997-01-16 00:15:11 +0000354 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000355 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 if (fv[i]) {
357 ckfree(argv[i]);
358 }
359 if (argv != argvStore)
360 ckfree(FREECAST argv);
361 if (fv != fvStore)
362 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 Py_DECREF(tmp);
365 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000366}
367
Barry Warsawfa701a81997-01-16 00:15:11 +0000368
369
Guido van Rossum18468821994-06-20 07:49:28 +0000370static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000371Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000372{
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 int argc;
374 char **argv;
375 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000376
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 if (list == NULL) {
378 Py_INCREF(Py_None);
379 return Py_None;
380 }
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Guido van Rossum00d93061998-05-28 23:06:38 +0000382 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 /* Not a list.
384 * Could be a quoted string containing funnies, e.g. {"}.
385 * Return the string itself.
386 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 return PyString_FromString(list);
388 }
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 if (argc == 0)
391 v = PyString_FromString("");
392 else if (argc == 1)
393 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000394 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000395 int i;
396 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000397
Barry Warsawfa701a81997-01-16 00:15:11 +0000398 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 Py_DECREF(v);
401 v = NULL;
402 break;
403 }
404 PyTuple_SetItem(v, i, w);
405 }
406 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000407 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000408 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000409}
410
Barry Warsawfa701a81997-01-16 00:15:11 +0000411
412
Guido van Rossum18468821994-06-20 07:49:28 +0000413/**** Tkapp Object ****/
414
415#ifndef WITH_APPINIT
416int
Fred Drake509d79a2000-07-08 04:04:38 +0000417Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000418{
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000420
Barry Warsawfa701a81997-01-16 00:15:11 +0000421 main = Tk_MainWindow(interp);
422 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000423 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 return TCL_ERROR;
425 }
426 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000427 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 return TCL_ERROR;
429 }
430 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000431}
432#endif /* !WITH_APPINIT */
433
Guido van Rossum18468821994-06-20 07:49:28 +0000434
Barry Warsawfa701a81997-01-16 00:15:11 +0000435
436
437/* Initialize the Tk application; see the `main' function in
438 * `tkMain.c'.
439 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000440
Thomas Wouters58d05102000-07-24 14:43:35 +0000441static void EnableEventHook(void); /* Forward */
442static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000445Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000446{
447 TkappObject *v;
448 char *argv0;
449
Guido van Rossumb18618d2000-05-03 23:44:39 +0000450 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 if (v == NULL)
452 return NULL;
453
454 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000455
Guido van Rossuma80649b2000-03-28 20:07:05 +0000456#if defined(macintosh)
457 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000458 ClearMenuBar();
459 TkMacInitMenus(v->interp);
460#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000461 /* Delete the 'exit' command, which can screw things up */
462 Tcl_DeleteCommand(v->interp, "exit");
463
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 if (screenName != NULL)
465 Tcl_SetVar2(v->interp, "env", "DISPLAY",
466 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (interactive)
469 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
470 else
471 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000472
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 /* This is used to get the application class for Tk 4.1 and up */
474 argv0 = (char*)ckalloc(strlen(className) + 1);
475 if (!argv0) {
476 PyErr_NoMemory();
477 Py_DECREF(v);
478 return NULL;
479 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000482 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 argv0[0] = tolower(argv0[0]);
484 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
485 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000486
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000488 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000489
Guido van Rossum7bf15641998-05-22 18:28:17 +0000490 EnableEventHook();
491
Barry Warsawfa701a81997-01-16 00:15:11 +0000492 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000493}
494
Barry Warsawfa701a81997-01-16 00:15:11 +0000495
496
Guido van Rossum18468821994-06-20 07:49:28 +0000497/** Tcl Eval **/
498
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000499#if TKMAJORMINOR >= 8001
500#define USING_OBJECTS
501#endif
502
503#ifdef USING_OBJECTS
504
505static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000506AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000507{
508 Tcl_Obj *result;
509
510 if (PyString_Check(value))
511 return Tcl_NewStringObj(PyString_AS_STRING(value),
512 PyString_GET_SIZE(value));
513 else if (PyInt_Check(value))
514 return Tcl_NewLongObj(PyInt_AS_LONG(value));
515 else if (PyFloat_Check(value))
516 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
517 else if (PyTuple_Check(value)) {
518 Tcl_Obj **argv = (Tcl_Obj**)
519 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
520 int i;
521 if(!argv)
522 return 0;
523 for(i=0;i<PyTuple_Size(value);i++)
524 argv[i] = AsObj(PyTuple_GetItem(value,i));
525 result = Tcl_NewListObj(PyTuple_Size(value), argv);
526 ckfree(FREECAST argv);
527 return result;
528 }
529 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000530#if TKMAJORMINOR <= 8001
531 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000532 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000533 if (!utf8)
534 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000535 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
536 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000537 Py_DECREF(utf8);
538 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000539#else /* TKMAJORMINOR > 8001 */
540 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
541 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
542 /* XXX Should really test this at compile time */
543 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000544 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000545 return 0;
546 }
547 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
548 PyUnicode_GET_SIZE(value));
549#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000550 }
551 else {
552 PyObject *v = PyObject_Str(value);
553 if (!v)
554 return 0;
555 result = AsObj(v);
556 Py_DECREF(v);
557 return result;
558 }
559}
560
Guido van Rossum18468821994-06-20 07:49:28 +0000561static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000562Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000563{
Guido van Rossum632de272000-03-29 00:19:50 +0000564 Tcl_Obj *objStore[ARGSZ];
565 Tcl_Obj **objv = NULL;
566 int objc = 0, i;
567 PyObject *res = NULL;
568 Tcl_Interp *interp = Tkapp_Interp(self);
569 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
570 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000571
Guido van Rossum632de272000-03-29 00:19:50 +0000572 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000573
Guido van Rossum212643f1998-04-29 16:22:14 +0000574 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000575 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
Guido van Rossum212643f1998-04-29 16:22:14 +0000577 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000578 objc = 1;
579 objv[0] = AsObj(args);
580 if (objv[0] == 0)
581 goto finally;
582 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000583 }
584 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000585 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000586
Guido van Rossum632de272000-03-29 00:19:50 +0000587 if (objc > ARGSZ) {
588 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
589 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000590 PyErr_NoMemory();
591 goto finally;
592 }
593 }
594
Guido van Rossum632de272000-03-29 00:19:50 +0000595 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000596 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000597 if (v == Py_None) {
598 objc = i;
599 break;
600 }
Guido van Rossum632de272000-03-29 00:19:50 +0000601 objv[i] = AsObj(v);
602 if (!objv[i])
603 goto finally;
604 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000605 }
606 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000607
Guido van Rossum62320c91998-06-15 04:36:09 +0000608 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000609
610 i = Tcl_EvalObjv(interp, objc, objv, flags);
611
Guido van Rossum62320c91998-06-15 04:36:09 +0000612 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000613 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000614 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000615 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000616 /* We could request the object result here, but doing
617 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000618 char *s = Tcl_GetStringResult(interp);
619 char *p = s;
620 /* If the result contains any bytes with the top bit set,
621 it's UTF-8 and we should decode it to Unicode */
622 while (*p != '\0') {
623 if (*p & 0x80)
624 break;
625 p++;
626 }
627 if (*p == '\0')
628 res = PyString_FromStringAndSize(s, (int)(p-s));
629 else {
630 /* Convert UTF-8 to Unicode string */
631 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000632 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
633 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000634 PyErr_Clear();
635 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000636 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000637 }
638 }
Guido van Rossum632de272000-03-29 00:19:50 +0000639
Guido van Rossum62320c91998-06-15 04:36:09 +0000640 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000641
Guido van Rossum212643f1998-04-29 16:22:14 +0000642 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000643 for (i = 0; i < objc; i++)
644 Tcl_DecrRefCount(objv[i]);
645 if (objv != objStore)
646 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000647 return res;
648}
649
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000650#else /* !USING_OBJECTS */
651
652static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000653Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000654{
655 /* This is copied from Merge() */
656 PyObject *tmp = NULL;
657 char *argvStore[ARGSZ];
658 char **argv = NULL;
659 int fvStore[ARGSZ];
660 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000661 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000662 PyObject *res = NULL; /* except this has a different type */
663 Tcl_CmdInfo info; /* and this is added */
664 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
665
666 if (!(tmp = PyList_New(0)))
667 return NULL;
668
669 argv = argvStore;
670 fv = fvStore;
671
672 if (args == NULL)
673 argc = 0;
674
675 else if (!PyTuple_Check(args)) {
676 argc = 1;
677 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000678 if (!(argv[0] = AsString(args, tmp)))
679 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000680 }
681 else {
682 argc = PyTuple_Size(args);
683
684 if (argc > ARGSZ) {
685 argv = (char **)ckalloc(argc * sizeof(char *));
686 fv = (int *)ckalloc(argc * sizeof(int));
687 if (argv == NULL || fv == NULL) {
688 PyErr_NoMemory();
689 goto finally;
690 }
691 }
692
693 for (i = 0; i < argc; i++) {
694 PyObject *v = PyTuple_GetItem(args, i);
695 if (PyTuple_Check(v)) {
696 fv[i] = 1;
697 if (!(argv[i] = Merge(v)))
698 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000699 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000700 }
701 else if (v == Py_None) {
702 argc = i;
703 break;
704 }
705 else {
706 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000707 if (!(argv[i] = AsString(v, tmp)))
708 goto finally;
709 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000710 }
711 }
712 }
713 /* End code copied from Merge() */
714
715 /* All this to avoid a call to Tcl_Merge() and the corresponding call
716 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
717 if (Py_VerboseFlag >= 2) {
718 for (i = 0; i < argc; i++)
719 PySys_WriteStderr("%s ", argv[i]);
720 }
721 ENTER_TCL
722 info.proc = NULL;
723 if (argc < 1 ||
724 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
725 info.proc == NULL)
726 {
727 char *cmd;
728 cmd = Tcl_Merge(argc, argv);
729 i = Tcl_Eval(interp, cmd);
730 ckfree(cmd);
731 }
732 else {
733 Tcl_ResetResult(interp);
734 i = (*info.proc)(info.clientData, interp, argc, argv);
735 }
736 ENTER_OVERLAP
737 if (info.proc == NULL && Py_VerboseFlag >= 2)
738 PySys_WriteStderr("... use TclEval ");
739 if (i == TCL_ERROR) {
740 if (Py_VerboseFlag >= 2)
741 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000742 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000743 Tkinter_Error(self);
744 }
745 else {
746 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000747 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
748 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000749 }
750 LEAVE_OVERLAP_TCL
751
752 /* Copied from Merge() again */
753 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000754 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000755 if (fv[i]) {
756 ckfree(argv[i]);
757 }
758 if (argv != argvStore)
759 ckfree(FREECAST argv);
760 if (fv != fvStore)
761 ckfree(FREECAST fv);
762
763 Py_DECREF(tmp);
764 return res;
765}
766
767#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000768
769static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000770Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000771{
Guido van Rossum212643f1998-04-29 16:22:14 +0000772 /* Could do the same here as for Tkapp_Call(), but this is not used
773 much, so I can't be bothered. Unfortunately Tcl doesn't export a
774 way for the user to do what all its Global* variants do (save and
775 reset the scope pointer, call the local version, restore the saved
776 scope pointer). */
777
Guido van Rossum62320c91998-06-15 04:36:09 +0000778 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000779 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000780
Guido van Rossum62320c91998-06-15 04:36:09 +0000781 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000782 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000783 int err;
784 ENTER_TCL
785 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000786 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000787 if (err == TCL_ERROR)
788 res = Tkinter_Error(self);
789 else
790 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000791 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000793 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000794
795 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000796}
797
798static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000799Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000800{
Barry Warsawfa701a81997-01-16 00:15:11 +0000801 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000802 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000803 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000804
Guido van Rossum43713e52000-02-29 13:59:29 +0000805 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 return NULL;
807
Guido van Rossum00d93061998-05-28 23:06:38 +0000808 ENTER_TCL
809 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000810 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000811 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000812 res = Tkinter_Error(self);
813 else
814 res = PyString_FromString(Tkapp_Result(self));
815 LEAVE_OVERLAP_TCL
816 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000817}
818
819static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000820Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000821{
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000823 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000824 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000825
Guido van Rossum43713e52000-02-29 13:59:29 +0000826 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000828
Guido van Rossum00d93061998-05-28 23:06:38 +0000829 ENTER_TCL
830 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000831 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000832 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000833 res = Tkinter_Error(self);
834 else
835 res = PyString_FromString(Tkapp_Result(self));
836 LEAVE_OVERLAP_TCL
837 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000838}
839
840static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000841Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000842{
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000844 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000845 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000846
Guido van Rossum43713e52000-02-29 13:59:29 +0000847 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000848 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000849
Guido van Rossum00d93061998-05-28 23:06:38 +0000850 ENTER_TCL
851 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000852 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000853 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000854 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000855
Guido van Rossum62320c91998-06-15 04:36:09 +0000856 else
857 res = PyString_FromString(Tkapp_Result(self));
858 LEAVE_OVERLAP_TCL
859 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000860}
861
862static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000863Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000864{
Barry Warsawfa701a81997-01-16 00:15:11 +0000865 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000866 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000867 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000868
Guido van Rossum35d43371997-08-02 00:09:09 +0000869 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum00d93061998-05-28 23:06:38 +0000872 ENTER_TCL
873 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000874 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000875 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000876 res = Tkinter_Error(self);
877 else
878 res = PyString_FromString(Tkapp_Result(self));
879 LEAVE_OVERLAP_TCL
880 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000881}
882
883static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000884Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000885{
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000887
Guido van Rossum43713e52000-02-29 13:59:29 +0000888 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000889 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000890 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000892 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000893
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 Py_INCREF(Py_None);
895 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000896}
897
Barry Warsawfa701a81997-01-16 00:15:11 +0000898
899
Guido van Rossum18468821994-06-20 07:49:28 +0000900/** Tcl Variable **/
901
902static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000903SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000904{
Guido van Rossum00d93061998-05-28 23:06:38 +0000905 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000906 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000907 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Guido van Rossum62320c91998-06-15 04:36:09 +0000909 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 if (!tmp)
911 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000912
Guido van Rossum43713e52000-02-29 13:59:29 +0000913 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000915 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000916 if (s == NULL)
917 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000918 ENTER_TCL
919 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
920 LEAVE_TCL
921 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000923 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000924 if (PyArg_ParseTuple(args, "ssO:setvar",
925 &name1, &name2, &newValue)) {
926 s = AsString(newValue, tmp);
927 if (s == NULL)
928 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000929 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000930 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000931 s, flags);
932 LEAVE_TCL
933 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000934 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000935 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000936 return NULL;
937 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000938 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000940
Barry Warsawfa701a81997-01-16 00:15:11 +0000941 if (!ok)
942 return Tkinter_Error(self);
943
944 Py_INCREF(Py_None);
945 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000946}
947
948static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000949Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000950{
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000952}
953
954static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000955Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000956{
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000958}
959
Barry Warsawfa701a81997-01-16 00:15:11 +0000960
961
Guido van Rossum18468821994-06-20 07:49:28 +0000962static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000963GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000964{
Guido van Rossum35d43371997-08-02 00:09:09 +0000965 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000966 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000967
Guido van Rossum43713e52000-02-29 13:59:29 +0000968 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000969 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000970 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000971 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000972 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000973
Barry Warsawfa701a81997-01-16 00:15:11 +0000974 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000975 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000976 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000977
Barry Warsawfa701a81997-01-16 00:15:11 +0000978 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000979 res = Tkinter_Error(self);
980 else
981 res = PyString_FromString(s);
982 LEAVE_OVERLAP_TCL
983 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000984}
985
986static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000987Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000988{
Barry Warsawfa701a81997-01-16 00:15:11 +0000989 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000990}
991
992static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000993Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000994{
Barry Warsawfa701a81997-01-16 00:15:11 +0000995 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000996}
997
Barry Warsawfa701a81997-01-16 00:15:11 +0000998
999
Guido van Rossum18468821994-06-20 07:49:28 +00001000static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001001UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001002{
Guido van Rossum35d43371997-08-02 00:09:09 +00001003 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001004 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001005 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001006
Guido van Rossum43713e52000-02-29 13:59:29 +00001007 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001009 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001010 if (name2 == NULL)
1011 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1012
1013 else
1014 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001015 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001016
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001018 res = Tkinter_Error(self);
1019 else {
1020 Py_INCREF(Py_None);
1021 res = Py_None;
1022 }
1023 LEAVE_OVERLAP_TCL
1024 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001025}
1026
1027static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001028Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001029{
Barry Warsawfa701a81997-01-16 00:15:11 +00001030 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001031}
1032
1033static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001034Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001035{
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001037}
1038
Barry Warsawfa701a81997-01-16 00:15:11 +00001039
1040
Guido van Rossum18468821994-06-20 07:49:28 +00001041/** Tcl to Python **/
1042
1043static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001044Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001045{
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 char *s;
1047 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001048
Guido van Rossum43713e52000-02-29 13:59:29 +00001049 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001051 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 return Tkinter_Error(self);
1053 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001054}
1055
1056static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001057Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001058{
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 char *s;
1060 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001061
Guido van Rossum43713e52000-02-29 13:59:29 +00001062 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001064 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 return Tkinter_Error(self);
1066 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001067}
1068
1069static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001070Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001071{
Barry Warsawfa701a81997-01-16 00:15:11 +00001072 char *s;
1073 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001074
Guido van Rossum43713e52000-02-29 13:59:29 +00001075 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001076 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001077 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1078 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001079 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001080}
1081
1082static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001083Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001084{
Barry Warsawfa701a81997-01-16 00:15:11 +00001085 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001086 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001087 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001088
Guido van Rossum43713e52000-02-29 13:59:29 +00001089 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001091 ENTER_TCL
1092 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001093 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001094 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001095 res = Tkinter_Error(self);
1096 else
1097 res = Py_BuildValue("s", Tkapp_Result(self));
1098 LEAVE_OVERLAP_TCL
1099 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001100}
1101
1102static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001103Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001104{
Barry Warsawfa701a81997-01-16 00:15:11 +00001105 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001106 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001107 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001108 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001109
Guido van Rossum43713e52000-02-29 13:59:29 +00001110 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001112 ENTER_TCL
1113 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001114 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001115 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001116 res = Tkinter_Error(self);
1117 else
1118 res = Py_BuildValue("l", v);
1119 LEAVE_OVERLAP_TCL
1120 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001121}
1122
1123static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001124Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001125{
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001127 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001129 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001130
Guido van Rossum43713e52000-02-29 13:59:29 +00001131 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001133 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001134 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001135 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001136 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001137 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001138 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001139 res = Tkinter_Error(self);
1140 else
1141 res = Py_BuildValue("d", v);
1142 LEAVE_OVERLAP_TCL
1143 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001144}
1145
1146static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001147Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001148{
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001150 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001151 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001153
Guido van Rossum43713e52000-02-29 13:59:29 +00001154 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001156 ENTER_TCL
1157 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001158 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001159 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001160 res = Tkinter_Error(self);
1161 else
1162 res = Py_BuildValue("i", v);
1163 LEAVE_OVERLAP_TCL
1164 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001165}
1166
Barry Warsawfa701a81997-01-16 00:15:11 +00001167
1168
Guido van Rossum18468821994-06-20 07:49:28 +00001169static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001170Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001171{
Barry Warsawfa701a81997-01-16 00:15:11 +00001172 char *list;
1173 int argc;
1174 char **argv;
1175 PyObject *v;
1176 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001177
Guido van Rossum43713e52000-02-29 13:59:29 +00001178 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001179 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001180
Barry Warsawfa701a81997-01-16 00:15:11 +00001181 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1182 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001183
Barry Warsawfa701a81997-01-16 00:15:11 +00001184 if (!(v = PyTuple_New(argc)))
1185 return NULL;
1186
1187 for (i = 0; i < argc; i++) {
1188 PyObject *s = PyString_FromString(argv[i]);
1189 if (!s || PyTuple_SetItem(v, i, s)) {
1190 Py_DECREF(v);
1191 v = NULL;
1192 goto finally;
1193 }
1194 }
Guido van Rossum18468821994-06-20 07:49:28 +00001195
Barry Warsawfa701a81997-01-16 00:15:11 +00001196 finally:
1197 ckfree(FREECAST argv);
1198 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001199}
1200
1201static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001202Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001203{
Barry Warsawfa701a81997-01-16 00:15:11 +00001204 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001205
Guido van Rossum43713e52000-02-29 13:59:29 +00001206 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001207 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001208 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001209}
1210
1211static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001212Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001213{
Barry Warsawfa701a81997-01-16 00:15:11 +00001214 char *s = Merge(args);
1215 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001216
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 if (s) {
1218 res = PyString_FromString(s);
1219 ckfree(s);
1220 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001221
1222 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001223}
1224
Barry Warsawfa701a81997-01-16 00:15:11 +00001225
1226
Guido van Rossum18468821994-06-20 07:49:28 +00001227/** Tcl Command **/
1228
Guido van Rossum00d93061998-05-28 23:06:38 +00001229/* Client data struct */
1230typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001231 PyObject *self;
1232 PyObject *func;
1233} PythonCmd_ClientData;
1234
1235static int
Fred Drake509d79a2000-07-08 04:04:38 +00001236PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001237{
1238 errorInCmd = 1;
1239 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1240 LEAVE_PYTHON
1241 return TCL_ERROR;
1242}
1243
Guido van Rossum18468821994-06-20 07:49:28 +00001244/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 * function or method.
1246 */
Guido van Rossum18468821994-06-20 07:49:28 +00001247static int
Fred Drake509d79a2000-07-08 04:04:38 +00001248PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001249{
Guido van Rossum00d93061998-05-28 23:06:38 +00001250 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001252 int i, rv;
1253 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001254
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001255 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001256
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 /* TBD: no error checking here since we know, via the
1258 * Tkapp_CreateCommand() that the client data is a two-tuple
1259 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001260 self = data->self;
1261 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001262
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 /* Create argument list (argv1, ..., argvN) */
1264 if (!(arg = PyTuple_New(argc - 1)))
1265 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001266
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 for (i = 0; i < (argc - 1); i++) {
1268 PyObject *s = PyString_FromString(argv[i + 1]);
1269 if (!s || PyTuple_SetItem(arg, i, s)) {
1270 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001271 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 }
1273 }
1274 res = PyEval_CallObject(func, arg);
1275 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001276
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 if (res == NULL)
1278 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001279
Barry Warsawfa701a81997-01-16 00:15:11 +00001280 if (!(tmp = PyList_New(0))) {
1281 Py_DECREF(res);
1282 return PythonCmd_Error(interp);
1283 }
1284
Guido van Rossum2834b972000-10-06 16:58:26 +00001285 s = AsString(res, tmp);
1286 if (s == NULL) {
1287 rv = PythonCmd_Error(interp);
1288 }
1289 else {
1290 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1291 rv = TCL_OK;
1292 }
1293
Barry Warsawfa701a81997-01-16 00:15:11 +00001294 Py_DECREF(res);
1295 Py_DECREF(tmp);
1296
Guido van Rossum00d93061998-05-28 23:06:38 +00001297 LEAVE_PYTHON
1298
Guido van Rossum2834b972000-10-06 16:58:26 +00001299 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001300}
1301
1302static void
Fred Drake509d79a2000-07-08 04:04:38 +00001303PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001304{
Guido van Rossum00d93061998-05-28 23:06:38 +00001305 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1306
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001307 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001308 Py_XDECREF(data->self);
1309 Py_XDECREF(data->func);
1310 PyMem_DEL(data);
1311 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001312}
1313
Barry Warsawfa701a81997-01-16 00:15:11 +00001314
1315
Guido van Rossum18468821994-06-20 07:49:28 +00001316static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001317Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001318{
Guido van Rossum00d93061998-05-28 23:06:38 +00001319 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001321 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001322 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001323
Guido van Rossum43713e52000-02-29 13:59:29 +00001324 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001325 return NULL;
1326 if (!PyCallable_Check(func)) {
1327 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001328 return NULL;
1329 }
Guido van Rossum18468821994-06-20 07:49:28 +00001330
Guido van Rossum00d93061998-05-28 23:06:38 +00001331 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001332 if (!data)
1333 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001334 Py_XINCREF(self);
1335 Py_XINCREF(func);
1336 data->self = self;
1337 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001338
Guido van Rossum00d93061998-05-28 23:06:38 +00001339 ENTER_TCL
1340 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1341 (ClientData)data, PythonCmdDelete);
1342 LEAVE_TCL
1343 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001344 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001345 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001346 return NULL;
1347 }
Guido van Rossum18468821994-06-20 07:49:28 +00001348
Barry Warsawfa701a81997-01-16 00:15:11 +00001349 Py_INCREF(Py_None);
1350 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001351}
1352
Barry Warsawfa701a81997-01-16 00:15:11 +00001353
1354
Guido van Rossum18468821994-06-20 07:49:28 +00001355static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001356Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001357{
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001359 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001360
Guido van Rossum43713e52000-02-29 13:59:29 +00001361 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001363 ENTER_TCL
1364 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1365 LEAVE_TCL
1366 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001367 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1368 return NULL;
1369 }
1370 Py_INCREF(Py_None);
1371 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001372}
1373
Barry Warsawfa701a81997-01-16 00:15:11 +00001374
1375
Guido van Rossum00d93061998-05-28 23:06:38 +00001376#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001377/** File Handler **/
1378
Guido van Rossum00d93061998-05-28 23:06:38 +00001379typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001380 PyObject *func;
1381 PyObject *file;
1382 int id;
1383 struct _fhcdata *next;
1384} FileHandler_ClientData;
1385
1386static FileHandler_ClientData *HeadFHCD;
1387
1388static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001389NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001390{
1391 FileHandler_ClientData *p;
1392 p = PyMem_NEW(FileHandler_ClientData, 1);
1393 if (p != NULL) {
1394 Py_XINCREF(func);
1395 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 p->func = func;
1397 p->file = file;
1398 p->id = id;
1399 p->next = HeadFHCD;
1400 HeadFHCD = p;
1401 }
1402 return p;
1403}
1404
1405static void
Fred Drake509d79a2000-07-08 04:04:38 +00001406DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001407{
1408 FileHandler_ClientData *p, **pp;
1409
1410 pp = &HeadFHCD;
1411 while ((p = *pp) != NULL) {
1412 if (p->id == id) {
1413 *pp = p->next;
1414 Py_XDECREF(p->func);
1415 Py_XDECREF(p->file);
1416 PyMem_DEL(p);
1417 }
1418 else
1419 pp = &p->next;
1420 }
1421}
1422
Guido van Rossuma597dde1995-01-10 20:56:29 +00001423static void
Fred Drake509d79a2000-07-08 04:04:38 +00001424FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001425{
Guido van Rossum00d93061998-05-28 23:06:38 +00001426 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001428
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001429 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001430 func = data->func;
1431 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001432
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 arg = Py_BuildValue("(Oi)", file, (long) mask);
1434 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001435 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001436
1437 if (res == NULL) {
1438 errorInCmd = 1;
1439 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1440 }
1441 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001443}
1444
Guido van Rossum18468821994-06-20 07:49:28 +00001445static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001446Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1447 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001448{
Guido van Rossum00d93061998-05-28 23:06:38 +00001449 FileHandler_ClientData *data;
1450 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001451 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001452
Guido van Rossum2834b972000-10-06 16:58:26 +00001453 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1454 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001455 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001456 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001457 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 return NULL;
1459 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001460 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 return NULL;
1462 }
1463
Guido van Rossuma80649b2000-03-28 20:07:05 +00001464 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001465 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 return NULL;
1467
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001469 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001470 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001471 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001472 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001474}
1475
1476static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001477Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001478{
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001480 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001481
Guido van Rossum43713e52000-02-29 13:59:29 +00001482 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001484 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001485 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001486 return NULL;
1487
Guido van Rossuma80649b2000-03-28 20:07:05 +00001488 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001489
Barry Warsawfa701a81997-01-16 00:15:11 +00001490 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001491 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001492 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001493 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001494 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001495 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001496}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001497#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001498
Barry Warsawfa701a81997-01-16 00:15:11 +00001499
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001500/**** Tktt Object (timer token) ****/
1501
1502staticforward PyTypeObject Tktt_Type;
1503
Guido van Rossum00d93061998-05-28 23:06:38 +00001504typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001506 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001507 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001508} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001509
1510static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001511Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001512{
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001514 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001515
Guido van Rossum43713e52000-02-29 13:59:29 +00001516 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001518 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001519 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001520 v->token = NULL;
1521 }
1522 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001524 Py_DECREF(func);
1525 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 }
1527 Py_INCREF(Py_None);
1528 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001529}
1530
1531static PyMethodDef Tktt_methods[] =
1532{
Guido van Rossum35d43371997-08-02 00:09:09 +00001533 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001535};
1536
1537static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001538Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001539{
Barry Warsawfa701a81997-01-16 00:15:11 +00001540 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001541
Guido van Rossumb18618d2000-05-03 23:44:39 +00001542 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001543 if (v == NULL)
1544 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001545
Guido van Rossum00d93061998-05-28 23:06:38 +00001546 Py_INCREF(func);
1547 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001549
1550 /* Extra reference, deleted when called or when handler is deleted */
1551 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001553}
1554
1555static void
Fred Drake509d79a2000-07-08 04:04:38 +00001556Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001557{
Guido van Rossum00d93061998-05-28 23:06:38 +00001558 TkttObject *v = (TkttObject *)self;
1559 PyObject *func = v->func;
1560
1561 Py_XDECREF(func);
1562
Guido van Rossumb18618d2000-05-03 23:44:39 +00001563 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001564}
1565
Guido van Rossum597ac201998-05-12 14:36:19 +00001566static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001567Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001568{
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001570 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001571
Fred Drakea44d3532000-06-30 15:01:00 +00001572 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001573 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001574 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001575}
1576
1577static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001578Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001579{
Barry Warsawfa701a81997-01-16 00:15:11 +00001580 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001581}
1582
1583static PyTypeObject Tktt_Type =
1584{
Guido van Rossum35d43371997-08-02 00:09:09 +00001585 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 0, /*ob_size */
1587 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001588 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 0, /*tp_itemsize */
1590 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001591 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 Tktt_GetAttr, /*tp_getattr */
1593 0, /*tp_setattr */
1594 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001595 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001596 0, /*tp_as_number */
1597 0, /*tp_as_sequence */
1598 0, /*tp_as_mapping */
1599 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001600};
1601
Barry Warsawfa701a81997-01-16 00:15:11 +00001602
1603
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001604/** Timer Handler **/
1605
1606static void
Fred Drake509d79a2000-07-08 04:04:38 +00001607TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001608{
Guido van Rossum00d93061998-05-28 23:06:38 +00001609 TkttObject *v = (TkttObject *)clientData;
1610 PyObject *func = v->func;
1611 PyObject *res;
1612
1613 if (func == NULL)
1614 return;
1615
1616 v->func = NULL;
1617
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001618 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001619
1620 res = PyEval_CallObject(func, NULL);
1621 Py_DECREF(func);
1622 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001623
Barry Warsawfa701a81997-01-16 00:15:11 +00001624 if (res == NULL) {
1625 errorInCmd = 1;
1626 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1627 }
1628 else
1629 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001630
1631 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001632}
1633
1634static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001635Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001636{
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 int milliseconds;
1638 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001639 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640
Guido van Rossum2834b972000-10-06 16:58:26 +00001641 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1642 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 return NULL;
1644 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001645 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001646 return NULL;
1647 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001648 v = Tktt_New(func);
1649 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1650 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001651
Guido van Rossum00d93061998-05-28 23:06:38 +00001652 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001653}
1654
Barry Warsawfa701a81997-01-16 00:15:11 +00001655
Guido van Rossum18468821994-06-20 07:49:28 +00001656/** Event Loop **/
1657
Guido van Rossum18468821994-06-20 07:49:28 +00001658static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001659Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001660{
Barry Warsawfa701a81997-01-16 00:15:11 +00001661 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001662#ifdef WITH_THREAD
1663 PyThreadState *tstate = PyThreadState_Get();
1664#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001665
Guido van Rossum43713e52000-02-29 13:59:29 +00001666 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001668
Barry Warsawfa701a81997-01-16 00:15:11 +00001669 quitMainLoop = 0;
1670 while (Tk_GetNumMainWindows() > threshold &&
1671 !quitMainLoop &&
1672 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001673 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001674 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001675
1676#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001677 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001678 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001679 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001680 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001681 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001682 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001683 if (result == 0)
1684 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001685 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001686#else
1687 result = Tcl_DoOneEvent(0);
1688#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001689
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 if (PyErr_CheckSignals() != 0)
1691 return NULL;
1692 if (result < 0)
1693 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001694 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001696
Barry Warsawfa701a81997-01-16 00:15:11 +00001697 if (errorInCmd) {
1698 errorInCmd = 0;
1699 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1700 excInCmd = valInCmd = trbInCmd = NULL;
1701 return NULL;
1702 }
1703 Py_INCREF(Py_None);
1704 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001705}
1706
1707static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001708Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001709{
Guido van Rossum35d43371997-08-02 00:09:09 +00001710 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001712
Guido van Rossum43713e52000-02-29 13:59:29 +00001713 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001714 return NULL;
1715
Guido van Rossum00d93061998-05-28 23:06:38 +00001716 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001717 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001718 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001720}
1721
1722static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001723Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001724{
1725
Guido van Rossum43713e52000-02-29 13:59:29 +00001726 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001727 return NULL;
1728
1729 quitMainLoop = 1;
1730 Py_INCREF(Py_None);
1731 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001732}
1733
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001734static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001735Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001736{
1737
Guido van Rossum43713e52000-02-29 13:59:29 +00001738 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001739 return NULL;
1740
1741 return PyInt_FromLong((long)Tkapp_Interp(self));
1742}
1743
Barry Warsawfa701a81997-01-16 00:15:11 +00001744
1745
Guido van Rossum18468821994-06-20 07:49:28 +00001746/**** Tkapp Method List ****/
1747
1748static PyMethodDef Tkapp_methods[] =
1749{
Guido van Rossum35d43371997-08-02 00:09:09 +00001750 {"call", Tkapp_Call, 0},
1751 {"globalcall", Tkapp_GlobalCall, 0},
1752 {"eval", Tkapp_Eval, 1},
1753 {"globaleval", Tkapp_GlobalEval, 1},
1754 {"evalfile", Tkapp_EvalFile, 1},
1755 {"record", Tkapp_Record, 1},
1756 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1757 {"setvar", Tkapp_SetVar, 1},
1758 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1759 {"getvar", Tkapp_GetVar, 1},
1760 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1761 {"unsetvar", Tkapp_UnsetVar, 1},
1762 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1763 {"getint", Tkapp_GetInt, 1},
1764 {"getdouble", Tkapp_GetDouble, 1},
1765 {"getboolean", Tkapp_GetBoolean, 1},
1766 {"exprstring", Tkapp_ExprString, 1},
1767 {"exprlong", Tkapp_ExprLong, 1},
1768 {"exprdouble", Tkapp_ExprDouble, 1},
1769 {"exprboolean", Tkapp_ExprBoolean, 1},
1770 {"splitlist", Tkapp_SplitList, 1},
1771 {"split", Tkapp_Split, 1},
1772 {"merge", Tkapp_Merge, 0},
1773 {"createcommand", Tkapp_CreateCommand, 1},
1774 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001775#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001776 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1777 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001778#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001779 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001780 {"mainloop", Tkapp_MainLoop, 1},
1781 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001782 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001783 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001784 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001785};
1786
Barry Warsawfa701a81997-01-16 00:15:11 +00001787
1788
Guido van Rossum18468821994-06-20 07:49:28 +00001789/**** Tkapp Type Methods ****/
1790
1791static void
Fred Drake509d79a2000-07-08 04:04:38 +00001792Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001793{
Guido van Rossum00d93061998-05-28 23:06:38 +00001794 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001795 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001796 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001797 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001798 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001799}
1800
1801static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001802Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001803{
Guido van Rossum35d43371997-08-02 00:09:09 +00001804 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001805}
1806
1807static PyTypeObject Tkapp_Type =
1808{
Guido van Rossum35d43371997-08-02 00:09:09 +00001809 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001810 0, /*ob_size */
1811 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001812 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001813 0, /*tp_itemsize */
1814 Tkapp_Dealloc, /*tp_dealloc */
1815 0, /*tp_print */
1816 Tkapp_GetAttr, /*tp_getattr */
1817 0, /*tp_setattr */
1818 0, /*tp_compare */
1819 0, /*tp_repr */
1820 0, /*tp_as_number */
1821 0, /*tp_as_sequence */
1822 0, /*tp_as_mapping */
1823 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001824};
1825
Barry Warsawfa701a81997-01-16 00:15:11 +00001826
1827
Guido van Rossum18468821994-06-20 07:49:28 +00001828/**** Tkinter Module ****/
1829
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001830typedef struct {
1831 PyObject* tuple;
1832 int size; /* current size */
1833 int maxsize; /* allocated size */
1834} FlattenContext;
1835
1836static int
1837_bump(FlattenContext* context, int size)
1838{
Guido van Rossum2834b972000-10-06 16:58:26 +00001839 /* expand tuple to hold (at least) size new items.
1840 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001841
1842 int maxsize = context->maxsize * 2;
1843
1844 if (maxsize < context->size + size)
1845 maxsize = context->size + size;
1846
1847 context->maxsize = maxsize;
1848
1849 return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0;
1850}
1851
1852static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001853_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001854{
1855 /* add tuple or list to argument tuple (recursively) */
1856
1857 int i, size;
1858
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001859 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001860 PyErr_SetString(PyExc_ValueError,
1861 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001862 return 0;
1863 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001864 size = PyList_GET_SIZE(item);
1865 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001866 if (context->size + size > context->maxsize &&
1867 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001868 return 0;
1869 /* copy items to output tuple */
1870 for (i = 0; i < size; i++) {
1871 PyObject *o = PyList_GET_ITEM(item, i);
1872 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001873 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001874 return 0;
1875 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001876 if (context->size + 1 > context->maxsize &&
1877 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001878 return 0;
1879 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001880 PyTuple_SET_ITEM(context->tuple,
1881 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001882 }
1883 }
1884 } else if (PyTuple_Check(item)) {
1885 /* same, for tuples */
1886 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001887 if (context->size + size > context->maxsize &&
1888 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001889 return 0;
1890 for (i = 0; i < size; i++) {
1891 PyObject *o = PyTuple_GET_ITEM(item, i);
1892 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001893 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001894 return 0;
1895 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001896 if (context->size + 1 > context->maxsize &&
1897 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001898 return 0;
1899 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001900 PyTuple_SET_ITEM(context->tuple,
1901 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001902 }
1903 }
1904 } else {
1905 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1906 return 0;
1907 }
1908 return 1;
1909}
1910
1911static PyObject *
1912Tkinter_Flatten(PyObject* self, PyObject* args)
1913{
1914 FlattenContext context;
1915 PyObject* item;
1916
1917 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1918 return NULL;
1919
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001920 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001921 if (context.maxsize <= 0)
1922 return PyTuple_New(0);
1923
1924 context.tuple = PyTuple_New(context.maxsize);
1925 if (!context.tuple)
1926 return NULL;
1927
1928 context.size = 0;
1929
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001930 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001931 return NULL;
1932
1933 if (_PyTuple_Resize(&context.tuple, context.size, 0))
1934 return NULL;
1935
1936 return context.tuple;
1937}
1938
Guido van Rossum18468821994-06-20 07:49:28 +00001939static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001940Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001941{
Barry Warsawfa701a81997-01-16 00:15:11 +00001942 char *screenName = NULL;
1943 char *baseName = NULL;
1944 char *className = NULL;
1945 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001946
Guido van Rossum35d43371997-08-02 00:09:09 +00001947 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 if (baseName != NULL)
1949 baseName++;
1950 else
1951 baseName = Py_GetProgramName();
1952 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001953
Guido van Rossum43713e52000-02-29 13:59:29 +00001954 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001955 &screenName, &baseName, &className,
1956 &interactive))
1957 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001958
Barry Warsawfa701a81997-01-16 00:15:11 +00001959 return (PyObject *) Tkapp_New(screenName, baseName, className,
1960 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001961}
1962
1963static PyMethodDef moduleMethods[] =
1964{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001965 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001966 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001967#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001968 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1969 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001970#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001971 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001972 {"mainloop", Tkapp_MainLoop, 1},
1973 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001974 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001975 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001976};
1977
Guido van Rossum7bf15641998-05-22 18:28:17 +00001978#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001979
1980static int stdin_ready = 0;
1981
Guido van Rossumad4db171998-06-13 13:56:28 +00001982#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001983static void
Fred Drake509d79a2000-07-08 04:04:38 +00001984MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001985{
1986 stdin_ready = 1;
1987}
Guido van Rossumad4db171998-06-13 13:56:28 +00001988#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001989
Guido van Rossum00d93061998-05-28 23:06:38 +00001990static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001991
Guido van Rossum18468821994-06-20 07:49:28 +00001992static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001993EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00001994{
Guido van Rossumad4db171998-06-13 13:56:28 +00001995#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001996 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001997#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001998#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001999 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002000#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002001 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002002 errorInCmd = 0;
2003#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002004 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002005 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002006#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002007 while (!errorInCmd && !stdin_ready) {
2008 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002009#ifdef MS_WINDOWS
2010 if (_kbhit()) {
2011 stdin_ready = 1;
2012 break;
2013 }
2014#endif
2015#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002016 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002017 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002018 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002019
Guido van Rossum00d93061998-05-28 23:06:38 +00002020 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002021
2022 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002023 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002024 if (result == 0)
2025 Sleep(20);
2026 Py_END_ALLOW_THREADS
2027#else
2028 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002029#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002030
2031 if (result < 0)
2032 break;
2033 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002034#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002035 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002036#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002037 if (errorInCmd) {
2038 errorInCmd = 0;
2039 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2040 excInCmd = valInCmd = trbInCmd = NULL;
2041 PyErr_Print();
2042 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002043#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002044 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002045#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002046 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002047}
Guido van Rossum18468821994-06-20 07:49:28 +00002048
Guido van Rossum00d93061998-05-28 23:06:38 +00002049#endif
2050
Guido van Rossum7bf15641998-05-22 18:28:17 +00002051static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002052EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002053{
Guido van Rossum00d93061998-05-28 23:06:38 +00002054#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002055 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002056#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002057 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002058#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002059 PyOS_InputHook = EventHook;
2060 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002061#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002062}
2063
2064static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002065DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002066{
Guido van Rossum00d93061998-05-28 23:06:38 +00002067#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002068 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2069 PyOS_InputHook = NULL;
2070 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002071#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002072}
2073
Barry Warsawfa701a81997-01-16 00:15:11 +00002074
2075/* all errors will be checked in one fell swoop in init_tkinter() */
2076static void
Fred Drake509d79a2000-07-08 04:04:38 +00002077ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002078{
2079 PyObject *v = PyInt_FromLong(val);
2080 if (v) {
2081 PyDict_SetItemString(d, name, v);
2082 Py_DECREF(v);
2083 }
2084}
2085static void
Fred Drake509d79a2000-07-08 04:04:38 +00002086ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002087{
2088 PyObject *v = PyString_FromString(val);
2089 if (v) {
2090 PyDict_SetItemString(d, name, v);
2091 Py_DECREF(v);
2092 }
2093}
2094
2095
Guido van Rossum3886bb61998-12-04 18:50:17 +00002096DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002097init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002098{
Barry Warsawfa701a81997-01-16 00:15:11 +00002099 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002100
Barry Warsawfa701a81997-01-16 00:15:11 +00002101 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002102
2103#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002104 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002105#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002106
Barry Warsawfa701a81997-01-16 00:15:11 +00002107 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002108
Barry Warsawfa701a81997-01-16 00:15:11 +00002109 d = PyModule_GetDict(m);
2110 Tkinter_TclError = Py_BuildValue("s", "TclError");
2111 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002112
Guido van Rossum35d43371997-08-02 00:09:09 +00002113 ins_long(d, "READABLE", TCL_READABLE);
2114 ins_long(d, "WRITABLE", TCL_WRITABLE);
2115 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2116 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2117 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2118 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2119 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2120 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2121 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002122 ins_string(d, "TK_VERSION", TK_VERSION);
2123 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002124
Guido van Rossum83551bf1997-09-13 00:44:23 +00002125 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002126
2127 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002128 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2129
Guido van Rossume187b0e2000-03-27 21:46:29 +00002130 /* This helps the dynamic loader; in Unicode aware Tcl versions
2131 it also helps Tcl find its encodings. */
2132 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002133
Barry Warsawfa701a81997-01-16 00:15:11 +00002134 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002135 return;
2136
Guido van Rossum43ff8681998-07-14 18:02:13 +00002137#if 0
2138 /* This was not a good idea; through <Destroy> bindings,
2139 Tcl_Finalize() may invoke Python code but at that point the
2140 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002141 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002142#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002143
Jack Jansen34cc5c31995-10-31 16:15:12 +00002144#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002145 /*
2146 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2147 ** Most of the initializations in that routine (toolbox init calls and
2148 ** such) have already been done for us, so we only need these.
2149 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002150 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002151
2152 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002153#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002154 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002155#endif /* GENERATINGCFM */
2156#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002157}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002158
Guido van Rossumec22c921996-02-25 04:50:29 +00002159
Barry Warsawfa701a81997-01-16 00:15:11 +00002160
Guido van Rossum9722ad81995-09-22 23:49:28 +00002161#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002162
2163/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002164** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002165*/
2166
Guido van Rossum9722ad81995-09-22 23:49:28 +00002167void
2168panic(char * format, ...)
2169{
Barry Warsawfa701a81997-01-16 00:15:11 +00002170 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002171
Barry Warsawfa701a81997-01-16 00:15:11 +00002172 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002173
Guido van Rossum227cf761998-08-05 13:53:32 +00002174 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002175 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002176
Barry Warsawfa701a81997-01-16 00:15:11 +00002177 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002178
Barry Warsawfa701a81997-01-16 00:15:11 +00002179 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002180}
Jack Jansen40b546d1995-11-14 10:34:45 +00002181
Guido van Rossumec22c921996-02-25 04:50:29 +00002182/*
2183** Pass events to SIOUX before passing them to Tk.
2184*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002185
Guido van Rossumec22c921996-02-25 04:50:29 +00002186static int
Fred Drake509d79a2000-07-08 04:04:38 +00002187PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002188{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002189 WindowPtr frontwin;
2190 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002191 ** Sioux eats too many events, so we don't pass it everything. We
2192 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002193 ** the Sioux window is frontmost. This means that Tk menus don't work
2194 ** in that case, but at least we can scroll the sioux window.
2195 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2196 ** part of the external interface of Sioux...
2197 */
2198 frontwin = FrontWindow();
2199 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2200 if (SIOUXHandleOneEvent(eventPtr))
2201 return 0; /* Nothing happened to the Tcl event queue */
2202 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002203 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002204}
2205
Guido van Rossumec22c921996-02-25 04:50:29 +00002206#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002207
2208/*
2209** Additional Mac specific code for dealing with shared libraries.
2210*/
2211
2212#include <Resources.h>
2213#include <CodeFragments.h>
2214
2215static int loaded_from_shlib = 0;
2216static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002217
Jack Jansen34cc5c31995-10-31 16:15:12 +00002218/*
2219** If this module is dynamically loaded the following routine should
2220** be the init routine. It takes care of adding the shared library to
2221** the resource-file chain, so that the tk routines can find their
2222** resources.
2223*/
2224OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002225init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002226{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002227 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002228 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002229 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002230 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2231 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002232 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002233 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2234 loaded_from_shlib = 1;
2235 }
2236 return noErr;
2237}
2238
2239/*
2240** Insert the library resources into the search path. Put them after
2241** the resources from the application. Again, we ignore errors.
2242*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002243static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002244mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002245{
2246 if ( !loaded_from_shlib )
2247 return;
2248 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2249}
2250
Guido van Rossumec22c921996-02-25 04:50:29 +00002251#endif /* GENERATINGCFM */
2252#endif /* macintosh */