blob: 92226633abbc1e08fddb9a46d79abd6602501dc7 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
Guido van Rossuma80649b2000-03-28 20:07:05 +000037 Only Tcl/Tk 8.0 and later are supported. Older versions are not
38 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
39 libraries.)
40*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
Guido van Rossuma80649b2000-03-28 20:07:05 +000042/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000043
44 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
45 intelligent mappings between Python objects and Tcl objects (e.g. ints,
46 floats and Tcl window pointers could be handled specially).
47
48 - Register a new Tcl type, "Python callable", which can be called more
49 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
50
Guido van Rossum7ffa7611996-08-13 21:10:16 +000051*/
52
Guido van Rossum35d43371997-08-02 00:09:09 +000053
Guido van Rossum9722ad81995-09-22 23:49:28 +000054#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000055#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000056
Guido van Rossum00d93061998-05-28 23:06:38 +000057#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000058#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000059#endif
60
Guido van Rossum2a5119b1998-05-29 01:28:40 +000061#ifdef MS_WINDOWS
62#include <windows.h>
63#endif
64
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000065#ifdef macintosh
66#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000067#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000068#endif
69
Guido van Rossum49b56061998-10-01 20:42:43 +000070#ifdef PYOS_OS2
71#include "myselect.h"
72#endif
73
Guido van Rossum18468821994-06-20 07:49:28 +000074#include <tcl.h>
75#include <tk.h>
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Guido van Rossuma80649b2000-03-28 20:07:05 +000079#if TKMAJORMINOR < 8000
80#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Guido van Rossuma80649b2000-03-28 20:07:05 +000083#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084/* Sigh, we have to include this to get at the tcl qd pointer */
85#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000086/* And this one we need to clear the menu bar */
87#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000088#endif
89
Guido van Rossuma80649b2000-03-28 20:07:05 +000090#if !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000091#define HAVE_CREATEFILEHANDLER
92#endif
93
Guido van Rossum00d93061998-05-28 23:06:38 +000094#ifdef HAVE_CREATEFILEHANDLER
95
96/* Tcl_CreateFileHandler() changed several times; these macros deal with the
97 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
98 Unix, only because Jack added it back); when available on Windows, it only
99 applies to sockets. */
100
Guido van Rossum7bf15641998-05-22 18:28:17 +0000101#ifdef MS_WINDOWS
102#define FHANDLETYPE TCL_WIN_SOCKET
103#else
104#define FHANDLETYPE TCL_UNIX_FD
105#endif
106
Guido van Rossum00d93061998-05-28 23:06:38 +0000107/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
108 which uses this to handle Tcl events while the user is typing commands. */
109
110#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000111#define WAIT_FOR_STDIN
112#endif
113
Guido van Rossum00d93061998-05-28 23:06:38 +0000114#endif /* HAVE_CREATEFILEHANDLER */
115
Guido van Rossumad4db171998-06-13 13:56:28 +0000116#ifdef MS_WINDOWS
117#include <conio.h>
118#define WAIT_FOR_STDIN
119#endif
120
Guido van Rossum00d93061998-05-28 23:06:38 +0000121#ifdef WITH_THREAD
122
123/* The threading situation is complicated. Tcl is not thread-safe, except for
124 Tcl 8.1, which will probably remain in alpha status for another 6 months
125 (and the README says that Tk will probably remain thread-unsafe forever).
126 So we need to use a lock around all uses of Tcl. Previously, the Python
127 interpreter lock was used for this. However, this causes problems when
128 other Python threads need to run while Tcl is blocked waiting for events.
129
130 To solve this problem, a separate lock for Tcl is introduced. Holding it
131 is incompatible with holding Python's interpreter lock. The following four
132 macros manipulate both locks together.
133
134 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
135 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
136 that could call an event handler, or otherwise affect the state of a Tcl
137 interpreter. These assume that the surrounding code has the Python
138 interpreter lock; inside the brackets, the Python interpreter lock has been
139 released and the lock for Tcl has been acquired.
140
Guido van Rossum5e977831998-06-15 14:03:52 +0000141 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
142 (For example, when transferring data from the Tcl interpreter result to a
143 Python string object.) This can be done by using different macros to close
144 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
145 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
146 releases the Tcl lock.
147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000149 handlers when the handler needs to use Python. Such event handlers are
150 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000152 the Python interpreter lock, restoring the appropriate thread state, and
153 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
154 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000155 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157 These locks expand to several statements and brackets; they should not be
158 used in branches of if statements and the like.
159
160*/
161
Guido van Rossum65d5b571998-12-21 19:32:43 +0000162static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000164
165#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000166 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000170 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000171
Guido van Rossum62320c91998-06-15 04:36:09 +0000172#define ENTER_OVERLAP \
173 Py_END_ALLOW_THREADS
174
175#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000176 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000177
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178#define ENTER_PYTHON \
179 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000181
182#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000184 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000185
186#else
187
188#define ENTER_TCL
189#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000190#define ENTER_OVERLAP
191#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000192#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000193#define LEAVE_PYTHON
194
195#endif
196
Guido van Rossumec22c921996-02-25 04:50:29 +0000197#ifdef macintosh
198
199/*
200** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000201** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000202*/
203
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000204/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000205#define FREECAST (char *)
206
Guido van Rossumec22c921996-02-25 04:50:29 +0000207#include <Events.h> /* For EventRecord */
208
209typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000210void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000211int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
212
213staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
214
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000215#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
216 #pragma import on
217#endif
218
219#include <SIOUX.h>
220extern int SIOUXIsAppWindow(WindowPtr);
221
222#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
223 #pragma import reset
224#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000225#endif /* macintosh */
226
Guido van Rossum97867b21996-08-08 19:09:53 +0000227#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000228#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000229#endif
230
Guido van Rossum18468821994-06-20 07:49:28 +0000231/**** Tkapp Object Declaration ****/
232
233staticforward PyTypeObject Tkapp_Type;
234
Guido van Rossum00d93061998-05-28 23:06:38 +0000235typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000236 PyObject_HEAD
237 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000238} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000239
240#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000241#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
242#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
243
Guido van Rossum35d43371997-08-02 00:09:09 +0000244#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000245(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Barry Warsawfa701a81997-01-16 00:15:11 +0000247
248
Guido van Rossum18468821994-06-20 07:49:28 +0000249/**** Error Handling ****/
250
251static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000252static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000253static int errorInCmd = 0;
254static PyObject *excInCmd;
255static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000257
Barry Warsawfa701a81997-01-16 00:15:11 +0000258
259
Guido van Rossum18468821994-06-20 07:49:28 +0000260static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000261Tkinter_Error(v)
262 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000263{
Barry Warsawfa701a81997-01-16 00:15:11 +0000264 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
265 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000266}
267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268
Barry Warsawfa701a81997-01-16 00:15:11 +0000269
Guido van Rossum18468821994-06-20 07:49:28 +0000270/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000271
272#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000273#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000274#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000275#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000276
Guido van Rossum00d93061998-05-28 23:06:38 +0000277/* Millisecond sleep() for Unix platforms. */
278
279static void
280Sleep(milli)
281 int milli;
282{
283 /* XXX Too bad if you don't have select(). */
284 struct timeval t;
285 double frac;
286 t.tv_sec = milli/1000;
287 t.tv_usec = (milli%1000) * 1000;
288 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
289}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000290#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000291#endif /* WITH_THREAD */
292
293
Guido van Rossum18468821994-06-20 07:49:28 +0000294static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000295AsString(value, tmp)
296 PyObject *value;
297 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000298{
Guido van Rossum35d43371997-08-02 00:09:09 +0000299 if (PyString_Check(value))
300 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 else {
302 PyObject *v = PyObject_Str(value);
303 PyList_Append(tmp, v);
304 Py_DECREF(v);
305 return PyString_AsString(v);
306 }
Guido van Rossum18468821994-06-20 07:49:28 +0000307}
308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309
310
Guido van Rossum18468821994-06-20 07:49:28 +0000311#define ARGSZ 64
312
313static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000314Merge(args)
315 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000316{
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 PyObject *tmp = NULL;
318 char *argvStore[ARGSZ];
319 char **argv = NULL;
320 int fvStore[ARGSZ];
321 int *fv = NULL;
322 int argc = 0, i;
323 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (!(tmp = PyList_New(0)))
326 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000327
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 argv = argvStore;
329 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (args == NULL)
332 argc = 0;
333
334 else if (!PyTuple_Check(args)) {
335 argc = 1;
336 fv[0] = 0;
337 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000338 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 else {
340 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000341
Barry Warsawfa701a81997-01-16 00:15:11 +0000342 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000343 argv = (char **)ckalloc(argc * sizeof(char *));
344 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000345 if (argv == NULL || fv == NULL) {
346 PyErr_NoMemory();
347 goto finally;
348 }
349 }
350
351 for (i = 0; i < argc; i++) {
352 PyObject *v = PyTuple_GetItem(args, i);
353 if (PyTuple_Check(v)) {
354 fv[i] = 1;
355 if (!(argv[i] = Merge(v)))
356 goto finally;
357 }
358 else if (v == Py_None) {
359 argc = i;
360 break;
361 }
362 else {
363 fv[i] = 0;
364 argv[i] = AsString(v, tmp);
365 }
366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 finally:
371 for (i = 0; i < argc; i++)
372 if (fv[i]) {
373 ckfree(argv[i]);
374 }
375 if (argv != argvStore)
376 ckfree(FREECAST argv);
377 if (fv != fvStore)
378 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 Py_DECREF(tmp);
381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000382}
383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384
385
Guido van Rossum18468821994-06-20 07:49:28 +0000386static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000387Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000389{
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 int argc;
391 char **argv;
392 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 if (list == NULL) {
395 Py_INCREF(Py_None);
396 return Py_None;
397 }
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 /* Not a list.
401 * Could be a quoted string containing funnies, e.g. {"}.
402 * Return the string itself.
403 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 return PyString_FromString(list);
405 }
Guido van Rossum18468821994-06-20 07:49:28 +0000406
Barry Warsawfa701a81997-01-16 00:15:11 +0000407 if (argc == 0)
408 v = PyString_FromString("");
409 else if (argc == 1)
410 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000411 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 int i;
413 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000416 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 Py_DECREF(v);
418 v = NULL;
419 break;
420 }
421 PyTuple_SetItem(v, i, w);
422 }
423 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000424 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427
Barry Warsawfa701a81997-01-16 00:15:11 +0000428
429
Guido van Rossum18468821994-06-20 07:49:28 +0000430/**** Tkapp Object ****/
431
432#ifndef WITH_APPINIT
433int
Guido van Rossum35d43371997-08-02 00:09:09 +0000434Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000436{
Barry Warsawfa701a81997-01-16 00:15:11 +0000437 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000438
Barry Warsawfa701a81997-01-16 00:15:11 +0000439 main = Tk_MainWindow(interp);
440 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000441 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000442 return TCL_ERROR;
443 }
444 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000445 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000446 return TCL_ERROR;
447 }
448 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000449}
450#endif /* !WITH_APPINIT */
451
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453
454
455/* Initialize the Tk application; see the `main' function in
456 * `tkMain.c'.
457 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000458
459static void EnableEventHook(); /* Forward */
460static void DisableEventHook(); /* Forward */
461
Barry Warsawfa701a81997-01-16 00:15:11 +0000462static TkappObject *
463Tkapp_New(screenName, baseName, className, interactive)
464 char *screenName;
465 char *baseName;
466 char *className;
467 int interactive;
468{
469 TkappObject *v;
470 char *argv0;
471
472 v = PyObject_NEW(TkappObject, &Tkapp_Type);
473 if (v == NULL)
474 return NULL;
475
476 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000477
Guido van Rossuma80649b2000-03-28 20:07:05 +0000478#if defined(macintosh)
479 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000480 ClearMenuBar();
481 TkMacInitMenus(v->interp);
482#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000483 /* Delete the 'exit' command, which can screw things up */
484 Tcl_DeleteCommand(v->interp, "exit");
485
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 if (screenName != NULL)
487 Tcl_SetVar2(v->interp, "env", "DISPLAY",
488 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 if (interactive)
491 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
492 else
493 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000494
Barry Warsawfa701a81997-01-16 00:15:11 +0000495 /* This is used to get the application class for Tk 4.1 and up */
496 argv0 = (char*)ckalloc(strlen(className) + 1);
497 if (!argv0) {
498 PyErr_NoMemory();
499 Py_DECREF(v);
500 return NULL;
501 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000504 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 argv0[0] = tolower(argv0[0]);
506 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
507 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000510 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000511
Guido van Rossum7bf15641998-05-22 18:28:17 +0000512 EnableEventHook();
513
Barry Warsawfa701a81997-01-16 00:15:11 +0000514 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000515}
516
Barry Warsawfa701a81997-01-16 00:15:11 +0000517
518
Guido van Rossum18468821994-06-20 07:49:28 +0000519/** Tcl Eval **/
520
521static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000522Tkapp_Call(self, args)
523 PyObject *self;
524 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000525{
Guido van Rossum212643f1998-04-29 16:22:14 +0000526 /* This is copied from Merge() */
527 PyObject *tmp = NULL;
528 char *argvStore[ARGSZ];
529 char **argv = NULL;
530 int fvStore[ARGSZ];
531 int *fv = NULL;
532 int argc = 0, i;
533 PyObject *res = NULL; /* except this has a different type */
534 Tcl_CmdInfo info; /* and this is added */
535 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000536
Guido van Rossum212643f1998-04-29 16:22:14 +0000537 if (!(tmp = PyList_New(0)))
538 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000539
Guido van Rossum212643f1998-04-29 16:22:14 +0000540 argv = argvStore;
541 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000542
Guido van Rossum212643f1998-04-29 16:22:14 +0000543 if (args == NULL)
544 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000545
Guido van Rossum212643f1998-04-29 16:22:14 +0000546 else if (!PyTuple_Check(args)) {
547 argc = 1;
548 fv[0] = 0;
549 argv[0] = AsString(args, tmp);
550 }
551 else {
552 argc = PyTuple_Size(args);
553
554 if (argc > ARGSZ) {
555 argv = (char **)ckalloc(argc * sizeof(char *));
556 fv = (int *)ckalloc(argc * sizeof(int));
557 if (argv == NULL || fv == NULL) {
558 PyErr_NoMemory();
559 goto finally;
560 }
561 }
562
563 for (i = 0; i < argc; i++) {
564 PyObject *v = PyTuple_GetItem(args, i);
565 if (PyTuple_Check(v)) {
566 fv[i] = 1;
567 if (!(argv[i] = Merge(v)))
568 goto finally;
569 }
570 else if (v == Py_None) {
571 argc = i;
572 break;
573 }
574 else {
575 fv[i] = 0;
576 argv[i] = AsString(v, tmp);
577 }
578 }
579 }
580 /* End code copied from Merge() */
581
582 /* All this to avoid a call to Tcl_Merge() and the corresponding call
583 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
584 if (Py_VerboseFlag >= 2) {
585 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000586 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000587 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000588 ENTER_TCL
589 info.proc = NULL;
Guido van Rossum212643f1998-04-29 16:22:14 +0000590 if (argc < 1 ||
591 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
592 info.proc == NULL)
593 {
594 char *cmd;
Guido van Rossum212643f1998-04-29 16:22:14 +0000595 cmd = Tcl_Merge(argc, argv);
596 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000597 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000598 }
599 else {
600 Tcl_ResetResult(interp);
601 i = (*info.proc)(info.clientData, interp, argc, argv);
602 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000603 ENTER_OVERLAP
604 if (info.proc == NULL && Py_VerboseFlag >= 2)
605 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000606 if (i == TCL_ERROR) {
607 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000608 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000609 interp->result);
610 Tkinter_Error(self);
611 }
612 else {
613 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000614 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000615 res = PyString_FromString(interp->result);
616 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000617 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000618
Guido van Rossum212643f1998-04-29 16:22:14 +0000619 /* Copied from Merge() again */
620 finally:
621 for (i = 0; i < argc; i++)
622 if (fv[i]) {
623 ckfree(argv[i]);
624 }
625 if (argv != argvStore)
626 ckfree(FREECAST argv);
627 if (fv != fvStore)
628 ckfree(FREECAST fv);
629
630 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 return res;
632}
633
634
635static PyObject *
636Tkapp_GlobalCall(self, args)
637 PyObject *self;
638 PyObject *args;
639{
Guido van Rossum212643f1998-04-29 16:22:14 +0000640 /* Could do the same here as for Tkapp_Call(), but this is not used
641 much, so I can't be bothered. Unfortunately Tcl doesn't export a
642 way for the user to do what all its Global* variants do (save and
643 reset the scope pointer, call the local version, restore the saved
644 scope pointer). */
645
Guido van Rossum62320c91998-06-15 04:36:09 +0000646 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000647 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000648
Guido van Rossum62320c91998-06-15 04:36:09 +0000649 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 if (!cmd)
651 PyErr_SetString(Tkinter_TclError, "merge failed");
652
Guido van Rossum00d93061998-05-28 23:06:38 +0000653 else {
654 int err;
655 ENTER_TCL
656 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000657 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000658 if (err == TCL_ERROR)
659 res = Tkinter_Error(self);
660 else
661 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000662 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000663 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000664
665 if (cmd)
666 ckfree(cmd);
667
668 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000669}
670
671static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000672Tkapp_Eval(self, args)
673 PyObject *self;
674 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000675{
Barry Warsawfa701a81997-01-16 00:15:11 +0000676 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000677 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000678 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000679
Guido van Rossum43713e52000-02-29 13:59:29 +0000680 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000681 return NULL;
682
Guido van Rossum00d93061998-05-28 23:06:38 +0000683 ENTER_TCL
684 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000685 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000686 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000687 res = Tkinter_Error(self);
688 else
689 res = PyString_FromString(Tkapp_Result(self));
690 LEAVE_OVERLAP_TCL
691 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000692}
693
694static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000695Tkapp_GlobalEval(self, args)
696 PyObject *self;
697 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000698{
Barry Warsawfa701a81997-01-16 00:15:11 +0000699 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000700 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000701 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000702
Guido van Rossum43713e52000-02-29 13:59:29 +0000703 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000704 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000705
Guido van Rossum00d93061998-05-28 23:06:38 +0000706 ENTER_TCL
707 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000708 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000709 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000710 res = Tkinter_Error(self);
711 else
712 res = PyString_FromString(Tkapp_Result(self));
713 LEAVE_OVERLAP_TCL
714 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000715}
716
717static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000718Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 PyObject *self;
720 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000721{
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000723 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000724 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000725
Guido van Rossum43713e52000-02-29 13:59:29 +0000726 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000727 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000728
Guido van Rossum00d93061998-05-28 23:06:38 +0000729 ENTER_TCL
730 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000731 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000732 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000733 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000734
Guido van Rossum62320c91998-06-15 04:36:09 +0000735 else
736 res = PyString_FromString(Tkapp_Result(self));
737 LEAVE_OVERLAP_TCL
738 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000739}
740
741static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000742Tkapp_Record(self, args)
743 PyObject *self;
744 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000745{
Barry Warsawfa701a81997-01-16 00:15:11 +0000746 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000747 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000748 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000749
Guido van Rossum35d43371997-08-02 00:09:09 +0000750 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000751 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000752
Guido van Rossum00d93061998-05-28 23:06:38 +0000753 ENTER_TCL
754 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000755 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000756 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000757 res = Tkinter_Error(self);
758 else
759 res = PyString_FromString(Tkapp_Result(self));
760 LEAVE_OVERLAP_TCL
761 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000762}
763
764static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000765Tkapp_AddErrorInfo(self, args)
766 PyObject *self;
767 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000768{
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000770
Guido van Rossum43713e52000-02-29 13:59:29 +0000771 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000772 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000773 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000774 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000775 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000776
Barry Warsawfa701a81997-01-16 00:15:11 +0000777 Py_INCREF(Py_None);
778 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000779}
780
Barry Warsawfa701a81997-01-16 00:15:11 +0000781
782
Guido van Rossum18468821994-06-20 07:49:28 +0000783/** Tcl Variable **/
784
785static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000786SetVar(self, args, flags)
787 PyObject *self;
788 PyObject *args;
789 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000790{
Guido van Rossum00d93061998-05-28 23:06:38 +0000791 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000793 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000794
Guido van Rossum62320c91998-06-15 04:36:09 +0000795 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000796 if (!tmp)
797 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000798
Guido van Rossum43713e52000-02-29 13:59:29 +0000799 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000800 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000801 s = AsString(newValue, tmp);
802 ENTER_TCL
803 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
804 LEAVE_TCL
805 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000807 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000808 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000809 s = AsString (newValue, tmp);
810 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000811 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000812 s, flags);
813 LEAVE_TCL
814 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000815 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000816 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000817 return NULL;
818 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000819 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000820 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000821
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 if (!ok)
823 return Tkinter_Error(self);
824
825 Py_INCREF(Py_None);
826 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000827}
828
829static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000830Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 PyObject *self;
832 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000833{
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000835}
836
837static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000838Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 PyObject *self;
840 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000841{
Barry Warsawfa701a81997-01-16 00:15:11 +0000842 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000843}
844
Barry Warsawfa701a81997-01-16 00:15:11 +0000845
846
Guido van Rossum18468821994-06-20 07:49:28 +0000847static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000848GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 PyObject *self;
850 PyObject *args;
851 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000852{
Guido van Rossum35d43371997-08-02 00:09:09 +0000853 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000854 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000855
Guido van Rossum43713e52000-02-29 13:59:29 +0000856 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000857 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000858 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000859 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000860 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000861
Barry Warsawfa701a81997-01-16 00:15:11 +0000862 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000863 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000864 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000865
Barry Warsawfa701a81997-01-16 00:15:11 +0000866 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000867 res = Tkinter_Error(self);
868 else
869 res = PyString_FromString(s);
870 LEAVE_OVERLAP_TCL
871 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000872}
873
874static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000875Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 PyObject *self;
877 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000878{
Barry Warsawfa701a81997-01-16 00:15:11 +0000879 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000880}
881
882static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000883Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000884 PyObject *self;
885 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000886{
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000888}
889
Barry Warsawfa701a81997-01-16 00:15:11 +0000890
891
Guido van Rossum18468821994-06-20 07:49:28 +0000892static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000893UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 PyObject *self;
895 PyObject *args;
896 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000897{
Guido van Rossum35d43371997-08-02 00:09:09 +0000898 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000899 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000900 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000901
Guido van Rossum43713e52000-02-29 13:59:29 +0000902 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000904 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000905 if (name2 == NULL)
906 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
907
908 else
909 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000910 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000911
Barry Warsawfa701a81997-01-16 00:15:11 +0000912 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000913 res = Tkinter_Error(self);
914 else {
915 Py_INCREF(Py_None);
916 res = Py_None;
917 }
918 LEAVE_OVERLAP_TCL
919 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000920}
921
922static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000923Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000924 PyObject *self;
925 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000926{
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000928}
929
930static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000931Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000932 PyObject *self;
933 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000934{
Barry Warsawfa701a81997-01-16 00:15:11 +0000935 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000936}
937
Barry Warsawfa701a81997-01-16 00:15:11 +0000938
939
Guido van Rossum18468821994-06-20 07:49:28 +0000940/** Tcl to Python **/
941
942static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000943Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 PyObject *self;
945 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000946{
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 char *s;
948 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000949
Guido van Rossum43713e52000-02-29 13:59:29 +0000950 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000952 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000953 return Tkinter_Error(self);
954 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000955}
956
957static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000958Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000959 PyObject *self;
960 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000961{
Barry Warsawfa701a81997-01-16 00:15:11 +0000962 char *s;
963 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000964
Guido van Rossum43713e52000-02-29 13:59:29 +0000965 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000966 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000967 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 return Tkinter_Error(self);
969 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000970}
971
972static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000973Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000974 PyObject *self;
975 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000976{
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 char *s;
978 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Guido van Rossum43713e52000-02-29 13:59:29 +0000980 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000981 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000982 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
983 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000985}
986
987static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000988Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000989 PyObject *self;
990 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000991{
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000993 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000994 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000995
Guido van Rossum43713e52000-02-29 13:59:29 +0000996 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000998 ENTER_TCL
999 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001000 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001001 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001002 res = Tkinter_Error(self);
1003 else
1004 res = Py_BuildValue("s", Tkapp_Result(self));
1005 LEAVE_OVERLAP_TCL
1006 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001007}
1008
1009static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001010Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 PyObject *self;
1012 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001013{
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001015 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001016 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001018
Guido van Rossum43713e52000-02-29 13:59:29 +00001019 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001020 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001021 ENTER_TCL
1022 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001023 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001024 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001025 res = Tkinter_Error(self);
1026 else
1027 res = Py_BuildValue("l", v);
1028 LEAVE_OVERLAP_TCL
1029 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001030}
1031
1032static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001033Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 PyObject *self;
1035 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001036{
Barry Warsawfa701a81997-01-16 00:15:11 +00001037 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001038 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001039 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001040 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001041
Guido van Rossum43713e52000-02-29 13:59:29 +00001042 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001044 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001045 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001046 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001047 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001048 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001049 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001050 res = Tkinter_Error(self);
1051 else
1052 res = Py_BuildValue("d", v);
1053 LEAVE_OVERLAP_TCL
1054 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001055}
1056
1057static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001058Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 PyObject *self;
1060 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001061{
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001063 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001064 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001066
Guido van Rossum43713e52000-02-29 13:59:29 +00001067 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001069 ENTER_TCL
1070 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001071 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001072 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001073 res = Tkinter_Error(self);
1074 else
1075 res = Py_BuildValue("i", v);
1076 LEAVE_OVERLAP_TCL
1077 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001078}
1079
Barry Warsawfa701a81997-01-16 00:15:11 +00001080
1081
Guido van Rossum18468821994-06-20 07:49:28 +00001082static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001083Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 PyObject *self;
1085 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001086{
Barry Warsawfa701a81997-01-16 00:15:11 +00001087 char *list;
1088 int argc;
1089 char **argv;
1090 PyObject *v;
1091 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001092
Guido van Rossum43713e52000-02-29 13:59:29 +00001093 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001094 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001095
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1097 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001098
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 if (!(v = PyTuple_New(argc)))
1100 return NULL;
1101
1102 for (i = 0; i < argc; i++) {
1103 PyObject *s = PyString_FromString(argv[i]);
1104 if (!s || PyTuple_SetItem(v, i, s)) {
1105 Py_DECREF(v);
1106 v = NULL;
1107 goto finally;
1108 }
1109 }
Guido van Rossum18468821994-06-20 07:49:28 +00001110
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 finally:
1112 ckfree(FREECAST argv);
1113 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001114}
1115
1116static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001117Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001118 PyObject *self;
1119 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001120{
Barry Warsawfa701a81997-01-16 00:15:11 +00001121 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001122
Guido van Rossum43713e52000-02-29 13:59:29 +00001123 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001124 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001125 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001126}
1127
1128static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001129Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001130 PyObject *self;
1131 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001132{
Barry Warsawfa701a81997-01-16 00:15:11 +00001133 char *s = Merge(args);
1134 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001135
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 if (s) {
1137 res = PyString_FromString(s);
1138 ckfree(s);
1139 }
1140 else
1141 PyErr_SetString(Tkinter_TclError, "merge failed");
1142
1143 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001144}
1145
Barry Warsawfa701a81997-01-16 00:15:11 +00001146
1147
Guido van Rossum18468821994-06-20 07:49:28 +00001148/** Tcl Command **/
1149
Guido van Rossum00d93061998-05-28 23:06:38 +00001150/* Client data struct */
1151typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001152 PyObject *self;
1153 PyObject *func;
1154} PythonCmd_ClientData;
1155
1156static int
1157PythonCmd_Error(interp)
1158 Tcl_Interp *interp;
1159{
1160 errorInCmd = 1;
1161 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1162 LEAVE_PYTHON
1163 return TCL_ERROR;
1164}
1165
Guido van Rossum18468821994-06-20 07:49:28 +00001166/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 * function or method.
1168 */
Guido van Rossum18468821994-06-20 07:49:28 +00001169static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001170PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001171 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001172 Tcl_Interp *interp;
1173 int argc;
1174 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001175{
Guido van Rossum00d93061998-05-28 23:06:38 +00001176 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 PyObject *self, *func, *arg, *res, *tmp;
1178 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001179
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001180 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001181
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 /* TBD: no error checking here since we know, via the
1183 * Tkapp_CreateCommand() that the client data is a two-tuple
1184 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001185 self = data->self;
1186 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001187
Barry Warsawfa701a81997-01-16 00:15:11 +00001188 /* Create argument list (argv1, ..., argvN) */
1189 if (!(arg = PyTuple_New(argc - 1)))
1190 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001191
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 for (i = 0; i < (argc - 1); i++) {
1193 PyObject *s = PyString_FromString(argv[i + 1]);
1194 if (!s || PyTuple_SetItem(arg, i, s)) {
1195 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001196 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 }
1198 }
1199 res = PyEval_CallObject(func, arg);
1200 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001201
Barry Warsawfa701a81997-01-16 00:15:11 +00001202 if (res == NULL)
1203 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001204
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 if (!(tmp = PyList_New(0))) {
1206 Py_DECREF(res);
1207 return PythonCmd_Error(interp);
1208 }
1209
1210 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1211 Py_DECREF(res);
1212 Py_DECREF(tmp);
1213
Guido van Rossum00d93061998-05-28 23:06:38 +00001214 LEAVE_PYTHON
1215
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001217}
1218
1219static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001220PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001221 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001222{
Guido van Rossum00d93061998-05-28 23:06:38 +00001223 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1224
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001225 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001226 Py_XDECREF(data->self);
1227 Py_XDECREF(data->func);
1228 PyMem_DEL(data);
1229 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001230}
1231
Barry Warsawfa701a81997-01-16 00:15:11 +00001232
1233
Guido van Rossum18468821994-06-20 07:49:28 +00001234static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001235Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 PyObject *self;
1237 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001238{
Guido van Rossum00d93061998-05-28 23:06:38 +00001239 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001241 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001242 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001243
Guido van Rossum43713e52000-02-29 13:59:29 +00001244 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001245 return NULL;
1246 if (!PyCallable_Check(func)) {
1247 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 return NULL;
1249 }
Guido van Rossum18468821994-06-20 07:49:28 +00001250
Guido van Rossum00d93061998-05-28 23:06:38 +00001251 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 if (!data)
1253 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001254 Py_XINCREF(self);
1255 Py_XINCREF(func);
1256 data->self = self;
1257 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001258
Guido van Rossum00d93061998-05-28 23:06:38 +00001259 ENTER_TCL
1260 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1261 (ClientData)data, PythonCmdDelete);
1262 LEAVE_TCL
1263 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001264 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001265 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001266 return NULL;
1267 }
Guido van Rossum18468821994-06-20 07:49:28 +00001268
Barry Warsawfa701a81997-01-16 00:15:11 +00001269 Py_INCREF(Py_None);
1270 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001271}
1272
Barry Warsawfa701a81997-01-16 00:15:11 +00001273
1274
Guido van Rossum18468821994-06-20 07:49:28 +00001275static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001276Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 PyObject *self;
1278 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001279{
Barry Warsawfa701a81997-01-16 00:15:11 +00001280 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001281 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001282
Guido van Rossum43713e52000-02-29 13:59:29 +00001283 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001285 ENTER_TCL
1286 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1287 LEAVE_TCL
1288 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001289 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1290 return NULL;
1291 }
1292 Py_INCREF(Py_None);
1293 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001294}
1295
Barry Warsawfa701a81997-01-16 00:15:11 +00001296
1297
Guido van Rossum00d93061998-05-28 23:06:38 +00001298#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001299/** File Handler **/
1300
Guido van Rossum00d93061998-05-28 23:06:38 +00001301typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001302 PyObject *func;
1303 PyObject *file;
1304 int id;
1305 struct _fhcdata *next;
1306} FileHandler_ClientData;
1307
1308static FileHandler_ClientData *HeadFHCD;
1309
1310static FileHandler_ClientData *
1311NewFHCD(func, file, id)
1312 PyObject *func;
1313 PyObject *file;
1314 int id;
1315{
1316 FileHandler_ClientData *p;
1317 p = PyMem_NEW(FileHandler_ClientData, 1);
1318 if (p != NULL) {
1319 Py_XINCREF(func);
1320 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001321 p->func = func;
1322 p->file = file;
1323 p->id = id;
1324 p->next = HeadFHCD;
1325 HeadFHCD = p;
1326 }
1327 return p;
1328}
1329
1330static void
1331DeleteFHCD(id)
1332 int id;
1333{
1334 FileHandler_ClientData *p, **pp;
1335
1336 pp = &HeadFHCD;
1337 while ((p = *pp) != NULL) {
1338 if (p->id == id) {
1339 *pp = p->next;
1340 Py_XDECREF(p->func);
1341 Py_XDECREF(p->file);
1342 PyMem_DEL(p);
1343 }
1344 else
1345 pp = &p->next;
1346 }
1347}
1348
Guido van Rossuma597dde1995-01-10 20:56:29 +00001349static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001350FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001351 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001352 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001353{
Guido van Rossum00d93061998-05-28 23:06:38 +00001354 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001355 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001356
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001357 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001358 func = data->func;
1359 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001360
Barry Warsawfa701a81997-01-16 00:15:11 +00001361 arg = Py_BuildValue("(Oi)", file, (long) mask);
1362 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001363 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001364
1365 if (res == NULL) {
1366 errorInCmd = 1;
1367 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1368 }
1369 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001370 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001371}
1372
1373static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001374GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 /* Either an int >= 0 or an object with a
1376 *.fileno() method that returns an int >= 0
1377 */
1378 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001379{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001380 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001381 int id;
1382 if (PyInt_Check(file)) {
1383 id = PyInt_AsLong(file);
1384 if (id < 0)
1385 PyErr_SetString(PyExc_ValueError, "invalid file id");
1386 return id;
1387 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001388 args = PyTuple_New(0);
1389 if (args == NULL)
1390 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001391
1392 meth = PyObject_GetAttrString(file, "fileno");
1393 if (meth == NULL) {
1394 Py_DECREF(args);
1395 return -1;
1396 }
1397
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001398 res = PyEval_CallObject(meth, args);
1399 Py_DECREF(args);
1400 Py_DECREF(meth);
1401 if (res == NULL)
1402 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001403
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001404 if (PyInt_Check(res))
1405 id = PyInt_AsLong(res);
1406 else
1407 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001408
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001409 if (id < 0)
1410 PyErr_SetString(PyExc_ValueError,
1411 "invalid fileno() return value");
1412 Py_DECREF(res);
1413 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001414}
1415
1416static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001417Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001418 PyObject *self;
1419 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001420{
Guido van Rossum00d93061998-05-28 23:06:38 +00001421 FileHandler_ClientData *data;
1422 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001423 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001424
Guido van Rossum43713e52000-02-29 13:59:29 +00001425 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001427 tfile = GetFileNo(file);
1428 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001429 return NULL;
1430 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001431 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 return NULL;
1433 }
1434
Guido van Rossuma80649b2000-03-28 20:07:05 +00001435 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001437 return NULL;
1438
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001440 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001441 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001442 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001443 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001445}
1446
1447static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001448Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001449 PyObject *self;
1450 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001451{
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001453 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001454 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001455
Guido van Rossum43713e52000-02-29 13:59:29 +00001456 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001458 tfile = GetFileNo(file);
1459 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001460 return NULL;
1461
Guido van Rossuma80649b2000-03-28 20:07:05 +00001462 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001463
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001465 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001467 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001468 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001470}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001471#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001472
Barry Warsawfa701a81997-01-16 00:15:11 +00001473
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001474/**** Tktt Object (timer token) ****/
1475
1476staticforward PyTypeObject Tktt_Type;
1477
Guido van Rossum00d93061998-05-28 23:06:38 +00001478typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001480 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001482} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001483
1484static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001485Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001486 PyObject *self;
1487 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001488{
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001490 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001491
Guido van Rossum43713e52000-02-29 13:59:29 +00001492 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001494 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001495 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001496 v->token = NULL;
1497 }
1498 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001499 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001500 Py_DECREF(func);
1501 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 }
1503 Py_INCREF(Py_None);
1504 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001505}
1506
1507static PyMethodDef Tktt_methods[] =
1508{
Guido van Rossum35d43371997-08-02 00:09:09 +00001509 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001511};
1512
1513static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001514Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001516{
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001518
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 v = PyObject_NEW(TkttObject, &Tktt_Type);
1520 if (v == NULL)
1521 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001522
Guido van Rossum00d93061998-05-28 23:06:38 +00001523 Py_INCREF(func);
1524 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001525 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001526
1527 /* Extra reference, deleted when called or when handler is deleted */
1528 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001530}
1531
1532static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001533Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001535{
Guido van Rossum00d93061998-05-28 23:06:38 +00001536 TkttObject *v = (TkttObject *)self;
1537 PyObject *func = v->func;
1538
1539 Py_XDECREF(func);
1540
Guido van Rossum35d43371997-08-02 00:09:09 +00001541 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001542}
1543
Guido van Rossum597ac201998-05-12 14:36:19 +00001544static PyObject *
1545Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001546 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001547{
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001549 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001550
Guido van Rossum597ac201998-05-12 14:36:19 +00001551 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001553 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001554}
1555
1556static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001557Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 PyObject *self;
1559 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001560{
Barry Warsawfa701a81997-01-16 00:15:11 +00001561 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001562}
1563
1564static PyTypeObject Tktt_Type =
1565{
Guido van Rossum35d43371997-08-02 00:09:09 +00001566 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 0, /*ob_size */
1568 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001569 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 0, /*tp_itemsize */
1571 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001572 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001573 Tktt_GetAttr, /*tp_getattr */
1574 0, /*tp_setattr */
1575 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001576 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001577 0, /*tp_as_number */
1578 0, /*tp_as_sequence */
1579 0, /*tp_as_mapping */
1580 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001581};
1582
Barry Warsawfa701a81997-01-16 00:15:11 +00001583
1584
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001585/** Timer Handler **/
1586
1587static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001588TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001590{
Guido van Rossum00d93061998-05-28 23:06:38 +00001591 TkttObject *v = (TkttObject *)clientData;
1592 PyObject *func = v->func;
1593 PyObject *res;
1594
1595 if (func == NULL)
1596 return;
1597
1598 v->func = NULL;
1599
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001600 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001601
1602 res = PyEval_CallObject(func, NULL);
1603 Py_DECREF(func);
1604 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001605
Barry Warsawfa701a81997-01-16 00:15:11 +00001606 if (res == NULL) {
1607 errorInCmd = 1;
1608 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1609 }
1610 else
1611 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001612
1613 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001614}
1615
1616static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001617Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001618 PyObject *self;
1619 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001620{
Barry Warsawfa701a81997-01-16 00:15:11 +00001621 int milliseconds;
1622 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001623 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001624
Guido van Rossum43713e52000-02-29 13:59:29 +00001625 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001626 return NULL;
1627 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001628 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001629 return NULL;
1630 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001631 v = Tktt_New(func);
1632 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1633 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001634
Guido van Rossum00d93061998-05-28 23:06:38 +00001635 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001636}
1637
Barry Warsawfa701a81997-01-16 00:15:11 +00001638
Guido van Rossum18468821994-06-20 07:49:28 +00001639/** Event Loop **/
1640
Guido van Rossum18468821994-06-20 07:49:28 +00001641static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001642Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001643 PyObject *self;
1644 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001645{
Barry Warsawfa701a81997-01-16 00:15:11 +00001646 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001647#ifdef WITH_THREAD
1648 PyThreadState *tstate = PyThreadState_Get();
1649#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001650
Guido van Rossum43713e52000-02-29 13:59:29 +00001651 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001652 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001653
Barry Warsawfa701a81997-01-16 00:15:11 +00001654 quitMainLoop = 0;
1655 while (Tk_GetNumMainWindows() > threshold &&
1656 !quitMainLoop &&
1657 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001658 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001659 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001660
1661#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001662 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001663 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001664 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001665 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001666 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001667 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001668 if (result == 0)
1669 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001670 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001671#else
1672 result = Tcl_DoOneEvent(0);
1673#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001674
Guido van Rossum35d43371997-08-02 00:09:09 +00001675 if (PyErr_CheckSignals() != 0)
1676 return NULL;
1677 if (result < 0)
1678 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001679 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001680 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001681
Barry Warsawfa701a81997-01-16 00:15:11 +00001682 if (errorInCmd) {
1683 errorInCmd = 0;
1684 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1685 excInCmd = valInCmd = trbInCmd = NULL;
1686 return NULL;
1687 }
1688 Py_INCREF(Py_None);
1689 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001690}
1691
1692static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001693Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 PyObject *self;
1695 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001696{
Guido van Rossum35d43371997-08-02 00:09:09 +00001697 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001698 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001699
Guido van Rossum43713e52000-02-29 13:59:29 +00001700 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 return NULL;
1702
Guido van Rossum00d93061998-05-28 23:06:38 +00001703 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001704 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001705 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001706 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001707}
1708
1709static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001710Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 PyObject *self;
1712 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001713{
1714
Guido van Rossum43713e52000-02-29 13:59:29 +00001715 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 return NULL;
1717
1718 quitMainLoop = 1;
1719 Py_INCREF(Py_None);
1720 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001721}
1722
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001723static PyObject *
1724Tkapp_InterpAddr(self, args)
1725 PyObject *self;
1726 PyObject *args;
1727{
1728
Guido van Rossum43713e52000-02-29 13:59:29 +00001729 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001730 return NULL;
1731
1732 return PyInt_FromLong((long)Tkapp_Interp(self));
1733}
1734
Barry Warsawfa701a81997-01-16 00:15:11 +00001735
1736
Guido van Rossum18468821994-06-20 07:49:28 +00001737/**** Tkapp Method List ****/
1738
1739static PyMethodDef Tkapp_methods[] =
1740{
Guido van Rossum35d43371997-08-02 00:09:09 +00001741 {"call", Tkapp_Call, 0},
1742 {"globalcall", Tkapp_GlobalCall, 0},
1743 {"eval", Tkapp_Eval, 1},
1744 {"globaleval", Tkapp_GlobalEval, 1},
1745 {"evalfile", Tkapp_EvalFile, 1},
1746 {"record", Tkapp_Record, 1},
1747 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1748 {"setvar", Tkapp_SetVar, 1},
1749 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1750 {"getvar", Tkapp_GetVar, 1},
1751 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1752 {"unsetvar", Tkapp_UnsetVar, 1},
1753 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1754 {"getint", Tkapp_GetInt, 1},
1755 {"getdouble", Tkapp_GetDouble, 1},
1756 {"getboolean", Tkapp_GetBoolean, 1},
1757 {"exprstring", Tkapp_ExprString, 1},
1758 {"exprlong", Tkapp_ExprLong, 1},
1759 {"exprdouble", Tkapp_ExprDouble, 1},
1760 {"exprboolean", Tkapp_ExprBoolean, 1},
1761 {"splitlist", Tkapp_SplitList, 1},
1762 {"split", Tkapp_Split, 1},
1763 {"merge", Tkapp_Merge, 0},
1764 {"createcommand", Tkapp_CreateCommand, 1},
1765 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001766#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001767 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1768 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001769#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001770 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001771 {"mainloop", Tkapp_MainLoop, 1},
1772 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001773 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001774 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001775 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001776};
1777
Barry Warsawfa701a81997-01-16 00:15:11 +00001778
1779
Guido van Rossum18468821994-06-20 07:49:28 +00001780/**** Tkapp Type Methods ****/
1781
1782static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001783Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001784 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001785{
Guido van Rossum00d93061998-05-28 23:06:38 +00001786 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001787 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001788 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001789 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001790 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001791}
1792
1793static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001794Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001795 PyObject *self;
1796 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001797{
Guido van Rossum35d43371997-08-02 00:09:09 +00001798 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001799}
1800
1801static PyTypeObject Tkapp_Type =
1802{
Guido van Rossum35d43371997-08-02 00:09:09 +00001803 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 0, /*ob_size */
1805 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001806 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001807 0, /*tp_itemsize */
1808 Tkapp_Dealloc, /*tp_dealloc */
1809 0, /*tp_print */
1810 Tkapp_GetAttr, /*tp_getattr */
1811 0, /*tp_setattr */
1812 0, /*tp_compare */
1813 0, /*tp_repr */
1814 0, /*tp_as_number */
1815 0, /*tp_as_sequence */
1816 0, /*tp_as_mapping */
1817 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001818};
1819
Barry Warsawfa701a81997-01-16 00:15:11 +00001820
1821
Guido van Rossum18468821994-06-20 07:49:28 +00001822/**** Tkinter Module ****/
1823
1824static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001825Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001826 PyObject *self;
1827 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001828{
Barry Warsawfa701a81997-01-16 00:15:11 +00001829 char *screenName = NULL;
1830 char *baseName = NULL;
1831 char *className = NULL;
1832 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001833
Guido van Rossum35d43371997-08-02 00:09:09 +00001834 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001835 if (baseName != NULL)
1836 baseName++;
1837 else
1838 baseName = Py_GetProgramName();
1839 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001840
Guido van Rossum43713e52000-02-29 13:59:29 +00001841 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001842 &screenName, &baseName, &className,
1843 &interactive))
1844 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001845
Barry Warsawfa701a81997-01-16 00:15:11 +00001846 return (PyObject *) Tkapp_New(screenName, baseName, className,
1847 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001848}
1849
1850static PyMethodDef moduleMethods[] =
1851{
Barry Warsawfa701a81997-01-16 00:15:11 +00001852 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001853#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001854 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1855 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001856#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001857 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 {"mainloop", Tkapp_MainLoop, 1},
1859 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001860 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001861 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001862};
1863
Guido van Rossum7bf15641998-05-22 18:28:17 +00001864#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001865
1866static int stdin_ready = 0;
1867
Guido van Rossumad4db171998-06-13 13:56:28 +00001868#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001869static void
1870MyFileProc(clientData, mask)
1871 void *clientData;
1872 int mask;
1873{
1874 stdin_ready = 1;
1875}
Guido van Rossumad4db171998-06-13 13:56:28 +00001876#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001877
Guido van Rossum00d93061998-05-28 23:06:38 +00001878static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001879
Guido van Rossum18468821994-06-20 07:49:28 +00001880static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001881EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001882{
Guido van Rossumad4db171998-06-13 13:56:28 +00001883#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001884 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001885#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001886#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001887 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001888#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001889 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001890 errorInCmd = 0;
1891#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001892 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001893 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001894#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001895 while (!errorInCmd && !stdin_ready) {
1896 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001897#ifdef MS_WINDOWS
1898 if (_kbhit()) {
1899 stdin_ready = 1;
1900 break;
1901 }
1902#endif
1903#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001904 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001905 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001906 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001907
Guido van Rossum00d93061998-05-28 23:06:38 +00001908 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001909
1910 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001911 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001912 if (result == 0)
1913 Sleep(20);
1914 Py_END_ALLOW_THREADS
1915#else
1916 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001917#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001918
1919 if (result < 0)
1920 break;
1921 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001922#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001923 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001924#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001925 if (errorInCmd) {
1926 errorInCmd = 0;
1927 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1928 excInCmd = valInCmd = trbInCmd = NULL;
1929 PyErr_Print();
1930 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001931#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001932 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001933#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001935}
Guido van Rossum18468821994-06-20 07:49:28 +00001936
Guido van Rossum00d93061998-05-28 23:06:38 +00001937#endif
1938
Guido van Rossum7bf15641998-05-22 18:28:17 +00001939static void
1940EnableEventHook()
1941{
Guido van Rossum00d93061998-05-28 23:06:38 +00001942#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001943 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001944#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001945 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001946#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001947 PyOS_InputHook = EventHook;
1948 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001949#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001950}
1951
1952static void
1953DisableEventHook()
1954{
Guido van Rossum00d93061998-05-28 23:06:38 +00001955#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001956 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1957 PyOS_InputHook = NULL;
1958 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001959#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001960}
1961
Barry Warsawfa701a81997-01-16 00:15:11 +00001962
1963/* all errors will be checked in one fell swoop in init_tkinter() */
1964static void
1965ins_long(d, name, val)
1966 PyObject *d;
1967 char *name;
1968 long val;
1969{
1970 PyObject *v = PyInt_FromLong(val);
1971 if (v) {
1972 PyDict_SetItemString(d, name, v);
1973 Py_DECREF(v);
1974 }
1975}
1976static void
1977ins_string(d, name, val)
1978 PyObject *d;
1979 char *name;
1980 char *val;
1981{
1982 PyObject *v = PyString_FromString(val);
1983 if (v) {
1984 PyDict_SetItemString(d, name, v);
1985 Py_DECREF(v);
1986 }
1987}
1988
1989
Guido van Rossum3886bb61998-12-04 18:50:17 +00001990DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00001991init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001992{
Barry Warsawfa701a81997-01-16 00:15:11 +00001993 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001994
Barry Warsawfa701a81997-01-16 00:15:11 +00001995 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00001996
1997#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00001998 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00001999#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002000
Barry Warsawfa701a81997-01-16 00:15:11 +00002001 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002002
Barry Warsawfa701a81997-01-16 00:15:11 +00002003 d = PyModule_GetDict(m);
2004 Tkinter_TclError = Py_BuildValue("s", "TclError");
2005 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002006
Guido van Rossum35d43371997-08-02 00:09:09 +00002007 ins_long(d, "READABLE", TCL_READABLE);
2008 ins_long(d, "WRITABLE", TCL_WRITABLE);
2009 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2010 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2011 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2012 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2013 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2014 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2015 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002016 ins_string(d, "TK_VERSION", TK_VERSION);
2017 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002018
Guido van Rossum83551bf1997-09-13 00:44:23 +00002019 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002020
2021 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002022 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2023
Guido van Rossume187b0e2000-03-27 21:46:29 +00002024 /* This helps the dynamic loader; in Unicode aware Tcl versions
2025 it also helps Tcl find its encodings. */
2026 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002027
Barry Warsawfa701a81997-01-16 00:15:11 +00002028 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002029 return;
2030
Guido van Rossum43ff8681998-07-14 18:02:13 +00002031#if 0
2032 /* This was not a good idea; through <Destroy> bindings,
2033 Tcl_Finalize() may invoke Python code but at that point the
2034 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002035 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002036#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002037
Jack Jansen34cc5c31995-10-31 16:15:12 +00002038#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002039 /*
2040 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2041 ** Most of the initializations in that routine (toolbox init calls and
2042 ** such) have already been done for us, so we only need these.
2043 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002044 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002045
2046 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002047#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002048 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002049#endif /* GENERATINGCFM */
2050#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002051}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002052
Guido van Rossumec22c921996-02-25 04:50:29 +00002053
Barry Warsawfa701a81997-01-16 00:15:11 +00002054
Guido van Rossum9722ad81995-09-22 23:49:28 +00002055#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002056
2057/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002058** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002059*/
2060
Guido van Rossum9722ad81995-09-22 23:49:28 +00002061void
2062panic(char * format, ...)
2063{
Barry Warsawfa701a81997-01-16 00:15:11 +00002064 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002065
Barry Warsawfa701a81997-01-16 00:15:11 +00002066 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002067
Guido van Rossum227cf761998-08-05 13:53:32 +00002068 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002069 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002070
Barry Warsawfa701a81997-01-16 00:15:11 +00002071 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002072
Barry Warsawfa701a81997-01-16 00:15:11 +00002073 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002074}
Jack Jansen40b546d1995-11-14 10:34:45 +00002075
Guido van Rossumec22c921996-02-25 04:50:29 +00002076/*
2077** Pass events to SIOUX before passing them to Tk.
2078*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002079
Guido van Rossumec22c921996-02-25 04:50:29 +00002080static int
2081PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002082 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002083{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002084 WindowPtr frontwin;
2085 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002086 ** Sioux eats too many events, so we don't pass it everything. We
2087 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002088 ** the Sioux window is frontmost. This means that Tk menus don't work
2089 ** in that case, but at least we can scroll the sioux window.
2090 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2091 ** part of the external interface of Sioux...
2092 */
2093 frontwin = FrontWindow();
2094 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2095 if (SIOUXHandleOneEvent(eventPtr))
2096 return 0; /* Nothing happened to the Tcl event queue */
2097 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002098 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002099}
2100
Guido van Rossumec22c921996-02-25 04:50:29 +00002101#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002102
2103/*
2104** Additional Mac specific code for dealing with shared libraries.
2105*/
2106
2107#include <Resources.h>
2108#include <CodeFragments.h>
2109
2110static int loaded_from_shlib = 0;
2111static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002112
Jack Jansen34cc5c31995-10-31 16:15:12 +00002113/*
2114** If this module is dynamically loaded the following routine should
2115** be the init routine. It takes care of adding the shared library to
2116** the resource-file chain, so that the tk routines can find their
2117** resources.
2118*/
2119OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002120init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002121{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002122 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002123 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002124 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002125 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2126 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002127 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002128 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2129 loaded_from_shlib = 1;
2130 }
2131 return noErr;
2132}
2133
2134/*
2135** Insert the library resources into the search path. Put them after
2136** the resources from the application. Again, we ignore errors.
2137*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002138static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002139mac_addlibresources()
2140{
2141 if ( !loaded_from_shlib )
2142 return;
2143 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2144}
2145
Guido van Rossumec22c921996-02-25 04:50:29 +00002146#endif /* GENERATINGCFM */
2147#endif /* macintosh */