blob: ea0c8b17d15b5d796df8643b4e4b802291871441 [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
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossum00d93061998-05-28 23:06:38 +000061#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000062#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000063#endif
64
Guido van Rossum2a5119b1998-05-29 01:28:40 +000065#ifdef MS_WINDOWS
66#include <windows.h>
67#endif
68
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000069#ifdef macintosh
70#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000071#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000072#endif
73
Guido van Rossum49b56061998-10-01 20:42:43 +000074#ifdef PYOS_OS2
75#include "myselect.h"
76#endif
77
Guido van Rossum18468821994-06-20 07:49:28 +000078#include <tcl.h>
79#include <tk.h>
80
Guido van Rossum3e819a71997-08-01 19:29:02 +000081#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
82
Guido van Rossum00d93061998-05-28 23:06:38 +000083#if TKMAJORMINOR < 4001
84 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
85#endif
86
Guido van Rossum0d2390c1997-08-14 19:57:07 +000087#if TKMAJORMINOR >= 8000 && defined(macintosh)
88/* Sigh, we have to include this to get at the tcl qd pointer */
89#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000090/* And this one we need to clear the menu bar */
91#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000092#endif
93
Guido van Rossumb0105441997-10-08 15:25:37 +000094#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000095#define HAVE_CREATEFILEHANDLER
96#endif
97
Guido van Rossum00d93061998-05-28 23:06:38 +000098#ifdef HAVE_CREATEFILEHANDLER
99
100/* Tcl_CreateFileHandler() changed several times; these macros deal with the
101 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
102 Unix, only because Jack added it back); when available on Windows, it only
103 applies to sockets. */
104
Guido van Rossum7bf15641998-05-22 18:28:17 +0000105#ifdef MS_WINDOWS
106#define FHANDLETYPE TCL_WIN_SOCKET
107#else
108#define FHANDLETYPE TCL_UNIX_FD
109#endif
110
111#if TKMAJORMINOR < 8000
112#define FHANDLE Tcl_File
113#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
114#else
115#define FHANDLE int
116#define MAKEFHANDLE(fd) (fd)
117#endif
118
Guido van Rossum00d93061998-05-28 23:06:38 +0000119/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
120 which uses this to handle Tcl events while the user is typing commands. */
121
122#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000123#define WAIT_FOR_STDIN
124#endif
125
Guido van Rossum00d93061998-05-28 23:06:38 +0000126#endif /* HAVE_CREATEFILEHANDLER */
127
Guido van Rossumad4db171998-06-13 13:56:28 +0000128#ifdef MS_WINDOWS
129#include <conio.h>
130#define WAIT_FOR_STDIN
131#endif
132
Guido van Rossum00d93061998-05-28 23:06:38 +0000133#ifdef WITH_THREAD
134
135/* The threading situation is complicated. Tcl is not thread-safe, except for
136 Tcl 8.1, which will probably remain in alpha status for another 6 months
137 (and the README says that Tk will probably remain thread-unsafe forever).
138 So we need to use a lock around all uses of Tcl. Previously, the Python
139 interpreter lock was used for this. However, this causes problems when
140 other Python threads need to run while Tcl is blocked waiting for events.
141
142 To solve this problem, a separate lock for Tcl is introduced. Holding it
143 is incompatible with holding Python's interpreter lock. The following four
144 macros manipulate both locks together.
145
146 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
147 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
148 that could call an event handler, or otherwise affect the state of a Tcl
149 interpreter. These assume that the surrounding code has the Python
150 interpreter lock; inside the brackets, the Python interpreter lock has been
151 released and the lock for Tcl has been acquired.
152
Guido van Rossum5e977831998-06-15 14:03:52 +0000153 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
154 (For example, when transferring data from the Tcl interpreter result to a
155 Python string object.) This can be done by using different macros to close
156 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
157 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
158 releases the Tcl lock.
159
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000160 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000161 handlers when the handler needs to use Python. Such event handlers are
162 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000164 the Python interpreter lock, restoring the appropriate thread state, and
165 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
166 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000167 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169 These locks expand to several statements and brackets; they should not be
170 used in branches of if statements and the like.
171
172*/
173
Guido van Rossum65d5b571998-12-21 19:32:43 +0000174static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000175static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000176
177#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000179 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000180
181#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000182 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000183
Guido van Rossum62320c91998-06-15 04:36:09 +0000184#define ENTER_OVERLAP \
185 Py_END_ALLOW_THREADS
186
187#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000188 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000189
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000190#define ENTER_PYTHON \
191 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000192 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000193
194#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000195 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000196 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000197
198#else
199
200#define ENTER_TCL
201#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000202#define ENTER_OVERLAP
203#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000204#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000205#define LEAVE_PYTHON
206
207#endif
208
Guido van Rossumec22c921996-02-25 04:50:29 +0000209#ifdef macintosh
210
211/*
212** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000213** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000214*/
215
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000216/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000217#define FREECAST (char *)
218
Guido van Rossumec22c921996-02-25 04:50:29 +0000219#include <Events.h> /* For EventRecord */
220
221typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000222/* They changed the name... */
223#if TKMAJORMINOR < 8000
224#define Tcl_MacSetEventProc TclMacSetEventProc
225#endif
226void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000227int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
228
229staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
230
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000231#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
232 #pragma import on
233#endif
234
235#include <SIOUX.h>
236extern int SIOUXIsAppWindow(WindowPtr);
237
238#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
239 #pragma import reset
240#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000241#endif /* macintosh */
242
Guido van Rossum97867b21996-08-08 19:09:53 +0000243#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000244#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000245#endif
246
Guido van Rossum18468821994-06-20 07:49:28 +0000247/**** Tkapp Object Declaration ****/
248
249staticforward PyTypeObject Tkapp_Type;
250
Guido van Rossum00d93061998-05-28 23:06:38 +0000251typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000252 PyObject_HEAD
253 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000254} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000255
256#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000257#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
258#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
259
Guido van Rossum35d43371997-08-02 00:09:09 +0000260#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000261(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000262
Barry Warsawfa701a81997-01-16 00:15:11 +0000263
264
Guido van Rossum18468821994-06-20 07:49:28 +0000265/**** Error Handling ****/
266
267static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000268static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000269static int errorInCmd = 0;
270static PyObject *excInCmd;
271static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000273
Barry Warsawfa701a81997-01-16 00:15:11 +0000274
275
Guido van Rossum18468821994-06-20 07:49:28 +0000276static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000277Tkinter_Error(v)
278 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000279{
Barry Warsawfa701a81997-01-16 00:15:11 +0000280 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
281 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000282}
283
Barry Warsawfa701a81997-01-16 00:15:11 +0000284
Barry Warsawfa701a81997-01-16 00:15:11 +0000285
Guido van Rossum18468821994-06-20 07:49:28 +0000286/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000287
288#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000289#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000290#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000291#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000292
Guido van Rossum00d93061998-05-28 23:06:38 +0000293/* Millisecond sleep() for Unix platforms. */
294
295static void
296Sleep(milli)
297 int milli;
298{
299 /* XXX Too bad if you don't have select(). */
300 struct timeval t;
301 double frac;
302 t.tv_sec = milli/1000;
303 t.tv_usec = (milli%1000) * 1000;
304 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
305}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000306#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000307#endif /* WITH_THREAD */
308
309
Guido van Rossum18468821994-06-20 07:49:28 +0000310static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000311AsString(value, tmp)
312 PyObject *value;
313 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000314{
Guido van Rossum35d43371997-08-02 00:09:09 +0000315 if (PyString_Check(value))
316 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 else {
318 PyObject *v = PyObject_Str(value);
319 PyList_Append(tmp, v);
320 Py_DECREF(v);
321 return PyString_AsString(v);
322 }
Guido van Rossum18468821994-06-20 07:49:28 +0000323}
324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325
326
Guido van Rossum18468821994-06-20 07:49:28 +0000327#define ARGSZ 64
328
329static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000330Merge(args)
331 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000332{
Barry Warsawfa701a81997-01-16 00:15:11 +0000333 PyObject *tmp = NULL;
334 char *argvStore[ARGSZ];
335 char **argv = NULL;
336 int fvStore[ARGSZ];
337 int *fv = NULL;
338 int argc = 0, i;
339 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000340
Barry Warsawfa701a81997-01-16 00:15:11 +0000341 if (!(tmp = PyList_New(0)))
342 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 argv = argvStore;
345 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000346
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 if (args == NULL)
348 argc = 0;
349
350 else if (!PyTuple_Check(args)) {
351 argc = 1;
352 fv[0] = 0;
353 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000354 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 else {
356 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000357
Barry Warsawfa701a81997-01-16 00:15:11 +0000358 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000359 argv = (char **)ckalloc(argc * sizeof(char *));
360 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 if (argv == NULL || fv == NULL) {
362 PyErr_NoMemory();
363 goto finally;
364 }
365 }
366
367 for (i = 0; i < argc; i++) {
368 PyObject *v = PyTuple_GetItem(args, i);
369 if (PyTuple_Check(v)) {
370 fv[i] = 1;
371 if (!(argv[i] = Merge(v)))
372 goto finally;
373 }
374 else if (v == Py_None) {
375 argc = i;
376 break;
377 }
378 else {
379 fv[i] = 0;
380 argv[i] = AsString(v, tmp);
381 }
382 }
Guido van Rossum18468821994-06-20 07:49:28 +0000383 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000385
Barry Warsawfa701a81997-01-16 00:15:11 +0000386 finally:
387 for (i = 0; i < argc; i++)
388 if (fv[i]) {
389 ckfree(argv[i]);
390 }
391 if (argv != argvStore)
392 ckfree(FREECAST argv);
393 if (fv != fvStore)
394 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000395
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 Py_DECREF(tmp);
397 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000398}
399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400
401
Guido van Rossum18468821994-06-20 07:49:28 +0000402static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000403Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000405{
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 int argc;
407 char **argv;
408 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000409
Barry Warsawfa701a81997-01-16 00:15:11 +0000410 if (list == NULL) {
411 Py_INCREF(Py_None);
412 return Py_None;
413 }
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Guido van Rossum00d93061998-05-28 23:06:38 +0000415 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 /* Not a list.
417 * Could be a quoted string containing funnies, e.g. {"}.
418 * Return the string itself.
419 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 return PyString_FromString(list);
421 }
Guido van Rossum18468821994-06-20 07:49:28 +0000422
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 if (argc == 0)
424 v = PyString_FromString("");
425 else if (argc == 1)
426 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000427 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 int i;
429 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000430
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000432 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 Py_DECREF(v);
434 v = NULL;
435 break;
436 }
437 PyTuple_SetItem(v, i, w);
438 }
439 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000440 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000441 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446/**** Tkapp Object ****/
447
448#ifndef WITH_APPINIT
449int
Guido van Rossum35d43371997-08-02 00:09:09 +0000450Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000452{
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 main = Tk_MainWindow(interp);
456 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000457 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 return TCL_ERROR;
459 }
460 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000461 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 return TCL_ERROR;
463 }
464 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000465}
466#endif /* !WITH_APPINIT */
467
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469
470
471/* Initialize the Tk application; see the `main' function in
472 * `tkMain.c'.
473 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000474
475static void EnableEventHook(); /* Forward */
476static void DisableEventHook(); /* Forward */
477
Barry Warsawfa701a81997-01-16 00:15:11 +0000478static TkappObject *
479Tkapp_New(screenName, baseName, className, interactive)
480 char *screenName;
481 char *baseName;
482 char *className;
483 int interactive;
484{
485 TkappObject *v;
486 char *argv0;
487
488 v = PyObject_NEW(TkappObject, &Tkapp_Type);
489 if (v == NULL)
490 return NULL;
491
492 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000493
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000494#if defined(macintosh) && TKMAJORMINOR >= 8000
495 /* This seems to be needed since Tk 8.0 */
496 ClearMenuBar();
497 TkMacInitMenus(v->interp);
498#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000499 /* Delete the 'exit' command, which can screw things up */
500 Tcl_DeleteCommand(v->interp, "exit");
501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502 if (screenName != NULL)
503 Tcl_SetVar2(v->interp, "env", "DISPLAY",
504 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000505
Barry Warsawfa701a81997-01-16 00:15:11 +0000506 if (interactive)
507 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
508 else
509 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000510
Barry Warsawfa701a81997-01-16 00:15:11 +0000511 /* This is used to get the application class for Tk 4.1 and up */
512 argv0 = (char*)ckalloc(strlen(className) + 1);
513 if (!argv0) {
514 PyErr_NoMemory();
515 Py_DECREF(v);
516 return NULL;
517 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000518
Barry Warsawfa701a81997-01-16 00:15:11 +0000519 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000520 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000521 argv0[0] = tolower(argv0[0]);
522 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
523 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000524
Barry Warsawfa701a81997-01-16 00:15:11 +0000525 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000526 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000527
Guido van Rossum7bf15641998-05-22 18:28:17 +0000528 EnableEventHook();
529
Barry Warsawfa701a81997-01-16 00:15:11 +0000530 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000531}
532
Barry Warsawfa701a81997-01-16 00:15:11 +0000533
534
Guido van Rossum18468821994-06-20 07:49:28 +0000535/** Tcl Eval **/
536
537static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000538Tkapp_Call(self, args)
539 PyObject *self;
540 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000541{
Guido van Rossum212643f1998-04-29 16:22:14 +0000542 /* This is copied from Merge() */
543 PyObject *tmp = NULL;
544 char *argvStore[ARGSZ];
545 char **argv = NULL;
546 int fvStore[ARGSZ];
547 int *fv = NULL;
548 int argc = 0, i;
549 PyObject *res = NULL; /* except this has a different type */
550 Tcl_CmdInfo info; /* and this is added */
551 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000552
Guido van Rossum212643f1998-04-29 16:22:14 +0000553 if (!(tmp = PyList_New(0)))
554 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000555
Guido van Rossum212643f1998-04-29 16:22:14 +0000556 argv = argvStore;
557 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000558
Guido van Rossum212643f1998-04-29 16:22:14 +0000559 if (args == NULL)
560 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000561
Guido van Rossum212643f1998-04-29 16:22:14 +0000562 else if (!PyTuple_Check(args)) {
563 argc = 1;
564 fv[0] = 0;
565 argv[0] = AsString(args, tmp);
566 }
567 else {
568 argc = PyTuple_Size(args);
569
570 if (argc > ARGSZ) {
571 argv = (char **)ckalloc(argc * sizeof(char *));
572 fv = (int *)ckalloc(argc * sizeof(int));
573 if (argv == NULL || fv == NULL) {
574 PyErr_NoMemory();
575 goto finally;
576 }
577 }
578
579 for (i = 0; i < argc; i++) {
580 PyObject *v = PyTuple_GetItem(args, i);
581 if (PyTuple_Check(v)) {
582 fv[i] = 1;
583 if (!(argv[i] = Merge(v)))
584 goto finally;
585 }
586 else if (v == Py_None) {
587 argc = i;
588 break;
589 }
590 else {
591 fv[i] = 0;
592 argv[i] = AsString(v, tmp);
593 }
594 }
595 }
596 /* End code copied from Merge() */
597
598 /* All this to avoid a call to Tcl_Merge() and the corresponding call
599 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
600 if (Py_VerboseFlag >= 2) {
601 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000602 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000603 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000604 ENTER_TCL
605 info.proc = NULL;
Guido van Rossum212643f1998-04-29 16:22:14 +0000606 if (argc < 1 ||
607 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
608 info.proc == NULL)
609 {
610 char *cmd;
Guido van Rossum212643f1998-04-29 16:22:14 +0000611 cmd = Tcl_Merge(argc, argv);
612 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000613 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000614 }
615 else {
616 Tcl_ResetResult(interp);
617 i = (*info.proc)(info.clientData, interp, argc, argv);
618 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000619 ENTER_OVERLAP
620 if (info.proc == NULL && Py_VerboseFlag >= 2)
621 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000622 if (i == TCL_ERROR) {
623 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000624 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000625 interp->result);
626 Tkinter_Error(self);
627 }
628 else {
629 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000630 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000631 res = PyString_FromString(interp->result);
632 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000633 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000634
Guido van Rossum212643f1998-04-29 16:22:14 +0000635 /* Copied from Merge() again */
636 finally:
637 for (i = 0; i < argc; i++)
638 if (fv[i]) {
639 ckfree(argv[i]);
640 }
641 if (argv != argvStore)
642 ckfree(FREECAST argv);
643 if (fv != fvStore)
644 ckfree(FREECAST fv);
645
646 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000647 return res;
648}
649
650
651static PyObject *
652Tkapp_GlobalCall(self, args)
653 PyObject *self;
654 PyObject *args;
655{
Guido van Rossum212643f1998-04-29 16:22:14 +0000656 /* Could do the same here as for Tkapp_Call(), but this is not used
657 much, so I can't be bothered. Unfortunately Tcl doesn't export a
658 way for the user to do what all its Global* variants do (save and
659 reset the scope pointer, call the local version, restore the saved
660 scope pointer). */
661
Guido van Rossum62320c91998-06-15 04:36:09 +0000662 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000664
Guido van Rossum62320c91998-06-15 04:36:09 +0000665 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 if (!cmd)
667 PyErr_SetString(Tkinter_TclError, "merge failed");
668
Guido van Rossum00d93061998-05-28 23:06:38 +0000669 else {
670 int err;
671 ENTER_TCL
672 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000673 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000674 if (err == TCL_ERROR)
675 res = Tkinter_Error(self);
676 else
677 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000678 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000679 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000680
681 if (cmd)
682 ckfree(cmd);
683
684 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000685}
686
687static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000688Tkapp_Eval(self, args)
689 PyObject *self;
690 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000691{
Barry Warsawfa701a81997-01-16 00:15:11 +0000692 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000693 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000694 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000695
Guido van Rossum35d43371997-08-02 00:09:09 +0000696 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000697 return NULL;
698
Guido van Rossum00d93061998-05-28 23:06:38 +0000699 ENTER_TCL
700 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000701 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000702 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000703 res = Tkinter_Error(self);
704 else
705 res = PyString_FromString(Tkapp_Result(self));
706 LEAVE_OVERLAP_TCL
707 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000708}
709
710static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000711Tkapp_GlobalEval(self, args)
712 PyObject *self;
713 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000714{
Barry Warsawfa701a81997-01-16 00:15:11 +0000715 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000716 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000717 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000718
Guido van Rossum35d43371997-08-02 00:09:09 +0000719 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000720 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000721
Guido van Rossum00d93061998-05-28 23:06:38 +0000722 ENTER_TCL
723 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000724 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000725 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000726 res = Tkinter_Error(self);
727 else
728 res = PyString_FromString(Tkapp_Result(self));
729 LEAVE_OVERLAP_TCL
730 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000731}
732
733static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000734Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000735 PyObject *self;
736 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000737{
Barry Warsawfa701a81997-01-16 00:15:11 +0000738 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000739 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000740 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000741
Guido van Rossum35d43371997-08-02 00:09:09 +0000742 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000743 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000744
Guido van Rossum00d93061998-05-28 23:06:38 +0000745 ENTER_TCL
746 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000747 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000748 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000749 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000750
Guido van Rossum62320c91998-06-15 04:36:09 +0000751 else
752 res = PyString_FromString(Tkapp_Result(self));
753 LEAVE_OVERLAP_TCL
754 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000755}
756
757static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000758Tkapp_Record(self, args)
759 PyObject *self;
760 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000761{
Barry Warsawfa701a81997-01-16 00:15:11 +0000762 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000763 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000764 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000765
Guido van Rossum35d43371997-08-02 00:09:09 +0000766 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000767 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Guido van Rossum00d93061998-05-28 23:06:38 +0000769 ENTER_TCL
770 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000771 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000772 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000773 res = Tkinter_Error(self);
774 else
775 res = PyString_FromString(Tkapp_Result(self));
776 LEAVE_OVERLAP_TCL
777 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000778}
779
780static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000781Tkapp_AddErrorInfo(self, args)
782 PyObject *self;
783 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000784{
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000786
Guido van Rossum35d43371997-08-02 00:09:09 +0000787 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000788 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000789 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000790 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000791 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000792
Barry Warsawfa701a81997-01-16 00:15:11 +0000793 Py_INCREF(Py_None);
794 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000795}
796
Barry Warsawfa701a81997-01-16 00:15:11 +0000797
798
Guido van Rossum18468821994-06-20 07:49:28 +0000799/** Tcl Variable **/
800
801static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000802SetVar(self, args, flags)
803 PyObject *self;
804 PyObject *args;
805 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000806{
Guido van Rossum00d93061998-05-28 23:06:38 +0000807 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000808 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000809 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000810
Guido van Rossum62320c91998-06-15 04:36:09 +0000811 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 if (!tmp)
813 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000814
Guido van Rossum00d93061998-05-28 23:06:38 +0000815 if (PyArg_ParseTuple(args, "sO", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000816 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000817 s = AsString(newValue, tmp);
818 ENTER_TCL
819 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
820 LEAVE_TCL
821 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000823 PyErr_Clear();
Guido van Rossum00d93061998-05-28 23:06:38 +0000824 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue)) {
825 s = AsString (newValue, tmp);
826 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000827 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000828 s, flags);
829 LEAVE_TCL
830 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000831 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000832 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000833 return NULL;
834 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000835 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000836 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000837
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 if (!ok)
839 return Tkinter_Error(self);
840
841 Py_INCREF(Py_None);
842 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000843}
844
845static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000846Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000847 PyObject *self;
848 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000849{
Barry Warsawfa701a81997-01-16 00:15:11 +0000850 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000851}
852
853static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000854Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000855 PyObject *self;
856 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000857{
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000859}
860
Barry Warsawfa701a81997-01-16 00:15:11 +0000861
862
Guido van Rossum18468821994-06-20 07:49:28 +0000863static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000864GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000865 PyObject *self;
866 PyObject *args;
867 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000868{
Guido van Rossum35d43371997-08-02 00:09:09 +0000869 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000870 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum35d43371997-08-02 00:09:09 +0000872 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
873 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000874 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000875 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000876 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000877
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000879 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000880 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000881
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000883 res = Tkinter_Error(self);
884 else
885 res = PyString_FromString(s);
886 LEAVE_OVERLAP_TCL
887 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000888}
889
890static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000891Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000892 PyObject *self;
893 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000894{
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000896}
897
898static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000899Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000900 PyObject *self;
901 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000902{
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000904}
905
Barry Warsawfa701a81997-01-16 00:15:11 +0000906
907
Guido van Rossum18468821994-06-20 07:49:28 +0000908static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000909UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 PyObject *self;
911 PyObject *args;
912 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000913{
Guido van Rossum35d43371997-08-02 00:09:09 +0000914 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000915 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000917
Guido van Rossum35d43371997-08-02 00:09:09 +0000918 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000919 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000920 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000921 if (name2 == NULL)
922 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
923
924 else
925 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000926 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000929 res = Tkinter_Error(self);
930 else {
931 Py_INCREF(Py_None);
932 res = Py_None;
933 }
934 LEAVE_OVERLAP_TCL
935 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000936}
937
938static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000939Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 PyObject *self;
941 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000942{
Barry Warsawfa701a81997-01-16 00:15:11 +0000943 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000944}
945
946static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000947Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 PyObject *self;
949 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000950{
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000952}
953
Barry Warsawfa701a81997-01-16 00:15:11 +0000954
955
Guido van Rossum18468821994-06-20 07:49:28 +0000956/** Tcl to Python **/
957
958static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000959Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000960 PyObject *self;
961 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000962{
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 char *s;
964 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000965
Guido van Rossum35d43371997-08-02 00:09:09 +0000966 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000968 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000969 return Tkinter_Error(self);
970 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000971}
972
973static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000974Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000975 PyObject *self;
976 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000977{
Barry Warsawfa701a81997-01-16 00:15:11 +0000978 char *s;
979 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000980
Guido van Rossum35d43371997-08-02 00:09:09 +0000981 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000982 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000983 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 return Tkinter_Error(self);
985 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000986}
987
988static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000989Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 PyObject *self;
991 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000992{
Barry Warsawfa701a81997-01-16 00:15:11 +0000993 char *s;
994 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000995
Guido van Rossum35d43371997-08-02 00:09:09 +0000996 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000998 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
999 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001000 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001001}
1002
1003static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001004Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001005 PyObject *self;
1006 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001007{
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001009 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001010 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001011
Guido van Rossum35d43371997-08-02 00:09:09 +00001012 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001014 ENTER_TCL
1015 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001016 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001017 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001018 res = Tkinter_Error(self);
1019 else
1020 res = Py_BuildValue("s", Tkapp_Result(self));
1021 LEAVE_OVERLAP_TCL
1022 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001023}
1024
1025static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001026Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 PyObject *self;
1028 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001029{
Barry Warsawfa701a81997-01-16 00:15:11 +00001030 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001031 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001032 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001033 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001034
Guido van Rossum35d43371997-08-02 00:09:09 +00001035 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001037 ENTER_TCL
1038 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001039 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001040 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001041 res = Tkinter_Error(self);
1042 else
1043 res = Py_BuildValue("l", v);
1044 LEAVE_OVERLAP_TCL
1045 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001046}
1047
1048static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001049Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 PyObject *self;
1051 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001052{
Barry Warsawfa701a81997-01-16 00:15:11 +00001053 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001054 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001056 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001057
Guido van Rossum35d43371997-08-02 00:09:09 +00001058 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001060 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001061 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001062 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001063 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001064 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001065 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001066 res = Tkinter_Error(self);
1067 else
1068 res = Py_BuildValue("d", v);
1069 LEAVE_OVERLAP_TCL
1070 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001071}
1072
1073static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001074Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 PyObject *self;
1076 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001077{
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001079 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001080 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001082
Guido van Rossum35d43371997-08-02 00:09:09 +00001083 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001085 ENTER_TCL
1086 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001087 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001088 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001089 res = Tkinter_Error(self);
1090 else
1091 res = Py_BuildValue("i", v);
1092 LEAVE_OVERLAP_TCL
1093 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001094}
1095
Barry Warsawfa701a81997-01-16 00:15:11 +00001096
1097
Guido van Rossum18468821994-06-20 07:49:28 +00001098static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001099Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001100 PyObject *self;
1101 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001102{
Barry Warsawfa701a81997-01-16 00:15:11 +00001103 char *list;
1104 int argc;
1105 char **argv;
1106 PyObject *v;
1107 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001108
Guido van Rossum35d43371997-08-02 00:09:09 +00001109 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001111
Barry Warsawfa701a81997-01-16 00:15:11 +00001112 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1113 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001114
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 if (!(v = PyTuple_New(argc)))
1116 return NULL;
1117
1118 for (i = 0; i < argc; i++) {
1119 PyObject *s = PyString_FromString(argv[i]);
1120 if (!s || PyTuple_SetItem(v, i, s)) {
1121 Py_DECREF(v);
1122 v = NULL;
1123 goto finally;
1124 }
1125 }
Guido van Rossum18468821994-06-20 07:49:28 +00001126
Barry Warsawfa701a81997-01-16 00:15:11 +00001127 finally:
1128 ckfree(FREECAST argv);
1129 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001130}
1131
1132static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001133Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 PyObject *self;
1135 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001136{
Barry Warsawfa701a81997-01-16 00:15:11 +00001137 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001138
Guido van Rossum35d43371997-08-02 00:09:09 +00001139 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001140 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001141 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001142}
1143
1144static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001145Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001146 PyObject *self;
1147 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001148{
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 char *s = Merge(args);
1150 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001151
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 if (s) {
1153 res = PyString_FromString(s);
1154 ckfree(s);
1155 }
1156 else
1157 PyErr_SetString(Tkinter_TclError, "merge failed");
1158
1159 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001160}
1161
Barry Warsawfa701a81997-01-16 00:15:11 +00001162
1163
Guido van Rossum18468821994-06-20 07:49:28 +00001164/** Tcl Command **/
1165
Guido van Rossum00d93061998-05-28 23:06:38 +00001166/* Client data struct */
1167typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001168 PyObject *self;
1169 PyObject *func;
1170} PythonCmd_ClientData;
1171
1172static int
1173PythonCmd_Error(interp)
1174 Tcl_Interp *interp;
1175{
1176 errorInCmd = 1;
1177 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1178 LEAVE_PYTHON
1179 return TCL_ERROR;
1180}
1181
Guido van Rossum18468821994-06-20 07:49:28 +00001182/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 * function or method.
1184 */
Guido van Rossum18468821994-06-20 07:49:28 +00001185static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001186PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001187 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001188 Tcl_Interp *interp;
1189 int argc;
1190 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001191{
Guido van Rossum00d93061998-05-28 23:06:38 +00001192 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001193 PyObject *self, *func, *arg, *res, *tmp;
1194 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001195
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001196 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001197
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 /* TBD: no error checking here since we know, via the
1199 * Tkapp_CreateCommand() that the client data is a two-tuple
1200 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001201 self = data->self;
1202 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001203
Barry Warsawfa701a81997-01-16 00:15:11 +00001204 /* Create argument list (argv1, ..., argvN) */
1205 if (!(arg = PyTuple_New(argc - 1)))
1206 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001207
Barry Warsawfa701a81997-01-16 00:15:11 +00001208 for (i = 0; i < (argc - 1); i++) {
1209 PyObject *s = PyString_FromString(argv[i + 1]);
1210 if (!s || PyTuple_SetItem(arg, i, s)) {
1211 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001212 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001213 }
1214 }
1215 res = PyEval_CallObject(func, arg);
1216 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001217
Barry Warsawfa701a81997-01-16 00:15:11 +00001218 if (res == NULL)
1219 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001220
Barry Warsawfa701a81997-01-16 00:15:11 +00001221 if (!(tmp = PyList_New(0))) {
1222 Py_DECREF(res);
1223 return PythonCmd_Error(interp);
1224 }
1225
1226 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1227 Py_DECREF(res);
1228 Py_DECREF(tmp);
1229
Guido van Rossum00d93061998-05-28 23:06:38 +00001230 LEAVE_PYTHON
1231
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001233}
1234
1235static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001236PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001237 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001238{
Guido van Rossum00d93061998-05-28 23:06:38 +00001239 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1240
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001241 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001242 Py_XDECREF(data->self);
1243 Py_XDECREF(data->func);
1244 PyMem_DEL(data);
1245 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001246}
1247
Barry Warsawfa701a81997-01-16 00:15:11 +00001248
1249
Guido van Rossum18468821994-06-20 07:49:28 +00001250static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001251Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 PyObject *self;
1253 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001254{
Guido van Rossum00d93061998-05-28 23:06:38 +00001255 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001258 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001259
1260 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1261 return NULL;
1262 if (!PyCallable_Check(func)) {
1263 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001264 return NULL;
1265 }
Guido van Rossum18468821994-06-20 07:49:28 +00001266
Guido van Rossum00d93061998-05-28 23:06:38 +00001267 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 if (!data)
1269 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001270 Py_XINCREF(self);
1271 Py_XINCREF(func);
1272 data->self = self;
1273 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001274
Guido van Rossum00d93061998-05-28 23:06:38 +00001275 ENTER_TCL
1276 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1277 (ClientData)data, PythonCmdDelete);
1278 LEAVE_TCL
1279 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001280 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001281 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001282 return NULL;
1283 }
Guido van Rossum18468821994-06-20 07:49:28 +00001284
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 Py_INCREF(Py_None);
1286 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001287}
1288
Barry Warsawfa701a81997-01-16 00:15:11 +00001289
1290
Guido van Rossum18468821994-06-20 07:49:28 +00001291static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001292Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 PyObject *self;
1294 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001295{
Barry Warsawfa701a81997-01-16 00:15:11 +00001296 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001297 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001298
Guido van Rossum35d43371997-08-02 00:09:09 +00001299 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001301 ENTER_TCL
1302 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1303 LEAVE_TCL
1304 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001305 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1306 return NULL;
1307 }
1308 Py_INCREF(Py_None);
1309 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001310}
1311
Barry Warsawfa701a81997-01-16 00:15:11 +00001312
1313
Guido van Rossum00d93061998-05-28 23:06:38 +00001314#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001315/** File Handler **/
1316
Guido van Rossum00d93061998-05-28 23:06:38 +00001317typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 PyObject *func;
1319 PyObject *file;
1320 int id;
1321 struct _fhcdata *next;
1322} FileHandler_ClientData;
1323
1324static FileHandler_ClientData *HeadFHCD;
1325
1326static FileHandler_ClientData *
1327NewFHCD(func, file, id)
1328 PyObject *func;
1329 PyObject *file;
1330 int id;
1331{
1332 FileHandler_ClientData *p;
1333 p = PyMem_NEW(FileHandler_ClientData, 1);
1334 if (p != NULL) {
1335 Py_XINCREF(func);
1336 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001337 p->func = func;
1338 p->file = file;
1339 p->id = id;
1340 p->next = HeadFHCD;
1341 HeadFHCD = p;
1342 }
1343 return p;
1344}
1345
1346static void
1347DeleteFHCD(id)
1348 int id;
1349{
1350 FileHandler_ClientData *p, **pp;
1351
1352 pp = &HeadFHCD;
1353 while ((p = *pp) != NULL) {
1354 if (p->id == id) {
1355 *pp = p->next;
1356 Py_XDECREF(p->func);
1357 Py_XDECREF(p->file);
1358 PyMem_DEL(p);
1359 }
1360 else
1361 pp = &p->next;
1362 }
1363}
1364
Guido van Rossuma597dde1995-01-10 20:56:29 +00001365static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001366FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001367 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001369{
Guido van Rossum00d93061998-05-28 23:06:38 +00001370 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001371 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001372
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001373 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 func = data->func;
1375 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001376
Barry Warsawfa701a81997-01-16 00:15:11 +00001377 arg = Py_BuildValue("(Oi)", file, (long) mask);
1378 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001379 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001380
1381 if (res == NULL) {
1382 errorInCmd = 1;
1383 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1384 }
1385 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001386 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001387}
1388
1389static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001390GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001391 /* Either an int >= 0 or an object with a
1392 *.fileno() method that returns an int >= 0
1393 */
1394 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001395{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001396 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001397 int id;
1398 if (PyInt_Check(file)) {
1399 id = PyInt_AsLong(file);
1400 if (id < 0)
1401 PyErr_SetString(PyExc_ValueError, "invalid file id");
1402 return id;
1403 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001404 args = PyTuple_New(0);
1405 if (args == NULL)
1406 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001407
1408 meth = PyObject_GetAttrString(file, "fileno");
1409 if (meth == NULL) {
1410 Py_DECREF(args);
1411 return -1;
1412 }
1413
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001414 res = PyEval_CallObject(meth, args);
1415 Py_DECREF(args);
1416 Py_DECREF(meth);
1417 if (res == NULL)
1418 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001419
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001420 if (PyInt_Check(res))
1421 id = PyInt_AsLong(res);
1422 else
1423 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001424
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001425 if (id < 0)
1426 PyErr_SetString(PyExc_ValueError,
1427 "invalid fileno() return value");
1428 Py_DECREF(res);
1429 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001430}
1431
1432static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001433Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 PyObject *self;
1435 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001436{
Guido van Rossum00d93061998-05-28 23:06:38 +00001437 FileHandler_ClientData *data;
1438 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001440 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001441
Guido van Rossum35d43371997-08-02 00:09:09 +00001442 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001443 return NULL;
1444 id = GetFileNo(file);
1445 if (id < 0)
1446 return NULL;
1447 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001448 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001449 return NULL;
1450 }
1451
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 data = NewFHCD(func, file, id);
1453 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001454 return NULL;
1455
Guido van Rossum7bf15641998-05-22 18:28:17 +00001456 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001458 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001459 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001460 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001461 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001462 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001463}
1464
1465static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001466Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001467 PyObject *self;
1468 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001469{
Barry Warsawfa701a81997-01-16 00:15:11 +00001470 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001471 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001473 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001474
Guido van Rossum35d43371997-08-02 00:09:09 +00001475 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 return NULL;
1477 id = GetFileNo(file);
1478 if (id < 0)
1479 return NULL;
1480
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001482
Guido van Rossum7bf15641998-05-22 18:28:17 +00001483 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001486 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001487 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001488 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001490}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001491#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001492
Barry Warsawfa701a81997-01-16 00:15:11 +00001493
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001494/**** Tktt Object (timer token) ****/
1495
1496staticforward PyTypeObject Tktt_Type;
1497
Guido van Rossum00d93061998-05-28 23:06:38 +00001498typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001499 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001500 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001501 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001502} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001503
1504static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001505Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001506 PyObject *self;
1507 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001508{
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001510 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001511
Guido van Rossum35d43371997-08-02 00:09:09 +00001512 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001514 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001515 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001516 v->token = NULL;
1517 }
1518 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001520 Py_DECREF(func);
1521 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001522 }
1523 Py_INCREF(Py_None);
1524 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001525}
1526
1527static PyMethodDef Tktt_methods[] =
1528{
Guido van Rossum35d43371997-08-02 00:09:09 +00001529 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001531};
1532
1533static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001534Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001535 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001536{
Barry Warsawfa701a81997-01-16 00:15:11 +00001537 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001538
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 v = PyObject_NEW(TkttObject, &Tktt_Type);
1540 if (v == NULL)
1541 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001542
Guido van Rossum00d93061998-05-28 23:06:38 +00001543 Py_INCREF(func);
1544 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001545 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001546
1547 /* Extra reference, deleted when called or when handler is deleted */
1548 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001550}
1551
1552static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001553Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001554 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001555{
Guido van Rossum00d93061998-05-28 23:06:38 +00001556 TkttObject *v = (TkttObject *)self;
1557 PyObject *func = v->func;
1558
1559 Py_XDECREF(func);
1560
Guido van Rossum35d43371997-08-02 00:09:09 +00001561 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001562}
1563
Guido van Rossum597ac201998-05-12 14:36:19 +00001564static PyObject *
1565Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001566 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001567{
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001569 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001570
Guido van Rossum597ac201998-05-12 14:36:19 +00001571 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001573 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001574}
1575
1576static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001577Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 PyObject *self;
1579 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001580{
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001582}
1583
1584static PyTypeObject Tktt_Type =
1585{
Guido van Rossum35d43371997-08-02 00:09:09 +00001586 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 0, /*ob_size */
1588 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001589 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001590 0, /*tp_itemsize */
1591 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001592 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001593 Tktt_GetAttr, /*tp_getattr */
1594 0, /*tp_setattr */
1595 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001596 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 0, /*tp_as_number */
1598 0, /*tp_as_sequence */
1599 0, /*tp_as_mapping */
1600 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001601};
1602
Barry Warsawfa701a81997-01-16 00:15:11 +00001603
1604
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001605/** Timer Handler **/
1606
1607static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001608TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001609 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001610{
Guido van Rossum00d93061998-05-28 23:06:38 +00001611 TkttObject *v = (TkttObject *)clientData;
1612 PyObject *func = v->func;
1613 PyObject *res;
1614
1615 if (func == NULL)
1616 return;
1617
1618 v->func = NULL;
1619
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001620 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001621
1622 res = PyEval_CallObject(func, NULL);
1623 Py_DECREF(func);
1624 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001625
Barry Warsawfa701a81997-01-16 00:15:11 +00001626 if (res == NULL) {
1627 errorInCmd = 1;
1628 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1629 }
1630 else
1631 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001632
1633 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001634}
1635
1636static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001637Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001638 PyObject *self;
1639 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001640{
Barry Warsawfa701a81997-01-16 00:15:11 +00001641 int milliseconds;
1642 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001643 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001644
Guido van Rossum35d43371997-08-02 00:09:09 +00001645 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001646 return NULL;
1647 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001648 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 return NULL;
1650 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001651 v = Tktt_New(func);
1652 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1653 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001654
Guido van Rossum00d93061998-05-28 23:06:38 +00001655 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001656}
1657
Barry Warsawfa701a81997-01-16 00:15:11 +00001658
Guido van Rossum18468821994-06-20 07:49:28 +00001659/** Event Loop **/
1660
Guido van Rossum18468821994-06-20 07:49:28 +00001661static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001662Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001663 PyObject *self;
1664 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001665{
Barry Warsawfa701a81997-01-16 00:15:11 +00001666 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001667#ifdef WITH_THREAD
1668 PyThreadState *tstate = PyThreadState_Get();
1669#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001670
Barry Warsawfa701a81997-01-16 00:15:11 +00001671 if (!PyArg_ParseTuple(args, "|i", &threshold))
1672 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001673
Barry Warsawfa701a81997-01-16 00:15:11 +00001674 quitMainLoop = 0;
1675 while (Tk_GetNumMainWindows() > threshold &&
1676 !quitMainLoop &&
1677 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001678 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001679 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001680
1681#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001682 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001683 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001684 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001685 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001686 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001687 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001688 if (result == 0)
1689 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001691#else
1692 result = Tcl_DoOneEvent(0);
1693#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001694
Guido van Rossum35d43371997-08-02 00:09:09 +00001695 if (PyErr_CheckSignals() != 0)
1696 return NULL;
1697 if (result < 0)
1698 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001699 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001700 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001701
Barry Warsawfa701a81997-01-16 00:15:11 +00001702 if (errorInCmd) {
1703 errorInCmd = 0;
1704 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1705 excInCmd = valInCmd = trbInCmd = NULL;
1706 return NULL;
1707 }
1708 Py_INCREF(Py_None);
1709 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001710}
1711
1712static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001713Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001714 PyObject *self;
1715 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001716{
Guido van Rossum35d43371997-08-02 00:09:09 +00001717 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001719
Barry Warsawfa701a81997-01-16 00:15:11 +00001720 if (!PyArg_ParseTuple(args, "|i", &flags))
1721 return NULL;
1722
Guido van Rossum00d93061998-05-28 23:06:38 +00001723 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001724 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001725 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001726 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001727}
1728
1729static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001730Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001731 PyObject *self;
1732 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001733{
1734
Guido van Rossum35d43371997-08-02 00:09:09 +00001735 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001736 return NULL;
1737
1738 quitMainLoop = 1;
1739 Py_INCREF(Py_None);
1740 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001741}
1742
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001743static PyObject *
1744Tkapp_InterpAddr(self, args)
1745 PyObject *self;
1746 PyObject *args;
1747{
1748
1749 if (!PyArg_ParseTuple(args, ""))
1750 return NULL;
1751
1752 return PyInt_FromLong((long)Tkapp_Interp(self));
1753}
1754
Barry Warsawfa701a81997-01-16 00:15:11 +00001755
1756
Guido van Rossum18468821994-06-20 07:49:28 +00001757/**** Tkapp Method List ****/
1758
1759static PyMethodDef Tkapp_methods[] =
1760{
Guido van Rossum35d43371997-08-02 00:09:09 +00001761 {"call", Tkapp_Call, 0},
1762 {"globalcall", Tkapp_GlobalCall, 0},
1763 {"eval", Tkapp_Eval, 1},
1764 {"globaleval", Tkapp_GlobalEval, 1},
1765 {"evalfile", Tkapp_EvalFile, 1},
1766 {"record", Tkapp_Record, 1},
1767 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1768 {"setvar", Tkapp_SetVar, 1},
1769 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1770 {"getvar", Tkapp_GetVar, 1},
1771 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1772 {"unsetvar", Tkapp_UnsetVar, 1},
1773 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1774 {"getint", Tkapp_GetInt, 1},
1775 {"getdouble", Tkapp_GetDouble, 1},
1776 {"getboolean", Tkapp_GetBoolean, 1},
1777 {"exprstring", Tkapp_ExprString, 1},
1778 {"exprlong", Tkapp_ExprLong, 1},
1779 {"exprdouble", Tkapp_ExprDouble, 1},
1780 {"exprboolean", Tkapp_ExprBoolean, 1},
1781 {"splitlist", Tkapp_SplitList, 1},
1782 {"split", Tkapp_Split, 1},
1783 {"merge", Tkapp_Merge, 0},
1784 {"createcommand", Tkapp_CreateCommand, 1},
1785 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001786#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001787 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1788 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001789#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001790 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001791 {"mainloop", Tkapp_MainLoop, 1},
1792 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001793 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001794 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001795 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001796};
1797
Barry Warsawfa701a81997-01-16 00:15:11 +00001798
1799
Guido van Rossum18468821994-06-20 07:49:28 +00001800/**** Tkapp Type Methods ****/
1801
1802static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001803Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001804 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001805{
Guido van Rossum00d93061998-05-28 23:06:38 +00001806 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001807 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001808 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001809 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001810 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001811}
1812
1813static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001814Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001815 PyObject *self;
1816 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001817{
Guido van Rossum35d43371997-08-02 00:09:09 +00001818 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001819}
1820
1821static PyTypeObject Tkapp_Type =
1822{
Guido van Rossum35d43371997-08-02 00:09:09 +00001823 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001824 0, /*ob_size */
1825 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001826 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001827 0, /*tp_itemsize */
1828 Tkapp_Dealloc, /*tp_dealloc */
1829 0, /*tp_print */
1830 Tkapp_GetAttr, /*tp_getattr */
1831 0, /*tp_setattr */
1832 0, /*tp_compare */
1833 0, /*tp_repr */
1834 0, /*tp_as_number */
1835 0, /*tp_as_sequence */
1836 0, /*tp_as_mapping */
1837 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001838};
1839
Barry Warsawfa701a81997-01-16 00:15:11 +00001840
1841
Guido van Rossum18468821994-06-20 07:49:28 +00001842/**** Tkinter Module ****/
1843
1844static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001845Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001846 PyObject *self;
1847 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001848{
Barry Warsawfa701a81997-01-16 00:15:11 +00001849 char *screenName = NULL;
1850 char *baseName = NULL;
1851 char *className = NULL;
1852 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001853
Guido van Rossum35d43371997-08-02 00:09:09 +00001854 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001855 if (baseName != NULL)
1856 baseName++;
1857 else
1858 baseName = Py_GetProgramName();
1859 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001860
Barry Warsawfa701a81997-01-16 00:15:11 +00001861 if (!PyArg_ParseTuple(args, "|zssi",
1862 &screenName, &baseName, &className,
1863 &interactive))
1864 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001865
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 return (PyObject *) Tkapp_New(screenName, baseName, className,
1867 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001868}
1869
1870static PyMethodDef moduleMethods[] =
1871{
Barry Warsawfa701a81997-01-16 00:15:11 +00001872 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001873#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001874 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1875 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001876#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001877 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001878 {"mainloop", Tkapp_MainLoop, 1},
1879 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001880 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001881 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001882};
1883
Guido van Rossum7bf15641998-05-22 18:28:17 +00001884#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001885
1886static int stdin_ready = 0;
1887
Guido van Rossumad4db171998-06-13 13:56:28 +00001888#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001889static void
1890MyFileProc(clientData, mask)
1891 void *clientData;
1892 int mask;
1893{
1894 stdin_ready = 1;
1895}
Guido van Rossumad4db171998-06-13 13:56:28 +00001896#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001897
Guido van Rossum00d93061998-05-28 23:06:38 +00001898static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001899
Guido van Rossum18468821994-06-20 07:49:28 +00001900static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001901EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001902{
Guido van Rossumad4db171998-06-13 13:56:28 +00001903#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001904 FHANDLE tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001905#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001906#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001907 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001908#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001909 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001910 errorInCmd = 0;
1911#ifndef MS_WINDOWS
1912 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001913 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001914#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001915 while (!errorInCmd && !stdin_ready) {
1916 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001917#ifdef MS_WINDOWS
1918 if (_kbhit()) {
1919 stdin_ready = 1;
1920 break;
1921 }
1922#endif
1923#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001924 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001925 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001926 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001927
Guido van Rossum00d93061998-05-28 23:06:38 +00001928 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001929
1930 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001931 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001932 if (result == 0)
1933 Sleep(20);
1934 Py_END_ALLOW_THREADS
1935#else
1936 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001937#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001938
1939 if (result < 0)
1940 break;
1941 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001942#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001943 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001944#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001945 if (errorInCmd) {
1946 errorInCmd = 0;
1947 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1948 excInCmd = valInCmd = trbInCmd = NULL;
1949 PyErr_Print();
1950 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001951#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001952 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001953#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001955}
Guido van Rossum18468821994-06-20 07:49:28 +00001956
Guido van Rossum00d93061998-05-28 23:06:38 +00001957#endif
1958
Guido van Rossum7bf15641998-05-22 18:28:17 +00001959static void
1960EnableEventHook()
1961{
Guido van Rossum00d93061998-05-28 23:06:38 +00001962#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001963 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001964#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001965 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001966#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001967 PyOS_InputHook = EventHook;
1968 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001969#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001970}
1971
1972static void
1973DisableEventHook()
1974{
Guido van Rossum00d93061998-05-28 23:06:38 +00001975#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001976 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1977 PyOS_InputHook = NULL;
1978 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001979#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001980}
1981
Barry Warsawfa701a81997-01-16 00:15:11 +00001982
1983/* all errors will be checked in one fell swoop in init_tkinter() */
1984static void
1985ins_long(d, name, val)
1986 PyObject *d;
1987 char *name;
1988 long val;
1989{
1990 PyObject *v = PyInt_FromLong(val);
1991 if (v) {
1992 PyDict_SetItemString(d, name, v);
1993 Py_DECREF(v);
1994 }
1995}
1996static void
1997ins_string(d, name, val)
1998 PyObject *d;
1999 char *name;
2000 char *val;
2001{
2002 PyObject *v = PyString_FromString(val);
2003 if (v) {
2004 PyDict_SetItemString(d, name, v);
2005 Py_DECREF(v);
2006 }
2007}
2008
2009
Guido van Rossum3886bb61998-12-04 18:50:17 +00002010DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002011init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002012{
Barry Warsawfa701a81997-01-16 00:15:11 +00002013 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002014
Barry Warsawfa701a81997-01-16 00:15:11 +00002015 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002016
2017#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002018 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002019#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002020
Barry Warsawfa701a81997-01-16 00:15:11 +00002021 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002022
Barry Warsawfa701a81997-01-16 00:15:11 +00002023 d = PyModule_GetDict(m);
2024 Tkinter_TclError = Py_BuildValue("s", "TclError");
2025 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002026
Guido van Rossum35d43371997-08-02 00:09:09 +00002027 ins_long(d, "READABLE", TCL_READABLE);
2028 ins_long(d, "WRITABLE", TCL_WRITABLE);
2029 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2030 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2031 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2032 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2033 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2034 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2035 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002036 ins_string(d, "TK_VERSION", TK_VERSION);
2037 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002038
Guido van Rossum83551bf1997-09-13 00:44:23 +00002039 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002040
2041 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002042 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2043
Barry Warsawfa701a81997-01-16 00:15:11 +00002044 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002045 return;
2046
Guido van Rossum43ff8681998-07-14 18:02:13 +00002047#if 0
2048 /* This was not a good idea; through <Destroy> bindings,
2049 Tcl_Finalize() may invoke Python code but at that point the
2050 interpreter and thread state have already been destroyed! */
Guido van Rossum26216371998-04-20 18:47:52 +00002051#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002052 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002053#endif
Guido van Rossum43ff8681998-07-14 18:02:13 +00002054#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002055
Jack Jansen34cc5c31995-10-31 16:15:12 +00002056#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002057 /*
2058 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2059 ** Most of the initializations in that routine (toolbox init calls and
2060 ** such) have already been done for us, so we only need these.
2061 */
2062#if TKMAJORMINOR >= 8000
2063 tcl_macQdPtr = &qd;
2064#endif
2065
2066 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002067#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002068 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002069#endif /* GENERATINGCFM */
2070#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002071}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002072
Guido van Rossumec22c921996-02-25 04:50:29 +00002073
Barry Warsawfa701a81997-01-16 00:15:11 +00002074
Guido van Rossum9722ad81995-09-22 23:49:28 +00002075#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002076
2077/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002078** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002079*/
2080
Guido van Rossum9722ad81995-09-22 23:49:28 +00002081void
2082panic(char * format, ...)
2083{
Barry Warsawfa701a81997-01-16 00:15:11 +00002084 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002085
Barry Warsawfa701a81997-01-16 00:15:11 +00002086 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002087
Guido van Rossum227cf761998-08-05 13:53:32 +00002088 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002089 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002090
Barry Warsawfa701a81997-01-16 00:15:11 +00002091 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002092
Barry Warsawfa701a81997-01-16 00:15:11 +00002093 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002094}
Jack Jansen40b546d1995-11-14 10:34:45 +00002095
Guido van Rossumec22c921996-02-25 04:50:29 +00002096/*
2097** Pass events to SIOUX before passing them to Tk.
2098*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002099
Guido van Rossumec22c921996-02-25 04:50:29 +00002100static int
2101PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002102 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002103{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002104 WindowPtr frontwin;
2105 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002106 ** Sioux eats too many events, so we don't pass it everything. We
2107 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002108 ** the Sioux window is frontmost. This means that Tk menus don't work
2109 ** in that case, but at least we can scroll the sioux window.
2110 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2111 ** part of the external interface of Sioux...
2112 */
2113 frontwin = FrontWindow();
2114 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2115 if (SIOUXHandleOneEvent(eventPtr))
2116 return 0; /* Nothing happened to the Tcl event queue */
2117 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002118 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002119}
2120
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002121#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002122/*
2123 * For Python we have to override this routine (from TclMacNotify),
2124 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2125 * to use GUSI select to see whether our socket is ready. Note that
2126 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2127 * files and sockets.
2128 *
2129 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2130 * for other versions. */
2131
2132int
2133Tcl_FileReady(file, mask)
2134 Tcl_File file; /* File handle for a stream. */
2135 int mask; /* OR'ed combination of TCL_READABLE,
2136 * TCL_WRITABLE, and TCL_EXCEPTION:
2137 * indicates conditions caller cares about. */
2138{
2139 int type;
2140 int fd;
2141
2142 fd = (int) Tcl_GetFileInfo(file, &type);
2143
2144 if (type == TCL_MAC_SOCKET) {
2145 return TclMacSocketReady(file, mask);
2146 } else if (type == TCL_MAC_FILE) {
2147 /*
2148 * Under the Macintosh, files are always ready, so we just
2149 * return the mask that was passed in.
2150 */
2151
2152 return mask;
2153 } else if (type == TCL_UNIX_FD) {
2154 fd_set readset, writeset, excset;
2155 struct timeval tv;
2156
2157 FD_ZERO(&readset);
2158 FD_ZERO(&writeset);
2159 FD_ZERO(&excset);
2160
2161 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2162 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2163 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2164
2165 tv.tv_sec = tv.tv_usec = 0;
2166 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2167 return 0;
2168
2169 mask = 0;
2170 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2171 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2172 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2173
2174 return mask;
2175 }
2176
2177 return 0;
2178}
2179#endif /* USE_GUSI */
2180
Guido van Rossumec22c921996-02-25 04:50:29 +00002181#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002182
2183/*
2184** Additional Mac specific code for dealing with shared libraries.
2185*/
2186
2187#include <Resources.h>
2188#include <CodeFragments.h>
2189
2190static int loaded_from_shlib = 0;
2191static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002192
Jack Jansen34cc5c31995-10-31 16:15:12 +00002193/*
2194** If this module is dynamically loaded the following routine should
2195** be the init routine. It takes care of adding the shared library to
2196** the resource-file chain, so that the tk routines can find their
2197** resources.
2198*/
2199OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002200init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002201{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002202 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002203 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002204 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002205 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2206 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002207 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002208 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2209 loaded_from_shlib = 1;
2210 }
2211 return noErr;
2212}
2213
2214/*
2215** Insert the library resources into the search path. Put them after
2216** the resources from the application. Again, we ignore errors.
2217*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002218static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002219mac_addlibresources()
2220{
2221 if ( !loaded_from_shlib )
2222 return;
2223 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2224}
2225
Guido van Rossumec22c921996-02-25 04:50:29 +00002226#endif /* GENERATINGCFM */
2227#endif /* macintosh */